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.
33 If "buffer" is NULL, the function allocates one buffer of "sampleframes" sample frames itself
34 (if "sampleframes" is 0, the function chooses the size).
37 snd_ringbuffer_t *Snd_CreateRingBuffer (const snd_format_t* format, unsigned int sampleframes, void* buffer)
39 snd_ringbuffer_t *ringbuffer;
41 // If the caller provides a buffer, it must give us its size
42 if (sampleframes == 0 && buffer != NULL)
45 ringbuffer = (snd_ringbuffer_t*)Mem_Alloc(snd_mempool, sizeof (*ringbuffer));
46 memset(ringbuffer, 0, sizeof(*ringbuffer));
47 memcpy(&ringbuffer->format, format, sizeof(ringbuffer->format));
49 // If we haven't been given a buffer
52 unsigned int maxframes;
55 if (sampleframes == 0)
56 maxframes = (format->speed + 1) / 2; // Make the sound buffer large enough for containing 0.5 sec of sound
58 maxframes = sampleframes;
60 memsize = maxframes * format->width * format->channels;
61 ringbuffer->ring = Mem_Alloc(snd_mempool, memsize);
62 ringbuffer->maxframes = maxframes;
66 ringbuffer->ring = buffer;
67 ringbuffer->maxframes = sampleframes;
79 snd_buffer_t *Snd_CreateSndBuffer (const unsigned char *samples, unsigned int sampleframes, const snd_format_t* in_format, unsigned int sb_speed)
81 size_t newsampleframes, memsize;
84 newsampleframes = (double)sampleframes * (double)sb_speed / (double)in_format->speed;
86 memsize = newsampleframes * in_format->channels * in_format->width;
87 memsize += sizeof (*sb) - sizeof (sb->samples);
89 sb = (snd_buffer_t*)Mem_Alloc (snd_mempool, memsize);
90 sb->format.channels = in_format->channels;
91 sb->format.width = in_format->width;
92 sb->format.speed = sb_speed;
93 sb->maxframes = newsampleframes;
96 if (!Snd_AppendToSndBuffer (sb, samples, sampleframes, in_format))
108 Snd_AppendToSndBuffer
111 qboolean Snd_AppendToSndBuffer (snd_buffer_t* sb, const unsigned char *samples, unsigned int sampleframes, const snd_format_t* format)
113 size_t srclength, outcount;
114 unsigned char *out_data;
116 //Con_DPrintf("ResampleSfx: %d samples @ %dHz -> %d samples @ %dHz\n",
117 // sampleframes, format->speed, outcount, sb->format.speed);
119 // If the formats are incompatible
120 if (sb->format.channels != format->channels || sb->format.width != format->width)
122 Con_Print("AppendToSndBuffer: incompatible sound formats!\n");
126 outcount = (double)sampleframes * (double)sb->format.speed / (double)format->speed;
128 // If the sound buffer is too short
129 if (outcount > sb->maxframes - sb->nbframes)
131 Con_Print("AppendToSndBuffer: sound buffer too short!\n");
135 out_data = &sb->samples[sb->nbframes * sb->format.width * sb->format.channels];
136 srclength = sampleframes * format->channels;
138 // Trivial case (direct transfer)
139 if (format->speed == sb->format.speed)
141 if (format->width == 1)
145 for (i = 0; i < srclength; i++)
146 ((signed char*)out_data)[i] = samples[i] - 128;
148 else // if (format->width == 2)
149 memcpy (out_data, samples, srclength * format->width);
152 // General case (linear interpolation with a fixed-point fractional
153 // step, 18-bit integer part and 14-bit fractional part)
154 // Can handle up to 2^18 (262144) samples per second (> 96KHz stereo)
155 # define FRACTIONAL_BITS 14
156 # define FRACTIONAL_MASK ((1 << FRACTIONAL_BITS) - 1)
157 # define INTEGER_BITS (sizeof(samplefrac)*8 - FRACTIONAL_BITS)
160 const unsigned int fracstep = (unsigned int)((double)format->speed / sb->format.speed * (1 << FRACTIONAL_BITS));
161 size_t remain_in = srclength, total_out = 0;
162 unsigned int samplefrac;
163 const unsigned char *in_ptr = samples;
164 unsigned char *out_ptr = out_data;
166 // Check that we can handle one second of that sound
167 if (format->speed * format->channels > (1 << INTEGER_BITS))
169 Con_Printf ("ResampleSfx: sound quality too high for resampling (%uHz, %u channel(s))\n",
170 format->speed, format->channels);
174 // We work 1 sec at a time to make sure we don't accumulate any
175 // significant error when adding "fracstep" over several seconds, and
176 // also to be able to handle very long sounds.
177 while (total_out < outcount)
179 size_t tmpcount, interpolation_limit, i, j;
180 unsigned int srcsample;
184 // If more than 1 sec of sound remains to be converted
185 if (outcount - total_out > sb->format.speed)
187 tmpcount = sb->format.speed;
188 interpolation_limit = tmpcount; // all samples can be interpolated
192 tmpcount = outcount - total_out;
193 interpolation_limit = (int)ceil((double)(((remain_in / format->channels) - 1) << FRACTIONAL_BITS) / fracstep);
194 if (interpolation_limit > tmpcount)
195 interpolation_limit = tmpcount;
199 if (format->width == 2)
201 const short* in_ptr_short;
204 for (i = 0; i < interpolation_limit; i++)
206 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
207 in_ptr_short = &((const short*)in_ptr)[srcsample];
209 for (j = 0; j < format->channels; j++)
214 b = *(in_ptr_short + format->channels);
215 *((short*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
218 out_ptr += sizeof (short);
221 samplefrac += fracstep;
224 // Non-interpolated part
225 for (/* nothing */; i < tmpcount; i++)
227 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
228 in_ptr_short = &((const short*)in_ptr)[srcsample];
230 for (j = 0; j < format->channels; j++)
232 *((short*)out_ptr) = *in_ptr_short;
235 out_ptr += sizeof (short);
238 samplefrac += fracstep;
242 else // if (format->width == 1)
244 const unsigned char* in_ptr_byte;
246 // Convert up to 1 sec of sound
247 for (i = 0; i < interpolation_limit; i++)
249 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
250 in_ptr_byte = &((const unsigned char*)in_ptr)[srcsample];
252 for (j = 0; j < format->channels; j++)
256 a = *in_ptr_byte - 128;
257 b = *(in_ptr_byte + format->channels) - 128;
258 *((signed char*)out_ptr) = (((b - a) * (samplefrac & FRACTIONAL_MASK)) >> FRACTIONAL_BITS) + a;
261 out_ptr += sizeof (signed char);
264 samplefrac += fracstep;
267 // Non-interpolated part
268 for (/* nothing */; i < tmpcount; i++)
270 srcsample = (samplefrac >> FRACTIONAL_BITS) * format->channels;
271 in_ptr_byte = &((const unsigned char*)in_ptr)[srcsample];
273 for (j = 0; j < format->channels; j++)
275 *((signed char*)out_ptr) = *in_ptr_byte - 128;
278 out_ptr += sizeof (signed char);
281 samplefrac += fracstep;
285 // Update the counters and the buffer position
286 remain_in -= format->speed * format->channels;
287 in_ptr += format->speed * format->channels * format->width;
288 total_out += tmpcount;
292 sb->nbframes += outcount;
297 //=============================================================================
304 qboolean S_LoadSound (sfx_t *sfx, qboolean complain)
306 char namebuffer[MAX_QPATH + 16];
309 // See if already loaded
310 if (sfx->fetcher != NULL)
313 // If we weren't able to load it previously, no need to retry
314 // Note: S_PrecacheSound clears this flag to cause a retry
315 if (sfx->flags & SFXFLAG_FILEMISSING)
319 if (snd_renderbuffer == NULL)
322 // Initialize volume peak to 0; if ReplayGain is supported, the loader will change this away
323 sfx->volume_peak = 0.0;
325 // LordHavoc: if the sound filename does not begin with sound/, try adding it
326 if (strncasecmp(sfx->name, "sound/", 6))
328 len = dpsnprintf (namebuffer, sizeof(namebuffer), "sound/%s", sfx->name);
332 Con_DPrintf("S_LoadSound: name \"%s\" is too long\n", sfx->name);
335 if (S_LoadWavFile (namebuffer, sfx))
337 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
338 memcpy (namebuffer + len - 3, "ogg", 4);
339 if (OGG_LoadVorbisFile (namebuffer, sfx))
343 // LordHavoc: then try without the added sound/ as wav and ogg
344 len = dpsnprintf (namebuffer, sizeof(namebuffer), "%s", sfx->name);
348 Con_DPrintf("S_LoadSound: name \"%s\" is too long\n", sfx->name);
351 if (S_LoadWavFile (namebuffer, sfx))
353 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
354 memcpy (namebuffer + len - 3, "ogg", 4);
355 if (OGG_LoadVorbisFile (namebuffer, sfx))
358 // Can't load the sound!
359 sfx->flags |= SFXFLAG_FILEMISSING;
361 Con_DPrintf("S_LoadSound: Couldn't load \"%s\"\n", sfx->name);