5

I have a speech-to-text function in my app, press & hold the button; a viewcontroller is animated from outside windowbounds into view and recording starts, release the button; recording stops and view is animated out of windowbounds.

Suddenly I'm getting some crashreports via Firebase Crashreporting that the function is crashing on some users (2 users / 5 instances, all the same incident).. Below is the code where my crashlog-events points me to.. BUT, I simply can't reproduce the error, I've tried maybe a 1000 times, stressloading (monkey-button-mashing it, etc.), it won't crash on my device..

Can anybody help me dissect the stacktrace in the bottom / advice? / have suggestions as to what is going wrong? what I can do to stabilize?

To my understanding it revolves around the installTapOnBus:0? Any suggestions for next step?

_audioEngine = [[AVAudioEngine alloc] init];
_speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:[NSLocale localeWithLocaleIdentifier:@"da"]];
[_speechRecognizer setDelegate:self];
_request = [[SFSpeechAudioBufferRecognitionRequest alloc] init];


AVAudioInputNode *node =[_audioEngine inputNode];
AVAudioFormat *recordingFormat = [node outputFormatForBus:0];


[node installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {

        [_request appendAudioPCMBuffer:buffer];

    }];
}

StackTrace:

1 CoreFoundation __exceptionPreprocess + 1232864

2 libobjc.A.dylib objc_exception_throw + 34100

3 CoreFoundation +[NSException raise:format:arguments:] + 1232560

4 AVFAudio AVAE_RaiseException(NSString*, ...) + 78280

5 AVFAudio AVAudioNodeImplBase::CreateRecordingTap(unsigned long, unsigned int, AVAudioFormat*, void (AVAudioPCMBuffer*, AVAudioTime*) block_pointer) + 554488

6 AVFAudio -[AVAudioNode installTapOnBus:bufferSize:format:block:] + 545144

7 shoppinglist 4295363296 + 297696

8 shoppinglist 4295358408 + 292808

9 UIKit -[UIViewController loadViewIfRequired] + 65212

10 UIKit -[UIViewController view] + 64152

11 shoppinglist 4295296168 + 230568

12 shoppinglist 4295272504 + 206904

13 shoppinglist 4295266368 + 200768

14 UIKit -[UIViewController _setViewAppearState:isAnimating:] + 162800

15 UIKit -[UIViewController __viewWillAppear:] + 162144

16 UIKit __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 3540196

17 UIKit _runAfterCACommitDeferredBlocks + 2738508

18 UIKit _cleanUpAfterCAFlushAndRunDeferredBlocks + 2681320

19 UIKit _afterCACommitHandler + 9796

20 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 895396

21 CoreFoundation __CFRunLoopDoObservers + 886316

22 CoreFoundation __CFRunLoopRun + 887416

23 CoreFoundation CFRunLoopRunSpecific + 36256

24 GraphicsServices GSEventRunModal + 49264

25 UIKit UIApplicationMain + 479316

26 shoppinglist 4295262124 + 196524

27 libdyld.dylib start + 17816
A O
  • 5,516
  • 3
  • 33
  • 68
  • do you have the exception for the crash as well? – A O Jun 08 '17 at 14:39
  • also can you paste the code for `-installTapOnBus:...`? – A O Jun 08 '17 at 14:41
  • The stacktrace listed is all I get from Firebase Crashreporting, it just says EXC_SOFTWARE / UNCAUGHT_NS_EXCEPTION ? -installTapOnBus:... is part of the AVAudioNode.h in the Framework: AVFoundation (not a function of mine) :-S – PeterAntonsen Jun 09 '17 at 07:53

1 Answers1

5

I also had the same crash but now it's fixed. So you need to check the rate of audio format:

AVAudioInputNode *node =[_audioEngine inputNode];
AVAudioFormat *recordingFormat = [node outputFormatForBus:0];

if (recordingFormat.sampleRate > 0)
{
    [node installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {

        [_request appendAudioPCMBuffer:buffer];

    }];
}
  • Thx for the suggestion! I'll accept this as the answer even though I have no real way of testing it :-S I've inserted the following code hoping that it will recover the node in a suitable state enabling the user to still record his voice.. `if (recordingFormat.sampleRate <= 0) { [self.audioEngine.inputNode reset]; recordingFormat = [[self.audioEngine inputNode] outputFormatForBus:0]; }` – PeterAntonsen Jul 19 '17 at 07:50
  • 1
    Try the following scenario for testing: call someone on skype or voice and keep the conversation open. After that open your app and try to record the voice. – Gales Vasile Jul 19 '17 at 14:53
  • The testing scenario and the fix have worked for me - thank you @GalesVasile. – jamix Nov 15 '19 at 10:46
  • Note I had to recreate the audio engine each time before attempting to install the tap, otherwise after the phone call ends the sample rate is still 0, or it's 48000 for example if you started recording prior to getting on the call and then recorded again in which case it still crashes. – Jordan H Mar 19 '23 at 02:00