]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_main.c
New OffscreenGecko scripting stuff
[xonotic/darkplaces.git] / snd_main.c
index e1e03a58c7976d403ca46828011ab2f190de31e0..03b1358d161a79e2562dce42c4535b1cfecf5db3 100644 (file)
@@ -23,10 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "snd_main.h"
 #include "snd_ogg.h"
+#include "snd_modplug.h"
 
 
 #define SND_MIN_SPEED 8000
-#define SND_MAX_SPEED 48000
+#define SND_MAX_SPEED 96000
 #define SND_MIN_WIDTH 1
 #define SND_MAX_WIDTH 2
 #define SND_MIN_CHANNELS 1
@@ -319,6 +320,7 @@ static qboolean S_ChooseCheaperFormat (snd_format_t* format, qboolean fixed_spee
                { 22050,                        2,                              2 },
                { 44100,                        2,                              2 },
                { 48000,                        2,                              6 },
+               { 96000,                        2,                              6 },
                { SND_MAX_SPEED,        SND_MAX_WIDTH,  SND_MAX_CHANNELS },
        };
        const unsigned int nb_thresholds = sizeof(thresholds) / sizeof(thresholds[0]);
@@ -688,6 +690,14 @@ void S_Shutdown(void)
 
 void S_Restart_f(void)
 {
+       // NOTE: we can't free all sounds if we are running a map (this frees sfx_t that are still referenced by precaches)
+       // So, refuse to do this if we are connected.
+       if(cls.state == ca_connected)
+       {
+               Con_Printf("snd_restart would wreak havoc if you do that while connected!\n");
+               return;
+       }
+
        S_Shutdown();
        S_Startup();
 }
@@ -712,7 +722,12 @@ void S_Init(void)
 
 // COMMANDLINEOPTION: Sound: -nosound disables sound (including CD audio)
        if (COM_CheckParm("-nosound"))
+       {
+               // dummy out Play and Play2 because mods stuffcmd that
+               Cmd_AddCommand("play", Host_NoOperation_f, "does nothing because -nosound was specified");
+               Cmd_AddCommand("play2", Host_NoOperation_f, "does nothing because -nosound was specified");
                return;
+       }
 
        snd_mempool = Mem_AllocPool("sound", 0, NULL);
 
@@ -750,6 +765,7 @@ void S_Init(void)
        memset(channels, 0, MAX_CHANNELS * sizeof(channel_t));
 
        OGG_OpenLibrary ();
+       ModPlug_OpenLibrary ();
 }
 
 
@@ -763,6 +779,7 @@ Shutdown and free all resources
 void S_Terminate (void)
 {
        S_Shutdown ();
+       ModPlug_CloseLibrary ();
        OGG_CloseLibrary ();
 
        // Free all SFXs
@@ -783,6 +800,14 @@ void S_UnloadAllSounds_f (void)
 {
        int i;
 
+       // NOTE: we can't free all sounds if we are running a map (this frees sfx_t that are still referenced by precaches)
+       // So, refuse to do this if we are connected.
+       if(cls.state == ca_connected)
+       {
+               Con_Printf("snd_unloadallsounds would wreak havoc if you do that while connected!\n");
+               return;
+       }
+
        // stop any active sounds
        S_StopAllSounds();
 
@@ -874,7 +899,7 @@ void S_FreeSfx (sfx_t *sfx, qboolean force)
 
        // Free it
        if (sfx->fetcher != NULL && sfx->fetcher->free != NULL)
-               sfx->fetcher->free (sfx);
+               sfx->fetcher->free (sfx->fetcher_data);
        Mem_Free (sfx);
 }
 
@@ -1172,7 +1197,6 @@ void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags,
        // Initialize the channel
        memset (target_chan, 0, sizeof (*target_chan));
        VectorCopy (origin, target_chan->origin);
-       target_chan->master_vol = (int)(fvol * 255);
        target_chan->sfx = sfx;
        target_chan->flags = flags;
        target_chan->pos = 0; // start of the sound
@@ -1189,6 +1213,9 @@ void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int flags,
 
        // Lock the SFX during play
        S_LockSfx (sfx);
+
+       // and finally, apply the volume
+       S_SetChannelVolume(target_chan - channels, fvol);
 }
 
 
@@ -1248,12 +1275,13 @@ void S_StopChannel (unsigned int channel_ind)
                {
                        snd_fetcher_endsb_t fetcher_endsb = sfx->fetcher->endsb;
                        if (fetcher_endsb != NULL)
-                               fetcher_endsb (ch);
+                               fetcher_endsb (ch->fetcher_data);
                }
 
                // Remove the lock it holds
                S_UnlockSfx (sfx);
 
+               ch->fetcher_data = NULL;
                ch->sfx = NULL;
        }
 }
@@ -1338,6 +1366,16 @@ void S_PauseGameSounds (qboolean toggle)
 
 void S_SetChannelVolume (unsigned int ch_ind, float fvol)
 {
+       sfx_t *sfx = channels[ch_ind].sfx;
+       if(sfx->volume_peak > 0)
+       {
+               // Replaygain support
+               // Con_DPrintf("Setting volume on ReplayGain-enabled track... %f -> ", fvol);
+               fvol *= sfx->volume_mult;
+               if(fvol * sfx->volume_peak > 1)
+                       fvol = 1 / sfx->volume_peak;
+               // Con_DPrintf("%f\n", fvol);
+       }
        channels[ch_ind].master_vol = (int)(fvol * 255.0f);
 }