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.
27 #include "snd_modplug.h"
34 If "buffer" is NULL, the function allocates one buffer of "sampleframes" sample frames itself
35 (if "sampleframes" is 0, the function chooses the size).
38 snd_ringbuffer_t *Snd_CreateRingBuffer (const snd_format_t* format, unsigned int sampleframes, void* buffer)
40 snd_ringbuffer_t *ringbuffer;
42 // If the caller provides a buffer, it must give us its size
43 if (sampleframes == 0 && buffer != NULL)
46 ringbuffer = (snd_ringbuffer_t*)Mem_Alloc(snd_mempool, sizeof (*ringbuffer));
47 memset(ringbuffer, 0, sizeof(*ringbuffer));
48 memcpy(&ringbuffer->format, format, sizeof(ringbuffer->format));
50 // If we haven't been given a buffer
53 unsigned int maxframes;
56 if (sampleframes == 0)
57 maxframes = (format->speed + 1) / 2; // Make the sound buffer large enough for containing 0.5 sec of sound
59 maxframes = sampleframes;
61 memsize = maxframes * format->width * format->channels;
62 ringbuffer->ring = Mem_Alloc(snd_mempool, memsize);
63 ringbuffer->maxframes = maxframes;
67 ringbuffer->ring = buffer;
68 ringbuffer->maxframes = sampleframes;
80 snd_buffer_t *Snd_CreateSndBuffer (const unsigned char *samples, unsigned int sampleframes, const snd_format_t* in_format, unsigned int sb_speed)
82 size_t newsampleframes, memsize;
85 newsampleframes = (double)sampleframes * (double)sb_speed / (double)in_format->speed;
87 memsize = newsampleframes * in_format->channels * in_format->width;
88 memsize += sizeof (*sb) - sizeof (sb->samples);
90 sb = (snd_buffer_t*)Mem_Alloc (snd_mempool, memsize);
91 sb->format.channels = in_format->channels;
92 sb->format.width = in_format->width;
93 sb->format.speed = sb_speed;
94 sb->maxframes = newsampleframes;
97 if (!Snd_AppendToSndBuffer (sb, samples, sampleframes, in_format))
109 Snd_AppendToSndBuffer
112 qboolean Snd_AppendToSndBuffer (snd_buffer_t* sb, const unsigned char *samples, unsigned int sampleframes, const snd_format_t* format)
114 size_t srclength, outcount;
115 unsigned char *out_data;
117 //Con_DPrintf("ResampleSfx: %d samples @ %dHz -> %d samples @ %dHz\n",
118 // sampleframes, format->speed, outcount, sb->format.speed);
120 // If the formats are incompatible
121 if (sb->format.channels != format->channels || sb->format.width != format->width)
123 Con_Print("AppendToSndBuffer: incompatible sound formats!\n");
127 outcount = (double)sampleframes * (double)sb->format.speed / (double)format->speed;
129 // If the sound buffer is too short
130 if (outcount > sb->maxframes - sb->nbframes)
132 Con_Print("AppendToSndBuffer: sound buffer too short!\n");
136 out_data = &sb->samples[sb->nbframes * sb->format.width * sb->format.channels];
137 srclength = sampleframes * format->channels;
139 // Trivial case (direct transfer)
140 if (format->speed == sb->format.speed)
142 if (format->width == 1)
146 for (i = 0; i < srclength; i++)
147 ((signed char*)out_data)[i] = samples[i] - 128;
149 else // if (format->width == 2)
150 memcpy (out_data, samples, srclength * format->width);
153 // General case (linear interpolation with a fixed-point fractional
154 // step, 18-bit integer part and 14-bit fractional part)
155 // Can handle up to 2^18 (262144) samples per second (> 96KHz stereo)
156 # define FRACTIONAL_BITS 14
157 # define FRACTIONAL_MASK ((1 << FRACTIONAL_BITS) - 1)
158 # define INTEGER_BITS (sizeof(samplefrac)*8 - FRACTIONAL_BITS)
161 const unsigned int fracstep = (unsigned int)((double)format->speed / sb->format.speed * (1 << FRACTIONAL_BITS));
162 size_t remain_in = srclength, total_out = 0;
163 unsigned int samplefrac;
164 const unsigned char *in_ptr = samples;
165 unsigned char *out_ptr = out_data;
167 // Check that we can handle one second of that sound
168 if (format->speed * format->channels > (1 << INTEGER_BITS))
170 Con_Printf ("ResampleSfx: sound quality too high for resampling (%uHz, %u channel(s))\n",
171 format->speed, format->channels);
175 // We work 1 sec at a time to make sure we don't accumulate any
176 // significant error when adding "fracstep" over several seconds, and
177 // also to be able to handle very long sounds.
178 while (total_out < outcount)
180 size_t tmpcount, interpolation_limit, i, j;
181 unsigned int srcsample;
185 // If more than 1 sec of sound remains to be converted
186 if (outcount - total_out > sb->format.speed)
188 tmpcount = sb->format.speed;
189 interpolation_limit = tmpcount; // all samples can be interpolated
193 tmpcount = outcount - total_out;
194 interpolation_limit = (int)ceil((double)(((remain_in / format->channels) - 1) << FRACTIONAL_BITS) / fracstep);
195 if (interpolation_limit > tmpcount)
196 interpolation_limit = tmpcount;
200 if (format->width == 2)
202 const short* in_ptr_short;
205 for (i = 0; i < interpolation_limit; i++)
207 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
208 in_ptr_short = &((const short*)in_ptr)[srcsample];
210 for (j = 0; j < format->channels; j++)
215 b = *(in_ptr_short + format->channels);
216 *((short*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
219 out_ptr += sizeof (short);
222 samplefrac += fracstep;
225 // Non-interpolated part
226 for (/* nothing */; i < tmpcount; i++)
228 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
229 in_ptr_short = &((const short*)in_ptr)[srcsample];
231 for (j = 0; j < format->channels; j++)
233 *((short*)out_ptr) = *in_ptr_short;
236 out_ptr += sizeof (short);
239 samplefrac += fracstep;
243 else // if (format->width == 1)
245 const unsigned char* in_ptr_byte;
247 // Convert up to 1 sec of sound
248 for (i = 0; i < interpolation_limit; i++)
250 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
251 in_ptr_byte = &((const unsigned char*)in_ptr)[srcsample];
253 for (j = 0; j < format->channels; j++)
257 a = *in_ptr_byte - 128;
258 b = *(in_ptr_byte + format->channels) - 128;
259 *((signed char*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
262 out_ptr += sizeof (signed char);
265 samplefrac += fracstep;
268 // Non-interpolated part
269 for (/* nothing */; i < tmpcount; i++)
271 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
272 in_ptr_byte = &((const unsigned char*)in_ptr)[srcsample];
274 for (j = 0; j < format->channels; j++)
276 *((signed char*)out_ptr) = *in_ptr_byte - 128;
279 out_ptr += sizeof (signed char);
282 samplefrac += fracstep;
286 // Update the counters and the buffer position
287 remain_in -= format->speed * format->channels;
288 in_ptr += format->speed * format->channels * format->width;
289 total_out += tmpcount;
293 sb->nbframes += outcount;
298 //=============================================================================
305 qboolean S_LoadSound (sfx_t *sfx, qboolean complain)
307 char namebuffer[MAX_QPATH + 16];
310 // See if already loaded
311 if (sfx->fetcher != NULL)
314 // If we weren't able to load it previously, no need to retry
315 // Note: S_PrecacheSound clears this flag to cause a retry
316 if (sfx->flags & SFXFLAG_FILEMISSING)
320 if (snd_renderbuffer == NULL)
323 // Initialize volume peak to 0; if ReplayGain is supported, the loader will change this away
324 sfx->volume_peak = 0.0;
326 if (developer_loading.integer)
327 Con_Printf("loading sound %s\n", sfx->name);
329 // LordHavoc: if the sound filename does not begin with sound/, try adding it
330 if (strncasecmp(sfx->name, "sound/", 6))
332 dpsnprintf (namebuffer, sizeof(namebuffer), "sound/%s", sfx->name);
333 len = strlen(namebuffer);
334 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
336 if (S_LoadWavFile (namebuffer, sfx))
338 memcpy (namebuffer + len - 3, "ogg", 4);
340 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".ogg"))
342 if (OGG_LoadVorbisFile (namebuffer, sfx))
347 if (ModPlug_LoadModPlugFile (namebuffer, sfx))
352 // LordHavoc: then try without the added sound/ as wav and ogg
353 dpsnprintf (namebuffer, sizeof(namebuffer), "%s", sfx->name);
354 len = strlen(namebuffer);
355 // request foo.wav: tries foo.wav, then foo.ogg
356 // request foo.ogg: tries foo.ogg only
357 // request foo.mod: tries foo.mod only
358 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
360 if (S_LoadWavFile (namebuffer, sfx))
362 memcpy (namebuffer + len - 3, "ogg", 4);
364 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".ogg"))
366 if (OGG_LoadVorbisFile (namebuffer, sfx))
371 if (ModPlug_LoadModPlugFile (namebuffer, sfx))
375 // Can't load the sound!
376 sfx->flags |= SFXFLAG_FILEMISSING;
378 Con_DPrintf("failed to load sound \"%s\"\n", sfx->name);