1

I am running an audio file on button tap using AVAudioPlayer (in a calculator app). The issue that I am facing on iOS7 is that whenever the buttons are tapped really fast, the audio player's play method causes an internal error in AVAudioPlayer. Here is the code section

@try
{
    if(self.allAudioPlayers == nil)
    {
        [self initializePlayer];
    }

    AVAudioPlayer *player = [self grabPlayer];

    if(player != nil)
    {
        NSLog(@"Playing....");
        [player play];       //Crashing Here
    }
    else
    {
        NSLog(@"Player nil");
    }
}
@catch (NSException *exception)
{
    NSLog(@"playCalculatorTickSound Exception: %@", [exception description]);
    NSLog(@"Call Stack: %@", [exception callStackSymbols]);
}

Once I got this issue ResolveOpageRef and now I am getting this issue _platform_memmov$VARIANT$CortexA8.

enter image description here

Here is another image of the call stack (it is never the same and varies at some level) enter image description here

My exception handling code is not catching the exception since its an internal error. Is there anyway to catch this, so that the app doesn't get crashed?

I am using threads to call this method. I am not sure but may be multiple threads are trying to read the file at the same time and [player play] is handling the synchronization of the threads and failing to do so.

Thanks in advance

Kamran Khan
  • 1,367
  • 1
  • 15
  • 19
  • 1
    Have you tried investigating the cause for this error? Are you sure it is an exception at all, and not a SIGSEGV/SIGBUS? – Krumelur Dec 31 '13 at 11:02
  • Its an internal issue of the AVAudioPlayer. I have tested the same code in iOS-6 and its working fine when same procedure is applied to it. This only happens when tapping speed is too fast, and is only reproducible on iOS7. I am trying to figure out the exact cause. I will try adding few millisecond pause between the calls and lets c if it get resolved. – Kamran Khan Dec 31 '13 at 11:20
  • I have added another image of the call stack, may be this will help you understand the issue. – Kamran Khan Dec 31 '13 at 11:28
  • Just an idea: what if you stop any previously playing audio before playing the new sample? – Krumelur Dec 31 '13 at 12:08
  • That will not meet the requirements. The audio clip has a very short length, may be 1 sec (Tick Sound). I have added the [player play] call on the GCD main thread ( dispatch_async(dispatch_get_main_queue(), ^{ [player play]; }); ) and it seems to have solved the issue. But I will test it a little bit and will update on the result. – Kamran Khan Dec 31 '13 at 12:41
  • Now that you mention it: why is the `playCalculatorTickSound` method executed in a different thread when it comes from a UI event? – Krumelur Dec 31 '13 at 12:44
  • Actually it was done so that the main thread is not blocked. So, I added the call to a thread, it only plays the audio. I was checking the following link http://stackoverflow.com/questions/6199599/any-suggestions-on-how-to-handle-this-crash-in-cgimagedestinationfinalize and Damien (the author) was facing a similar issue but for a different set of problem. The code that I used was working perfect, and it only causes the crash if multiple taps are used at once and at a rapid speed. – Kamran Khan Dec 31 '13 at 12:50
  • You can try to debug this internal exception by adding a breakpoint for `All Exceptions`. Please refer to the screenshot to add the all exception breakpoint. ![enter image description here](http://i.stack.imgur.com/1SnK7.png) – san Dec 31 '13 at 10:54

1 Answers1

0

Thanks everyone for your comments. I think the issue is solved. Here is the updated code. It seems that threading was the main issue. The play method of the AVAudioPlayer was not doing very well with multiple threads at the same time. I don't know how it is internally working but i think it is managing some sort of queue (judging from the call stack). I executed it on main thread and its working fine now.

 @try
    {
        if(self.allAudioPlayers == nil)
        {
            [self initializePlayer];
        }

        AVAudioPlayer *player = [self grabPlayer];

        if(player != nil)
        {
            NSLog(@"Playing....");

            dispatch_async(dispatch_get_main_queue(), ^{

                [player play];
            });
        }
        else
        {
            NSLog(@"Player nil");
        }
    }
    @catch (NSException *exception)
    {
        NSLog(@"playCalculatorTickSound Exception: %@", [exception description]);
        NSLog(@"Call Stack: %@", [exception callStackSymbols]);
    }

Also, thanks to this Any suggestions on how to handle this crash in CGImageDestinationFinalize? I was able to divert my attention on threading issue.

Community
  • 1
  • 1
Kamran Khan
  • 1,367
  • 1
  • 15
  • 19