I have installed OpenEars in my project, and as I said it is working like a dream. Most of the time…
However, every now and then I get a weird and random moment when things just stop working. I have researched the error and turned on logging to try and find out what is happening and I believe the issue is called because I am alternating between Voice Recognition and AVPlayer/AVAudioPlayer Movies and Sound clips.
Each time I switch between the two I can see this error when logging is switched on….
– – – – – – – –
Audio route has changed for the following reason:
2013-05-31 23:05:09.665 Timmy Tickle Baby[980:707] There has been a change of category
2013-05-31 23:05:09.666 Timmy Tickle Baby[980:707] The previous audio route was SpeakerAndMicrophone
2013-05-31 23:05:09.668 Timmy Tickle Baby[980:707] This is not a case in which OpenEars performs a route change voluntarily. At the close of this function, the audio route is SpeakerAndMicrophone
2013-05-31 23:05:10.439 Timmy Tickle Baby[980:707] Audio route has changed for the following reason:
2013-05-31 23:05:10.440 Timmy Tickle Baby[980:707] There has been a change of category
2013-05-31 23:05:10.444 Timmy Tickle Baby[980:707] The previous audio route was Speaker
2013-05-31 23:05:10.445 Timmy Tickle Baby[980:707] This is not a case in which OpenEars performs a route change voluntarily. At the close of this function, the audio route is SpeakerAndMicrophone
– – – – – – – –
…and sometimes I get the following as well, though not as often…
– – – – – – – –
2013-05-31 23:05:09.440 Timmy Tickle Baby[980:3c9b] 23:05:09.440 <0x2bfc000> shm_open failed: “AppleAURemoteIO.o.24024” (23) flags=0x2 errno=2
2013-05-31 23:05:09.442 Timmy Tickle Baby[980:3c9b] 23:05:09.442 <0x2bfc000> AURemoteIO::ChangeHardwareFormats: error 2
– – – – – – – –
I Googled these errors and found them both to be to do with the Audio Hardware. I found a thread on your support website in which someone describes the problems I am having.
/forums/topic/cant-recognize-speech/
In this thread in Jan 2011 you state that you have updated Open Ears to support the re-instigation of the audio session, which is why I assume this problem doesn’t happen that often.
I also found this thread interesting…
/forums/topic/speech-not-always-detected/
Particularly your comment here : I don’t really want to give advice here regarding forcing the audio session to reset because in 99% of cases the issue is not due to the audio session and folks will read the steps here and do stuff to the audio session directly and end up with messed-up apps that are very confusing for me to troubleshoot. That said, in this one case it might be worth your while to go investigate how the shared audio session manager is started by the internal classes and give it a go.
Essentially what I am doing in the app is the following –
Starting OpenEars
Pausing recognition
Playing an AVPlayer M4V
…when finished
Playing an AVAudioPlayer MP3
…when finished
Resuming recognition
Recognising something
Pausing recognition
Playing an AVPlayer M4V OR AVAudioPlayer MP3
…when finished back to Resuming recognition
This happens in a loop continuously. The video has always finished before the recognition starts and the recognition has always finished before the video plays.
Could I be one of the few who needs to force restart the OpenEars AudioSession – and if so how do I do it?
Thanks Halle!
]]>[[AudioSessionManager sharedAudioSessionManager] startAudioSession];
[self.pocketsphinxController resumeRecognition];
I have also found that after you suspend the recognition you need to delay a little before you re-configure the audio session to how you want it, otherwise pocket sphinx can crash. You will also need to give a little time for the audio session to be re-configured before you play your mp3/movie otherwise I’ve found the first part of the audio can be cut off.
Example code:
[self.pocketsphinxController suspendRecognition];
[self performSelector:@selector(reconfigureAudioForPlayingMovie) withObject:nil afterDelay: 1.0];
[self performSelector:@selector(playMovie) withObject:nil afterDelay: 2.0];
This works for me. Hope it helps!
Josh
]]>Does Josh’s suggestion work for you? Of the two issues you are showing, the first one in which the audio session is reset is 100% correct behavior — it means that PocketsphinxController detected that AVPlayer overrode the audio session settings and didn’t return them to their previous state at the right point in the loop, so it is doing so before it tries to start input recording. There’s no problem there. This one is the only problem:
<0x2bfc000> AURemoteIO::ChangeHardwareFormats: error 2
That means that at some point the switch back to the audio settings required by Pocketsphinx isn’t successfully instantiating the audio unit so no further audio input is going to be available. Josh’s advice sounds good to me as a workaround for this issue, which is probably related to the close timing between restarting listening and the amount of things that have to be done with the audio session and audio unit in order to recover from AVPlayer’s override.
]]>That does seem to have done the trick. It slows things down a little, but that’s preferable to random crashing : )
Thanks for you help!
In case anyone else is wondering how to fix this. This is what I did…
First you add this to your header –
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
#import <OpenEars/AudioSessionManager.h>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Then you need to initialise the AVAudio session so you can manually reset it
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];
if (!success) {
NSLog(@”Audio Session Error”);
}
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
After suspending recognition in OpenEars with this –
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[self.pocketsphinxController suspendRecognition];
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
– manually reset the audio session on a delay with this call –
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[self performSelector:@selector(reconfigureAudioForPlayingMovie) withObject:nil afterDelay: 1.0];
}
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
– and this (this is the AVAudioSessionCategory I believe I need for playing an M4V in AVPlayer or an Mp3 in AVAudioPlayer ) –
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
-(void)reconfigureAudioForPlayingMovie {
NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryAmbient
error: &setCategoryError];
if (!success) {
NSLog(@”Audio Session Error”);
}
NSLog(@”Audio Session Reconfigured”);
}
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
And then give a little delay before playing your video/audio.
When you want to listen again you resume the Audio session and OpenEars
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
[[AudioSessionManager sharedAudioSessionManager] startAudioSession];
[self.pocketsphinxController resumeRecognition];
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
I’ve been testing this most of the day and playing around with how long the delays need to be.
I’ll post an update here if I figure anything else out.
Harriet
]]>