Xcode AVAudioPlayer isn't playing - ios

I have a ViewController : GLKViewController
with this code:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"background-music-aac" ofType:#"caf"];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithData:data error:nil];
audio.delegate = self;
audio.volume = 1.0;
audio.numberOfLoops = -1;
[audio prepareToPlay];
[audio play];
[self setupContext];
[self setupDisplay];
}
However... my graphical things working fine but the iOS simulator plays no music.
did I something wrong?

Assuming you are using ARC, the player is getting deallocated as soon your method returns to its caller. To quote from this answer:
ARC inserts a release call to the audio player, so it's deallocated right after leaving the method where it is created.
Try implementing the AVAudioPlayer as a property.
If your data is nil, the file was not properly added to the project. To add your file to the project, just drag and drop it and add it to your targets.
Also, AVAudioPlayer has a method, initWithContentsOfURL:, which you might want to use.

Related

Proper use of AVAudioPlayer

The application I'm building is essentially an instrument with ten buttons, each linked to a separate AVAudioPlayer. When I try and allocate and initialize memory for each AVAudioPlayer in the ViewDidLoad method, I get no errors however the responsiveness of each button lags and there is considerable lag time before the same button can be triggered/heard again. I've rectified this situation by implementing the code below, however I'm not convinced it's the proper way of handling memory, especially because I have 10 of these methods.
- (IBAction)note1:(id)sender {
url1 = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"note1" ofType:#"wav"]];
unit1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:nil];
[unit1 play];
}
One thing you can try,
Call prepareToPlay method of AVAudioPlayer before playing that file.
The problem with your current code is that you are creating new instance of AVAudioPlayer every time you call a -note1: You can try this improvement:
- (IBAction)note1:(id)sender {
if (!url1)
url1 = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"note1" ofType:#"wav"]];
if (!unit1)
unit1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:nil];
[unit1 play];
}
However best way is to initialise your AVAudioPlayers at one place, when your UIViewController is loaded:
- (void) initializePlayers {
url1 = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"note1" ofType:#"wav"]];
unit1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:nil];
}
- (void) viewDidLoad {
[self initializePlayers];
}
- (IBAction)note1:(id)sender {
[unit1 play];
}
Do any additional setup after loading the view, typically from a nib.
NSURL* url = [[NSBundle mainBundle] URLForResource:#"Rondo_Alla_Turka_Short" withExtension:#"aiff"];
NSAssert(url, #"URL is valid.");
NSError* error = nil;
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if(!self.player)
{
NSLog(#"Error creating player: %#", error);
}

Playing a sound in background

I have read some threads about this topic, and currently have this:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *soundFilePath = [NSString stringWithFormat:#"%#/testsoundsr.aiff",
[[NSBundle mainBundle] resourcePath]];
NSURL *soundFileURL = [NSURL fileURLWithPath: soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL
error:nil];
player.numberOfLoops = -1; //Infinite
[player play];
}
The sound is not played though, and I can only imagine that the problem is with the NSString definition which is used to reference the file
The file I'm trying to play is named 'testsoundsr.aiff' and I have dragged that into the project. Also I have added several frameworks to the project, including AudioToolBox.framework
---UPDATE---
I have now tried using an .mp3 file instead, but still getting no sound through.
Try player.delegate = self before [player play]

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

Cannot play audio in Xcode project

This code works in a test app, but not in the app in which I want the audio to play.
-(void) playTutorialAudio
{
_theAudioFile = [[NSBundle mainBundle] pathForResource:#"Welcome" ofType:#"mp3"];
NSLog(#"playTutorialAudio _theAudioFile %#",_theAudioFile);
NSURL *playTutorialURL = [NSURL fileURLWithPath:_theAudioFile ];
_audioPlayAlert = [[AVAudioPlayer alloc] initWithContentsOfURL:playTutorialURL error:NULL];
[_audioPlayAlert setDelegate:self];
[_audioPlayAlert prepareToPlay];
_audioPlayAlert.volume = 1.0;
[_audioPlayAlert play];
}
The code works with other audio files.
It will work, You need to change your implementation like this. Please notice your init method.
#property (nonatomic, retain) AVAudioPlayer *cellTapSound;
may be in viewDidLoad
cellTapSound = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:#"ting" withExtension:#"wav"] error:nil];
[cellTapSound prepareToPlay];
Now may be on click of some button, you can give a shot like this :
if (cellTapSound.isPlaying) [cellTapSound setCurrentTime:0.0];
[cellTapSound play];
hope that helps.

Pick songs from plist(NSArray) and play using AVAudioPlayer?

I'm student working on a coding exercise and I am stumped!
I have two instances of AVAudioPlayer in my app - I can load the songs into each player using a direct path no problem.
What I'd like to be able to do is play multiple songs held within an array on each player.
Is this possible? and if so how would I go about doing this?
In my plist I have the key set to "One.mp3" as a string and the value as the path to the file... (was guessing at that part).
Thanks for any insight.
- (void)viewDidLoad {
[super viewDidLoad];
//multiple song array
NSString *soundsPath = [[NSBundle mainBundle] pathForResource:#"soundslist"
ofType:#"plist"];
soundsList = [[NSArray alloc] initWithContentsOfFile:soundsPath];
NSString* filename = [soundsList objectAtIndex:0];
NSString *path = [[NSBundle mainBundle] pathForResource:filename
ofType:#"mp3"];
AVAudioPlayer * newAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]
error:NULL];
self.audioPlayer = newAudio; // automatically retain audio and dealloc old file if new file is loaded
[newAudio release]; // release the audio safely
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer setNumberOfLoops:0];
[audioPlayer play];
}
It sounds like you want to try to play multiple songs on a single player. This isn't possible as stated in the AVAudioPlayer Overview (4th bullet). It is possible to play multiple songs with multiple AVAudioPlayers. Something like this:
NSMutableArray *audioPlayers = [NSMutableArray arrayWithCapacity:[soundsList count]];
for (NSString *soundPath in soundsList) {
NSError *error = nil;
AVAudioPlayer *audioPlayer = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
[audioPlayers addObject:audioPlayer];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer setNumberOfLoops:0];
[audioPlayer play];
}
I would suggest that you hardcode the file path instead of reading it in with a plist. Once you get that working, then you can try reading it in with the plist. Something like this would work:
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:#"One" withExtension:#"mp3"];
AVAudioPlayer *soundPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:&error]
This way, you remove one level of indirection and one point of failure.

Resources