The iOSAudioIODevice never sets the sample rate given as a parameter in the open function and only supports one sample rate, the one that has been set on the system when the app launched. This causes nondeterministic behavior as the app might run at different sample rate at different times.
I propose this patch that fixes the issue with sample rate not being correctly set in open and also providing more sample rates to choose from.
In open I've added the following code which sets the sample rate given as a parameter in open and updates the list of available sample rates.
... fixAudioRouteIfSetToReceiver(); updateDeviceInfo(); AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(sampleRate), &sampleRate); updateSampleRates(); ...
The updateSampleRate function looks like this. The code assumes that a Array<Float64> sampleRates has been added to iOSAudioIODevice
void updateSampleRates() { static const double commonSampleRates[6] = { 8000.0, 16000.0, 22050.0, 32000.0, 44100.0, 48000.0}; UInt32 size = sizeof (sampleRate); AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareSampleRate, &size, &sampleRate); sampleRates.clear(); sampleRates.add(sampleRate); for(int i = 0; i < 6; ++i) { if(commonSampleRates[i] == sampleRate) { continue; } AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(commonSampleRates[i]), &commonSampleRates[i]); Float64 actualSampleRate = 0.0; UInt32 size = sizeof (actualSampleRate); AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareSampleRate, &size, &actualSampleRate); if(actualSampleRate == commonSampleRates[i]) { sampleRates.add(actualSampleRate); } } DefaultElementComparator<Float64> comparator; sampleRates.sort(comparator); AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareSampleRate, sizeof(sampleRate), &sampleRate); size = sizeof (sampleRate); AudioSessionGetProperty (kAudioSessionProperty_CurrentHardwareSampleRate, &size, &sampleRate); }
From what I can tell from the AudioSession API there is no way to get a list of all the supported sample rates, so I just try some common ones and see if they work.
Lastly, I've changed the following 2 functions
int getNumSampleRates() { return jmax(sampleRates.size(),1); } double getSampleRate (int index) { return sampleRates.size() > 0 ? sampleRates[index] : sampleRate; }
I've tested this code on an iPad 2 running iOS 7.0.2,