From 4f16d8163cedb8b42ac01512c32a54023708b0ec Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 11 Feb 2008 22:59:51 +0000 Subject: Add support for sample rate conversion using libsamplerate (thanks to David Flater for this patch). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 1076 --- src/i_sdlsound.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++------- src/m_misc.c | 5 +++ 2 files changed, 113 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/i_sdlsound.c b/src/i_sdlsound.c index e10cb5ee..5c68d00f 100644 --- a/src/i_sdlsound.c +++ b/src/i_sdlsound.c @@ -3,6 +3,7 @@ // // Copyright(C) 1993-1996 Id Software, Inc. // Copyright(C) 2005 Simon Howard +// Copyright(C) 2008 David Flater // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -25,11 +26,18 @@ //----------------------------------------------------------------------------- +#include "config.h" + #include #include +#include #include "SDL.h" #include "SDL_mixer.h" +#ifdef HAVE_LIBSAMPLERATE +#include +#endif + #include "deh_main.h" #include "s_sound.h" #include "m_argv.h" @@ -48,6 +56,10 @@ static int channels_playing[NUM_CHANNELS]; static int mixer_freq; static Uint16 mixer_format; static int mixer_channels; +static void (*ExpandSoundData)(byte *data, int samplerate, int length, + Mix_Chunk *destination) = NULL; + +int use_libsamplerate = 0; // When a sound stops, check if it is still playing. If it is not, // we can mark the sound data as CACHE to be freed back for other @@ -78,6 +90,72 @@ static void ReleaseSoundOnChannel(int channel) Z_ChangeTag(sound_chunks[id].abuf, PU_CACHE); } +#ifdef HAVE_LIBSAMPLERATE + +// libsamplerate-based generic sound expansion function for any sample rate +// unsigned 8 bits --> signed 16 bits +// mono --> stereo +// samplerate --> mixer_freq +// Rewritten by DWF 2008-02-10: + +static void ExpandSoundData_SRC(byte *data, + int samplerate, + int length, + Mix_Chunk *destination) +{ + SRC_DATA src_data; + uint32_t i, abuf_index=0; + int retn; + int16_t *expanded; + + src_data.input_frames = length; + src_data.data_in = malloc(length * sizeof(float)); + src_data.src_ratio = (double)mixer_freq / samplerate; + src_data.output_frames = src_data.src_ratio * length + samplerate; + src_data.data_out = malloc(src_data.output_frames * sizeof(float)); + + assert(src_data.data_in != NULL && src_data.data_out != NULL); + + // Convert input data to floats + + for (i=0; ialen = src_data.output_frames_gen * 4; + destination->abuf = Z_Malloc(destination->alen, PU_STATIC, + &destination->abuf); + expanded = (int16_t *) destination->abuf; + + for (i=0; i 16 bit and mono -> stereo + + expanded_length *= 4; + + destination->alen = expanded_length; + destination->abuf + = Z_Malloc(expanded_length, PU_STATIC, &destination->abuf); + + // If we can, use the standard / optimised SDL conversion routines. if (samplerate <= mixer_freq && ConvertibleRatio(samplerate, mixer_freq) @@ -172,7 +265,6 @@ static boolean CacheSFX(int sound) unsigned int lumplen; int samplerate; unsigned int length; - unsigned int expanded_length; byte *data; // need to load the sound @@ -205,19 +297,11 @@ static boolean CacheSFX(int sound) } // Sample rate conversion - - expanded_length = (uint32_t) ((((uint64_t) length) * mixer_freq) / samplerate); - - // Double up twice: 8 -> 16 bit and mono -> stereo - - expanded_length *= 4; + // DWF 2008-02-10: sound_chunks[sound].alen and abuf are determined + // by ExpandSoundData. sound_chunks[sound].allocated = 1; - sound_chunks[sound].alen = expanded_length; - sound_chunks[sound].abuf - = Z_Malloc(expanded_length, PU_STATIC, &sound_chunks[sound].abuf); sound_chunks[sound].volume = MIX_MAX_VOLUME; - ExpandSoundData(data + 8, samplerate, length, @@ -416,6 +500,15 @@ static boolean I_SDL_InitSound() return false; } + ExpandSoundData = ExpandSoundData_SDL; + +#ifdef HAVE_LIBSAMPLERATE + if (use_libsamplerate) + { + ExpandSoundData = ExpandSoundData_SRC; + } +#endif + Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels); Mix_AllocateChannels(NUM_CHANNELS); diff --git a/src/m_misc.c b/src/m_misc.c index d3f531b0..d1b9c567 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -299,6 +299,10 @@ extern int snd_musicdevice; extern int snd_sfxdevice; extern int snd_samplerate; +// controls whether to use libsamplerate for sample rate conversions + +extern int use_libsamplerate; + // dos specific options: these are unused but should be maintained // so that the config file can be shared between chocolate // doom and doom.exe @@ -444,6 +448,7 @@ static default_t extra_defaults_list[] = {"mouseb_backward", &mousebbackward, DEFAULT_INT, 0, 0}, {"dclick_use", &dclick_use, DEFAULT_INT, 0, 0}, + {"use_libsamplerate", &use_libsamplerate, DEFAULT_INT, 0, 0}, }; static default_collection_t extra_defaults = -- cgit v1.2.3