diff options
author | Simon Howard | 2007-03-14 13:05:03 +0000 |
---|---|---|
committer | Simon Howard | 2007-03-14 13:05:03 +0000 |
commit | b7906ef4baad9f3a2a7e1b32a9d739e29e001f79 (patch) | |
tree | 4f9b1e8811487507200b9f3bf87a144e87921734 /src | |
parent | bccb85d1c3c978f072b99a0ad692c6bcd3402351 (diff) | |
download | chocolate-doom-b7906ef4baad9f3a2a7e1b32a9d739e29e001f79.tar.gz chocolate-doom-b7906ef4baad9f3a2a7e1b32a9d739e29e001f79.tar.bz2 chocolate-doom-b7906ef4baad9f3a2a7e1b32a9d739e29e001f79.zip |
Use SDL's built-in audio conversion routines to convert sound effects to
the output mixer device's sample rate. Simplistic (naive) resampling in
cases where SDL's routines can't do a conversion. This needs a bit more
work to filter out the high frequency artifacts at 48khz output rate.
Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 856
Diffstat (limited to 'src')
-rw-r--r-- | src/i_sound.c | 93 |
1 files changed, 60 insertions, 33 deletions
diff --git a/src/i_sound.c b/src/i_sound.c index 33a4cf1c..16118622 100644 --- a/src/i_sound.c +++ b/src/i_sound.c @@ -79,6 +79,10 @@ static boolean music_initialised = false; static Mix_Chunk sound_chunks[NUMSFX]; static int channels_playing[NUM_CHANNELS]; +static int mixer_freq; +static Uint16 mixer_format; +static int mixer_channels; + // Disable music on OSX by default; there are problems with SDL_mixer. #ifndef __MACOSX__ @@ -117,53 +121,71 @@ void ReleaseSoundOnChannel(int channel) Z_ChangeTag(sound_chunks[id].abuf, PU_CACHE); } -// Expands the 11025Hz, 8bit, mono sound effects in Doom to -// 22050Hz, 16bit stereo - -static void ExpandSoundData(byte *data, int samplerate, int length, - Mix_Chunk *destination) +static boolean ConvertibleRatio(int freq1, int freq2) { - Sint16 *expanded = (Sint16 *) destination->abuf; - int expanded_length; - int expand_ratio; - int i; + int ratio; - if (samplerate == 11025) + if (freq1 > freq2) { - // Most of Doom's sound effects are 11025Hz - - // need to expand to 2 channels, 11025->22050 and 8->16 bit + return ConvertibleRatio(freq2, freq1); + } + else if ((freq2 % freq1) != 0) + { + // Not in a direct ratio - for (i=0; i<length; ++i) - { - Sint16 sample; + return false; + } + else + { + // Check the ratio is a power of 2 - sample = data[i] | (data[i] << 8); - sample -= 32768; + ratio = freq2 / freq1; - expanded[i * 4] = expanded[i * 4 + 1] - = expanded[i * 4 + 2] = expanded[i * 4 + 3] = sample; + while ((ratio & 1) == 0) + { + ratio = ratio >> 1; } + + return ratio == 1; } - else if (samplerate == 22050) - { - for (i=0; i<length; ++i) - { - Sint16 sample; +} - sample = data[i] | (data[i] << 8); - sample -= 32768; +// Generic sound expansion function for any sample rate - expanded[i * 2] = expanded[i * 2 + 1] = sample; - } +static void ExpandSoundData(byte *data, + int samplerate, + int length, + Mix_Chunk *destination) +{ + SDL_AudioCVT convertor; + + if (ConvertibleRatio(samplerate, mixer_freq) + && SDL_BuildAudioCVT(&convertor, + AUDIO_U8, 1, samplerate, + mixer_format, mixer_channels, mixer_freq)) + { + convertor.buf = destination->abuf; + convertor.len = length; + memcpy(convertor.buf, data, length); + + SDL_ConvertAudio(&convertor); } else { - // Generic expansion function for all other sample rates + Sint16 *expanded = (Sint16 *) destination->abuf; + int expanded_length; + int expand_ratio; + int i; + + // Generic expansion if conversion does not work: + // + // SDL's audio conversion only works for rate conversions that are + // powers of 2; if the two formats are not in a direct power of 2 + // ratio, do this naive conversion instead. // number of samples in the converted sound - expanded_length = (length * 22050) / samplerate; + expanded_length = (length * mixer_freq) / samplerate; expand_ratio = (length << 8) / expanded_length; for (i=0; i<expanded_length; ++i) @@ -224,7 +246,7 @@ static boolean CacheSFX(int sound) return false; } - expanded_length = (uint32_t) ((((uint64_t) length) * 4 * 22050) / samplerate); + expanded_length = (uint32_t) ((((uint64_t) length) * 4 * mixer_freq) / samplerate); sound_chunks[sound].allocated = 1; sound_chunks[sound].alen = expanded_length; @@ -232,7 +254,10 @@ static boolean CacheSFX(int sound) = Z_Malloc(expanded_length, PU_STATIC, &sound_chunks[sound].abuf); sound_chunks[sound].volume = MIX_MAX_VOLUME; - ExpandSoundData(data + 8, samplerate, length - 8, &sound_chunks[sound]); + ExpandSoundData(data + 8, + samplerate, + length - 8, + &sound_chunks[sound]); // don't need the original lump any more @@ -573,6 +598,8 @@ I_InitSound() return; } + Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels); + Mix_AllocateChannels(NUM_CHANNELS); SDL_PauseAudio(0); |