Slight buzz in audio in Mercurial

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?

Best regards.

Are we changing the sample rate in your output?

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.

1 Like

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.

Yeah it’s only the default audio driver (I assume WASAPI) with the problem. If I force it to directsound or winmm the buzz goes away.

DirectSound and winmm handle resampling for us, so I would assume it’s the new resampler, which we need in the WASAPI target.

If you set your audio hardware to the same sample rate, I assume it’ll fix the problem, suggesting it’s not WASAPI in general.

You’re right. The sample rate on the hardware was 48000 Hz. As I said I’m requesting 44100 Hz. If I change the hardware to 44100 it sounds good.

Is there a way to retrieve the hardware sampling rate? I could just use whatever it is.

(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:

mydev = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);

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.)

Thanks, it’s working well like this with all drivers.

Is there a public bug tracker where I could report the issue with the resampler (if it hasn’t been already)?

Yep, the SDL bugtracker is https://bugzilla.libsdl.org/

The new resampler is in. Thanks, Ryan.

A very quick test (with the same program I used above) shows this is now much better.

1 Like

This is great to have a real band-limited resampler! :smiley:

I can still hear a bit of ticking / static with loopwave playing a 44100Hz wav into the WASAPI backend at 48000Hz, as of https://hg.libsdl.org/SDL/rev/433786fcf04a

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.

I filed a few bugs for the new resampler:
https://bugzilla.libsdl.org/show_bug.cgi?id=3848
https://bugzilla.libsdl.org/show_bug.cgi?id=3849
https://bugzilla.libsdl.org/show_bug.cgi?id=3851

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.).

1 Like

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!)

1 Like