2 Copyright (C) 2003 Mathieu Olivier
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:
18 Free Software Foundation, Inc.
19 59 Temple Place - Suite 330
20 Boston, MA 02111-1307, USA
29 extern void ResampleSfx (sfxcache_t *sc, qbyte *data, char *name);
33 =================================================================
35 Minimal set of definitions from the Ogg Vorbis lib
36 (C) COPYRIGHT 1994-2001 by the XIPHOPHORUS Company
39 WARNING: for a matter of simplicity, several pointer types are
40 casted to "void*", and most enumerated values are not included
42 =================================================================
46 typedef __int64 ogg_int64_t;
48 typedef long long ogg_int64_t;
53 size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource);
54 int (*seek_func) (void *datasource, ogg_int64_t offset, int whence);
55 int (*close_func) (void *datasource);
56 long (*tell_func) (void *datasource);
84 unsigned char *body_data;
89 ogg_int64_t *granule_vals;
94 unsigned char header[282];
100 ogg_int64_t packetno;
101 ogg_int64_t granulepos;
119 ogg_int64_t granulepos;
120 ogg_int64_t sequence;
121 ogg_int64_t glue_bits;
122 ogg_int64_t time_bits;
123 ogg_int64_t floor_bits;
124 ogg_int64_t res_bits;
132 unsigned char *buffer;
147 ogg_int64_t granulepos;
148 ogg_int64_t sequence;
149 vorbis_dsp_state *vd;
154 void *reap; // VOIDED POINTER
170 ogg_int64_t *offsets;
171 ogg_int64_t *dataoffsets;
173 ogg_int64_t *pcmlengths;
175 void *vc; // VOIDED POINTER
176 ogg_int64_t pcm_offset;
178 long current_serialno;
185 ov_callbacks callbacks;
190 =================================================================
192 DarkPlaces definitions
194 =================================================================
197 // Functions exported from the vorbisfile library
198 static int (*qov_clear) (OggVorbis_File *vf);
199 static vorbis_info* (*qov_info) (OggVorbis_File *vf,int link);
200 static int (*qov_open_callbacks) (void *datasource, OggVorbis_File *vf,
201 char *initial, long ibytes,
202 ov_callbacks callbacks);
203 static ogg_int64_t (*qov_pcm_total) (OggVorbis_File *vf,int i);
204 static long (*qov_read) (OggVorbis_File *vf,char *buffer,int length,
205 int bigendianp,int word,int sgned,int *bitstream);
207 static dllfunction_t oggvorbisfuncs[] =
209 {"ov_clear", (void **) &qov_clear},
210 {"ov_info", (void **) &qov_info},
211 {"ov_open_callbacks", (void **) &qov_open_callbacks},
212 {"ov_pcm_total", (void **) &qov_pcm_total},
213 {"ov_read", (void **) &qov_read},
217 // Handle for the Vorbisfile DLL
218 static dllhandle_t vf_dll = NULL;
223 ogg_int64_t ind, buffsize;
227 static size_t ovcb_read (void *ptr, size_t size, size_t nb, void *datasource)
229 ov_decode_t *ov_decode = (ov_decode_t*)datasource;
232 remain = ov_decode->buffsize - ov_decode->ind;
235 len = remain - remain % size;
237 memcpy (ptr, ov_decode->buffer + ov_decode->ind, len);
238 ov_decode->ind += len;
243 static int ovcb_seek (void *datasource, ogg_int64_t offset, int whence)
245 ov_decode_t *ov_decode = (ov_decode_t*)datasource;
252 offset += ov_decode->ind;
255 offset += ov_decode->buffsize;
260 if (offset < 0 || offset > ov_decode->buffsize)
263 ov_decode->ind = offset;
267 static int ovcb_close (void *ov_decode)
272 static long ovcb_tell (void *ov_decode)
274 return ((ov_decode_t*)ov_decode)->ind;
279 =================================================================
283 =================================================================
290 Try to load the VorbisFile DLL
293 qboolean OGG_OpenLibrary (void)
296 const dllfunction_t *func;
303 dllname = "vorbisfile.dll";
305 dllname = "libvorbisfile.so";
309 for (func = oggvorbisfuncs; func && func->name != NULL; func++)
310 *func->funcvariable = NULL;
313 if (! (vf_dll = Sys_LoadLibrary (dllname)))
315 Con_DPrintf("Can't find %s. Ogg Vorbis support disabled\n", dllname);
319 // Get the function adresses
320 for (func = oggvorbisfuncs; func && func->name != NULL; func++)
321 if (!(*func->funcvariable = (void *) Sys_GetProcAddress (vf_dll, func->name)))
323 Con_Printf("missing function \"%s\" - broken Ogg Vorbis library!\n", func->name);
328 Con_DPrintf("%s loaded. Ogg Vorbis support enabled\n", dllname);
337 Unload the VorbisFile DLL
340 void OGG_CloseLibrary (void)
345 Sys_UnloadLibrary (vf_dll);
351 =================================================================
355 =================================================================
362 Load an Ogg Vorbis file into a sfxcache_t
365 sfxcache_t *OGG_LoadVorbisFile (const char *filename, sfx_t *s)
368 ov_decode_t ov_decode;
370 ov_callbacks callbacks = {ovcb_read, ovcb_seek, ovcb_close, ovcb_tell};
383 data = FS_LoadFile (filename, false);
387 // Open it with the VorbisFile API
388 ov_decode.buffer = data;
390 ov_decode.buffsize = fs_filesize;
391 if (qov_open_callbacks (&ov_decode, &vf, NULL, 0, callbacks) < 0)
393 Con_Printf ("error while opening Ogg Vorbis file \"%s\"\n", filename);
398 // Get the stream information
399 vi = qov_info (&vf, -1);
400 if (vi->channels < 1 || vi->channels > 2)
402 Con_Printf ("%s has an unsupported number of channels (%i)\n",
403 s->name, vi->channels);
410 len = qov_pcm_total (&vf, -1) * vi->channels * 2; // 16 bits => "* 2"
411 buff = Mem_Alloc (tempmempool, (int)len);
414 while ((ret = qov_read (&vf, &buff[done], (int)(len - done), 0, 2, 1, &bs)) > 0)
417 // Calculate resampled length
418 len = (double)done * (double)shm->speed / (double)vi->rate;
421 Mem_FreePool (&s->mempool);
422 s->mempool = Mem_AllocPool (s->name);
423 sc = s->sfxcache = Mem_Alloc (s->mempool, (int)len + sizeof (sfxcache_t));
426 sc->length = (int)done / (vi->channels * 2);
428 sc->speed = vi->rate;
429 sc->width = 2; // We always work with 16 bits samples
430 sc->stereo = (vi->channels == 2);
432 ResampleSfx (sc, buff, s->name);
436 Con_Printf ("failed to allocate memory for sound \"%s\"\n", s->name);
437 Mem_FreePool (&s->mempool);