- SFXs no longer allocate mempools, they use the sound mempool directly.
authormolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 18 Sep 2005 16:43:45 +0000 (16:43 +0000)
committermolivier <molivier@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 18 Sep 2005 16:43:45 +0000 (16:43 +0000)
It saved 21KB and 129 mempools (from 191 to 62) in my quick test.
- removed unused function S_UnloadSound
- changed an endian test in the Ogg Vorbis code to look more coherent

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5725 d7cf8633-e32d-0410-b094-e92efae38249

snd_coreaudio.c
snd_main.c
snd_main.h
snd_mem.c
snd_ogg.c
snd_sdl.c
snd_wav.c
snd_wav.h

index 899ccf6..3a132f9 100644 (file)
@@ -43,8 +43,6 @@ static qboolean s_isRunning;
 static AudioDeviceID outputDeviceID;
 static AudioStreamBasicDescription outputStreamBasicDescription;
 
-extern mempool_t *snd_mempool;
-
 
 /*
 ===============
index bf0bc3d..fafb23c 100644 (file)
@@ -272,6 +272,7 @@ sfx_t *S_FindName (const char *name)
        sfx = Mem_Alloc (snd_mempool, sizeof (*sfx));
        memset (sfx, 0, sizeof(*sfx));
        strlcpy (sfx->name, name, sizeof (sfx->name));
+       sfx->memsize = sizeof(*sfx);
        sfx->next = known_sfx;
        known_sfx = sfx;
 
@@ -287,6 +288,8 @@ S_FreeSfx
 */
 void S_FreeSfx (sfx_t *sfx, qboolean force)
 {
+       unsigned int i;
+
        // Never free a locked sfx unless forced
        if (!force && (sfx->locks > 0 || (sfx->flags & SFXFLAG_PERMANENTLOCK)))
                return;
@@ -313,8 +316,14 @@ void S_FreeSfx (sfx_t *sfx, qboolean force)
                }
        }
 
+       // Stop all channels using this sfx
+       for (i = 0; i < total_channels; i++)
+               if (channels[i].sfx == sfx)
+                       S_StopChannel (i);
+
        // Free it
-       Mem_FreePool (&sfx->mempool);
+       if (sfx->fetcher != NULL && sfx->fetcher->free != NULL)
+               sfx->fetcher->free (sfx);
        Mem_Free (sfx);
 }
 
@@ -631,9 +640,9 @@ void S_StopChannel (unsigned int channel_ind)
 
                if (sfx->fetcher != NULL)
                {
-                       snd_fetcher_end_t fetcher_end = sfx->fetcher->end;
-                       if (fetcher_end != NULL)
-                               fetcher_end (ch);
+                       snd_fetcher_endsb_t fetcher_endsb = sfx->fetcher->endsb;
+                       if (fetcher_endsb != NULL)
+                               fetcher_endsb (ch);
                }
 
                // Remove the lock it holds
@@ -1024,7 +1033,7 @@ void S_SoundList(void)
        {
                if (sfx->fetcher != NULL)
                {
-                       size = (int)sfx->mempool->totalsize;
+                       size = (int)sfx->memsize;
                        total += size;
                        Con_Printf ("%c%c%c%c(%2db, %6s) %8i : %s\n",
                                                (sfx->loopstart >= 0) ? 'L' : ' ',
index 0248a92..0eea61a 100644 (file)
@@ -50,7 +50,7 @@ struct sfx_s
 {
        char                            name[MAX_QPATH];
        sfx_t                           *next;
-       mempool_t                       *mempool;
+       size_t                          memsize;                // total memory used (including sfx_t and fetcher data)
        int                                     locks;                  // One lock is automatically granted while the sfx is
                                                                                // playing (and removed when stopped). Locks can also be
                                                                                // added by S_PrecacheSound and S_ServerSounds.
@@ -91,11 +91,13 @@ typedef struct
 } channel_t;
 
 typedef const sfxbuffer_t* (*snd_fetcher_getsb_t) (channel_t* ch, unsigned int start, unsigned int nbsamples);
-typedef void (*snd_fetcher_end_t) (channel_t* ch);
+typedef void (*snd_fetcher_endsb_t) (channel_t* ch);
+typedef void (*snd_fetcher_free_t) (sfx_t* sfx);
 struct snd_fetcher_s
 {
        snd_fetcher_getsb_t             getsb;
-       snd_fetcher_end_t               end;
+       snd_fetcher_endsb_t             endsb;
+       snd_fetcher_free_t              free;
 };
 
 void S_PaintChannels(int endtime);
@@ -112,7 +114,6 @@ void SNDDMA_Submit(void);
 void SNDDMA_Shutdown(void);
 
 qboolean S_LoadSound (sfx_t *s, qboolean complain);
-void S_UnloadSound(sfx_t *s);
 
 void S_LockSfx (sfx_t *sfx);
 void S_UnlockSfx (sfx_t *sfx);
@@ -123,8 +124,6 @@ void S_UnlockBuffer(void);
 extern size_t ResampleSfx (const qbyte *in_data, size_t in_length, const snd_format_t* in_format, qbyte *out_data, const char* sfxname);
 
 // ====================================================================
-// User-setable variables
-// ====================================================================
 
 // 0 to NUM_AMBIENTS - 1 = water, etc
 // NUM_AMBIENTS to NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS - 1 = normal entity sounds
@@ -145,5 +144,7 @@ extern cvar_t snd_streaming;
 
 extern int snd_blocked;
 
+extern mempool_t *snd_mempool;
+
 
 #endif
index 281e513..1e94c27 100644 (file)
--- a/snd_mem.c
+++ b/snd_mem.c
@@ -213,20 +213,3 @@ qboolean S_LoadSound (sfx_t *s, qboolean complain)
                Con_Printf("S_LoadSound: Couldn't load \"%s\"\n", s->name);
        return false;
 }
-
-void S_UnloadSound (sfx_t *s)
-{
-       if (s->fetcher != NULL)
-       {
-               unsigned int i;
-
-               // Stop all channels that use this sound
-               for (i = 0; i < total_channels ; i++)
-                       if (channels[i].sfx == s)
-                               S_StopChannel (i);
-
-               s->fetcher = NULL;
-               s->fetcher_data = NULL;
-               Mem_FreePool(&s->mempool);
-       }
-}
index a342f4a..a95ce23 100644 (file)
--- a/snd_ogg.c
+++ b/snd_ogg.c
@@ -1,5 +1,5 @@
 /*
-       Copyright (C) 2003-2004  Mathieu Olivier
+       Copyright (C) 2003-2005  Mathieu Olivier
 
        This program is free software; you can redistribute it and/or
        modify it under the terms of the GNU General Public License
@@ -370,6 +370,7 @@ void OGG_CloseLibrary (void)
 */
 
 #define STREAM_BUFFER_DURATION 1.5f    // 1.5 sec
+#define STREAM_BUFFER_SIZE(format_ptr) (ceil (STREAM_BUFFER_DURATION * ((format_ptr)->speed * (format_ptr)->width * (format_ptr)->channels)))
 
 // We work with 1 sec sequences, so this buffer must be able to contain
 // 1 sec of sound of the highest quality (48 KHz, 16 bit samples, stereo)
@@ -406,6 +407,7 @@ static const sfxbuffer_t* OGG_FetchSound (channel_t* ch, unsigned int start, uns
        ogg_stream_perchannel_t* per_ch;
        sfxbuffer_t* sb;
        sfx_t* sfx;
+       snd_format_t* format;
        ogg_stream_persfx_t* per_sfx;
        int newlength, done, ret, bigendian;
        unsigned int factor;
@@ -414,14 +416,18 @@ static const sfxbuffer_t* OGG_FetchSound (channel_t* ch, unsigned int start, uns
        per_ch = ch->fetcher_data;
        sfx = ch->sfx;
        per_sfx = sfx->fetcher_data;
-       buff_len = ceil (STREAM_BUFFER_DURATION * (sfx->format.speed * sfx->format.width * sfx->format.channels));
+       format = &sfx->format;
+       buff_len = STREAM_BUFFER_SIZE(format);
 
        // If there's no fetcher structure attached to the channel yet
        if (per_ch == NULL)
        {
+               size_t memsize;
                ogg_stream_persfx_t* per_sfx;
 
-               per_ch = Mem_Alloc (sfx->mempool, sizeof (*per_ch) - sizeof (per_ch->sb.data) + buff_len);
+               memsize = sizeof (*per_ch) - sizeof (per_ch->sb.data) + buff_len;
+               per_ch = Mem_Alloc (snd_mempool, memsize);
+               sfx->memsize += memsize;
                per_sfx = sfx->fetcher_data;
 
                // Open it with the VorbisFile API
@@ -486,10 +492,10 @@ static const sfxbuffer_t* OGG_FetchSound (channel_t* ch, unsigned int start, uns
        newlength = per_sfx->format.speed * factor;  // -> 1 sec of sound before resampling
 
        // Decompress in the resampling_buffer
-#if BYTE_ORDER == LITTLE_ENDIAN
-       bigendian = 0;
-#else
+#if BYTE_ORDER == BIG_ENDIAN
        bigendian = 1;
+#else
+       bigendian = 0;
 #endif
        done = 0;
        while ((ret = qov_read (&per_ch->vf, &resampling_buffer[done], (int)(newlength - done), bigendian, 2, 1, &per_ch->bs)) > 0)
@@ -515,15 +521,44 @@ static void OGG_FetchEnd (channel_t* ch)
        per_ch = ch->fetcher_data;
        if (per_ch != NULL)
        {
+               size_t buff_len;
+               snd_format_t* format;
+
                // Free the ogg vorbis decoder
                qov_clear (&per_ch->vf);
 
                Mem_Free (per_ch);
                ch->fetcher_data = NULL;
+               
+               format = &ch->sfx->format;
+               buff_len = STREAM_BUFFER_SIZE(format);
+               ch->sfx->memsize -= sizeof (*per_ch) - sizeof (per_ch->sb.data) + buff_len;
        }
 }
 
-static const snd_fetcher_t ogg_fetcher = { OGG_FetchSound, OGG_FetchEnd };
+
+/*
+====================
+OGG_FreeSfx
+====================
+*/
+static void OGG_FreeSfx (sfx_t* sfx)
+{
+       ogg_stream_persfx_t* per_sfx = sfx->fetcher_data;
+
+       // Free the Ogg Vorbis file
+       Mem_Free(per_sfx->file);
+       sfx->memsize -= per_sfx->filesize;
+
+       // Free the stream structure
+       Mem_Free(per_sfx);
+       sfx->memsize -= sizeof (*per_sfx);
+
+       sfx->fetcher_data = NULL;
+       sfx->fetcher = NULL;
+}
+
+static const snd_fetcher_t ogg_fetcher = { OGG_FetchSound, OGG_FetchEnd, OGG_FreeSfx };
 
 
 /*
@@ -544,16 +579,14 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
        if (!vf_dll)
                return false;
 
-       Mem_FreePool (&s->mempool);
-       s->mempool = Mem_AllocPool (s->name, 0, NULL);
+       // Already loaded?
+       if (s->fetcher != NULL)
+               return true;
 
        // Load the file
-       data = FS_LoadFile (filename, s->mempool, false);
+       data = FS_LoadFile (filename, snd_mempool, false);
        if (data == NULL)
-       {
-               Mem_FreePool (&s->mempool);
                return false;
-       }
 
        Con_DPrintf ("Loading Ogg Vorbis file \"%s\"\n", filename);
 
@@ -564,7 +597,7 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
        if (qov_open_callbacks (&ov_decode, &vf, NULL, 0, callbacks) < 0)
        {
                Con_Printf ("error while opening Ogg Vorbis file \"%s\"\n", filename);
-               Mem_FreePool (&s->mempool);
+               Mem_Free(data);
                return false;
        }
 
@@ -575,7 +608,7 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
                Con_Printf("%s has an unsupported number of channels (%i)\n",
                                        s->name, vi->channels);
                qov_clear (&vf);
-               Mem_FreePool (&s->mempool);
+               Mem_Free(data);
                return false;
        }
 
@@ -588,9 +621,11 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
                ogg_stream_persfx_t* per_sfx;
 
                Con_DPrintf ("\"%s\" will be streamed\n", filename);
-               per_sfx = Mem_Alloc (s->mempool, sizeof (*per_sfx));
+               per_sfx = Mem_Alloc (snd_mempool, sizeof (*per_sfx));
+               s->memsize += sizeof (*per_sfx);
                per_sfx->file = data;
                per_sfx->filesize = fs_filesize;
+               s->memsize += fs_filesize;
 
                per_sfx->format.speed = vi->rate;
                per_sfx->format.width = 2;  // We always work with 16 bits samples
@@ -612,11 +647,12 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
                int bs, bigendian;
                long ret;
                sfxbuffer_t *sb;
+               size_t memsize;
 
                Con_DPrintf ("\"%s\" will be cached\n", filename);
 
                // Decode it
-               buff = Mem_Alloc (s->mempool, (int)len);
+               buff = Mem_Alloc (snd_mempool, (int)len);
                done = 0;
                bs = 0;
 #if BYTE_ORDER == LITTLE_ENDIAN
@@ -631,7 +667,9 @@ qboolean OGG_LoadVorbisFile (const char *filename, sfx_t *s)
                len = (double)done * (double)shm->format.speed / (double)vi->rate;
 
                // Resample it
-               sb = Mem_Alloc (s->mempool, (size_t)len + sizeof (*sb) - sizeof (sb->data));
+               memsize = (size_t)len + sizeof (*sb) - sizeof (sb->data);
+               sb = Mem_Alloc (snd_mempool, memsize);
+               s->memsize += memsize;
                s->fetcher_data = sb;
                s->fetcher = &wav_fetcher;
                s->format.speed = vi->rate;
index 38fb205..ddd87fe 100644 (file)
--- a/snd_sdl.c
+++ b/snd_sdl.c
@@ -39,7 +39,6 @@ typedef struct AudioState_s
 } AudioState;
 
 
-extern mempool_t *snd_mempool;
 static AudioState       as;
 
 static void Buffer_Callback(void *userdata, Uint8 *stream, int len);
index 439ec73..d8af145 100644 (file)
--- a/snd_wav.c
+++ b/snd_wav.c
@@ -228,8 +228,24 @@ static const sfxbuffer_t* WAV_FetchSound (channel_t* ch, unsigned int start, uns
        return ch->sfx->fetcher_data;
 }
 
+/*
+====================
+WAV_FreeSfx
+====================
+*/
+static void WAV_FreeSfx (sfx_t* sfx)
+{
+       sfxbuffer_t* sb = sfx->fetcher_data;
 
-snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL };
+       // Free the sound buffer
+       sfx->memsize -= (sb->length * sfx->format.channels * sfx->format.width) + sizeof (*sb) - sizeof (sb->data);
+       Mem_Free(sb);
+
+       sfx->fetcher_data = NULL;
+       sfx->fetcher = NULL;
+}
+
+const snd_fetcher_t wav_fetcher = { WAV_FetchSound, NULL, WAV_FreeSfx };
 
 
 /*
@@ -242,23 +258,22 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *s)
        qbyte *data;
        wavinfo_t info;
        int len;
+       size_t memsize;
        sfxbuffer_t* sb;
 
-       Mem_FreePool (&s->mempool);
-       s->mempool = Mem_AllocPool(s->name, 0, NULL);
+       // Already loaded?
+       if (s->fetcher != NULL)
+               return true;
 
        // Load the file
-       data = FS_LoadFile(filename, s->mempool, false);
+       data = FS_LoadFile(filename, snd_mempool, false);
        if (!data)
-       {
-               Mem_FreePool (&s->mempool);
                return false;
-       }
 
        // Don't try to load it if it's not a WAV file
        if (memcmp (data, "RIFF", 4) || memcmp (data + 8, "WAVE", 4))
        {
-               Mem_FreePool (&s->mempool);
+               Mem_Free(data);
                return false;
        }
 
@@ -269,7 +284,7 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *s)
        if (info.channels < 1 || info.channels > 2)
        {
                Con_Printf("%s has an unsupported number of channels (%i)\n",s->name, info.channels);
-               Mem_FreePool (&s->mempool);
+               Mem_Free(data);
                return false;
        }
        //if (info.channels == 2)
@@ -279,13 +294,15 @@ qboolean S_LoadWavFile (const char *filename, sfx_t *s)
        len = (int) ((double) info.samples * (double) shm->format.speed / (double) info.rate);
        len = len * info.width * info.channels;
 
-       sb = Mem_Alloc (s->mempool, len + sizeof (*sb) - sizeof (sb->data));
+       memsize = len + sizeof (*sb) - sizeof (sb->data);
+       sb = Mem_Alloc (snd_mempool, memsize);
        if (sb == NULL)
        {
                Con_Printf("failed to allocate memory for sound \"%s\"\n", s->name);
-               Mem_FreePool(&s->mempool);
+               Mem_Free(data);
                return false;
        }
+       s->memsize += memsize;
 
        s->fetcher = &wav_fetcher;
        s->fetcher_data = sb;
index 638d1d3..ae47162 100644 (file)
--- a/snd_wav.h
+++ b/snd_wav.h
@@ -26,7 +26,7 @@
 #define SND_WAV_H
 
 
-extern snd_fetcher_t wav_fetcher;
+extern const snd_fetcher_t wav_fetcher;
 
 qboolean S_LoadWavFile (const char *filename, sfx_t *s);