How to release the NSDATA from AVAudioPlayer? - ios

Here I used to play the songs using AVAudioPlayer Framework. Hopefully it's playing, but if I click on other songs from the Songslist I will check the condition :
if(player.isPlaying == YES)
{
[player stop];
// And also i need to release or remove the existing NSDATA from the Player. otherwise the player won't release the existing data. So the memory pressure occurring in my project.
}
self.audioPlayer = [self.audioPlayer initWithData:m_currentMusic.fileData error:&error];
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];

AVAudioPlayer#data is a read-only non-retained property. So, the data is not retained and you have no need to releease it (it's assigned as by default).
However, as I said, it's read-only so you can't set it if you wish to change tracks. You also shouldn't call init... on an already initialied object, as in your code:
self.audioPlayer=[self.audioPlayer initWithData:m_currentMusic.fileData error:&error];
I believe the intended action for what you want is to relesae your existing self.audioPlayer and re-create a new one, as follows:
// stop player as in your original code...
[self.audioPlayer release];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithData:m_currentMusic.fileData error:&error];
self.audioPlayer = newPlayer;
[self.audioPlayer setDelegate:self];
[newPlayer release];
Note that the release will cause your original track data to be reclaimed (as it's non-retained).
See also Core Audio Overview

Related

How to play audio with different speed?

For example, play a local audio file with double speed or half speed.
I've already checked several Github projects, but none of them supports that.
Any idea about how to make it will be appreciated.
player.rate = 2.0 // Whatever speed you want
Assuming you're using AVAudioPlayer. you can change speed by changing the rate.
detail doc: https://developer.apple.com/documentation/avfoundation/avaudioplayer#jumpTo_15
Now it is possible to change the speed of sound.
here is my sample code:
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:path] error:&err];
player.volume = 0.4f;
player.enableRate=YES;
[player prepareToPlay];
[player setNumberOfLoops:0];
player.rate=2.0f;
[player play];
you set "enableRate" to YES and you can change it.

How to Stop the Audio After Coming Back From that audio ViewController IOS7

Hi I'm playing the audio file in one view controller when i going the another view controller its still playing the audio how to pause the audio when we going back to another view controller.
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"audio" ofType:#"mp3" ];
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
[self.audioPlayer play];
Please tell where i have to put the pause code for the audio when I'm going for another view controller.
Thanks.
in your viewController dealloc method add code to stop your audioPlayer
- (void)dealloc {
if ([self.audioPlayer isPlaying])
[self.audioPlayer stop];
[super dealloc]; // call if you are not using ARC
}
You can also put the stop audio code in ViewWillDisappear method if you are going deeper into heirarchy

Play multiple sounds (one by one) with AVAudioPlayer

I am using AVAudioPlayer to make an MP3 player. I have multiple MP3 sounds and would like to play these sounds one by one. Following is the logic of my app:
///// For playing 1st sound
mp3Player = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:nil];
[mp3Player prepareToPlay];
[mp3Player play];
///// For playing 2nd sound
mp3Player = nil;
mp3Player = [[AVAudioPlayer alloc] initWithContentsOfURL:url2 error:nil];
[mp3Player prepareToPlay];
[mp3Player play];
///// For playing 3rd sound
mp3Player = nil;
mp3Player = [[AVAudioPlayer alloc] initWithContentsOfURL:url3 error:nil];
[mp3Player prepareToPlay];
[mp3Player play];
etc...
Just would like to know: I nil out the player and alloc AVAudioPlayer before playing the next sound. Is there any performance (speed) or memory (leak) concern in this logic? (I am using ARC). If so, is there any way to alloc AVAudioPlayer just ONE time, and to accept diffrent URLs pointing to those sounds? Thanks a lot in advance.
I think below link may help you:
How to play multiple audio files in sequence by loop in AVAudioPlayer?
In which audioPlayerDidFinishPlaying is used to play next song after one finishes.

AVAudioPlayer sound file location not changing / updating

*This is my first stackoverflow question so apologies if I am doing something wrong.
I am trying to create a simple sound board app. I'm having trouble getting my AVAudioPlayer on xCode 4.1 (iOS 6.1.2) to update where the sound file to play is located. I wanted to avoid having multiple audio players (audioPlayer2, audioPlayer3, etc) so I am trying to use the same audio player but instead, update where the sound file is located. I only want one sound playing at a time so multiple sounds is obviously not an issue. Here is my code:
- (IBAction)play {
if (audioPlayer.playing == NO) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/k.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
//I added the next two lines to allow me to play AVAudio with MPiPodPlayer (which I found on this site, too) simultaneously.
AVAudioSession *audiosession = [AVAudioSession sharedInstance];
[audiosession setCategory:AVAudioSessionCategoryAmbient error:nil];
[audioPlayer play];
[start setTitle:#"Stop" forState:UIControlStateNormal];
}
else
if (audioPlayer.playing == YES) {
[audioPlayer stop];
[start setTitle:#"Start" forState:UIControlStateNormal];
}
}
- (IBAction)play2 {
if (audioPlayer.playing == NO) {
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/chicken.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
AVAudioSession *audiosession = [AVAudioSession sharedInstance];
[audiosession setCategory:AVAudioSessionCategoryAmbient error:nil];
[audioPlayer play];
[start2 setTitle:#"Stop" forState:UIControlStateNormal];
clicked = 1;
clicked2 = 0;
} else
if (audioPlayer.playing == YES) {
[audioPlayer stop];
[start2 setTitle:#"Start" forState:UIControlStateNormal];
clicked = 0;
}
}
My IBActions are linked to UIButtons and the 'start's are UIButton references. Whenever I click on 'start' it plays 'k.mp3' fine, however if I then click on 'start2' AFTER it starts to play the 'k.mp3' file, and not the chicken file. Whichever button I click on first is what the url is set to. This is my first iPhone OS application project so I realize there are probably some embarrassing coding mistakes in there (feel free to correct me). I'd like an answer that would be applicable to multiple buttons, even for some 30 buttons so I do not have to copy and paste stop audio player 1, 2, and 3 for each button.
To summarize: I have multiple buttons that play one sound each, I would like no more than one sound playing at a time; when I click on a button it plays 1 sound and all other audio players stop. I would prefer having only one AVAudioPlayer instance for simplicity. Thanks in advance!
Check if application control goes into - (IBAction)play2
And if control goes in it and it is still not working then you might try [audioPlayer release] before
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
that might do the trick for you

AVAudioPlayer intermittently wont play sound

I have a music player app on ipad. I download m4a files from a server and save them to doc dir. I also use Core Data to save the playlist info. I have over 1000 songs and my table loads perfectly and plays perfectly. I can play the playlists thru with no problems. BUT... every once in a while one song does not play. NO SOUND! I can press the cell to play the song or goto the next song and everything works again. So this problem is random and intermittent. It's never the same song that gets stuck. I cant give you any debug statements, cus like I said, it's so random and intermittent that it's hard to duplicate. I'm wondering if it's an ARC problem. Please help, as this app is going to production very soon.
Relative code:
// setup music session
NSError *error = nil;
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &error];
[[AVAudioSession sharedInstance] setActive: YES error: &error];
NSLog(#"error AVAudioSession:%#", [error description]);
AVAudioPlayer *player = [[AVAudioPlayer alloc] init];
NSString *fullPath = fullPath = [self.docDirPath stringByAppendingPathComponent:filename];
NSURL *musicFileURL = [[NSURL alloc] initFileURLWithPath:fullPath];
// getting song from docDir
NSData *songData = [[NSData alloc] initWithContentsOfURL:musicFileURL];
player = [player initWithData:songData error:&error];
NSLog(#"error player reg:%#", [error description]);
//NSLog(#"playing %# at index:%d", musicFileURL, index);
self.appPlayer = player;
[self.appPlayer prepareToPlay];
[self.appPlayer setEnableRate: YES];
[self.appPlayer setDelegate: self];
[self.appPlayer play];
If you use ARC a good point to start to solve your problem is to watch the reference counting in Instruments. I had the problem as well. None of my files were playing. I've seen in Instruments that the AVAudioPlayer instance was released BEFORE the sound started to play. At least it looked like it was released. After i've stored the reference of AVAudioPlayer in the core data model the bug was fixed! In another project without ARC the same code did work without storing the reference.
or you can try to use strong instead of retain in the property declaration
#property(nonatomic, strong) AVAudioPlayer *player;

Resources