Xcode Exception Breakpoint Always Pauses On Property - ios

This has driven me nuts for a long time now. I am using Xcode 4.6 but this has been happening for several versions. When I turn on breakpoints and add the Exception Breakpoint, it always pauses on a line of code where I'm setting up an audio player. I set some up before and after the same way, but it only pauses on that one.
Here is the code I'm using:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
self.playedSongs = [NSMutableSet setWithCapacity:9];
[self loadSettingsFromFile];
NSURL *sfxPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Snap.aiff" ofType:nil]];
self.snapSfx = [[[AVAudioPlayer alloc]initWithContentsOfURL:sfxPath error:nil]autorelease];
self.snapSfx.volume = 1.f;
NSURL *fireworksPath;
if ([OriginalIPadChecker isNotiPadOriginal]) {
fireworksPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"FireworksSFX.mp3" ofType:nil]];
}
else{
fireworksPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"NoFireworksSFX.mp3" ofType:nil]];
}
self.fireWorksSfx = [[[AVAudioPlayer alloc]initWithContentsOfURL:fireworksPath error:nil]autorelease];
self.fireWorksSfx.volume = 1.f;
NSURL *poofPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Remove Poof.mp3" ofType:nil]];
//The line below is the one that it pauses on
self.removePoof = [[[AVAudioPlayer alloc]initWithContentsOfURL:poofPath error:nil]autorelease];
self.removePoof.volume = 1.f;
NSURL *newHighScorePath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"New High Score.mp3" ofType:nil]];
self.theNewHighScore = [[[AVAudioPlayer alloc]initWithContentsOfURL:newHighScorePath error:nil]autorelease];
self.theNewHighScore.volume = 1.f;
NSURL *badgeInTrophyPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Badge In Trophy.aiff" ofType:nil]];
self.badgeInTrophy = [[[AVAudioPlayer alloc]initWithContentsOfURL:badgeInTrophyPath error:nil]autorelease];
self.badgeInTrophy.volume = 1.f;
NSURL *dingPath = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:#"Ding.aif" ofType:nil]];
self.ding = [[[AVAudioPlayer alloc]initWithContentsOfURL:dingPath error:nil]autorelease];
self.ding.volume = 1.f;
The app doesn't crash and the sound plays fine, but the debugger always pauses on that one line—even if I move it somewhere else, it still pauses. I can continue the execution and it works just fine, but this really bugs me.
I don't get why it pauses. Any ideas?

As explained in the comment of Xcode stops on prepareToPlay, the reason for the breakpoint is that you were setting a generic breakpoint of type 'exception on All' which responds to a signal which is fired by the c++ library. It is better to use an "Objective-c" exception breakpoint, which will protect for such cases.

Try this and update the question on where it stops (if it stops):
AVAudioPlayer *foo;
NSError *error = nil;
assert(poofPath);
foo = [AVAudioPlayer alloc];
foo = [foo initWithContentsOfURL:poofPath error:&error];
assert(foo);
[self setRemovePoof:foo];
[foo release];
If the assert kicks in, that's probably an Apple issue. Unfortunately there are cases of Apple internal frameworks using try/catch, and they will trigger the breakpoint. Its not common but does happen.
If in the end that foo is not nil and the error is also nil, the best you can do is enter a bug report at bugreporter.apple.com (which would be great). Also, did you look at poofPath - is there any chance that the URL returns anything other than pristine audio?
My guess is that Apple tries to open and process the file, its gets an internal exception because there is something "odd" or abnormal about the file. Then the framework does additional work, and manages to read the file. So you get your sound but the exception too. Take some common type of mp3 and put that in your app bundle, and try to open it. See if it (and maybe a few other files) gives the same error. Or create a demo project with the sound and upload it (in the end you may need to submit the demo project to Apple in a bug report). These kinds of things should be bug reported.
EDIT: Unfortunately there are cases of Apple internal frameworks using try/catch, and they will trigger the breakpoint. Then, as mentioned earlier, some later code finally figures out how to decode the file and does.
The original poster has responded in a comment that this particular file was created with Audacity, and has heard that such files often have decode issues.

Related

Xcode pre-load many audio files into one AVAudioPLayer?

I managed to load an audio file onto a player and play it via the following method:
- (void) play:(NSString*)loop{
NSString* resourcePath = [[NSBundle mainBundle] pathForResource:loop
ofType:#"mp3"];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
[NSURL fileURLWithPath:resourcePath]];
player.delegate = self;
[player play];
player.numberOfLoops = 1;
player.currentTime = 0;
player.volume = 1.0;
}
}
(I removed a couple of lines in this post but the method itself works great)
The problem here is, that the sound only gets loaded when the method play() is being called which results in a little delay in between the button click that calls the method and the player actually playing it.
I have about 200 sounds in my app and one way would be to load each sound in its own AVAudioPLayer in the viewDidLoad, but I doubt that this is considered good code.
On Android, I am using the SoundPool for this concern and it works great but I don't think there is an equivalent for this on iOS.
I now managed to do it via AudioServicesPlaySystemSound()
I use a method that loads all the sounds in a giant array
- (void)prepSounds{
NSString *soundPath =
[[NSBundle mainBundle] pathForResource:#"bl3"
ofType:#"mp3"];
NSURL *soundPathURL = [NSURL fileURLWithPath:soundPath];
AudioServicesCreateSystemSoundID(
(__bridge CFURLRef)soundPathURL, &soundID[0]);
AudioServicesPlaySystemSound(soundID[0]);
}
where soundID[] is an array of SystemSoundID declared in the header.
Now, I can just easily fire the sound via AudioServicesPlaySystemSound(soundID[0]) where 0 relates to the first sound I loaded. The latency is close to 0 (I would guess 5ms)
However, this only works for sounds no longer than about 30 seconds.
If you need any assistance with that, just comment here, I'm glad to help.

iOS Streaming mp3

I've been searching for a good tutorial for playing and streaming audio finally I found this which seems to offer an offline audio playing.
in the YMCAudioPlayer class I've commented loading a resource and provided NSURL* generated by a direct link instead like so.
- (void)initPlayer:(NSString*) audioFile fileExtension:(NSString*)fileExtension
{
//NSURL *audioFileLocationURL = [[NSBundle mainBundle] URLForResource:audioFile withExtension:fileExtension];
NSURL *audioFileLocationURL = [NSURL URLWithString:#"http://188.95.64.47/AghaninaDownload/Content/per_singer/JFire/Audios/J-FirE_and_Omar_khalid_wlaKelmeh-sample.mp3"];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileLocationURL error:&error];
}
And I've ensured that it's a valid link, but seems not to play on emulator. what have I missed there?
EDIT
It generates the following error
Error Domain=NSOSStatusErrorDomain Code=-43 "The operation couldn’t be completed. (OSStatus error -43.)
Might be a stupid question, but did you make it play ?
[self.audioPlayer play];
Then I would try this, to ensure your settings are correct :
[self.audioPlayer prepareToPlay];
[self.audioPlayer setCurrentTime:0.0];
[self.audioPlayer setVolume:1.0];
[self.audioPlayer play];
You can also use the delegate of AVAudioPlayer to check if something happens when you play.
Else it might be an URL of format issue.
I think you cannot play audio on EMULATOR, you have to test it on device.
Here mentioned on apple developer guid -
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/iOS_Simulator_Guide/TestingontheiOSSimulator/TestingontheiOSSimulator.html#//apple_ref/doc/uid/TP40012848-CH4-SW1
I've found the answer in the accepted answer here
"I was able to fix the issue by loading the file first into an NSData element and then using that to initialize the AVAudioPlayer instead, like so:"
NSData *songFile = [[NSData alloc] initWithContentsOfURL:songCacheURL options:NSDataReadingMappedIfSafe error:&error1 ];
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:songFile error:&error2];

Audio wont play in objective c

I have the following code that used to work to play a sound in my project however after iv done some playing around over the past few weeks on other aspects of the project it dose not seem to play.
The audio file is in the main directory and works in preview.
Any ideas?
//playsound
AVAudioPlayer *showsound;
NSString *audiopath = [[NSBundle mainBundle] pathForResource:#"mouse1" ofType:#"wav"];
NSURL *audiourl = [NSURL fileURLWithPath:audiopath];
showsound = [[AVAudioPlayer alloc]initWithContentsOfURL:audiourl error:Nil];
[showsound play];
It's because after the line showsound play your method comes to an end and showsound (your AVAudioPlayer) is released. Hence there is nothing to do any playing any more. Solution: retain it! (For example, set an instance variable to hold on to it.)

AVAudioPlayer Stops Before End of File

I have a function that is almost working. A different audio file is played depending on what page you're on. The problem is, some of the audio files end abruptly. For example, while the audio file plays to the end on "case 1", on "case 2" it stops about 90% in.
- (void)playAudio
{
NSURL *audioURL;
[voiceAudio release];
switch (pageNumber)
{
case 1:
audioURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"file1" ofType:#"aac"]];
voiceAudio = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioURL error:nil];
[audioURL release];
voiceAudio.delegate = self;
[voiceAudio play];
break;
case 2:
audioURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:#"file2" ofType:#"aac"]];
voiceAudio = [[AVAudioPlayer alloc]
initWithContentsOfURL:audioURL error:nil];
[audioURL release];
voiceAudio.delegate = self;
[voiceAudio play];
break;
// And so on...
}
}
The AACs are a few minutes long. Maybe there's a better way to go about this? AVAudioPlayer can be a bit funky. Thanks!
Edit: AVAudioPlayer is a bit unpredictable with the 64kb mono AACs I made in Adobe Soundbooth, but seems to run fine after remuxing the files to M4A. I used MP4Box to convert them using the syntax: "mp4box -add source.aac:mpeg4 -sbr -ipod target.m4a" (credit)
Reencoding to a higher bitrate (128kb) seemed to fix some, but not all, of the files as well. I didn't thoroughly test this before I discovered remuxing.

AVAudioPlayer working fine in 5.0, issues in 4.0-4.3.5

I have an app which plays and controls music across different ViewControllers. To do this, I created two instances of AVAudioPLayer in the app delegate's DidFinishLaunchingMethod:
NSString *path = [[NSBundle mainBundle] pathForResource:#"minnie1" ofType:#"mp3"];
NSURL *path1 = [[NSURL alloc] initFileURLWithPath:path];
menuLoop =[[AVAudioPlayer alloc] initWithContentsOfURL:path1 error:NULL];
[menuLoop setDelegate:self];
menuLoop.numberOfLoops = -1;
[menuLoop play];
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"minnie2" ofType:#"mp3"];
NSURL *path3 = [[NSURL alloc] initFileURLWithPath:path2];
gameLoop=[[AVAudioPlayer alloc] initWithContentsOfURL:path3 error:NULL];
gameLoop.numberOfLoops = -1;
[gameLoop setDelegate:self];
[gameLoop prepareToPlay];
After this I call it in various viewControllers, to stop or restart using code like:
- (IBAction)playGameLoop{
NSLog(#"Begin playGameLoop");
FPAppDelegate *app = (FPAppDelegate *)[[UIApplication sharedApplication] delegate];
if ([FPAVManager audioEnabled] == NO){
//DO NOTHING
}
else {
if (app.gameLoop.playing ==YES ) {
//DO NOTHING
}
else { [app.gameLoop play];
NSLog(#"End playGameLoop");
}
}
The audio files play fine the first time and they stop when asked to stop. Though, on iOS4 devices, they won't start replaying when called again.
Thanks!
From the docs:
Calling this method [stop] or allowing a sound to finish playing,
undoes the setup performed upon calling the play or prepareToPlay
methods.
The stop method does not reset the value of the currentTime property
to 0. In other words, if you call stop during playback and then call
play, playback resumes at the point where it left off.
Where you are looping the sounds, I would expect to be able to call stop and then call play. But I have fuzzy recollection of running into this myself. I found that calling pause, rather than stop, was a better solution. Especially since I could then call play again to resume play. Calling stop always seemed to require calling prepareToPlay again before calling play, at least in my experience.
It's possible that there were some changes in the API implemetation between iOS4.x and iOS5, too. You should check the API diffs on the Developer web site to be sure.

Resources