2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 size_t ResampleSfx (const qbyte *in_data, size_t in_length, const snd_format_t* in_format, qbyte *out_data, const char* sfxname)
36 size_t srclength, outcount, i;
38 srclength = in_length * in_format->channels;
39 outcount = (double)in_length * shm->format.speed / in_format->speed;
41 //Con_DPrintf("ResampleSfx(%s): %d samples @ %dHz -> %d samples @ %dHz\n",
42 // sfxname, in_length, in_format->speed, outcount, shm->format.speed);
44 // Trivial case (direct transfer)
45 if (in_format->speed == shm->format.speed)
47 if (in_format->width == 1)
49 for (i = 0; i < srclength; i++)
50 ((signed char*)out_data)[i] = in_data[i] - 128;
52 else // if (in_format->width == 2)
53 memcpy (out_data, in_data, srclength * in_format->width);
56 // General case (linear interpolation with a fixed-point fractional
57 // step, 18-bit integer part and 14-bit fractional part)
58 // Can handle up to 2^18 (262144) samples per second (> 96KHz stereo)
59 #define FRACTIONAL_BITS 14
60 #define FRACTIONAL_MASK ((1 << FRACTIONAL_BITS) - 1)
61 #define INTEGER_BITS (sizeof(samplefrac)*8 - FRACTIONAL_BITS)
64 const unsigned int fracstep = (double)in_format->speed / shm->format.speed * (1 << FRACTIONAL_BITS);
65 size_t remain_in = srclength, total_out = 0;
66 unsigned int samplefrac;
67 const qbyte *in_ptr = in_data;
68 qbyte *out_ptr = out_data;
70 // Check that we can handle one second of that sound
71 if (in_format->speed * in_format->channels > (1 << INTEGER_BITS))
72 Sys_Error ("ResampleSfx: sound quality too high for resampling (%uHz, %u channel(s))",
73 in_format->speed, in_format->channels);
75 // We work 1 sec at a time to make sure we don't accumulate any
76 // significant error when adding "fracstep" over several seconds, and
77 // also to be able to handle very long sounds.
78 while (total_out < outcount)
84 // If more than 1 sec of sound remains to be converted
85 if (outcount - total_out > shm->format.speed)
86 tmpcount = shm->format.speed;
88 tmpcount = outcount - total_out;
90 // Convert up to 1 sec of sound
91 for (i = 0; i < tmpcount; i++)
94 unsigned int srcsample = (samplefrac >> FRACTIONAL_BITS) * in_format->channels;
98 if (in_format->width == 2)
100 for (j = 0; j < in_format->channels; j++, srcsample++)
102 // No value to interpolate with?
103 if (srcsample + in_format->channels < remain_in)
105 a = ((const short*)in_ptr)[srcsample];
106 b = ((const short*)in_ptr)[srcsample + in_format->channels];
107 *((short*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
110 *((short*)out_ptr) = ((const short*)in_ptr)[srcsample];
112 out_ptr += sizeof (short);
116 else // if (in_format->width == 1)
118 for (j = 0; j < in_format->channels; j++, srcsample++)
120 // No more value to interpolate with?
121 if (srcsample + in_format->channels < remain_in)
123 a = ((const qbyte*)in_ptr)[srcsample] - 128;
124 b = ((const qbyte*)in_ptr)[srcsample + in_format->channels] - 128;
125 *((signed char*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
128 *((signed char*)out_ptr) = ((const qbyte*)in_ptr)[srcsample] - 128;
130 out_ptr += sizeof (signed char);
134 samplefrac += fracstep;
137 // Update the counters and the buffer position
138 remain_in -= in_format->speed * in_format->channels;
139 in_ptr += in_format->speed * in_format->channels * in_format->width;
140 total_out += tmpcount;
147 //=============================================================================
154 qboolean S_LoadSound (sfx_t *s, qboolean complain)
156 char namebuffer[MAX_QPATH + 16];
159 if (!shm || !shm->format.speed)
162 // If we weren't able to load it previously, no need to retry
163 if (s->flags & SFXFLAG_FILEMISSING)
167 if (s->fetcher != NULL)
169 if (s->format.speed != shm->format.speed)
170 Sys_Error ("S_LoadSound: sound %s hasn't been resampled (%uHz instead of %uHz)", s->name);
174 // LordHavoc: if the sound filename does not begin with sound/, try adding it
175 if (strncasecmp(s->name, "sound/", 6))
177 len = dpsnprintf (namebuffer, sizeof(namebuffer), "sound/%s", s->name);
181 Con_Printf("S_LoadSound: name \"%s\" is too long\n", s->name);
184 if (S_LoadWavFile (namebuffer, s))
186 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
187 strcpy (namebuffer + len - 3, "ogg");
188 if (OGG_LoadVorbisFile (namebuffer, s))
192 // LordHavoc: then try without the added sound/ as wav and ogg
193 len = dpsnprintf (namebuffer, sizeof(namebuffer), "%s", s->name);
197 Con_Printf("S_LoadSound: name \"%s\" is too long\n", s->name);
200 if (S_LoadWavFile (namebuffer, s))
202 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
203 strcpy (namebuffer + len - 3, "ogg");
204 if (OGG_LoadVorbisFile (namebuffer, s))
207 // Can't load the sound!
208 s->flags |= SFXFLAG_FILEMISSING;
210 Con_Printf("S_LoadSound: Couldn't load \"%s\"\n", s->name);
214 void S_UnloadSound (sfx_t *s)
216 if (s->fetcher != NULL)
220 // Stop all channels that use this sound
221 for (i = 0; i < total_channels ; i++)
222 if (channels[i].sfx == s)
226 s->fetcher_data = NULL;
227 Mem_FreePool(&s->mempool);