How to release the AVAudioPlayer in the below code - objective-c

I want to release the memory which I allocated for AVAudioPlayer, but when I tried to release it then the sound is not playing.It is potential memory leak, how can I get out of this.
here the below code is used when wrong selection is picked then I am playing the error sound, If I select multiple time wrong selection then It is allocated multiple times then how can I rid out of this.
else
{
NSString *soundName=#"Error.mp3";
NSError *error;
NSURL *urlString = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%s", [[NSBundle mainBundle] resourcePath],[soundName UTF8String]]];
AVAudioPlayer *worngAudioPlay = [[AVAudioPlayer alloc] initWithContentsOfURL:urlString error:&error];// here I also used to release using autorelease then not played sound
worngAudioPlay.delegate = self;
if (worngAudioPlay == nil)
{
}
else
{
[worngAudioPlay play];
}
// [worngAudioPlay release]; // Here I released then not played sound
}
Thank you,
Madan Mohan.

you can release in avaudio player delegate method named audioDidFinishPlaying. I don't know the name exactly. but you might get an idea what I am talking about

Make it a retained property of your class, and release it in the dealloc.
In your header file:
#property(retain)AVAudioPlayer *player;
In your implementation (.m) file:
#synthesize player;
In your code above:
else
{
NSString *soundName=#"Error.mp3";
NSError *error;
NSURL *urlString = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%s", [[NSBundle mainBundle] resourcePath],[soundName UTF8String]]];
AVAudioPlayer *worngAudioPlay = [[AVAudioPlayer alloc] initWithContentsOfURL:urlString error:&error];
if (worngAudioPlay != nil)
{
// this will cause the previous one to be released
[self setPlayer:worngAudioPlay];
[worngAudioPlay release];
worngAudioPlay.delegate = self;
[worngAudioPlay play];
}
}
In your dealloc:
-(void)dealloc {
[player release];
[super dealloc];
}

Related

Getting my AVAudio player to work

I'm trying to use AVAudioPlayer to play an mp3. Here is the code that I have:
- (void) playClip {
NSString *mp3File = [[NSBundle mainBundle] pathForResource:#"inFavor" ofType:#"mp3"];
AVAudioPlayer *avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3File] error:NULL];
[avPlayer play];
}
the name of the file that I'm referencing is "inFavor.mp3"
I'm a bit new to Objective-C so I'm not exactly sure why this isn't working. I'm using Xcode 5.
Make the AVAudioPlayer a property of the class so that it is not released when the function goes out of scope.
#property (strong, nonatomic) AVAudioPlayer* avPlayer;
Then initialize with
self.avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:mp3File] error:NULL];
try this code, you need to check the error. paste the log you are getting in error
NSError *error;
NSString *path = [[NSBundle mainBundle] pathForResource:#"inFavor"
ofType:#"mp3"];
AVAudioPlayer* avPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:&error];
if (error) {
NSLog(#"failed playing error: %#", error);
}else{
//avPlayer.delegate = self;
[avPlayer play];
}

How do I play audio when my ios app starts?

I have been following tutorials and looking at other posts but I can't seem to get audio to start playing automatically when my app starts.
I want the wav file to just keep playing in the background and looping. I do NOT want start and stop controls etc...
Below is the code I have in my ViewController.m file (is this the right place?) and I have added the AVFoundation.frameowrk and imported it to my .m file. Additionally I have added my wav file called AlienRoom to my supporting files. Any help would be awesome! I am new so please go step by step or make it real clear if you can. Thank you!!!
p.s. I haven't added the code to make it loop so any help there would be great too!
//play background sound upon opening app
-(void) awakeFromNib
{
NSString *path = [[NSBundle mainBundle] pathForResource: #"AlienRoom" ofType: #"wav"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[theAudio play];
}
Implement AVAudioPlayerDelegate in ViewController.h
#interface ViewController : UIViewController <AVAudioPlayerDelegate>
#property(nonatomic,strong)AVAudioPlayer *theAudio;
ViewController.m file
-(void)viewWillAppear:(BOOL)animated
{
NSString *path = [[NSBundle mainBundle] pathForResource: #"AlienRoom" ofType: #"wav"];
if(!self.theAudio)
self.theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
self.theAudio.delegate = self;
[self.theAudio play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)data successfully:(BOOL)flag{
[NSThread detachNewThreadSelector:#selector(playAudioAgain) toTarget:self withObject:nil];
}
- (void)playAudioAgain{
[self.theAudio play];
}
-(void)viewWillDisappear:(BOOL)animated
{
if(self.theAudio.isPlaying)
{
self.theAudio.delegate = nil;
[self.theAudio stop];
}
}

background music

(using AVFoundation.framework)
#import "AVFoundation/AVFoundation.h"
So I got a problem, I tried this code first in init method of my class (that is the one that is loaded first)
NSString* soundFilePath = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"];
NSURL* soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops=-1;
[player play];
But it didn't work, than I decided to do it in thread:
in init method:
[NSThread detachNewThreadSelector:#selector(playMusic) toTarget:self withObject:nil];
and method itself:
-(void) playMusic {
NSString* soundFilePath = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"];
NSURL* soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer* player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops=-1;
[player play];
}
it is declared in *.h file of course. It also didn't work.
I tried to debug, on line
}
of playMusic method the file is played for 2 or 3 seconds and then stops. It isn't played without debug. What is the problem?
The AVAudioPlayer will be deallocated immediately. You need to retain the player.
So make the AVAudioPlayer an instance variable of the class.

Prompting AVAudioPlayer to play based on a timer

I am trying to setup a stopwatch alarm that is enabled via UISwitch. I want the alarm to be triggered after an x amount of secs after the timer has started. I have an ivar int variable (timerCount) that holds the amount of secs that has passed and I want to play a sound based on that ivar. When the timer begins and I enable the switch I would hope that the player would fire at 10 secs, but that is not the case. I know the "if statement" is the culprit because when I remove it the AVPlayer will play the wav file when the switch is enabled. I just need another set of eyeballs to look at this and figure out what I missed.
Here is the code snippet:
- (IBAction)timerSound{
if (voiceSwitch.on){
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"horn"
ofType:#"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
if (timerCount == 10)
[self.player play];
}
else {
[self.player stop];
}
}
You are looking for playAt:.
Example based on yours –
- (IBAction)valueChanged:(id)sender {
UISwitch *aSwitch = (UISwitch*)sender;
if ( aSwitch.on ) {
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"horn"
ofType:#"wav"];
NSURL *fileURL = [NSURL fileURLWithPath:soundFilePath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
error:nil];
[audioPlayer playAtTime:(audioPlayer.deviceCurrentTime + 3)];
} else {
[audioPlayer stop];
}
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
[self.theSwitch setOn:NO animated:YES];
[player release];
}

Can I play loops using Audio Toolbox?

in my app i use AudioToolbox framework and i need to play a loop can i ?
this is the AVAudioplayer code that goes slowly with 2 touches simultaneously
- (AVAudioPlayer *)getNoteFromFilename:(NSString *)name andoftype:(NSString *)type{
NSString *soundPath = [[NSBundle mainBundle] pathForResource:name
ofType:type];
NSURL *fileURL = [NSURL fileURLWithPath:soundPath];
AVAudioPlayer *note = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL
error:nil] autorelease];
return note;
}
in the viewdidload
ViewDidLoad {
self.Note = [self getNoteFromFilename:#"Note" andoftype:#"wav"];
}
calling it by this in IBAction :
[Note prepareToPlay];
[Note play];
NB: i have retaind all the button and the AVAudioPlayer
Use AVAudioPlayer instead. There you can easily loop using the numberOfLoops property.