Re: Some questions and problems on recording in measurement mode
Re: Some questions and problems on recording in measurement mode
- Subject: Re: Some questions and problems on recording in measurement mode
- From: Soares Chen <email@hidden>
- Date: Wed, 13 Feb 2013 16:40:27 +0100
Hi Dave,
Thanks for the tips. I tried to set a callback to the kAudioSessionProperty_InputGainAvailable property change event and in the callback I can change the gain on Phone successfully. It was likely that in the code changes I configured the audio session too early, during the app initialization instead of before the record button is pressed. The audio gain can only be configured briefly after the app is started.
However doing so I still can't find a way to change the input gain in iPad. No matter how I tried, with measurement and default mode, there is no InputGainAvailable event fired and the property value is always false.
I tried to verify the behavior and found that on iPhone, the input gain can be adjusted both in measurement mode and in the default mode with AGC, as long as it is not set during app initialization. Do anyone know if it is possible to adjust input gain on iPad?
Thanks.
Soares
On Feb 13, 2013, at 2:20 AM, Dave Fernandes <email@hidden> wrote:
> I don't know why input gain setting is not available, but looking at your code, I would note one problem with the way you are setting the property. You are assuming that AudioSessionSetProperty will make changes synchronously. In Core Audio, you generally cannot assume this. If it has to go out to hardware to change a setting, that might take some time. The correct approach is to register a listener, and wait for the callback to tell you that the setting has actually been changed.
>
> Are you able to set the gain in other modes besides kAudioSessionMode_Measurement?
>
> Dave
>
> On 2013-02-12, at 3:12 PM, Soares Chen <email@hidden> wrote:
>
>> Hello,
>>
>> I have a couple of questions that are loosely related to the nature of the our app. We are developing an iPhone app that perform musical analysis on recorded audio from the iPhone. Our app implementation make use of the Audio Queue service to receive raw audio buffers from the audio queue callback.
>>
>> In the first version of our app we had the problem of too much clipping on the recording which degrade the accuracy of our analysis. We also suspected that the noise canceling algorithm in iPhone 5 produce distorted sound, which is not much noticeable by human ear but distorted enough to affect our sensitive algorithm.
>>
>> I found that the solution to our problem is to set the audio session mode to kAudioSessionMode_Measurement. This session mode is supposed to give maximum freedom for us to control the microphone input, which include turning off the automatic gain control and probably noise canceling as well.
>>
>> Q1. How to adjust input gain level?
>> The solution worked very well for us in the beginning, however after some further code changes I messed up somewhere and ended up being unable to change the input gain even after setting the audio session mode to measurement. Unfortunately I didn't commit immediately when it worked so I lost the original code that worked. I was pretty sure that my first attempt of changing the input gain worked, as I printed the value before and after setting to the console. The value of kAudioSessionProperty_InputGainAvailable I got back is now false, and I don't know how to make it available on iOS again.
>>
>> Q2. Strange recording glitch in iPhone 5
>> Other than that, I notice that setting the session to measurement mode introduce a strange waveform glitch in the beginning of all recordings on iPhone 5. It is very hard to explain the waveform I get, so I have attached two recordings so that you can see it visually
>>
>> https://www.dropbox.com/s/pdr4mgqfgduxlmf/iphone5_strange_waveform_at_beginning-quiet.ogg
>> This recording is made in an almost quite environment, and you can see the weird spike in the beginning of the recording.
>>
>> https://www.dropbox.com/s/w8pxxobplci5t0i/iphone5_strange_waveform_at_beginning-noisy.ogg
>> This recording is made with constant background noise, and you can see that the actual sound wave is offset from the strange curve and gradually increase to its original volume.
>>
>> This waveform only happens on iPhone 5 devices that we tested, and there is no problem at all for iPhone 4S and older generations. I have tried various settings and the glitch is still unavoidable as long as I set the audio session mode to kAudioSessionMode_Measurement. I also find similar glitch in one of our iPhone 5 devices, in which the glitch happens even if I try to set just the input gain level without changing the session mode.
>>
>> I am not sure if this is a hardware-related bug in iPhone 5, or if it is fixable software glitch in the future version of iOS. Currently I found a strange workaround to the problem: If a sound playback is made first, the recording that is immediately followed by the playback will not contain the glitch. The glitch will come back in the second recording, so I have to perform a playback every time before doing recording to fix the glitch.
>>
>> I tried two of my existing playback solution: one that use output audio queue and one that use MusicPlayer and MusicSequence. None of the playback code have any audio session manipulation, and an operation as simple as AudioQueueStart can make the glitch disappear "magically".
>>
>> I have attached at the end of this mail a snippet of the refactored audio session configuration code I have written. I'd appreciate if anyone can tell me what went wrong in my code.
>>
>> Q3. Is there any way to disable just the built-in noise canceling feature?
>>
>> Q4. Can I record from all three microphones of iPhone 5 in separate channels?
>>
>> Thank you.
>>
>> Best Regards,
>>
>> Soares Chen
>> http://scorecleaner.com/
>>
>>
>> Code snippet for my audio session configuration:
>>
>> *****
>> #include <AudioToolbox/AudioSession.h>
>>
>> const Float32 kCustomGain = 0;
>>
>> static void SetAudioInputGain(Float32 newGain) {
>> printf("Attempt to set input gain to %f.\n", newGain);
>>
>> OSStatus res = noErr;
>> Float32 currentGain = 0;
>> UInt32 gainSize = sizeof(currentGain);
>>
>> AudioSessionGetProperty(kAudioSessionProperty_InputGainScalar, &gainSize, ¤tGain);
>> printf("Current microphone gain is %f.\n", currentGain);
>>
>> res = AudioSessionSetProperty(kAudioSessionProperty_InputGainScalar, gainSize, &newGain);
>> if(res != noErr) printf("Failed to set input gain.\n");
>>
>> AudioSessionGetProperty(kAudioSessionProperty_InputGainScalar, &gainSize, ¤tGain);
>> printf("New microphone gain is %f.\n", currentGain);
>> }
>>
>> static void ConfigureAudioSession() {
>> AudioSessionInitialize(NULL, NULL, NULL, NULL);
>> OSStatus res = noErr;
>>
>> printf("Setting audio session category to record mode.\n");
>> UInt32 sessionCategory = kAudioSessionCategory_RecordAudio;
>> res = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
>> if(res != noErr) printf("Failed to set audio session category.\n");
>>
>> printf("Setting audio session mode to measurement mode.\n");
>> UInt32 sessionMode = kAudioSessionMode_Measurement;
>> res = AudioSessionSetProperty(kAudioSessionProperty_Mode, sizeof(sessionMode), &sessionMode);
>> if(res != noErr) printf("Failed to set audio session mode.\n");
>>
>> UInt32 inputGainAvailable = 0;
>> UInt32 inputGainAvailableSize = sizeof(inputGainAvailable);
>> res = AudioSessionGetProperty(kAudioSessionProperty_InputGainAvailable, &inputGainAvailableSize, &inputGainAvailable);
>>
>> if(res != noErr) printf("Failed to get input gain availability.\n");
>> if(!inputGainAvailable) printf("Input gain is not available.\n");
>>
>> SetAudioInputGain(kCustomGain);
>>
>> printf("Activating audio session.\n");
>> res = AudioSessionSetActive(true);
>> if(res != noErr) printf("Failed to activate audio session.\n");
>> }
>> *****
>>
>> Running ConfigureAudioSession() on my iPad for example would print the following to the console:
>>
>> Setting audio session category to record mode.
>> Setting audio session mode to measurement mode.
>> Input gain is not available.
>> Attempt to set input gain to 0.000000.
>> Current microphone gain is 0.500000.
>> New microphone gain is 0.500000.
>> Activating audio session.
>
>
On Feb 13, 2013, at 2:20 AM, Dave Fernandes <email@hidden> wrote:
> I don't know why input gain setting is not available, but looking at your code, I would note one problem with the way you are setting the property. You are assuming that AudioSessionSetProperty will make changes synchronously. In Core Audio, you generally cannot assume this. If it has to go out to hardware to change a setting, that might take some time. The correct approach is to register a listener, and wait for the callback to tell you that the setting has actually been changed.
>
> Are you able to set the gain in other modes besides kAudioSessionMode_Measurement?
>
> Dave
>
> On 2013-02-12, at 3:12 PM, Soares Chen <email@hidden> wrote:
>
>> Hello,
>>
>> I have a couple of questions that are loosely related to the nature of the our app. We are developing an iPhone app that perform musical analysis on recorded audio from the iPhone. Our app implementation make use of the Audio Queue service to receive raw audio buffers from the audio queue callback.
>>
>> In the first version of our app we had the problem of too much clipping on the recording which degrade the accuracy of our analysis. We also suspected that the noise canceling algorithm in iPhone 5 produce distorted sound, which is not much noticeable by human ear but distorted enough to affect our sensitive algorithm.
>>
>> I found that the solution to our problem is to set the audio session mode to kAudioSessionMode_Measurement. This session mode is supposed to give maximum freedom for us to control the microphone input, which include turning off the automatic gain control and probably noise canceling as well.
>>
>> Q1. How to adjust input gain level?
>> The solution worked very well for us in the beginning, however after some further code changes I messed up somewhere and ended up being unable to change the input gain even after setting the audio session mode to measurement. Unfortunately I didn't commit immediately when it worked so I lost the original code that worked. I was pretty sure that my first attempt of changing the input gain worked, as I printed the value before and after setting to the console. The value of kAudioSessionProperty_InputGainAvailable I got back is now false, and I don't know how to make it available on iOS again.
>>
>> Q2. Strange recording glitch in iPhone 5
>> Other than that, I notice that setting the session to measurement mode introduce a strange waveform glitch in the beginning of all recordings on iPhone 5. It is very hard to explain the waveform I get, so I have attached two recordings so that you can see it visually
>>
>> https://www.dropbox.com/s/pdr4mgqfgduxlmf/iphone5_strange_waveform_at_beginning-quiet.ogg
>> This recording is made in an almost quite environment, and you can see the weird spike in the beginning of the recording.
>>
>> https://www.dropbox.com/s/w8pxxobplci5t0i/iphone5_strange_waveform_at_beginning-noisy.ogg
>> This recording is made with constant background noise, and you can see that the actual sound wave is offset from the strange curve and gradually increase to its original volume.
>>
>> This waveform only happens on iPhone 5 devices that we tested, and there is no problem at all for iPhone 4S and older generations. I have tried various settings and the glitch is still unavoidable as long as I set the audio session mode to kAudioSessionMode_Measurement. I also find similar glitch in one of our iPhone 5 devices, in which the glitch happens even if I try to set just the input gain level without changing the session mode.
>>
>> I am not sure if this is a hardware-related bug in iPhone 5, or if it is fixable software glitch in the future version of iOS. Currently I found a strange workaround to the problem: If a sound playback is made first, the recording that is immediately followed by the playback will not contain the glitch. The glitch will come back in the second recording, so I have to perform a playback every time before doing recording to fix the glitch.
>>
>> I tried two of my existing playback solution: one that use output audio queue and one that use MusicPlayer and MusicSequence. None of the playback code have any audio session manipulation, and an operation as simple as AudioQueueStart can make the glitch disappear "magically".
>>
>> I have attached at the end of this mail a snippet of the refactored audio session configuration code I have written. I'd appreciate if anyone can tell me what went wrong in my code.
>>
>> Q3. Is there any way to disable just the built-in noise canceling feature?
>>
>> Q4. Can I record from all three microphones of iPhone 5 in separate channels?
>>
>> Thank you.
>>
>> Best Regards,
>>
>> Soares Chen
>> http://scorecleaner.com/
>>
>>
>> Code snippet for my audio session configuration:
>>
>> *****
>> #include <AudioToolbox/AudioSession.h>
>>
>> const Float32 kCustomGain = 0;
>>
>> static void SetAudioInputGain(Float32 newGain) {
>> printf("Attempt to set input gain to %f.\n", newGain);
>>
>> OSStatus res = noErr;
>> Float32 currentGain = 0;
>> UInt32 gainSize = sizeof(currentGain);
>>
>> AudioSessionGetProperty(kAudioSessionProperty_InputGainScalar, &gainSize, ¤tGain);
>> printf("Current microphone gain is %f.\n", currentGain);
>>
>> res = AudioSessionSetProperty(kAudioSessionProperty_InputGainScalar, gainSize, &newGain);
>> if(res != noErr) printf("Failed to set input gain.\n");
>>
>> AudioSessionGetProperty(kAudioSessionProperty_InputGainScalar, &gainSize, ¤tGain);
>> printf("New microphone gain is %f.\n", currentGain);
>> }
>>
>> static void ConfigureAudioSession() {
>> AudioSessionInitialize(NULL, NULL, NULL, NULL);
>> OSStatus res = noErr;
>>
>> printf("Setting audio session category to record mode.\n");
>> UInt32 sessionCategory = kAudioSessionCategory_RecordAudio;
>> res = AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
>> if(res != noErr) printf("Failed to set audio session category.\n");
>>
>> printf("Setting audio session mode to measurement mode.\n");
>> UInt32 sessionMode = kAudioSessionMode_Measurement;
>> res = AudioSessionSetProperty(kAudioSessionProperty_Mode, sizeof(sessionMode), &sessionMode);
>> if(res != noErr) printf("Failed to set audio session mode.\n");
>>
>> UInt32 inputGainAvailable = 0;
>> UInt32 inputGainAvailableSize = sizeof(inputGainAvailable);
>> res = AudioSessionGetProperty(kAudioSessionProperty_InputGainAvailable, &inputGainAvailableSize, &inputGainAvailable);
>>
>> if(res != noErr) printf("Failed to get input gain availability.\n");
>> if(!inputGainAvailable) printf("Input gain is not available.\n");
>>
>> SetAudioInputGain(kCustomGain);
>>
>> printf("Activating audio session.\n");
>> res = AudioSessionSetActive(true);
>> if(res != noErr) printf("Failed to activate audio session.\n");
>> }
>> *****
>>
>> Running ConfigureAudioSession() on my iPad for example would print the following to the console:
>>
>> Setting audio session category to record mode.
>> Setting audio session mode to measurement mode.
>> Input gain is not available.
>> Attempt to set input gain to 0.000000.
>> Current microphone gain is 0.500000.
>> New microphone gain is 0.500000.
>> Activating audio session.
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden