Hi,
this patch makes three changes:
- sets default sample rate to 44100
- when loadas8bit is set to 0, convert all sound effects to 16-bit upon loading. the reason for doing this is that resampling benefits from being done at 16-bit precision instead of 8.
- improves the resampler used on sound effects (in snd_mem.c) in the upsampling case. first, it linearly interpolates new samples between the old ones instead of just repeating the old samples like id's resampler. second, it adds a simple low-pass filter (box filter) to remove the high-frequency junk which resampling generates. This gets rid of the "crunchy" sound.
Earlier this year I experimented with integrating a much more complex resampler from an external library (speex), but this reasonably simple patch sounds just about as good to me.
Thanks.
Haven't had a chance to test yet, but by just looking at it this only handles snd_mem.c whereas resampling can also happen in snd_dma.c::S_RawSamples()
And it has a problem with the warpspasm/quoth sounds at 48000 Hz. Loading the attached save like:
./quakespasm -basedir [mybasedir] -sndspeed 48000 -quoth -game warp +load s4
... outputs sound with a lot of stuttering
warpspasm save showing stuttering sound at 45 KHz
hmm, I wasn't able to reproduce stuttering in warpspasm with your savegame and -sndspeed 48000. I tried various sndspeed settings up to 96000 and down to 10000 and they seemed to work. I tested on Mac OS 10.7. What OS are you on? Does the stuttering also happen if you set loadas8bit to 1? If it isn't too much trouble would you be able to record an mp3/ogg of the stuttering?
I may hold off on this for now and work on refactoring the original id resampler in to a separate function which S_RawSamples and S_LoadSound can both use. On a related note, would you be interested in a patch to convert snd_mem over to using the codec system for sfx loading?
thanks for trying the patch, btw.
Running under x86 linux. It seems like the stutter is there only when SDL uses its esd backend and with 44.1 or 48 KHz: if it uses oss (dsp) or pulse, no stutter, if I specify 11 or 22 KHz, no stutter. Esd is old and known to be laggy, however without your patch it doesn't stutter.
As for snd_mem to use codec layer for loading sfx: IIRC, ioquake3 did that, however the snd_mem parser looks for some stupid chunks to extract data whereas snd_wave of codec layer does not, so I am not sure it is a good idea. (I can review patches, though, and there is a chance that I may like it.)
new resampler patch
Hi, sorry for taking so long to reply. I uploaded a new patch, which I hope will fix the problem you heard with ESD. This new patch is more conservative - it does not change the default sample rate or load all samples at 16-bit, like the old patch did. It also uses a better interpolation algorithm.
Thanks, and yes I think this is better. Can you also handle resampling snd_dma.c:S_RawSamples()? (maybe add a new snd_resample.c or something ???) We can then merge this.
I tested this on a few operating systems, including my G4 Mac (patching qs-0.85.4, with warpspasm s4.sav)
and win32 (qs-0.85.7, id1 e4m[456]) and it seems fine.
great. I'm working factoring out the resampler so it can be used by S_RawSamples. I'll post here when it's complete. -Eric
Finally revisited this..
The last resampler I posted still produces a lot of high-frequency distortion, sounds like there’s ringing on top of all of the sounds. I figured we should do something that is not noticeably worse than my operating system’s resampler (Mac OS X 10.9).
Here’a a new patch that uses the resampler from libspeexdsp, and also uses it in S_RawSamples().
some notes:
The speex resampler quality ranges from 0 to 10. Quality 0 sounds muffled and bad, but 1 and higher sound good to me. As you go higher they get slower, and the sound gets “harsher”, not really an improvement for the Quake sfx, so I’m using quality 1 here.
I also auditioned libsamplerate, and while It sounded good at the SRC_SINC_MEDIUM_QUALITY quality setting, it’s too slow (takes over a second to resample the sounds when starting a game in id1, on a core i7 CPU).
It really is critical to store the up-sampled sfx at 16-bit, even though the source is usually 8-bit. Upsampling and then storing the sample as 8 bit introduces another layer of noise that’s easily audible.
It’s also important to deal with the fact that a resampled sfx can have higher peaks than the source. This is why I have the max_amplitude variable in snd_mem.c and scale down the sample volume to prevent clipping. This volume scaling step could be avoided if we stored the samples as floats before mixing, but that would be another doubling of memory usage for sounds.
I attached a sample recording of demo1; this sample is using this patch plus my other patch which eliminates pops + glitches at -sndspeed 44100.
Steve, Kristian: Can you please review?
https://sourceforge.net/p/quakespasm/patches/5/
See patch #23 (https://sourceforge.net/p/quakespasm/patches/23/) for issues I encountered.
Updated to fix case when USE_SPEEX_RESAMPLER is not defined
v0.90.0 has Eric's other sound resampling code merged in.
If this one is still relevant needs updated patch with explanations.
This can also be closed.
OK, closed.
Log in to post a comment.