Not sure which change caused this but between using the latest official DLL and building Mercurial a slight buzz was introduced in audio. I generate pure tones for music and SFX and feed them directly to the audio stream and there is now a buzz/ringing in them if I swap DLLs. Does anyone know if there were any changes that might be relevant?
I noticed this as well when testing the new WASAPI audio driver. I set the Windows device to take 48000 Hz data. SDL opens a 44100 Hz device and probably upsamples to 48000 Hz.
I tested this upsampling with SDL_ConvertAudio and get the same artifacts. Test was with 440 Hz sine wave in the format of S16 at 44100 Hz converted to the format of F32 at 48000 Hz.
Input data:
Output data:
Image of the first few sample points. Upper signal is input, lower signal is output. There are bumps visible.
I thought perhaps there was a different driver being used but I didn’t investigate. Sounds like the WASAPI driver could be the issue. I’m requesting a 44100 Hz S16 stream indeed. I can force it to use another driver and check it out.
(Obviously the resampler needs improvements in any case but…) Yes, you can open the audio device with the “obtained” parameter not set to NULL, and the SDL_AUDIO_ALLOW_FREQUENCY_CHANGE flag:
This will give you a device opened with the exact format and channels you asked for (with the hardware set to that format if possible and SDL handling the conversion in between your code and the hardware if not), but the sample rate will be set to the closest thing the hardware supports if it can’t get exactly what you asked for, and SDL will do no resampling. In the case of WASAPI, there’s exactly one sample rate the target supports, and that’s whatever you set it to in the system preferences.
(Note that if you change it in the system preferences while your app is running, SDL will start resampling on your behalf anyhow to keep everything limping along, but that’s an uncommon case. And, again, we need to improve the resampler anyhow. But for your case–where you can handle any frequency anyhow–this will solve the problem.)
I am assuming it’s because of this FIXME: streaming current resamples on Put, because of probably good reasons I can't remember right now, but if we resample on Get, we'd be able to access legit right padding values ?
Not sure if this is useful, but in a similar resampler I implemented, I only used a “left padding” buffer in the resampler state, and it is as wide as the full kernel (left+right “wings”). When the right edge of the kernel gets to the end of the input I stop producing output and save the end of the buffer to the “left padding” resampler state. Then, the next time the resampler is called, it starts with the kernel centered in the “left padding” buffer.
I mentioned noise in the bugtracker ticket for the new resampler also, also mentioned it sounded like unfilled buffer static so you might be onto something.
The last one has a patch that seems to eliminate all of the artifacts for 44100->48000 streaming resampling (e.g. for WASAPI when Windows is set to 48kHz and SDL is playing 44100Hz.).
Thanks. I check the patch in the last bug and I don’t hear any noise anymore either. Sounds perfect now, so thank you… If that’s not the fix that sticks I’ll check the next one too (not that you need me!)