]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - snd_main.c
Split the global cmd interpreter into 4 separate ones for specific uses (client conso...
[xonotic/darkplaces.git] / snd_main.c
index 251084a06fb38a2281c4d09e9a70914d5fb384f2..93770ad825d9b24f23afb3017e3d54ad5dccb2dd 100644 (file)
@@ -25,9 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "snd_ogg.h"
 #include "csprogs.h"
 #include "cl_collision.h"
-#ifdef CONFIG_CD
 #include "cdaudio.h"
-#endif
 
 
 #define SND_MIN_SPEED 8000
@@ -51,24 +49,24 @@ static const speakerlayout_t snd_speakerlayouts[] =
        {
                "surround71", 8,
                {
-                       {0, 45, 0.2, 0.2, 0.5}, // front left
-                       {1, 315, 0.2, 0.2, 0.5}, // front right
-                       {2, 135, 0.2, 0.2, 0.5}, // rear left
-                       {3, 225, 0.2, 0.2, 0.5}, // rear right
-                       {4, 0, 0.2, 0.2, 0.5}, // front center
+                       {0, 45, 0.2f, 0.2f, 0.5f}, // front left
+                       {1, 315, 0.2f, 0.2f, 0.5f}, // front right
+                       {2, 135, 0.2f, 0.2f, 0.5f}, // rear left
+                       {3, 225, 0.2f, 0.2f, 0.5f}, // rear right
+                       {4, 0, 0.2f, 0.2f, 0.5f}, // front center
                        {5, 0, 0, 0, 0}, // lfe (we don't have any good lfe sound sources and it would take some filtering work to generate them (and they'd probably still be wrong), so...  no lfe)
-                       {6, 90, 0.2, 0.2, 0.5}, // side left
-                       {7, 180, 0.2, 0.2, 0.5}, // side right
+                       {6, 90, 0.2f, 0.2f, 0.5f}, // side left
+                       {7, 180, 0.2f, 0.2f, 0.5f}, // side right
                }
        },
        {
                "surround51", 6,
                {
-                       {0, 45, 0.2, 0.2, 0.5}, // front left
-                       {1, 315, 0.2, 0.2, 0.5}, // front right
-                       {2, 135, 0.2, 0.2, 0.5}, // rear left
-                       {3, 225, 0.2, 0.2, 0.5}, // rear right
-                       {4, 0, 0.2, 0.2, 0.5}, // front center
+                       {0, 45, 0.2f, 0.2f, 0.5f}, // front left
+                       {1, 315, 0.2f, 0.2f, 0.5f}, // front right
+                       {2, 135, 0.2f, 0.2f, 0.5f}, // rear left
+                       {3, 225, 0.2f, 0.2f, 0.5f}, // rear right
+                       {4, 0, 0.2f, 0.2f, 0.5f}, // front center
                        {5, 0, 0, 0, 0}, // lfe (we don't have any good lfe sound sources and it would take some filtering work to generate them (and they'd probably still be wrong), so...  no lfe)
                        {0, 0, 0, 0, 0},
                        {0, 0, 0, 0, 0},
@@ -79,10 +77,10 @@ static const speakerlayout_t snd_speakerlayouts[] =
                // channel of its own
                "surround40", 4,
                {
-                       {0, 45, 0.3, 0.3, 0.8}, // front left
-                       {1, 315, 0.3, 0.3, 0.8}, // front right
-                       {2, 135, 0.3, 0.3, 0.8}, // rear left
-                       {3, 225, 0.3, 0.3, 0.8}, // rear right
+                       {0, 45, 0.3f, 0.3f, 0.8f}, // front left
+                       {1, 315, 0.3f, 0.3f, 0.8f}, // front right
+                       {2, 135, 0.3f, 0.3f, 0.8f}, // rear left
+                       {3, 225, 0.3f, 0.3f, 0.8f}, // rear right
                        {0, 0, 0, 0, 0},
                        {0, 0, 0, 0, 0},
                        {0, 0, 0, 0, 0},
@@ -94,8 +92,8 @@ static const speakerlayout_t snd_speakerlayouts[] =
                // channel of its own
                "stereo", 2,
                {
-                       {0, 90, 0.5, 0.5, 1}, // side left
-                       {1, 270, 0.5, 0.5, 1}, // side right
+                       {0, 90, 0.5f, 0.5f, 1}, // side left
+                       {1, 270, 0.5f, 0.5f, 1}, // side right
                        {0, 0, 0, 0, 0},
                        {0, 0, 0, 0, 0},
                        {0, 0, 0, 0, 0},
@@ -239,10 +237,10 @@ static cvar_t ambient_fade = {0, "ambient_fade", "100", "rate of volume fading w
 static cvar_t snd_noextraupdate = {0, "snd_noextraupdate", "0", "disables extra sound mixer calls that are meant to reduce the chance of sound breakup at very low framerates"};
 static cvar_t snd_show = {0, "snd_show", "0", "shows some statistics about sound mixing"};
 
-// Default sound format is 48KHz, 16-bit, stereo
+// Default sound format is 48KHz, 32bit float, stereo
 // (48KHz because a lot of onboard sound cards sucks at any other speed)
 static cvar_t snd_speed = {CVAR_SAVE, "snd_speed", "48000", "sound output frequency, in hertz"};
-static cvar_t snd_width = {CVAR_SAVE, "snd_width", "2", "sound output precision, in bytes (1 and 2 supported)"};
+static cvar_t snd_width = {CVAR_SAVE, "snd_width", "4", "sound output precision, in bytes - 1 = 8bit, 2 = 16bit, 4 = 32bit float"};
 static cvar_t snd_channels = {CVAR_SAVE, "snd_channels", "2", "number of channels for the sound output (2 for stereo; up to 8 supported for 3D sound)"};
 
 static cvar_t snd_startloopingsounds = {0, "snd_startloopingsounds", "1", "whether to start sounds that would loop (you want this to be 1); existing sounds are not affected"};
@@ -263,17 +261,17 @@ static const char* ambient_names [2] = { "sound/ambience/water1.wav", "sound/amb
 
 void S_FreeSfx (sfx_t *sfx, qboolean force);
 
-static void S_Play_Common (float fvol, float attenuation)
+static void S_Play_Common (cmd_state_t *cmd, float fvol, float attenuation)
 {
        int i, ch_ind;
        char name [MAX_QPATH];
        sfx_t *sfx;
 
        i = 1;
-       while (i < Cmd_Argc ())
+       while (i < Cmd_Argc (cmd))
        {
                // Get the name, and appends ".wav" as an extension if there's none
-               strlcpy (name, Cmd_Argv (i), sizeof (name));
+               strlcpy (name, Cmd_Argv(cmd, i), sizeof (name));
                if (!strrchr (name, '.'))
                        strlcat (name, ".wav", sizeof (name));
                i++;
@@ -281,7 +279,7 @@ static void S_Play_Common (float fvol, float attenuation)
                // If we need to get the volume from the command line
                if (fvol == -1.0f)
                {
-                       fvol = atof (Cmd_Argv (i));
+                       fvol = atof (Cmd_Argv(cmd, i));
                        i++;
                }
 
@@ -299,22 +297,22 @@ static void S_Play_Common (float fvol, float attenuation)
        }
 }
 
-static void S_Play_f(void)
+static void S_Play_f(cmd_state_t *cmd)
 {
-       S_Play_Common (1.0f, 1.0f);
+       S_Play_Common(cmd, 1.0f, 1.0f);
 }
 
-static void S_Play2_f(void)
+static void S_Play2_f(cmd_state_t *cmd)
 {
-       S_Play_Common (1.0f, 0.0f);
+       S_Play_Common(cmd, 1.0f, 0.0f);
 }
 
-static void S_PlayVol_f(void)
+static void S_PlayVol_f(cmd_state_t *cmd)
 {
-       S_Play_Common (-1.0f, 0.0f);
+       S_Play_Common(cmd, -1.0f, 0.0f);
 }
 
-static void S_SoundList_f (void)
+static void S_SoundList_f(cmd_state_t *cmd)
 {
        unsigned int i;
        sfx_t *sfx;
@@ -346,7 +344,7 @@ static void S_SoundList_f (void)
 }
 
 
-static void S_SoundInfo_f(void)
+static void S_SoundInfo_f(cmd_state_t *cmd)
 {
        if (snd_renderbuffer == NULL)
        {
@@ -373,77 +371,6 @@ int S_GetSoundChannels(void)
 }
 
 
-static qboolean S_ChooseCheaperFormat (snd_format_t* format, qboolean fixed_speed, qboolean fixed_width, qboolean fixed_channels)
-{
-       static const snd_format_t thresholds [] =
-       {
-               // speed                        width                   channels
-               { SND_MIN_SPEED,        SND_MIN_WIDTH,  SND_MIN_CHANNELS },
-               { 11025,                        1,                              2 },
-               { 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]);
-       unsigned int speed_level, width_level, channels_level;
-
-       // If we have reached the minimum values, there's nothing more we can do
-       if ((format->speed == thresholds[0].speed || fixed_speed) &&
-               (format->width == thresholds[0].width || fixed_width) &&
-               (format->channels == thresholds[0].channels || fixed_channels))
-               return false;
-
-       // Check the min and max values
-       #define CHECK_BOUNDARIES(param)                                                         \
-       if (format->param < thresholds[0].param)                                        \
-       {                                                                                                                       \
-               format->param = thresholds[0].param;                                    \
-               return true;                                                                                    \
-       }                                                                                                                       \
-       if (format->param > thresholds[nb_thresholds - 1].param)        \
-       {                                                                                                                       \
-               format->param = thresholds[nb_thresholds - 1].param;    \
-               return true;                                                                                    \
-       }
-       CHECK_BOUNDARIES(speed);
-       CHECK_BOUNDARIES(width);
-       CHECK_BOUNDARIES(channels);
-       #undef CHECK_BOUNDARIES
-
-       // Find the level of each parameter
-       #define FIND_LEVEL(param)                                                                       \
-       param##_level = 0;                                                                                      \
-       while (param##_level < nb_thresholds - 1)                                       \
-       {                                                                                                                       \
-               if (format->param <= thresholds[param##_level].param)   \
-                       break;                                                                                          \
-                                                                                                                               \
-               param##_level++;                                                                                \
-       }
-       FIND_LEVEL(speed);
-       FIND_LEVEL(width);
-       FIND_LEVEL(channels);
-       #undef FIND_LEVEL
-
-       // Decrease the parameter with the highest level to the previous level
-       if (channels_level >= speed_level && channels_level >= width_level && !fixed_channels)
-       {
-               format->channels = thresholds[channels_level - 1].channels;
-               return true;
-       }
-       if (speed_level >= width_level && !fixed_speed)
-       {
-               format->speed = thresholds[speed_level - 1].speed;
-               return true;
-       }
-
-       format->width = thresholds[width_level - 1].width;
-       return true;
-}
-
-
 #define SWAP_LISTENERS(l1, l2, tmpl) { tmpl = (l1); (l1) = (l2); (l2) = tmpl; }
 
 static void S_SetChannelLayout (void)
@@ -617,7 +544,7 @@ void S_Startup (void)
                chosen_fmt.speed = atoi (com_argv[i + 1]);
                fixed_speed = true;
        }
-// COMMANDLINEOPTION: Sound: -sndbits <bits> chooses 8 bit or 16 bit sound output
+// COMMANDLINEOPTION: Sound: -sndbits <bits> chooses 8 bit or 16 bit or 32bit float sound output
        i = COM_CheckParm ("-sndbits");
        if (0 < i && i < com_argc - 1)
        {
@@ -626,7 +553,7 @@ void S_Startup (void)
        }
 
 #if 0
-       // LordHavoc: now you can with the resampler...
+       // LadyHavoc: now you can with the resampler...
        // You can't change sound speed after start time (not yet supported)
        if (prev_render_format.speed != 0)
        {
@@ -657,6 +584,11 @@ void S_Startup (void)
                chosen_fmt.width = SND_MIN_WIDTH;
                fixed_width = false;
        }
+    else if (chosen_fmt.width == 3)
+       {
+               chosen_fmt.width = 4;
+               fixed_width = false;
+       }
        else if (chosen_fmt.width > SND_MAX_WIDTH)
        {
                chosen_fmt.width = SND_MAX_WIDTH;
@@ -677,39 +609,12 @@ void S_Startup (void)
        // create the sound buffer used for sumitting the samples to the plaform-dependent module
        if (!simsound)
        {
-               snd_format_t suggest_fmt;
-               qboolean accepted;
+               Con_Printf("S_Startup: initializing sound output format: %dHz, %d bit, %d channels...\n",
+                                       chosen_fmt.speed,
+                                       chosen_fmt.width,
+                                       chosen_fmt.channels);
 
-               accepted = false;
-               do
-               {
-                       Con_Printf("S_Startup: initializing sound output format: %dHz, %d bit, %d channels...\n",
-                                               chosen_fmt.speed, chosen_fmt.width * 8,
-                                               chosen_fmt.channels);
-
-                       memset(&suggest_fmt, 0, sizeof(suggest_fmt));
-                       accepted = SndSys_Init(&chosen_fmt, &suggest_fmt);
-
-                       if (!accepted)
-                       {
-                               Con_Printf("S_Startup: sound output initialization FAILED\n");
-
-                               // If the module is suggesting another one
-                               if (suggest_fmt.speed != 0)
-                               {
-                                       memcpy(&chosen_fmt, &suggest_fmt, sizeof(chosen_fmt));
-                                       Con_Printf ("           Driver has suggested %dHz, %d bit, %d channels. Retrying...\n",
-                                                               suggest_fmt.speed, suggest_fmt.width * 8,
-                                                               suggest_fmt.channels);
-                               }
-                               // Else, try to find a less resource-demanding format
-                               else if (!S_ChooseCheaperFormat (&chosen_fmt, fixed_speed, fixed_width, fixed_channels))
-                                       break;
-                       }
-               } while (!accepted);
-
-               // If we haven't found a suitable format
-               if (!accepted)
+               if (!SndSys_Init(&chosen_fmt))
                {
                        Con_Print("S_Startup: SndSys_Init failed.\n");
                        sound_spatialized = false;
@@ -778,7 +683,7 @@ void S_Shutdown(void)
        sound_spatialized = false;
 }
 
-static void S_Restart_f(void)
+static void S_Restart_f(cmd_state_t *cmd)
 {
        // 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.
@@ -874,8 +779,8 @@ void S_Init(void)
        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");
+               Cmd_AddCommand(&cmd_client, "play", Host_NoOperation_f, "does nothing because -nosound was specified");
+               Cmd_AddCommand(&cmd_client, "play2", Host_NoOperation_f, "does nothing because -nosound was specified");
                return;
        }
 
@@ -885,14 +790,14 @@ void S_Init(void)
        if (COM_CheckParm("-simsound"))
                simsound = true;
 
-       Cmd_AddCommand("play", S_Play_f, "play a sound at your current location (not heard by anyone else)");
-       Cmd_AddCommand("play2", S_Play2_f, "play a sound globally throughout the level (not heard by anyone else)");
-       Cmd_AddCommand("playvol", S_PlayVol_f, "play a sound at the specified volume level at your current location (not heard by anyone else)");
-       Cmd_AddCommand("stopsound", S_StopAllSounds, "silence");
-       Cmd_AddCommand("soundlist", S_SoundList_f, "list loaded sounds");
-       Cmd_AddCommand("soundinfo", S_SoundInfo_f, "print sound system information (such as channels and speed)");
-       Cmd_AddCommand("snd_restart", S_Restart_f, "restart sound system");
-       Cmd_AddCommand("snd_unloadallsounds", S_UnloadAllSounds_f, "unload all sound files");
+       Cmd_AddCommand(&cmd_client, "play", S_Play_f, "play a sound at your current location (not heard by anyone else)");
+       Cmd_AddCommand(&cmd_client, "play2", S_Play2_f, "play a sound globally throughout the level (not heard by anyone else)");
+       Cmd_AddCommand(&cmd_client, "playvol", S_PlayVol_f, "play a sound at the specified volume level at your current location (not heard by anyone else)");
+       Cmd_AddCommand(&cmd_client, "stopsound", S_StopAllSounds_f, "silence");
+       Cmd_AddCommand(&cmd_client, "soundlist", S_SoundList_f, "list loaded sounds");
+       Cmd_AddCommand(&cmd_client, "soundinfo", S_SoundInfo_f, "print sound system information (such as channels and speed)");
+       Cmd_AddCommand(&cmd_client, "snd_restart", S_Restart_f, "restart sound system");
+       Cmd_AddCommand(&cmd_client, "snd_unloadallsounds", S_UnloadAllSounds_f, "unload all sound files");
 
        Cvar_RegisterVariable(&nosound);
        Cvar_RegisterVariable(&snd_precache);
@@ -945,7 +850,7 @@ void S_Terminate (void)
 S_UnloadAllSounds_f
 ==================
 */
-void S_UnloadAllSounds_f (void)
+void S_UnloadAllSounds_f(cmd_state_t *cmd)
 {
        int i;
 
@@ -1457,7 +1362,7 @@ static void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
        ch->mixspeed = mixspeed;
 
        // anything coming from the view entity will always be full volume
-       // LordHavoc: make sounds with ATTN_NONE have no spatialization
+       // LadyHavoc: make sounds with ATTN_NONE have no spatialization
        if (ch->entnum == cl.viewentity || ch->entnum == CL_VM_GetViewEntity() || ch->distfade == 0)
        {
                ch->prologic_invert = 1;
@@ -1493,7 +1398,7 @@ static void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
                        if (snd_spatialization_occlusion.integer)
                        {
                                if(snd_spatialization_occlusion.integer & 1)
-                                       if(listener_pvs)
+                                       if(listener_pvs && cl.worldmodel)
                                        {
                                                int cluster = cl.worldmodel->brush.PointInLeaf(cl.worldmodel, ch->origin)->clusterindex;
                                                if(cluster >= 0 && cluster < 8 * listener_pvsbytes && !CHECKPVSBIT(listener_pvs, cluster))
@@ -1502,7 +1407,7 @@ static void SND_Spatialize_WithSfx(channel_t *ch, qboolean isstatic, sfx_t *sfx)
 
                                if(snd_spatialization_occlusion.integer & 2)
                                        if(!occluded)
-                                               if(cl.worldmodel && cl.worldmodel->brush.TraceLineOfSight && !cl.worldmodel->brush.TraceLineOfSight(cl.worldmodel, listener_origin, ch->origin))
+                                               if(cl.worldmodel && cl.worldmodel->brush.TraceLineOfSight && !cl.worldmodel->brush.TraceLineOfSight(cl.worldmodel, listener_origin, ch->origin, ch->origin, ch->origin))
                                                        occluded = true;
                        }
                        if(occluded)
@@ -1812,7 +1717,7 @@ void S_StopSound(int entnum, int entchannel)
                }
 }
 
-void S_StopAllSounds (void)
+void S_StopAllSounds(void)
 {
        unsigned int i;
 
@@ -1820,10 +1725,8 @@ void S_StopAllSounds (void)
        if (snd_renderbuffer == NULL)
                return;
 
-#ifdef CONFIG_CD
        // stop CD audio because it may be using a faketrack
        CDAudio_Stop();
-#endif
 
        if (simsound || SndSys_LockRenderBuffer ())
        {
@@ -1847,6 +1750,12 @@ void S_StopAllSounds (void)
        }
 }
 
+void S_StopAllSounds_f(cmd_state_t *cmd)
+{
+       S_StopAllSounds();
+}
+
+
 void S_PauseGameSounds (qboolean toggle)
 {
        unsigned int i;