Reputation: 379
For pitch detection, I use the Novocaine framework in order to process my data captured by the microphone.
Initially - I overwrote the original Novocaine class in order to set my own (reduced) sample rate:
_inputFormat.mSampleRate = PREFERRED_SAMPLING_RATE;// my own value _outputFormat.mSampleRate = PREFERRED_SAMPLING_RATE; // my own value
I reduced the sample rate to 44100.0 / 4.0 in order to capture also the low frequencies (s.th. between 20 Hz and 100 Hz). This works very fine!
When I try to get the higher frequencies (s.th. starting from 500 Hz), I get deviations due to the low sample rate. Thus I need to increase the sample rate to 44100.0 in order to achieve more precision.
My question: as Novocaine is a singleton, is there a way to change the sample rate DYNAMICALLY within the output block?
As Novocaine relies on AVAudioSession, I've tried in vain to do the following:
[audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) {
self->ringBuffer->FetchInterleavedData(data, numFrames, numChannels);
[[AVAudioSession sharedInstance] setPreferredSampleRate:NEW_SAMPLING_RATE error:nil];
… }
But this doesn't have no effect on the sample rate of the Novocaine framework.
Is there a possibility to change the sample rate without creating a new Audio session? The problem is, that the output block belongs to the current running session.
Upvotes: 0
Views: 2358
Reputation: 581
When you call setPreferredSampleRate:error:
, the system may not respond to the sample rate change immediately (or ever). From the docs:
Your requested changes might not take effect immediately. For example, you can use the
setPreferredDataSource:error:
method on the built-in microphone port to select the front microphone while a headset is plugged in—this preference does not take effect until the headset is unplugged and the audio route changes.
There's also guidance on changing parameters in Technical Q&A QA1631 AVAudioSession - Requesting Audio Session Preferences:
In most cases where setting a preferred value causes some sort of audio system reconfiguration with an active audio session, audio data I/O will be stopped and then restarted. Therefore, if an application plans to set multiple preferred values, it is generally advisable to deactivate the session first, set the preferences, reactivate the session and then check the actual values.
And per this post in the Apple Developer Forum, the iPhone 6S and 6S+ only support 48KHz through the built-in speaker. You should never assume that the preferred sample rate you request will be the sample rate used by the hardware.
Separately, I'm not sure why you would be seeing 'deviations' at 500Hz with a sample rate of 11025Hz -- you should be able to accurately capture that. You should also be able to capture 20-100Hz with a sample rate of 44100Hz - you'll just need to increase your buffer size by a factor of 4.
Upvotes: 0