summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Howard2007-03-14 13:05:03 +0000
committerSimon Howard2007-03-14 13:05:03 +0000
commitb7906ef4baad9f3a2a7e1b32a9d739e29e001f79 (patch)
tree4f9b1e8811487507200b9f3bf87a144e87921734 /src
parentbccb85d1c3c978f072b99a0ad692c6bcd3402351 (diff)
downloadchocolate-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.c93
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);