mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
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:
parent
ddf4f257f4
commit
930ba48862
4 changed files with 61 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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 !!!
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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, ¤t_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, ¤t_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);
|
||||
|
|
Loading…
Reference in a new issue