HomeForumsOpenEars[Resolved] Keep system sounds while listening

This topic has 5 voices, contains 35 replies, and was last updated by  Halle 14 days ago.

Viewing 36 posts - 1 through 36 (of 36 total)
Author Posts
Author Posts
October 25, 2011 at 4:28 pm #7772

slowfoxtrot

I would like to keep my system sounds going (text alerts, calendar beeps, lock and unlock sounds) going while pocketsphinx is listening. How can I keep those sounds from being turned off while recording? I found this but don’t know how it would apply to OpenEars:

https://developer.apple.com/library/ios/#codinghowtos/AudioAndVideo/_index.html

Thanks for your help!

Brock Haymond

October 25, 2011 at 4:30 pm #7773

slowfoxtrot

Here is the full URL:
https://developer.apple.com/library/ios/codinghowtos/AudioAndVideo/_index.html#//apple_ref/doc/uid/TP40007426-CH1-DontLinkElementID_13

I can already play sound from my app while listening. What I want the built in system sounds.

October 25, 2011 at 5:06 pm #7774

Halle

Hi Brock,

What currently happens when a calendar alert pops up? Is it silent? I would check out this workaround and see if it helps:

http://www.politepix.com/forums/topic/simultaneous-mpmovieplayercontroller-video-and-speech-recognition/

October 25, 2011 at 5:23 pm #7775

slowfoxtrot

Yes, all my system sounds and alerts (including vibration) are muted while pocketsphinx is listening. Did I do something to make this happen in my project or is this by OpenEars design? I will look into that link and let you know if it makes any difference.

October 25, 2011 at 5:29 pm #7776

Halle

It isn’t by design but it isn’t something I’ve actively investigated either since I didn’t expect that OpenEars would be able to put a stop to system sounds :) . Actually, I know that it can ring when a call comes in since I’ve tested that quite a bit when proofing route changes; are you also not getting ringing? If you let me know the device and OS version I’ll check it out.

October 25, 2011 at 5:31 pm #7777

slowfoxtrot

Halle,

I actually already tried that fix yesterday. It allows for simultaneous playing of sound from within the app while recording, but system sounds are still muted. I can play my own beep fine but all system beeps/vibrations are muted. I would really like email notifications and text alerts to still beep/vibrate the phone while pocketsphinx is listening. Any other ideas?

Thanks for your quick response and help!
Brock

October 25, 2011 at 5:34 pm #7778

slowfoxtrot

Halle,

No, ringing works because it is stopping the audio session. Anything that stops the audio session gives the system back its sounds. But as soon as pocketsphinx starts back up all system alerts get muted. In this way the phone will always ring, but text messages will never beep/vibrate. I am testing on an iPhone 4 running 4.3.3.

October 25, 2011 at 5:39 pm #7779

Halle

OK, that’s interesting — I will try to check this out tomorrow and get back to you about it. I think it would be generally preferable for this to be configurable but I don’t know offhand how involved that will be before taking a look at it.

October 25, 2011 at 5:40 pm #7780

Halle

BTW, be aware that if system sounds are passed through the audio session while recognition is in session, they will trigger recognition.

October 25, 2011 at 5:40 pm #7781

slowfoxtrot

Ok, upon more testing it looks like it isn’t actually the audio session. I can start the audio session and maintain system sounds. It is when I call pocketsphinx to start listening that all system sounds are muted. Then as soon as I stop pocketsphinx they start back up again. All without interrupting the audio session. Hope this helps!

Brock

October 25, 2011 at 5:45 pm #7782

slowfoxtrot

Yes, I have considered that system beeps might trigger recognition but that is acceptable to me in my app design. System sounds outweigh false-positives in recognition.

October 25, 2011 at 6:13 pm #7783

Halle

It is when I call pocketsphinx to start listening that all system sounds are muted. Then as soon as I stop pocketsphinx they start back up again.

How strange that AVAudioPlayer plays back while PocketsphinxController is running but the system sounds don’t. I’ll be interested to see what’s up with this when I get a moment. Have you tried this with the sample app to confirm that it isn’t the result of a change you’ve made?

October 25, 2011 at 6:13 pm #7784

slowfoxtrot

Halle,

I don’t know if this is related, but it would appear in the ContinuousAudioUnit.mm that you set

AudioUnitSetProperty(audioDriver->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));

for the input but

AudioUnitSetProperty(audioDriver->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 1, &enableIO, sizeof(enableIO));

seems to be missing. Is this needed to enable output alongside the input? Could this be causing the issue? I am referring to the code found here:

http://atastypixel.com/blog/using-remoteio-audio-unit/

Hope this helps!

October 25, 2011 at 6:15 pm #7785

slowfoxtrot

Yes, all testing I am doing is on your default sample app.

Brock

October 25, 2011 at 6:42 pm #7786

Halle

Hmm, I wouldn’t expect that the system sounds would need an output from my audio unit (the audio unit itself definitely does not need one), but there’s absolutely no harm in trying it and there’s no basis for ruling it out. Let me know if it helps.

October 25, 2011 at 6:49 pm #7787

slowfoxtrot

Hmm…. interesting. As I have tried to include this code I find I cannot successfully enable output on the audio unit, while I can disable it:

(Trying to enable)
AudioUnitElement outputBus = 1;
OSStatus setEnableIOStatusOutput = AudioUnitSetProperty (
audioDriver->audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
outputBus,
&enableIO,
sizeof(enableIO)
);
if(setEnableIOStatusOutput != noErr) {
OpenEarsLog(@”Couldn’t enable IO output: %d”,setEnableIOStatusOutput);
audioDriver->unitIsRunning = 0;
return NULL;
}
else
OpenEarsLog(@”Enabled IO Output successfully: %d”,setEnableIOStatusOutput);

2011-10-25 11:42:37.797 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: Starting openAudioDevice on the device.
2011-10-25 11:42:37.798 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: Audio unit wrapper successfully created.
2011-10-25 11:42:37.802 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: Successfully got new audio unit component instance: 0
2011-10-25 11:42:37.803 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: Success 0: set maximum frames property.
2011-10-25 11:42:37.804 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: Enabled IO Input successfully: 0
2011-10-25 11:42:37.805 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: Couldn’t enable IO output: -10877
2011-10-25 11:42:37.806 OpenEarsSampleProject[1219:1607] OPENEARSLOGGING: openAudioDevice failed

(Trying to disable)
UInt32 disableIO = 0;
AudioUnitElement outputBus = 0;
OSStatus setEnableIOStatusOutput = AudioUnitSetProperty (
audioDriver->audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
outputBus,
&disableIO,
sizeof(disableIO)
);
if(setEnableIOStatusOutput != noErr) {
OpenEarsLog(@”Couldn’t disable IO output: %d”,setEnableIOStatusOutput);
audioDriver->unitIsRunning = 0;
return NULL;
}
else
OpenEarsLog(@”Disabled IO Output successfully: %d”,setEnableIOStatusOutput);

2011-10-25 11:47:32.099 OpenEarsSampleProject[1235:1607] OPENEARSLOGGING: Starting openAudioDevice on the device.
2011-10-25 11:47:32.103 OpenEarsSampleProject[1235:1607] OPENEARSLOGGING: Audio unit wrapper successfully created.
2011-10-25 11:47:32.106 OpenEarsSampleProject[1235:1607] OPENEARSLOGGING: Successfully got new audio unit component instance: 0
2011-10-25 11:47:32.109 OpenEarsSampleProject[1235:1607] OPENEARSLOGGING: Success 0: set maximum frames property.
2011-10-25 11:47:32.110 OpenEarsSampleProject[1235:1607] OPENEARSLOGGING: Enabled IO Input successfully: 0
2011-10-25 11:47:32.110 OpenEarsSampleProject[1235:1607] OPENEARSLOGGING: Disabled IO Output successfully: 0

So why can I not enable the audio output on the unit? Am I doing something wrong here?

Brock

October 25, 2011 at 7:01 pm #7788

slowfoxtrot

Never mind I got it. The output bus is 0 and the input bus is 1 to enable IO. Setting the bus properly allowed me to enable output on your audio unit. Unfortunately… still no system sounds once pocketsphinx starts listening. What’s next?

Brock

October 25, 2011 at 7:31 pm #7789

Halle

Next is I’ll take a look at it when I get some time. I wouldn’t really have expected it to be related to the audio unit since it should only have to do with what goes in and out of the audio unit’s buffer callback, which is just speech going in for analysis. Other outgoing audio in the app doesn’t route through the audio unit which is why it has no output.

October 25, 2011 at 8:42 pm #7790

slowfoxtrot

Awesome, thank you so much for your help Halle. Please let me know if there is anything else I can do to help.

Brock

October 25, 2011 at 9:12 pm #7791

Halle

Can you revert the sample app to its original code and then try out this code:

UInt32 allowMixing = true;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);

after the audio session chunk as follows:

		UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; // Set the Audio Session category to kAudioSessionCategory_PlayAndRecord.
		OSStatus audioCategoryStatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
		if (audioCategoryStatus != 0) {
			OpenEarsLog(@"Error %d: Unable to set audio category.", (int)audioCategoryStatus);
		}
  • This reply was modified 206 days ago by  Halle.
October 25, 2011 at 11:47 pm #7795

slowfoxtrot

Ok. This is what I set:

UInt32 allowMixing = true;
OSStatus playbackMixStatus = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof(allowMixing),
&allowMixing);
if (playbackMixStatus != 0) {
OpenEarsLog(@”Error %d: Unable to set playback mix.”, (int)playbackMixStatus);
}
else
OpenEarsLog(@”Success %d: Set playback mix.”, (int)playbackMixStatus);

OSStatus playbackDuckStatus = AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck,
sizeof(allowMixing),
&allowMixing);
if (playbackDuckStatus != 0) {
OpenEarsLog(@”Error %d: Unable to set playback duck.”, (int)playbackDuckStatus);
}
else
OpenEarsLog(@”Success %d: Set playback duck.”, (int)playbackDuckStatus);

And in the log:
2011-10-25 16:42:06.407 OpenEarsSampleProject[2461:507] OPENEARSLOGGING: The audio session has never been initialized so we will do that now.
2011-10-25 16:42:06.416 OpenEarsSampleProject[2461:507] OPENEARSLOGGING: Success 0: Set playback mix.
2011-10-25 16:42:06.418 OpenEarsSampleProject[2461:507] OPENEARSLOGGING: Success 0: Set playback duck.
2011-10-25 16:42:07.874 OpenEarsSampleProject[2461:507] OPENEARSLOGGING: AudioSessionManager startAudioSession has reached the end of the initialization.
2011-10-25 16:42:07.891 OpenEarsSampleProject[2461:507] OPENEARSLOGGING: Exiting startAudioSession.

So the settings took successfully. Still no system sounds while Pocketsphinx is listening tho. I’m not sure this is where the problem is at, however, because after the audio session is initialized I still have system sounds/vibration with or without the code above. It is only when I start pocketsphinx listening that system sounds/vibration are muted. So it doesn’t appear to be a problem with the audio session itself.

October 25, 2011 at 11:55 pm #7796

slowfoxtrot

This is confirmed on an original copy of your sample app with no changes but the addition you just suggested to make.

October 26, 2011 at 3:05 am #7797

slowfoxtrot

I have narrowed it down to exactly when the system sounds are muted during the audio startup process to this line in ContinuousAudioUnit.mm:

OSStatus startAudioUnitOutputStatus = AudioOutputUnitStart(audioDriver->audioUnit);

Before this call startup sounds are still passed to the speaker and after both sounds and vibration are stopped.

October 26, 2011 at 6:19 pm #7799

Halle

OK, I’ve set up a test and done some research on the results and this seems to be a bug (or an undocumented but expected behavior) of the kAudioSessionCategory_PlayAndRecord:

https://devforums.apple.com/message/181931
http://webcache.googleusercontent.com/search?q=cache:qbwbNiXXabQJ:lists.apple.com/archives/coreaudio-api/2011/Jul/msg00055.html+AudioServicesPlaySystemSound+%22audio+unit%22&cd=5&hl=en&ct=clnk
http://stackoverflow.com/questions/3589294/iphone-does-not-vibrate-while-recording
http://stackoverflow.com/questions/1183366/play-alert-sound-vibrate-while-audioqueue-is-recording

(nearly all of these links refer to AudioQueueServices rather than Audio Unit since a lot more people use queues, but I believe it’s the same underlying issue).

I attempted to replicate the behavior by seeing if AudioServicesPlayAlertSound() could be shown to play a sound when Pocketsphinx wasn’t listening and be unable to play a sound when it was, which I think correlates closely enough to the issue you’re reporting to serve as a good test. I was able to replicate the issue with this simulated system sound. Then I looked into reports of AudioServicesPlayAlertSound failing while using a recording category while the recording was started, and there were many reports. Sorry to be the bearer of bad news, really odd that they have AVAudioPlayer working differently in this case.

October 27, 2011 at 4:38 pm #7808

slowfoxtrot

Awesome thanks so much for your help! So if this is a bug in the OS is there any fixing it? Are there any workarounds you can think of?

Brock

October 27, 2011 at 4:53 pm #7810

Halle

Well, I guess the question is how you ended up with the specification to pass through alert sounds. If it’s a generalized UX preference (fair enough, it would be better for it to work that way) I don’t have any advice, because as far as I know the only alerts you can listen for within the app are local and remote notifications, which means you don’t have the option of intercepting an alert and playing the sound it ought to make using an AVAudioPlayer. Maybe I’m incorrect about this (I haven’t ever thought about it particularly) and there is a way to listen for alerts or an indirect way of knowing when an alert comes in. It would probably make a good Stack Overflow search.

However, if there is a very particular app-related reason for wanting the alerts (e.g. the alerts and the app somehow have significance to each other), this is where I would question whether there is another way to accomplish your goal besides having the alert play (for instance, whatever the incoming event is that is important, maybe it could be a local or remote notification instead so that you can capture the event and play a sound).

You could also use one of your Apple support questions and ask them why you can’t hear system sounds when using kAudioSessionCategory_PlayAndRecord and recording, and see what they tell you.

November 13, 2011 at 11:45 pm #8059

culov

I’ve noticed that if I’m playing music from my library and then I go back to my app where Pocketsphinx is listening, the music immediately fades out.

Is this caused by the same bug that is being discussed in this thread?

November 14, 2011 at 4:25 am #8060

slowfoxtrot

Yes it is, it turns out that I have sorted this bug out. The order in which you set the AudioSessionSetProperty is significant. The order (if you want them all to play nice together) HAS TO BE THESE IN THIS ORDER:

-set category to playandrecord

-set property bluetooth

-set property overridecategorydefaulttospeaker

-set property to mixwithothers

If you don’t set these in this order in the AudioSessionManager.m file it won’t layer with bluetooth and music at the same time and either of these will interrupt music playing. I don’t know why Apple didn’t specify that order is significant when setting these flags but much trial and error has shown it does. For the code see: http://pastie.org/2859849. Let me know if you have any questions.

November 14, 2011 at 1:33 pm #8061

Halle

Interesting, and useful. I’m going to reprint the code here so it isn’t dependent on that pastie being there indefinitely, let me know if you would prefer that I not do that for whatever reason and I’ll remove it.

- (void) startAudioSession {

  OSStatus audioSessionInitializationError = AudioSessionInitialize(NULL, NULL, audioSessionInterruptionListener, NULL); // Try to initialize the audio session.

  if (audioSessionInitializationError !=0 && audioSessionInitializationError != kAudioSessionAlreadyInitialized) { // There was an error and it wasn't that the audio session is already initialized.
    OpenEarsLog(@"Error %d: Unable to initialize the audio session.", (int)audioSessionInitializationError);
  } else { // If there was no error we'll set the properties of the audio session now.

    if (audioSessionInitializationError !=0 && audioSessionInitializationError == kAudioSessionAlreadyInitialized) {
      OpenEarsLog(@"The audio session has already been initialized but we will override its properties.");
    } else {
      OpenEarsLog(@"The audio session has never been initialized so we will do that now.");
    }

    // Projects using Pocketsphinx and Flite should use the Audio Session Category kAudioSessionCategory_PlayAndRecord.
    // Using this category routes playback to the ear speaker when the headphones aren't plugged in.
    // This isn't really appropriate for a speech recognition/tts app as far as I can see so I'm re-routing the output to the
    // main speaker.

    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; // Set the Audio Session category to kAudioSessionCategory_PlayAndRecord.
    OSStatus audioCategoryStatus = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory);
    if (audioCategoryStatus != 0) {
      OpenEarsLog(@"Error %d: Unable to set audio category.", (int)audioCategoryStatus);
    }

    UInt32 bluetoothInput = 1;
    OSStatus bluetoothInputStatus = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput,sizeof (bluetoothInput), &bluetoothInput);
    if (bluetoothInputStatus != 0) {
      OpenEarsLog(@"Error %d: Unable to set bluetooth input.", (int)bluetoothInputStatus);
    }

    UInt32 overrideCategoryDefaultToSpeaker = 1; // Re-route sound output to the main speaker.
    OSStatus overrideCategoryDefaultToSpeakerError = AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof (overrideCategoryDefaultToSpeaker), &overrideCategoryDefaultToSpeaker);
    if (overrideCategoryDefaultToSpeakerError != 0) {
      OpenEarsLog(@"Error %d: Unable to override the default speaker.", (int)overrideCategoryDefaultToSpeakerError);
    }

    UInt32 allowMixing = true;
    OSStatus playbackMixStatus = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(allowMixing), &allowMixing);
    if (playbackMixStatus != 0) {
      OpenEarsLog(@"Error %d: Unable to set playback mix.", (int)playbackMixStatus);
    } 

    Float32 currentPreferredBufferSize = kBufferLength;
    UInt32 sizeOfCurrentPreferredBufferSize = sizeof(currentPreferredBufferSize);
    OSStatus getCurrentPreferredBufferSizeStatus = AudioSessionGetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, &sizeOfCurrentPreferredBufferSize, &currentPreferredBufferSize);
    if(getCurrentPreferredBufferSizeStatus != noErr) {
      OpenEarsLog(@"getCurrentPreferredBufferSizeStatus is %d, currentPreferredBufferSize is %f",(int)getCurrentPreferredBufferSizeStatus, currentPreferredBufferSize);
    }
November 14, 2011 at 3:00 pm #8062

slowfoxtrot

That is great Halle. Only make sure if you are copying and pasting this code folks, I only pasted the top of the method. When it gets down to currentPreferredBufferSize the method continues. Don’t paste this (and only this) into your AudioSessionManager.m file or you’ll kill your OpenEars. You will need the rest of the method also as it appears in AudioSessionManager.m, but since no changes were needed I didn’t see a need to paste it.

November 16, 2011 at 9:00 am #8086

culov

Thanks a lot for posting this. It sure saved me a lot of time.

November 17, 2011 at 8:00 pm #8095

anu

Hi,

I’m facing the same problem with 0.912. I added the following code in ContinuousAudioUnit.mm openAudioDevice method

OSStatus setEnableIOOutputStatus = AudioUnitSetProperty(audioDriver->audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
if(setEnableIOOutputStatus != noErr) {
OpenEarsLog(@”Couldn’t enable IO output bus: %d”,setEnableIOStatus);
audioDriver->unitIsRunning = 0;
return NULL;
}

and my AudioSessionManager.StartSession has the right order as mentioned in this thread. Am I missing something?

Thanks in advance.

November 17, 2011 at 8:13 pm #8096

Halle

I don’t think there is any reason to change anything in ContinuousAudioUnit.mm and if not, it isn’t a good idea to make changes there. The working fix sounds like it only required a change of ordering in startAudioSession.

November 17, 2011 at 9:16 pm #8097

anu

Thanks Halle for your response. The problem I’m trying to fix is our iPhone app when connected to Car Bluetooth, it blocks the speaker output. If a music is playing, as soon as the app is launched (it startsAudioSession on appLaunch) the music no longer plays. I tried the same with other sounds on the device and noticed the same behavior with a Calendar event notification that the app is blocking the device sound. Appreciate your help.

Thanks

May 4, 2012 at 9:18 am #9604

nvrtd frst

Hi Halle and SlowFoxTrot

I am currently on v1.01. I can’t seem to get those system sounds (txt msg sounds, etc) to play when OpenEars sample app is running. (Like mentioned, if you press “stop listening” txt sounds will play).

Halle, I noticed you pretty much put in the big code snippet into v1.01 so i didn’t change the audioSessionManager. I did however set soundMixing = TRUE. I thought this would have solved the problem, but alas no txt msg sounds. Any thoughts?

Jason

May 4, 2012 at 10:41 am #9607

Halle

The change in AudioSessionManager that I added is only intended to fix the interaction of PocketsphinxController and media objects such as MPMovieController and AVPlayer while listening is not in progress, its purpose isn’t explicitly for keeping system sounds while listening. I don’t have any insight into this issue beyond what is discussed in this topic.

Viewing 36 posts - 1 through 36 (of 36 total)

You must be logged in to reply to this topic.