- int outcount;
- int srcsample, srclength;
- float stepscale;
- int i;
- int samplefrac, fracstep;
- sfxcache_t *sc;
-
- sc = Cache_Check (&sfx->cache);
- if (!sc)
- return;
-
- stepscale = (float)inrate / shm->speed; // this is usually 0.5, 1, or 2
-
- srclength = sc->length << sc->stereo;
-
- outcount = sc->length / stepscale;
- sc->length = outcount;
- if (sc->loopstart != -1)
- sc->loopstart = sc->loopstart / stepscale;
-
- sc->speed = shm->speed;
-// if (loadas8bit.value)
-// sc->width = 1;
-// else
-// sc->width = inwidth;
-// sc->stereo = 0;
-
-// resample / decimate to the current source rate
-
- if (stepscale == 1/* && inwidth == 1*/ && sc->width == 1)
+ snd_ringbuffer_t *ringbuffer;
+
+ // If the caller provides a buffer, it must give us its size
+ if (sampleframes == 0 && buffer != NULL)
+ return NULL;
+
+ ringbuffer = (snd_ringbuffer_t*)Mem_Alloc(snd_mempool, sizeof (*ringbuffer));
+ memset(ringbuffer, 0, sizeof(*ringbuffer));
+ memcpy(&ringbuffer->format, format, sizeof(ringbuffer->format));
+
+ // If we haven't been given a buffer
+ if (buffer == NULL)
+ {
+ unsigned int maxframes;
+ size_t memsize;
+
+ if (sampleframes == 0)
+ maxframes = (format->speed + 1) / 2; // Make the sound buffer large enough for containing 0.5 sec of sound
+ else
+ maxframes = sampleframes;
+
+ memsize = maxframes * format->width * format->channels;
+ ringbuffer->ring = (unsigned char *) Mem_Alloc(snd_mempool, memsize);
+ ringbuffer->maxframes = maxframes;
+ }
+ else
+ {
+ ringbuffer->ring = (unsigned char *) buffer;
+ ringbuffer->maxframes = sampleframes;
+ }
+
+ return ringbuffer;
+}
+
+
+/*
+====================
+Snd_CreateSndBuffer
+====================
+*/
+snd_buffer_t *Snd_CreateSndBuffer (const unsigned char *samples, unsigned int sampleframes, const snd_format_t* in_format, unsigned int sb_speed)
+{
+ size_t newsampleframes, memsize;
+ snd_buffer_t* sb;
+
+ newsampleframes = (size_t) ceil((double)sampleframes * (double)sb_speed / (double)in_format->speed);
+
+ memsize = newsampleframes * in_format->channels * in_format->width;
+ memsize += sizeof (*sb) - sizeof (sb->samples);
+
+ sb = (snd_buffer_t*)Mem_Alloc (snd_mempool, memsize);
+ sb->format.channels = in_format->channels;
+ sb->format.width = in_format->width;
+ sb->format.speed = sb_speed;
+ sb->maxframes = newsampleframes;
+ sb->nbframes = 0;
+
+ if (!Snd_AppendToSndBuffer (sb, samples, sampleframes, in_format))
+ {
+ Mem_Free (sb);
+ return NULL;
+ }
+
+ return sb;
+}
+
+
+/*
+====================
+Snd_AppendToSndBuffer
+====================
+*/
+qboolean Snd_AppendToSndBuffer (snd_buffer_t* sb, const unsigned char *samples, unsigned int sampleframes, const snd_format_t* format)
+{
+ size_t srclength, outcount;
+ unsigned char *out_data;
+
+ //Con_DPrintf("ResampleSfx: %d samples @ %dHz -> %d samples @ %dHz\n",
+ // sampleframes, format->speed, outcount, sb->format.speed);
+
+ // If the formats are incompatible
+ if (sb->format.channels != format->channels || sb->format.width != format->width)
+ {
+ Con_Print("AppendToSndBuffer: incompatible sound formats!\n");
+ return false;
+ }
+
+ outcount = (size_t) ((double)sampleframes * (double)sb->format.speed / (double)format->speed);
+
+ // If the sound buffer is too short
+ if (outcount > sb->maxframes - sb->nbframes)