AVAudioSession / Audio Session Services Output

Ok, I have my AVAudioSession defined as follows (yes, a combination of c and obj-c calls). Also note that the application has background sound, because when recording, it should continue to do this while the application is in the background:

[(AVAudioSession *)[AVAudioSession sharedInstance] setDelegate: self]; // Allow the app sound to continue to play when the screen is locked. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; //Turn off automatic gain on the microphone [[AVAudioSession sharedInstance] setMode:AVAudioSessionModeMeasurement error:nil]; //Turn on the ability to mix with others UInt32 doSetProperty = 1; AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty); //Activate the audio session [[AVAudioSession sharedInstance] setActive:YES error:nil]; 

There are several different sound options in the application (only the first two have been programmed):

  • Normal: there is no sound from the application, so do not bother with external sound
  • Headset microphone recording only: must not have gain control and do not bother with external sound (which will be played through the headset).
  • Play music from an application without recording: Stop external audio and play through the current output (speaker or headset)
  • Play music from the microphone of the application and record. Muting external sound, recording and playback only through the headset.

Recording works well in the foreground and in the background, and I will add later. However, I just noticed today that if the sound is already playing (Pandora) on the speaker, and I went into my application and activated the recording mode, it switches Pandora to play through the phone’s speaker and even after the audio recording is turned off and the application based (but not forcibly closed), the sound continues to play through the speaker of the phone until I close the application.

 //Deactivate the audio session [[AVAudioSession sharedInstance] setActive:NO error:nil]; 

On the other hand, if the headset is turned on and the music is played through the headset when the application is launched in recording mode, then there is only a short pause, and the music continues to play at the same volume (correctly, without biases).

I see no reason why the route should change when I activate an audio session without a headset and why it does not change when the session is deactivated. This is especially true for the phone! Is there something I'm doing wrong, or do I just need to define AVAudioSession differently depending on what the user wants to do (instead of playing in clothes + recording and measuring mode)? And even if I need to define it separately for different use cases. For example, the sound will always go through the headset if the application is recording, and if the application is not being recorded, then the audio signal outputs either the headset or the loudspeaker (depending on whether the user is connected to the headset or not - i.e. normal behavior).

additional information

Ok, I tried switching all the c code and noticed a note in the docs about kAudioSessionSphere_OverrideAudioRoute

kAudioSessionOverrideAudioRoute_None
Specifies for the kAudioSessionCategory_PlayAndRecord category the output audio signal should go to the receiver. This is the default audio output for this category.

So, I tried to set this property (these properties) in three ways:

  • kAudioSessionProperty_OverrideAudioRoute with kAudioSessionOverrideAudioRoute_Speaker continues to play the sound, but switches it through the receiver and shows the route as ReceiverAndMicrophone
  • kAudioSessionProperty_OverrideCategoryDefaultToSpeaker with kAudioSessionOverrideAudioRoute_Speaker stops the currently playing sound and shows the route as SpeakerAndMicrophone
  • kAudioSessionProperty_OverrideCategoryDefaultToSpeaker with a value of 1 does the same as kAudioSessionOverrideAudioRoute_Speaker

Thus, basically the documents say that the default is to switch to the receiver. However, no matter what I do, I cannot save the output of the Speaker and not play external sound.

+8
source share
1 answer

Apparently, the order in which properties are set does matter, although this is not mentioned in the documents. For those who find this in the end, here's what works:

 //Init and set the interrupt listener. last parameter is passed to interruptlistener AudioSessionInitialize(NULL, NULL, interruptlistener, NULL); //Allow the app sound to continue to play when the screen is locked. UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); //Force current audio out through speaker UInt32 routeSpeaker = kAudioSessionOverrideAudioRoute_Speaker; AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(routeSpeaker), &routeSpeaker); //Turn on the ability to mix with others UInt32 doSetProperty = 1; AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty); 
+9
source

Source: https://habr.com/ru/post/1203795/


All Articles