other than sounds that are ment to loop not looping (due to losing that info

when converting to ogg (I've got some ideas on that)), ogg/vorbis support is
working. Doesn't seem to be too much of a load-time hit.
This commit is contained in:
Bill Currie 2002-06-15 05:43:56 +00:00
parent ddf4f257f4
commit 930ba48862
4 changed files with 61 additions and 20 deletions

View file

@ -63,7 +63,8 @@ typedef struct
int speed;
int width;
int stereo;
byte data[1]; // variable sized
int size;
byte data[4]; // variable sized
} sfxcache_t;
typedef struct

View file

@ -78,7 +78,8 @@
#define sfxc_speed 8
#define sfxc_width 12
#define sfxc_stereo 16
#define sfxc_data 20
#define sfxc_size 20
#define sfxc_data 24
// channel_t structure
// !!! if this is changed, it much be changed in sound.h too !!!

View file

@ -50,14 +50,38 @@ wavinfo_t SND_GetWavinfo (const char *name, byte * wav, int wavlength);
sfxcache_t *SND_LoadSound (sfx_t *sfx, cache_allocator_t allocator);
sfxcache_t *SND_LoadOgg (VFile *file, sfx_t *sfx, cache_allocator_t allocator);
sfxcache_t *
SND_GetCache (long samples, int rate, int inwidth, int channels,
sfx_t *sfx, cache_allocator_t allocator)
{
int size;
int width;
sfxcache_t *sc;
width = snd_loadas8bit->int_val ? 1 : 2;
size = samples / ((float) rate / shm->speed);
size *= width * channels;
sc = allocator (&sfx->cache, size + sizeof (sfxcache_t), sfx->name);
if (!sc)
return 0;
sc->length = samples;
sc->speed = rate;
sc->width = inwidth;
sc->stereo = channels;
sc->size = size;
memcpy (sc->data + size, "\xde\xad\xbe\xef", 4);
return sc;
}
void
SND_ResampleSfx (sfxcache_t *sc, int inrate, int inwidth, byte * data)
SND_ResampleSfx (sfxcache_t *sc, byte * data)
{
unsigned char *ib, *ob;
int fracstep, outcount, sample, samplefrac, srcsample, i;
float stepscale;
short *is, *os;
int inwidth = sc->width;
int inrate = sc->speed;
is = (short *) data;
os = (short *) sc->data;
@ -150,6 +174,8 @@ SND_ResampleSfx (sfxcache_t *sc, int inrate, int inwidth, byte * data)
sc->length = outcount;
if (sc->loopstart != -1)
sc->loopstart = sc->loopstart / stepscale;
if (memcmp (sc->data + sc->size, "\xde\xad\xbe\xef", 4))
Sys_Error ("SND_ResampleSfx screwed the pooch");
}
sfxcache_t *
@ -199,18 +225,14 @@ SND_LoadSound (sfx_t *sfx, cache_allocator_t allocator)
len = len * 2 * info.channels;
}
sc = allocator (&sfx->cache, len + sizeof (sfxcache_t), sfx->name);
sc = SND_GetCache (info.samples, info.rate, info.width, info.channels,
sfx, allocator);
if (!sc)
return NULL;
sc->length = info.samples;
sc->loopstart = info.loopstart;
sc->speed = info.rate;
sc->width = info.width;
sc->stereo = info.channels;
SND_ResampleSfx (sc, sc->speed, sc->width, data + info.dataofs);
SND_ResampleSfx (sc, data + info.dataofs);
return sc;
}

View file

@ -33,6 +33,12 @@ static const char rcsid[] =
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include "string.h"
#endif
#ifdef HAVE_STRINGS_H
# include "strings.h"
#endif
#ifdef HAVE_VORBIS
@ -45,7 +51,9 @@ static const char rcsid[] =
#include "QF/vfile.h"
//FIXME should be in header
void SND_ResampleSfx (sfxcache_t *sc, int inrate, int inwidth, byte * data);
void SND_ResampleSfx (sfxcache_t *sc, byte * data);
sfxcache_t *SND_GetCache (long samples, int rate, int inwidth, int channels,
sfx_t *sfx, cache_allocator_t allocator);
static size_t
read_func (void *ptr, size_t size, size_t nmemb, void *datasource)
@ -85,7 +93,7 @@ SND_LoadOgg (VFile *file, sfx_t *sfx, cache_allocator_t allocator)
OggVorbis_File vf;
vorbis_info *vi;
long samples, size;
void *data;
byte *data, *d;
int current_section;
sfxcache_t *sc = 0;
@ -110,16 +118,25 @@ SND_LoadOgg (VFile *file, sfx_t *sfx, cache_allocator_t allocator)
data = malloc (size);
if (!data)
goto bail;
sc = allocator (&sfx->cache, size + sizeof (sfxcache_t), sfx->name);
sc = SND_GetCache (samples, vi->rate, 2, vi->channels, sfx, allocator);
if (!sc)
goto bail;
ov_read (&vf, data, size, 0, 2, 1, &current_section);
sc->length = samples;
sc->loopstart = 0;
sc->speed = vi->rate;
sc->width = 2;
sc->stereo = vi->channels;
SND_ResampleSfx (sc, sc->speed, sc->width, data);
d = data;
while (size) {
int res = ov_read (&vf, d, size, 0, 2, 1, &current_section);
if (res > 0) {
size -= res;
d += res;
} else if (res < 0) {
Sys_Printf ("vorbis error %d\n", res);
goto bail;
} else {
Sys_Printf ("unexpected eof\n");
break;
}
}
sc->loopstart = -1; //FIXME this breaks looped sounds
SND_ResampleSfx (sc, data);
bail:
if (data)
free (data);