]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_ogg.c
allow linking to libvorbis
[xonotic/darkplaces.git] / snd_ogg.c
index 5b7bbcba10d8570a42fcadb38f690e0ed3be6780..c3143ac9ba6bf381ff7d77cca0c03aaca73c8f17 100644 (file)
--- a/snd_ogg.c
+++ b/snd_ogg.c
 #include "snd_ogg.h"
 #include "snd_wav.h"
 
+#ifdef LINK_TO_LIBVORBIS
+#define OV_EXCLUDE_STATIC_CALLBACKS
+#include <ogg/ogg.h>
+#include <vorbis/vorbisfile.h>
+
+#define qov_clear ov_clear
+#define qov_info ov_info
+#define qov_comment ov_comment
+#define qov_open_callbacks ov_open_callbacks
+#define qov_pcm_seek ov_pcm_seek
+#define qov_pcm_total ov_pcm_total
+#define qov_read ov_read
+#define qvorbis_comment_query vorbis_comment_query
+
+qboolean OGG_OpenLibrary (void) {return true;}
+void OGG_CloseLibrary (void) {}
+#else
 
 /*
 =================================================================
@@ -236,63 +253,6 @@ static dllfunction_t vorbisfuncs[] =
 static dllhandle_t vo_dll = NULL;
 static dllhandle_t vf_dll = NULL;
 
-typedef struct
-{
-       unsigned char *buffer;
-       ogg_int64_t ind, buffsize;
-} ov_decode_t;
-
-
-static size_t ovcb_read (void *ptr, size_t size, size_t nb, void *datasource)
-{
-       ov_decode_t *ov_decode = (ov_decode_t*)datasource;
-       size_t remain, len;
-
-       remain = ov_decode->buffsize - ov_decode->ind;
-       len = size * nb;
-       if (remain < len)
-               len = remain - remain % size;
-
-       memcpy (ptr, ov_decode->buffer + ov_decode->ind, len);
-       ov_decode->ind += len;
-
-       return len / size;
-}
-
-static int ovcb_seek (void *datasource, ogg_int64_t offset, int whence)
-{
-       ov_decode_t *ov_decode = (ov_decode_t*)datasource;
-
-       switch (whence)
-       {
-               case SEEK_SET:
-                       break;
-               case SEEK_CUR:
-                       offset += ov_decode->ind;
-                       break;
-               case SEEK_END:
-                       offset += ov_decode->buffsize;
-                       break;
-               default:
-                       return -1;
-       }
-       if (offset < 0 || offset > ov_decode->buffsize)
-               return -1;
-
-       ov_decode->ind = offset;
-       return 0;
-}
-
-static int ovcb_close (void *ov_decode)
-{
-       return 0;
-}
-
-static long ovcb_tell (void *ov_decode)
-{
-       return ((ov_decode_t*)ov_decode)->ind;
-}
-
 
 /*
 =================================================================
@@ -313,9 +273,7 @@ qboolean OGG_OpenLibrary (void)
 {
        const char* dllnames_vo [] =
        {
-#if defined(WIN64)
-               "libvorbis64.dll",
-#elif defined(WIN32)
+#if defined(WIN32)
                "libvorbis.dll",
                "vorbis.dll",
 #elif defined(MACOSX)
@@ -328,9 +286,7 @@ qboolean OGG_OpenLibrary (void)
        };
        const char* dllnames_vf [] =
        {
-#if defined(WIN64)
-               "libvorbisfile64.dll",
-#elif defined(WIN32)
+#if defined(WIN32)
                "libvorbisfile.dll",
                "vorbisfile.dll",
 #elif defined(MACOSX)
@@ -370,6 +326,7 @@ void OGG_CloseLibrary (void)
        Sys_UnloadLibrary (&vo_dll);
 }
 
+#endif
 
 /*
 =================================================================
@@ -379,6 +336,62 @@ void OGG_CloseLibrary (void)
 =================================================================
 */
 
+typedef struct
+{
+       unsigned char *buffer;
+       ogg_int64_t ind, buffsize;
+} ov_decode_t;
+
+static size_t ovcb_read (void *ptr, size_t size, size_t nb, void *datasource)
+{
+       ov_decode_t *ov_decode = (ov_decode_t*)datasource;
+       size_t remain, len;
+
+       remain = ov_decode->buffsize - ov_decode->ind;
+       len = size * nb;
+       if (remain < len)
+               len = remain - remain % size;
+
+       memcpy (ptr, ov_decode->buffer + ov_decode->ind, len);
+       ov_decode->ind += len;
+
+       return len / size;
+}
+
+static int ovcb_seek (void *datasource, ogg_int64_t offset, int whence)
+{
+       ov_decode_t *ov_decode = (ov_decode_t*)datasource;
+
+       switch (whence)
+       {
+               case SEEK_SET:
+                       break;
+               case SEEK_CUR:
+                       offset += ov_decode->ind;
+                       break;
+               case SEEK_END:
+                       offset += ov_decode->buffsize;
+                       break;
+               default:
+                       return -1;
+       }
+       if (offset < 0 || offset > ov_decode->buffsize)
+               return -1;
+
+       ov_decode->ind = offset;
+       return 0;
+}
+
+static int ovcb_close (void *ov_decode)
+{
+       return 0;
+}
+
+static long ovcb_tell (void *ov_decode)
+{
+       return ((ov_decode_t*)ov_decode)->ind;
+}
+
 // Per-sfx data structure
 typedef struct
 {
@@ -412,7 +425,7 @@ static const snd_buffer_t* OGG_FetchSound (void *sfxfetcher, void **chfetcherpoi
        ogg_stream_perchannel_t* per_ch = (ogg_stream_perchannel_t *)*chfetcherpointer;
        ogg_stream_persfx_t* per_sfx = (ogg_stream_persfx_t *)sfxfetcher;
        snd_buffer_t* sb;
-       int newlength, done, ret, bigendian;
+       int newlength, done, ret;
        unsigned int real_start;
        unsigned int factor;
 
@@ -515,27 +528,23 @@ static const snd_buffer_t* OGG_FetchSound (void *sfxfetcher, void **chfetcherpoi
 
        per_ch->sb_offset = real_start;
 
-       // We add exactly 1 sec of sound to the buffer:
-       // 1- to ensure we won't lose any sample during the resampling process
-       // 2- to force one call to OGG_FetchSound per second to regulate the workload
-       if ((int)(sb->format.speed * STREAM_BUFFER_FILL) + sb->nbframes > sb->maxframes)
+       // We add more than one frame of sound to the buffer:
+       // 1- to ensure we won't lose many samples during the resampling process
+       // 2- to reduce calls to OGG_FetchSound to regulate workload
+       newlength = (int)(per_sfx->format.speed*STREAM_BUFFER_FILL);
+       if (newlength + sb->nbframes > sb->maxframes)
        {
                Con_Printf ("OGG_FetchSound: stream buffer overflow (%u sample frames / %u)\n",
                                        sb->format.speed + sb->nbframes, sb->maxframes);
                return NULL;
        }
-       newlength = (int)(per_sfx->format.speed*STREAM_BUFFER_FILL) * factor;  // -> 1 sec of sound before resampling
+       newlength *= factor; // convert from sample frames to bytes
        if(newlength > (int)sizeof(resampling_buffer))
                newlength = sizeof(resampling_buffer);
 
        // Decompress in the resampling_buffer
-#if BYTE_ORDER == BIG_ENDIAN
-       bigendian = 1;
-#else
-       bigendian = 0;
-#endif
        done = 0;
-       while ((ret = qov_read (&per_ch->vf, (char *)&resampling_buffer[done], (int)(newlength - done), bigendian, 2, 1, &per_ch->bs)) > 0)
+       while ((ret = qov_read (&per_ch->vf, (char *)&resampling_buffer[done], (int)(newlength - done), mem_bigendian, 2, 1, &per_ch->bs)) > 0)
                done += ret;
 
        Snd_AppendToSndBuffer (sb, resampling_buffer, (size_t)done / (size_t)factor, &per_sfx->format);
@@ -663,8 +672,10 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
        ogg_int64_t len, buff_len;
        double peak, gaindb;
 
+#ifndef LINK_TO_LIBVORBIS
        if (!vf_dll)
                return false;
+#endif
 
        // Already loaded?
        if (sfx->fetcher != NULL)
@@ -704,7 +715,7 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
 
        // Decide if we go for a stream or a simple PCM cache
        buff_len = (int)ceil (STREAM_BUFFER_DURATION * snd_renderbuffer->format.speed) * 2 * vi->channels;
-       if (snd_streaming.integer && len > (ogg_int64_t)filesize + 3 * buff_len)
+       if (snd_streaming.integer && (len > (ogg_int64_t)filesize + 3 * buff_len || snd_streaming.integer >= 2))
        {
                ogg_stream_persfx_t* per_sfx;
 
@@ -734,7 +745,7 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
        {
                char *buff;
                ogg_int64_t done;
-               int bs, bigendian;
+               int bs;
                long ret;
                snd_buffer_t *sb;
                snd_format_t ogg_format;
@@ -746,12 +757,7 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *sfx)
                buff = (char *)Mem_Alloc (snd_mempool, (int)len);
                done = 0;
                bs = 0;
-#if BYTE_ORDER == BIG_ENDIAN
-               bigendian = 1;
-#else
-               bigendian = 0;
-#endif
-               while ((ret = qov_read (&vf, &buff[done], (int)(len - done), bigendian, 2, 1, &bs)) > 0)
+               while ((ret = qov_read (&vf, &buff[done], (int)(len - done), mem_bigendian, 2, 1, &bs)) > 0)
                        done += ret;
 
                // Build the sound buffer