COREAUDIO_OpenDevice on iOS ignores sample rate
Function COREAUDIO_OpenDevice has following code:
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setPreferredSampleRate:this->spec.freq error:nil];
this->spec.freq = (int)session.sampleRate;
It has several problems:
- Does not check if it was successful so you don't know if sample rate was changed
- Will fail to 48000 Hz in many cases
Is it possible to put this code under #if guard? Now if I use SDL_OpenAudio with sample rate 44100 Hz then I get 48000 Hz on my iPhone. If I remove that setPreferredSampleRate call then it works and I get 44100 Hz.
Do you actually get 44100Hz if you don't explicitly set that? It's a weird choice of defaults, and it's even weirder that explicitly asking for it gets you something different than not asking for it, if it is the default.
(We don't check for errors here because we don't care if it fails, since we have to take whatever frequency the session tells us in any case.)
Do you actually get 44100Hz
Yes, I check obtained spec from SDL_OpenAudio() call. Also I checked how that code works on my device, and it looks like setPreferredSampleRate: returns YES, but when I print this->spec.freq after this line:
this->spec.freq = (int)session.sampleRate;
printf("this->spec.freq=%d\n", this->spec.freq);
I see 48000 Hz. Since you use spec.freq below to setup output source, you set it to 48000 Hz too:
/* Setup a AudioStreamBasicDescription with the requested format */
SDL_zerop(strdesc);
strdesc->mFormatID = kAudioFormatLinearPCM;
strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked;
strdesc->mChannelsPerFrame = this->spec.channels;
strdesc->mSampleRate = this->spec.freq;
strdesc->mFramesPerPacket = 1;