Experimental sound restart code: * snd_restart without changing the driver works. some static sounds (such as the fire sound of a nearby torch) get lost. * Driver switching is not stable enough: ALSA <-> OSS switching seems to work at first. But if you switch between them a lot of times, then the sound is muted for a very long time and further switchings are not stable. If you do a lot of snd_restart in OSS mode, and then try changing into ALSA, it crashes. With SDL as the previous driver, switching to another driver always crashes. These issues aren't properly traced, yet. * Format switching (such as sample rate) isn't implemented. If a sound driver is allocating dma memory for itself, make sure that it does not allocate on the hunk. At present, only the windows wave- sound driver and the alternative sdl audio driver (which is available as an extra patch) does that. Therefore, if you try this patch: * Edit your snd_sdl2.c and make sure that the USE_HUNK_ALLOC definition is 0 * If you compile for windows, edit your snd_win.c and make sure that the USE_HUNK_ALLOC definition is 0 diff -urNp uhexen2-20070915/hexen2/snd_dma.c uhexen2-20070915x/hexen2/snd_dma.c --- uhexen2-20070915/hexen2/snd_dma.c 2007-09-15 14:10:03.000000000 +0300 +++ uhexen2-20070915x/hexen2/snd_dma.c 2007-09-15 16:36:46.000000000 +0300 @@ -113,6 +113,67 @@ static void S_SoundInfo_f (void) } +static void S_ListDrivers_f (void) +{ + unsigned int i = 0; + + while (i < S_SYS_MAX) + { + if (snd_drivers[i].available) + Con_Printf ("%u : %s\n", i, snd_drivers[i].name); + ++i; + } +} + + +static void S_Restart_f (void) +{ + int c; + + c = Cmd_Argc(); + + if (c > 2 || (c > 1 && !strcmp(Cmd_Argv(1),"help"))) + { + Con_Printf ("snd_restart : restart sound system\n" + "snd_restart : restart sound system with new driver\n"); +invalid: + Con_Printf ("(type \"sounddrivers\" to have a list of available drivers)\n"); + return; + } + + if (c == 2) + { + c = atoi (Cmd_Argv(1)); + if (c < 0 || c >= S_SYS_MAX || !snd_drivers[c].available) + { + Con_Printf ("invalid driver number %d\n", c); + goto invalid; + } + snd_system = c; + S_InitDrivers(); + } + + Con_Printf("Restarting sound system in %s mode\n", snd_drivers[snd_system].name); + Cache_Flush(); + S_StopAllSounds (true); + + S_Shutdown(); + Con_Printf("Sound Shutdown: OK.\n"); + + S_Startup(); + if (sound_started == 0) + return; + + ambient_sfx[AMBIENT_WATER] = S_PrecacheSound ("ambience/water1.wav"); + ambient_sfx[AMBIENT_SKY] = S_PrecacheSound ("ambience/wind2.wav"); + + S_StopAllSounds (true); + + if (developer.integer) + S_SoundInfo_f(); +} + + /* ================ S_Startup @@ -203,6 +264,8 @@ void S_Init (void) Cmd_AddCommand("mute", S_ToggleMute); Cmd_AddCommand("volumeup", S_VolumeUp); Cmd_AddCommand("volumedown", S_VolumeDown); + Cmd_AddCommand("sounddrivers", S_ListDrivers_f); + Cmd_AddCommand("snd_restart", S_Restart_f); Cvar_RegisterVariable(&nosound); Cvar_RegisterVariable(&sfxvolume);