I initialize an AVAudioPlayer instance:
NSString* path = [[NSBundle mainBundle] pathForResource:#"foo" ofType:#"wav"];
AVAudioPlayer* player =[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil]; //Returned object not nil, indicating that the file has loaded successfully
BOOL b = [player prepareToPlay]; //returns TRUE
BOOL b2 = [player play];
//returns TRUE, goes immediately to the next line since asynchronous
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]; //wait 1 sec
printf("%10.4f\n",player.duration); //duration is 2s
printf("%10.4f\n",player.currentTime); //position remains 0
/* There is no sound output, player is also stuck since position==0 */
Does anyone know why the AVAudioPlayer is not responding? Is there something that I am overlooking while initializing, playing the audioplayer? Boilerplate code maybe?
I am running this on the iPhone simulator. Also, AudioServicesPlaySystemSound() works for the same file, which is puzzling, but this indicates that sound playback might work with AVAudioPlayer as well.
I have 2 quick suggestions:
Check to see if that path actually gives you data. Alloc a NSData object using [[NSData alloc] initWithContentsOfFile:path] and inspect it in the debugger to see if you're actually loading that wav file.
I wrote a sample project that uses AVAudioPlayer here: AVAudioPlayer Example. As the code is pretty much the same as yours, the only thing I can imagine is that there is a problem with your data.
Check those out and see if it gets you anywhere!
I have just had a similar problem. I am not sure if it is the same solution, but my application records audio through the iphone and then plays it back to the user.
I thought I was doing the correct thing by telling my audio session that it was going to record data, so I did the following:
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
Using this setting playback worked on the Simulator but not on the device.... the didFinishPlaying event never got raised.
I removed this line after realising I didn't need it an audio playback started working correctly. Now I just need to work out why it is so quiet :)
Paul
Related
I'm looking to play a sound on my iPhone (iOS 6.1) depending on pressed buttons.
After converting to aif, caf, wav and compressed formats, I could not get sound on the device. Sound volumes have been checked, device has been rebooted, no uppercase letters are included in filenames.
I read many topics about this problem and could not find a proper solution, which means my problem is either more complex or plain stupid - surely plain stupid.
Here is my code to play the sound:
// Plays sound of given filename
- (void) playSound:(NSString*)name {
SystemSoundID sound = [self createSoundID:name];
AudioServicesPlaySystemSound(sound);
NSLog(#"file played: %#",name);
}
// Creates a playable sound out of filename
-(SystemSoundID) createSoundID:(NSString*) name
{
NSString *path = [NSString stringWithFormat: #"%#/%#",
[[NSBundle mainBundle] resourcePath], name];
NSURL* filePath = [NSURL fileURLWithPath: path isDirectory: NO];
SystemSoundID soundID;
AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID);
return soundID;
}
If the sound works fine on simulator but not in real device that means you should turn on your device's Ringer and Alert Settings. you should also check the mute button, if its' on or not.
The problem was that the method calling playSound was not called with an NSTimer. It seems that for the sounds to play, they must be called by the main thread of the application (which seems legit...).
So I modified the app so that the main thread would call those sounds and voila, it worked on the device as well. The code above was correct.
NSString *path = [[NSBundle mainBundle] pathForResource:#"hit-pipe" ofType:#"wav"];
audioPlayer =[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil];
[self.audioPlayer setDelegate:self];
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
It takes time to load the sound for the first time.
It takes time to load because it is loading the file. There will always be a tiny bit of usually unnoticeable lag when you play an AVAudioPlayer, and more lag when you load the file. How much lag depends on the size and file format of your file. If it is a problem, try allocating and loading your AVAudioPlayer earlier or using a smaller sound file.
You could put the code to load when the app is loading (for example in init or viewDidLoad). Then call audioplayer play when you need to play it. I'm doing this for my app and I did not notice any delay. It plays instantly when I call it.
I am trying to create buttons that play single sound files and one button that stops all of the sounds that are currently playing. If the user clicks multiple buttons or the same button in a short amount of time, the app should be playing all of the sounds simultaneously. I have accomplished this without much difficulty using the System Sound Services of iOS. However, the System Sound Services play the sounds through the volume that the iPhone's ringer is set to. I am now trying to use the AVAudioPlayer so that users can play the sounds through the media volume. Here is the code that I am currently (yet unsuccessfully) using the play the sounds:
-(IBAction)playSound:(id)sender
{
AVAudioPlayer *audioPlayer;
NSString *soundFile = [[NSBundle mainBundle] pathForResource:#"Hello" ofType:#"wav"];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile] error:nil];
[audioPlayer prepareToPlay];
[audioPlayer play];
}
Whenever I run this code in the iPhone Simulator, it does not play the sound but does display a ton of output. When I run this on my iPhone, the sound simply does not play. After doing some research and testing, I found that the audioPlayer variable is being released by Automatic Reference Counting. Also, this code works when the audioPlayer variable is defined as an instance variable and a property in my interface file, but it does not allow me to play multiple sounds at once.
First thing's first: How can I play an infinite number of sounds at once using the AVAudioPlayer and sticking with Automatic Reference Counting? Also: When these sounds are playing, how can I implement a second IBAction method to stop playing all of them?
First off, put the declaration and alloc/init of audioplayer on the same line. Also, you can only play one sound per AVAudioPlayer BUT you can make as many as you want simultaneously. And then to stop all of the sounds, maybe use a NSMutableArray, add all of the players to it, and then iterate though and [audioplayer stop];
//Add this to the top of your file
NSMutableArray *soundsArray;
//Add this to viewDidLoad
soundsArray = [NSMutableArray new]
//Add this to your stop method
for (AVAudioPlayer *a in soundsArray) [a stop];
//Modified playSound method
-(IBAction)playSound:(id)sender {
NSString *soundFile = [[NSBundle mainBundle] pathForResource:#"Hello" ofType:#"wav"];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile] error:nil];
[soundsArray addObject:audioPlayer];
[audioPlayer prepareToPlay];
[audioPlayer play];
}
That should do what you need.
I am using the following code to play a audio in iOS using **AVAudioPlayer** class.
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"myAudio" ofType:#"mp3"];
NSURL *audioURL = [[NSURL alloc] initFileURLWithPath:audioPath];
NSError *error;
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
[audioPlayer play];
This is working fine in simulator. But, i am not getting the sound output when i run it on the device. The delegate methods ofAVAudioPlayerDelegate are also being called but there is no volume output. Where am i going wrong here.... Another important aspect i'v noticed here is that, i am getting a large message in my GDB while playing the audio file on simulator. But the same thing is not happening on device... Please refer the screenshot below for GDB messages while running on the simulator.
Check if your device is on loudspeaker mode or not..
to listen the sound through Loundspeaker use this -
// set audio to loudSpeaker mode for iphone
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
or you can increase the volume of your audio file using this -
Player.volume = 10.0;
Have you tried the .caf or .wav file? might possible that .mp3 is not working on iPhone. Also check the duration of your file not greater than 30 sec.
I was so so stupid.... My volume button was turned off. That was the reason.
Really sorry for wasting your time guys... My sincere apologies.
When I use my app (on the device), the actual volume works OK for a while, but after a few days it seems to get 'stuck' at a low level.
Adjusting the volume rocker has no effect - and it shows 'Ringer' text. I've noticed that other people's apps are similarly affected if they show the 'Ringer' text when adjusting the volume. But apps which don't show 'Ringer' text are not affected by this.
How would I remove the 'Ringer' text and get my app to respond properly to different volumes?
I found some code on Apple's forums which fixes it. You have to use the AVFoundation.framework and put a bit of code into your app delegate. And put an audio file called 'blank.aif' into your project. Basically, it's a hack which prepares a file to play, but then never plays it. This fools the system into thinking that sound is being played all the time, which allows the user to use the main volume control.
#import <AVFoundation/AVFoundation.h>
//...
-(void)applicationDidFinishLaunching:(UIApplication *)application {
//volume control hack
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"blanksound" ofType:#"aif"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *volumeHack = [[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil]retain];
[fileURL release];
[volumeHack prepareToPlay];
// other applicationDidFinishLaunching stuff
}