void *internal;
} vorbis_block;
+typedef struct
+{
+ char **user_comments;
+ int *comment_lengths;
+ int comments;
+ char *vendor;
+} vorbis_comment;
+
typedef struct
{
void *datasource;
long *serialnos;
ogg_int64_t *pcmlengths;
vorbis_info *vi;
- void *vc; // VOIDED POINTER
+ vorbis_comment *vc;
ogg_int64_t pcm_offset;
int ready_state;
long current_serialno;
// Functions exported from the vorbisfile library
static int (*qov_clear) (OggVorbis_File *vf);
static vorbis_info* (*qov_info) (OggVorbis_File *vf,int link);
+static vorbis_comment* (*qov_comment) (OggVorbis_File *vf,int link);
+static char * (*qvorbis_comment_query) (vorbis_comment *vc, char *tag, int count);
static int (*qov_open_callbacks) (void *datasource, OggVorbis_File *vf,
char *initial, long ibytes,
ov_callbacks callbacks);
static long (*qov_read) (OggVorbis_File *vf,char *buffer,int length,
int bigendianp,int word,int sgned,int *bitstream);
-static dllfunction_t oggvorbisfuncs[] =
+static dllfunction_t vorbisfilefuncs[] =
+{
+ {"ov_clear", (void **) &qov_clear},
+ {"ov_info", (void **) &qov_info},
+ {"ov_comment", (void **) &qov_comment},
+ {"ov_open_callbacks", (void **) &qov_open_callbacks},
+ {"ov_pcm_seek", (void **) &qov_pcm_seek},
+ {"ov_pcm_total", (void **) &qov_pcm_total},
+ {"ov_read", (void **) &qov_read},
+ {NULL, NULL}
+};
+
+static dllfunction_t vorbisfuncs[] =
{
- {"ov_clear", (void **) &qov_clear},
- {"ov_info", (void **) &qov_info},
- {"ov_open_callbacks", (void **) &qov_open_callbacks},
- {"ov_pcm_seek", (void **) &qov_pcm_seek},
- {"ov_pcm_total", (void **) &qov_pcm_total},
- {"ov_read", (void **) &qov_read},
+ {"vorbis_comment_query", (void **) &qvorbis_comment_query},
{NULL, NULL}
};
// Load the DLLs
// We need to load both by hand because some OSes seem to not load
// the vorbis DLL automatically when loading the VorbisFile DLL
- if (! Sys_LoadLibrary (dllnames_vo, &vo_dll, NULL) ||
- ! Sys_LoadLibrary (dllnames_vf, &vf_dll, oggvorbisfuncs))
+ if (! Sys_LoadLibrary (dllnames_vo, &vo_dll, vorbisfuncs) ||
+ ! Sys_LoadLibrary (dllnames_vf, &vf_dll, vorbisfilefuncs))
{
Sys_UnloadLibrary (&vo_dll);
Con_Printf ("Ogg Vorbis support disabled\n");
ch->fetcher_data = per_ch;
}
-
+
real_start = *start;
sb = &per_ch->sb;
unsigned int time_start;
ogg_int64_t ogg_start;
int err;
-
- if (real_start > sfx->total_length)
+
+ if (real_start > (unsigned int)sfx->total_length)
{
Con_Printf ("OGG_FetchSound: asked for a start position after the end of the sfx! (%u > %u)\n",
real_start, sfx->total_length);
qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
{
unsigned char *data;
+ const char *loopcomment;
fs_offset_t filesize;
ov_decode_t ov_decode;
OggVorbis_File vf;
vorbis_info *vi;
+ vorbis_comment *vc;
ogg_int64_t len, buff_len;
if (!vf_dll)
sfx->fetcher_data = per_sfx;
sfx->fetcher = &ogg_fetcher;
- sfx->loopstart = -1;
sfx->flags |= SFXFLAG_STREAMED;
sfx->total_length = (int)((size_t)len / (per_sfx->format.channels * 2) * ((double)snd_renderbuffer->format.speed / per_sfx->format.speed));
+ sfx->loopstart = sfx->total_length;
+ vc = qov_comment(&vf, -1);
+ if(vc)
+ {
+ loopcomment = qvorbis_comment_query(vc, "LOOP_START", 0);
+ if(loopcomment)
+ sfx->loopstart = bound(0, (unsigned int) (atof(loopcomment) * (double)snd_renderbuffer->format.speed / (double)per_sfx->format.speed), sfx->total_length);
+ }
}
else
{
sfx->total_length = sb->nbframes;
sfx->memsize += sb->maxframes * sb->format.channels * sb->format.width + sizeof (*sb) - sizeof (sb->samples);
- sfx->loopstart = -1;
+ sfx->loopstart = sfx->total_length;
sfx->flags &= ~SFXFLAG_STREAMED;
+ vc = qov_comment(&vf, -1);
+ if(vc)
+ {
+ loopcomment = qvorbis_comment_query(vc, "LOOP_START", 0);
+ if(loopcomment)
+ sfx->loopstart = bound(0, (unsigned int) (atoi(loopcomment) * (double)snd_renderbuffer->format.speed / (double)sb->format.speed), sfx->total_length);
+ }
qov_clear (&vf);
Mem_Free (data);