summaryrefslogtreecommitdiff
path: root/src/i_sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i_sound.c')
-rw-r--r--src/i_sound.c436
1 files changed, 436 insertions, 0 deletions
diff --git a/src/i_sound.c b/src/i_sound.c
new file mode 100644
index 00000000..0c771dc2
--- /dev/null
+++ b/src/i_sound.c
@@ -0,0 +1,436 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+// DESCRIPTION: none
+//
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "SDL_mixer.h"
+
+#include "config.h"
+#include "doomfeatures.h"
+#include "doomtype.h"
+
+#include "i_sound.h"
+#include "i_video.h"
+#include "m_argv.h"
+#include "m_config.h"
+
+// Sound sample rate to use for digital output (Hz)
+
+int snd_samplerate = 44100;
+
+// Low-level sound and music modules we are using
+
+static sound_module_t *sound_module;
+static music_module_t *music_module;
+
+int snd_musicdevice = SNDDEVICE_GENMIDI;
+int snd_sfxdevice = SNDDEVICE_SB;
+
+// Sound modules
+
+extern sound_module_t sound_sdl_module;
+extern sound_module_t sound_pcsound_module;
+extern music_module_t music_sdl_module;
+extern music_module_t music_opl_module;
+
+// For OPL module:
+
+extern int opl_io_port;
+
+// DOS-specific options: These are unused but should be maintained
+// so that the config file can be shared between chocolate
+// doom and doom.exe
+
+static int snd_sbport = 0;
+static int snd_sbirq = 0;
+static int snd_sbdma = 0;
+static int snd_mport = 0;
+
+// Compiled-in sound modules:
+
+static sound_module_t *sound_modules[] =
+{
+#ifdef FEATURE_SOUND
+ &sound_sdl_module,
+ &sound_pcsound_module,
+#endif
+ NULL,
+};
+
+// Compiled-in music modules:
+
+static music_module_t *music_modules[] =
+{
+#ifdef FEATURE_SOUND
+ &music_sdl_module,
+ &music_opl_module,
+#endif
+ NULL,
+};
+
+// Check if a sound device is in the given list of devices
+
+static boolean SndDeviceInList(snddevice_t device, snddevice_t *list,
+ int len)
+{
+ int i;
+
+ for (i=0; i<len; ++i)
+ {
+ if (device == list[i])
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Find and initialize a sound_module_t appropriate for the setting
+// in snd_sfxdevice.
+
+static void InitSfxModule(boolean use_sfx_prefix)
+{
+ int i;
+
+ sound_module = NULL;
+
+ for (i=0; sound_modules[i] != NULL; ++i)
+ {
+ // Is the sfx device in the list of devices supported by
+ // this module?
+
+ if (SndDeviceInList(snd_sfxdevice,
+ sound_modules[i]->sound_devices,
+ sound_modules[i]->num_sound_devices))
+ {
+ // Initialize the module
+
+ if (sound_modules[i]->Init(use_sfx_prefix))
+ {
+ sound_module = sound_modules[i];
+ return;
+ }
+ }
+ }
+}
+
+// Initialize music according to snd_musicdevice.
+
+static void InitMusicModule(void)
+{
+ int i;
+
+ music_module = NULL;
+
+ for (i=0; music_modules[i] != NULL; ++i)
+ {
+ // Is the music device in the list of devices supported
+ // by this module?
+
+ if (SndDeviceInList(snd_musicdevice,
+ music_modules[i]->sound_devices,
+ music_modules[i]->num_sound_devices))
+ {
+ // Initialize the module
+
+ if (music_modules[i]->Init())
+ {
+ music_module = music_modules[i];
+ return;
+ }
+ }
+ }
+}
+
+//
+// Initializes sound stuff, including volume
+// Sets channels, SFX and music volume,
+// allocates channel buffer, sets S_sfx lookup.
+//
+
+void I_InitSound(boolean use_sfx_prefix)
+{
+ boolean nosound, nosfx, nomusic;
+
+ //!
+ // @vanilla
+ //
+ // Disable all sound output.
+ //
+
+ nosound = M_CheckParm("-nosound") > 0;
+
+ //!
+ // @vanilla
+ //
+ // Disable sound effects.
+ //
+
+ nosfx = M_CheckParm("-nosfx") > 0;
+
+ //!
+ // @vanilla
+ //
+ // Disable music.
+ //
+
+ nomusic = M_CheckParm("-nomusic") > 0;
+
+ // Initialize the sound and music subsystems.
+
+ if (!nosound && !screensaver_mode)
+ {
+ if (!nosfx)
+ {
+ InitSfxModule(use_sfx_prefix);
+ }
+
+ if (!nomusic)
+ {
+ InitMusicModule();
+ }
+ }
+}
+
+void I_ShutdownSound(void)
+{
+ if (sound_module != NULL)
+ {
+ sound_module->Shutdown();
+ }
+
+ if (music_module != NULL)
+ {
+ music_module->Shutdown();
+ }
+}
+
+int I_GetSfxLumpNum(sfxinfo_t *sfxinfo)
+{
+ if (sound_module != NULL)
+ {
+ return sound_module->GetSfxLumpNum(sfxinfo);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void I_UpdateSound(void)
+{
+ if (sound_module != NULL)
+ {
+ sound_module->Update();
+ }
+}
+
+static void CheckVolumeSeparation(int *sep, int *vol)
+{
+ if (*sep < 0)
+ {
+ *sep = 0;
+ }
+ else if (*sep > 254)
+ {
+ *sep = 254;
+ }
+
+ if (*vol < 0)
+ {
+ *vol = 0;
+ }
+ else if (*vol > 127)
+ {
+ *vol = 127;
+ }
+}
+
+void I_UpdateSoundParams(int channel, int vol, int sep)
+{
+ if (sound_module != NULL)
+ {
+ CheckVolumeSeparation(&vol, &sep);
+ sound_module->UpdateSoundParams(channel, vol, sep);
+ }
+}
+
+int I_StartSound(sfxinfo_t *sfxinfo, int channel, int vol, int sep)
+{
+ if (sound_module != NULL)
+ {
+ CheckVolumeSeparation(&vol, &sep);
+ return sound_module->StartSound(sfxinfo, channel, vol, sep);
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void I_StopSound(int channel)
+{
+ if (sound_module != NULL)
+ {
+ sound_module->StopSound(channel);
+ }
+}
+
+boolean I_SoundIsPlaying(int channel)
+{
+ if (sound_module != NULL)
+ {
+ return sound_module->SoundIsPlaying(channel);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void I_PrecacheSounds(sfxinfo_t *sounds, int num_sounds)
+{
+ if (sound_module != NULL && sound_module->CacheSounds != NULL)
+ {
+ sound_module->CacheSounds(sounds, num_sounds);
+ }
+}
+
+void I_InitMusic(void)
+{
+}
+
+void I_ShutdownMusic(void)
+{
+
+}
+
+void I_SetMusicVolume(int volume)
+{
+ if (music_module != NULL)
+ {
+ music_module->SetMusicVolume(volume);
+ }
+}
+
+void I_PauseSong(void)
+{
+ if (music_module != NULL)
+ {
+ music_module->PauseMusic();
+ }
+}
+
+void I_ResumeSong(void)
+{
+ if (music_module != NULL)
+ {
+ music_module->ResumeMusic();
+ }
+}
+
+void *I_RegisterSong(void *data, int len)
+{
+ if (music_module != NULL)
+ {
+ return music_module->RegisterSong(data, len);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+void I_UnRegisterSong(void *handle)
+{
+ if (music_module != NULL)
+ {
+ music_module->UnRegisterSong(handle);
+ }
+}
+
+void I_PlaySong(void *handle, boolean looping)
+{
+ if (music_module != NULL)
+ {
+ music_module->PlaySong(handle, looping);
+ }
+}
+
+void I_StopSong(void)
+{
+ if (music_module != NULL)
+ {
+ music_module->StopSong();
+ }
+}
+
+boolean I_MusicIsPlaying(void)
+{
+ if (music_module != NULL)
+ {
+ return music_module->MusicIsPlaying();
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void I_BindSoundVariables(void)
+{
+ extern int use_libsamplerate;
+
+ M_BindVariable("snd_musicdevice", &snd_musicdevice);
+ M_BindVariable("snd_sfxdevice", &snd_sfxdevice);
+ M_BindVariable("snd_sbport", &snd_sbport);
+ M_BindVariable("snd_sbirq", &snd_sbirq);
+ M_BindVariable("snd_sbdma", &snd_sbdma);
+ M_BindVariable("snd_mport", &snd_mport);
+ M_BindVariable("snd_samplerate", &snd_samplerate);
+ M_BindVariable("opl_io_port", &opl_io_port);
+#ifdef FEATURE_SOUND
+ M_BindVariable("use_libsamplerate", &use_libsamplerate);
+#endif
+
+ // Before SDL_mixer version 1.2.11, MIDI music caused the game
+ // to crash when it looped. If this is an old SDL_mixer version,
+ // disable MIDI.
+
+#ifdef __MACOSX__
+ {
+ const SDL_version *v = Mix_Linked_Version();
+
+ if (SDL_VERSIONNUM(v->major, v->minor, v->patch)
+ < SDL_VERSIONNUM(1, 2, 11))
+ {
+ snd_musicdevice = SNDDEVICE_NONE;
+ }
+ }
+#endif
+}
+