diff --git a/doomsday/engine/api/sys_audiod.h b/doomsday/engine/api/sys_audiod.h index 7e53b8d171..32a5e024f5 100644 --- a/doomsday/engine/api/sys_audiod.h +++ b/doomsday/engine/api/sys_audiod.h @@ -20,8 +20,8 @@ * 02110-1301 USA */ -#ifndef LIBDENG_AUDIO_DRIVER_H -#define LIBDENG_AUDIO_DRIVER_H +#ifndef LIBDENG_AUDIO_DRIVER_INTERFACE_H +#define LIBDENG_AUDIO_DRIVER_INTERFACE_H /** * @defgroup audio Audio @@ -52,6 +52,10 @@ typedef struct audiodriver_s { int (*Set) (int prop, const void* ptr); } audiodriver_t; +typedef struct audiointerface_base_s { + int (*Init) (void); +} audiointerface_base_t; + ///@} -#endif /* LIBDENG_AUDIO_DRIVER_H */ +#endif /* LIBDENG_AUDIO_DRIVER_INTERFACE_H */ diff --git a/doomsday/engine/engine.pro b/doomsday/engine/engine.pro index c558dcb8ce..5b2aed5577 100644 --- a/doomsday/engine/engine.pro +++ b/doomsday/engine/engine.pro @@ -112,6 +112,7 @@ DENG_API_HEADERS = \ DENG_HEADERS = \ portable/include/abstractfile.h \ portable/include/abstractresource.h \ + portable/include/audiodriver.h \ portable/include/bitmapfont.h \ portable/include/blockset.h \ portable/include/bsp_edge.h \ @@ -284,7 +285,6 @@ DENG_HEADERS = \ portable/include/svg.h \ portable/include/sys_audio.h \ portable/include/sys_audiod_dummy.h \ - portable/include/sys_audiod_loader.h \ portable/include/sys_console.h \ portable/include/sys_direc.h \ portable/include/sys_findfile.h \ @@ -360,7 +360,6 @@ HEADERS += \ DENG_UNIX_SOURCES += \ portable/src/sys_sdl_window.c \ unix/src/dd_uinit.c \ - unix/src/sys_audiod_loader.c \ unix/src/sys_console.c \ unix/src/sys_findfile.c \ unix/src/sys_input.c \ @@ -368,7 +367,6 @@ DENG_UNIX_SOURCES += \ DENG_WIN32_SOURCES += \ win32/src/dd_winit.c \ - win32/src/sys_audiod_loader.c \ win32/src/sys_console.c \ win32/src/sys_findfile.c \ win32/src/sys_input.c \ @@ -376,6 +374,7 @@ DENG_WIN32_SOURCES += \ SOURCES += \ portable/src/abstractfile.c \ + portable/src/audiodriver.c \ portable/src/animator.c \ portable/src/bitmapfont.c \ portable/src/blockset.c \ diff --git a/doomsday/engine/portable/include/audiodriver.h b/doomsday/engine/portable/include/audiodriver.h new file mode 100644 index 0000000000..78bb3a4bb4 --- /dev/null +++ b/doomsday/engine/portable/include/audiodriver.h @@ -0,0 +1,56 @@ +/** + * @file audiodriver.h + * Audio driver loading and interface management. @ingroup audio + * + * @authors Copyright © 2012 Jaakko Keränen + * @authors Copyright © 2012 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LIBDENG_AUDIO_DRIVER_H +#define LIBDENG_AUDIO_DRIVER_H + +#include "sys_audiod.h" +#include "sys_audiod_sfx.h" +#include "sys_audiod_mus.h" + +boolean AudioDriver_Init(void); +void AudioDriver_Shutdown(void); + +/** + * Retrieves the main interface of the audio driver to which @a sfxMusicOrCd belongs to. + */ +audiodriver_t* AudioDriver_Interface(void* sfxMusicOrCd); + +/** + * Returns the current active SFX interface. @c NULL is returned is no SFX + * playback is available. + */ +audiointerface_sfx_generic_t* AudioDriver_SFX(void); + +/** + * Returns the currently active Music interface. @c NULL is returned if no music + * playback is available. + */ +audiointerface_music_t* AudioDriver_Music(void); + +/** + * Returns the currently active CD playback interface. @c NULL is returned if + * CD playback is not available. + */ +audiointerface_cd_t* AudioDriver_CD(void); + +#endif // LIBDENG_AUDIO_DRIVER_H diff --git a/doomsday/engine/portable/include/de_audio.h b/doomsday/engine/portable/include/de_audio.h index 11d1ba2102..c65d550c88 100644 --- a/doomsday/engine/portable/include/de_audio.h +++ b/doomsday/engine/portable/include/de_audio.h @@ -29,6 +29,7 @@ #ifndef __DOOMSDAY_AUDIO__ #define __DOOMSDAY_AUDIO__ +#include "audiodriver.h" #include "s_main.h" #include "s_environ.h" #include "s_sfx.h" diff --git a/doomsday/engine/portable/include/s_main.h b/doomsday/engine/portable/include/s_main.h index 63ce418674..2830d4c6be 100644 --- a/doomsday/engine/portable/include/s_main.h +++ b/doomsday/engine/portable/include/s_main.h @@ -44,8 +44,6 @@ extern int showSoundInfo; extern int soundMinDist, soundMaxDist; extern int sfxVolume, musVolume; -extern audiodriver_t* audioDriver; - void S_Register(void); boolean S_Init(void); void S_Shutdown(void); diff --git a/doomsday/engine/portable/include/sys_audio.h b/doomsday/engine/portable/include/sys_audio.h index 1fa8bbb604..e96afd60a1 100644 --- a/doomsday/engine/portable/include/sys_audio.h +++ b/doomsday/engine/portable/include/sys_audio.h @@ -36,8 +36,6 @@ #include "sys_audiod.h" #include "sys_audiod_sfx.h" #include "sys_audiod_mus.h" - -#include "sys_audiod_loader.h" #include "sys_audiod_dummy.h" #ifndef DENG_DISABLE_SDLMIXER diff --git a/doomsday/engine/portable/include/sys_audiod_loader.h b/doomsday/engine/portable/include/sys_audiod_loader.h deleted file mode 100644 index d79206b5f7..0000000000 --- a/doomsday/engine/portable/include/sys_audiod_loader.h +++ /dev/null @@ -1,44 +0,0 @@ -/**\file sys_audiod_loader.h - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html - * - *\author Copyright © 2003-2012 Jaakko Keränen - *\author Copyright © 2009-2012 Daniel Swanson - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * Audio Driver Loader. - */ - -#ifndef LIBDENG_SYSTEM_AUDIO_LOADER_H -#define LIBDENG_SYSTEM_AUDIO_LOADER_H - -#include "sys_audiod.h" - -/** - * Attempt to load the specified audio driver, import the entry points and - * add to the available audio drivers. - * - * @param name Name of the driver to be loaded e.g., "openal". - * @return Ptr to the audio driver interface if successful, else @c NULL. - */ -audiodriver_t* Sys_LoadAudioDriver(const char* name); - -void Sys_ShutdownAudioDriver(void); -#endif /* LIBDENG_SYSTEM_AUDIO_LOADER_H */ diff --git a/doomsday/engine/portable/src/audiodriver.c b/doomsday/engine/portable/src/audiodriver.c new file mode 100644 index 0000000000..61982b17a9 --- /dev/null +++ b/doomsday/engine/portable/src/audiodriver.c @@ -0,0 +1,360 @@ +/** + * @file audiodriver.c + * Audio driver loading and interface management implementation. @ingroup audio + * + * @authors Copyright © 2012 Jaakko Keränen + * @authors Copyright © 2012 Daniel Swanson + * + * @par License + * GPL: http://www.gnu.org/licenses/gpl.html + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include "de_base.h" +#include "de_console.h" +#include "de_misc.h" +#include "de_audio.h" +#include "sys_audio.h" +#include "audiodriver.h" + +typedef struct driver_s { + Library* library; + audiodriver_t interface; + audiointerface_sfx_t sfx; + audiointerface_music_t music; + audiointerface_cd_t cd; +} driver_t; + +static driver_t drivers[AUDIODRIVER_COUNT]; + +// The active interfaces. +static audiointerface_sfx_t* iSFX; +static audiointerface_music_t* iMusic; +static audiointerface_cd_t* iCD; + +#ifdef MACOSX +/// Built-in QuickTime audio interface implemented by MusicPlayer.m +extern audiointerface_music_t audiodQuickTimeMusic; +#endif + +static void importInterfaces(driver_t* d) +{ +#define Imp(name) Library_Symbol(d->library, name) + + d->interface.Init = Imp("DS_Init"); + d->interface.Shutdown = Imp("DS_Shutdown"); + d->interface.Event = Imp("DS_Event"); + d->interface.Set = Imp("DS_Set"); + + if(Imp("DS_SFX_Init")) + { + d->sfx.gen.Init = Imp("DS_SFX_Init"); + d->sfx.gen.Create = Imp("DS_SFX_CreateBuffer"); + d->sfx.gen.Destroy = Imp("DS_SFX_DestroyBuffer"); + d->sfx.gen.Load = Imp("DS_SFX_Load"); + d->sfx.gen.Reset = Imp("DS_SFX_Reset"); + d->sfx.gen.Play = Imp("DS_SFX_Play"); + d->sfx.gen.Stop = Imp("DS_SFX_Stop"); + d->sfx.gen.Refresh = Imp("DS_SFX_Refresh"); + d->sfx.gen.Set = Imp("DS_SFX_Set"); + d->sfx.gen.Setv = Imp("DS_SFX_Setv"); + d->sfx.gen.Listener = Imp("DS_SFX_Listener"); + d->sfx.gen.Listenerv = Imp("DS_SFX_Listenerv"); + d->sfx.gen.Getv = Imp("DS_SFX_Getv"); + } + + if(Imp("DM_Music_Init")) + { + d->music.gen.Init = Imp("DM_Music_Init"); + d->music.gen.Update = Imp("DM_Music_Update"); + d->music.gen.Get = Imp("DM_Music_Get"); + d->music.gen.Set = Imp("DM_Music_Set"); + d->music.gen.Pause = Imp("DM_Music_Pause"); + d->music.gen.Stop = Imp("DM_Music_Stop"); + d->music.SongBuffer = Imp("DM_Music_SongBuffer"); + d->music.Play = Imp("DM_Music_Play"); + d->music.PlayFile = Imp("DM_Music_PlayFile"); + } + + if(Imp("DM_CDAudio_Init")) + { + d->cd.gen.Init = Imp("DM_CDAudio_Init"); + d->cd.gen.Update = Imp("DM_CDAudio_Update"); + d->cd.gen.Set = Imp("DM_CDAudio_Set"); + d->cd.gen.Get = Imp("DM_CDAudio_Get"); + d->cd.gen.Pause = Imp("DM_CDAudio_Pause"); + d->cd.gen.Stop = Imp("DM_CDAudio_Stop"); + d->cd.Play = Imp("DM_CDAudio_Play"); + } + +#undef Imp +} + +static boolean loadAudioDriver(driver_t* driver, const char* name) +{ + boolean ok = false; + + if(name && name[0]) + { + ddstring_t libPath; + + // Compose the name using the prefix "ds". + Str_Init(&libPath); +#ifdef WIN32 + Str_Appendf(&libPath, "%sds%s.dll", ddBinPath, name); +#elif defined(MACOSX) + Str_Appendf(&libPath, "ds%s.bundle", name); +#else + Str_Appendf(&libPath, "libds%s.so", name); +#endif + + // Load the audio driver library and import symbols. + if((driver->library = Library_New(Str_Text(&libPath))) != 0) + { + importInterfaces(driver); + ok = true; + } + else + { + Con_Message("Warning: loadAudioDriver: Loading of \"%s\" failed.\n", Str_Text(&libPath)); + } + Str_Free(&libPath); + } + return ok; +} + + +static const char* getDriverName(audiodriver_e id) +{ + static const char* audioDriverNames[AUDIODRIVER_COUNT] = { + /* AUDIOD_DUMMY */ "Dummy", + /* AUDIOD_SDL_MIXER */ "SDLMixer", + /* AUDIOD_OPENAL */ "OpenAL", + /* AUDIOD_FMOD */ "FMOD Ex", + /* AUDIOD_DSOUND */ "DirectSound", // Win32 only + /* AUDIOD_WINMM */ "Windows Multimedia" // Win32 only + }; + if(VALID_AUDIODRIVER_IDENTIFIER(id)) + return audioDriverNames[id]; + Con_Error("S_GetDriverName: Unknown driver id %i.\n", id); + return 0; // Unreachable. +} + +/** + * Initializes the audio driver interfaces. + * + * @return @c true iff successful. + */ +static boolean initDriver(audiodriver_e id) +{ + driver_t* d = &drivers[id]; + memset(d, 0, sizeof(*d)); + + switch(id) + { + case AUDIOD_DUMMY: // built-in + memcpy(&d->interface, &audiod_dummy, sizeof(d->interface)); + memcpy(&d->sfx, &audiod_dummy_sfx, sizeof(d->sfx)); + break; + +#ifndef DENG_DISABLE_SDLMIXER + case AUDIOD_SDL_MIXER: // built-in + memcpy(&d->interface, &audiod_sdlmixer, sizeof(d->interface)); + memcpy(&d->sfx, &audiod_sdlmixer_sfx, sizeof(d->sfx)); + memcpy(&d->music, &audiod_sdlmixer_music, sizeof(d->music)); + break; +#endif + + case AUDIOD_OPENAL: + if(!loadAudioDriver(d, "openal")) + return false; + break; + + case AUDIOD_FMOD: + if(!loadAudioDriver(d, "fmod")) + return false; + break; + +#ifdef WIN32 + case AUDIOD_DSOUND: + if(!loadAudioDriver(d, "directsound")) + return false; + break; + + case AUDIOD_WINMM: + if(!loadAudioDriver(d, "winmm")) + return false; + break; +#endif + default: + Con_Error("initDriver: Unknown audio driver id %i.\n", id); + return false; // Unreachable. + } + + // Initialize. + assert(d->interface.Init != 0); + return d->interface.Init(); +} + +/** + * Chooses the default audio driver based on configuration options. + */ +static audiodriver_e chooseAudioDriver(void) +{ + // No audio output? + if(isDedicated || ArgExists("-dummy")) + return AUDIOD_DUMMY; + + if(ArgExists("-fmod")) + return AUDIOD_FMOD; + + if(ArgExists("-oal")) + return AUDIOD_OPENAL; + +#ifdef WIN32 + // DirectSound with 3D sound support, EAX effects? + if(ArgExists("-dsound")) + return AUDIOD_DSOUND; + + // Windows Multimedia? + if(ArgExists("-winmm")) + return AUDIOD_WINMM; +#endif + +#ifndef DENG_DISABLE_SDLMIXER + if(ArgExists("-sdlmixer")) + return AUDIOD_SDL_MIXER; +#endif + + // The default audio driver. + return AUDIOD_FMOD; +} + +static void selectInterfaces(audiodriver_e defaultDriverId) +{ + driver_t* d = &drivers[defaultDriverId]; + + iSFX = 0; + iMusic = 0; + iCD = 0; + + if(d->sfx.gen.Init) iSFX = &d->sfx; + if(d->music.gen.Init) iMusic = &d->music; + if(d->cd.gen.Init) iCD = &d->cd; + +#ifdef MACOSX + if(!iMusic && defaultDriverId != AUDIOD_DUMMY) + { + // On the Mac, use the built-in QuickTime interface as the fallback for music. + iMusic = &audiodQuickTimeMusic; + } +#endif +} + +static boolean initInterface(audiointerface_base_t* interface) +{ + if(!interface) return true; + if(interface->Init) + { + return interface->Init(); + } + return false; +} + +boolean AudioDriver_Init(void) +{ + audiodriver_e defaultDriverId; + boolean ok = false; + + if(ArgExists("-nosound")) return false; + + defaultDriverId = chooseAudioDriver(); + ok = initDriver(defaultDriverId); + if(!ok) + { + Con_Message("Warning: Failed initializing audio driver \"%s\"\n", getDriverName(defaultDriverId)); + } + + // Fallback option for the default driver. +#ifndef DENG_DISABLE_SDLMIXER + if(!ok) + { + defaultDriverId = AUDIOD_SDL_MIXER; + ok = initDriver(defaultDriverId); + } +#endif + + // Choose the interfaces to use. + selectInterfaces(defaultDriverId); + + // TODO: Load overriding plugins for specific interfaces. + + return ok; +} + +void AudioDriver_Shutdown(void) +{ + int i; + + // Shut down all the loaded drivers. + for(i = 0; i < AUDIODRIVER_COUNT; ++i) + { + driver_t* d = &drivers[i]; + if(d->interface.Shutdown) d->interface.Shutdown(); + + // Unload the plugins. + if(d->library) + { + Library_Delete(d->library); + } + + memset(d, 0, sizeof(*d)); + } + + // No more interfaces available. + iSFX = 0; + iMusic = 0; + iCD = 0; +} + +audiodriver_t* AudioDriver_Interface(void* sfxMusicOrCd) +{ + int i; + + for(i = 0; i < AUDIODRIVER_COUNT; ++i) + { + driver_t* d = &drivers[i]; + if((void*)&d->sfx == sfxMusicOrCd || + (void*)&d->music == sfxMusicOrCd || + (void*)&d->cd == sfxMusicOrCd) + { + return &d->interface; + } + } + return 0; +} + +audiointerface_sfx_generic_t* AudioDriver_SFX(void) +{ + return (audiointerface_sfx_generic_t*) iSFX; +} + +audiointerface_music_t* AudioDriver_Music(void) +{ + return iMusic; +} + +audiointerface_cd_t* AudioDriver_CD(void) +{ + return iCD; +} diff --git a/doomsday/engine/portable/src/s_main.c b/doomsday/engine/portable/src/s_main.c index 7ebac5df1b..799a1ff6a6 100644 --- a/doomsday/engine/portable/src/s_main.c +++ b/doomsday/engine/portable/src/s_main.c @@ -102,102 +102,6 @@ void S_Register(void) Mus_Register(); } -const char* S_GetDriverName(audiodriver_e id) -{ - static const char* audioDrivers[AUDIODRIVER_COUNT] = { - /* AUDIOD_DUMMY */ "Dummy", - /* AUDIOD_SDL_MIXER */ "SDLMixer", - /* AUDIOD_OPENAL */ "OpenAL", - /* AUDIOD_FMOD */ "FMOD Ex", - /* AUDIOD_DSOUND */ "DirectSound", // Win32 only - /* AUDIOD_WINMM */ "Windows Multimedia" // Win32 only - }; - if(VALID_AUDIODRIVER_IDENTIFIER(id)) - return audioDrivers[id]; - Con_Error("S_GetDriverName: Unknown driver id %i.\n", id); - return 0; // Unreachable. -} - -/** - * Initializes the audio driver interfaces. - * - * @return @c true iff successful. - */ -boolean S_InitDriver(audiodriver_e drvid) -{ - switch(drvid) - { - case AUDIOD_DUMMY: - audioDriver = &audiod_dummy; - break; - -#ifndef DENG_DISABLE_SDLMIXER - case AUDIOD_SDL_MIXER: - audioDriver = &audiod_sdlmixer; - break; -#endif - - case AUDIOD_FMOD: - if(!(audioDriver = Sys_LoadAudioDriver("fmod"))) - return false; - break; - - case AUDIOD_OPENAL: - if(!(audioDriver = Sys_LoadAudioDriver("openal"))) - return false; - break; - -#ifdef WIN32 - case AUDIOD_DSOUND: - if(!(audioDriver = Sys_LoadAudioDriver("directsound"))) - return false; - break; - - case AUDIOD_WINMM: - if(!(audioDriver = Sys_LoadAudioDriver("winmm"))) - return false; - break; -#endif - default: - Con_Error("S_InitDriver: Unknown driver id %i.\n", drvid); - return false; // Unreachable. - } - - // Initialize. - return audioDriver->Init(); -} - -audiodriver_e S_ChooseAudioDriver(void) -{ - // No audio output? - if(isDedicated || ArgExists("-dummy")) - return AUDIOD_DUMMY; - - if(ArgExists("-fmod")) - return AUDIOD_FMOD; - - if(ArgExists("-oal")) - return AUDIOD_OPENAL; - -#ifdef WIN32 - // DirectSound with 3D sound support, EAX effects? - if(ArgExists("-dsound")) - return AUDIOD_DSOUND; - - // Windows Multimedia? - if(ArgExists("-winmm")) - return AUDIOD_WINMM; -#endif - -#ifndef DENG_DISABLE_SDLMIXER - if(ArgExists("-sdlmixer")) - return AUDIOD_SDL_MIXER; -#endif - - // The default audio driver. - return AUDIOD_FMOD; -} - /** * Main sound system initialization. Inits both the Sfx and Mus modules. * @@ -210,29 +114,11 @@ boolean S_Init(void) if(ArgExists("-nosound")) return true; - // First let's set up the drivers. First we must choose which one we want to use. - if(!ArgExists("-nosound")) - { - audiodriver_e drvid = S_ChooseAudioDriver(); - - ok = S_InitDriver(drvid); - if(!ok) - Con_Message("Warning: Failed initializing audio driver \"%s\"\n", S_GetDriverName(drvid)); - - // Fallback option for the default driver. -#ifndef DENG_DISABLE_SDLMIXER - if(!ok) - { - ok = S_InitDriver(AUDIOD_SDL_MIXER); - } -#endif - } - - // Did we manage to load a driver? - if(!ok) + // Try to load the audio driver plugin(s). + if(!AudioDriver_Init()) { Con_Message("Music and Sound Effects disabled.\n"); - return ArgExists("-nosound"); + return false; } // Disable random pitch changes? @@ -241,8 +127,12 @@ boolean S_Init(void) sfxOK = Sfx_Init(); musOK = Mus_Init(); - Con_Message("S_Init: %s.\n", (sfxOK && musOK? "OK" : "Errors during initialization.")); - return (sfxOK && musOK); + if(!sfxOK || !musOK) + { + Con_Message("Errors during audio subsystem initialization.\n"); + return false; + } + return true; } /** @@ -254,8 +144,7 @@ void S_Shutdown(void) Mus_Shutdown(); // Finally, close the audio driver. - Sys_ShutdownAudioDriver(); - audioDriver = NULL; + AudioDriver_Shutdown(); } /** diff --git a/doomsday/engine/portable/src/s_mus.c b/doomsday/engine/portable/src/s_mus.c index a24bab3946..4137eb6d58 100644 --- a/doomsday/engine/portable/src/s_mus.c +++ b/doomsday/engine/portable/src/s_mus.c @@ -44,20 +44,17 @@ #include "sys_reslocator.h" #include "m_mus2midi.h" -// MACROS ------------------------------------------------------------------ - -#define NUM_INTERFACES (sizeof(interfaces)/sizeof(interfaces[0])) - -// TYPES ------------------------------------------------------------------- - typedef struct interface_info_s { - audiointerface_music_generic_t** ip; + audiointerface_music_generic_t* ip; const char* name; } interface_info_t; -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- +static interface_info_t interfaces[] = { + { 0, "Music"}, + { 0, "CD"} +}; -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- +#define NUM_INTERFACES (sizeof(interfaces)/sizeof(interfaces[0])) D_CMD(PlayMusic); D_CMD(PauseMusic); @@ -70,12 +67,8 @@ static void Mus_UpdateSoundFont(void); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- // Music playback interfaces loaded from a sound driver plugin. -extern audiointerface_music_t audiodExternalIMusic; -extern audiointerface_cd_t audiodExternalICD; - -#ifdef MACOSX -extern audiointerface_music_t audiodQuickTimeMusic; -#endif +//extern audiointerface_music_t audiodExternalIMusic; +//extern audiointerface_cd_t audiodExternalICD; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -91,17 +84,6 @@ static int currentBufFile = 0; static char* soundFontPath = ""; -// The interfaces. -static audiointerface_music_t* iMusic; -static audiointerface_cd_t* iCD; - -// The interface list. Used to access the common features of all the -// interfaces conveniently. -static interface_info_t interfaces[] = { - {(audiointerface_music_generic_t**) &iMusic, "Music"}, - {(audiointerface_music_generic_t**) &iCD, "CD"} -}; - // CODE -------------------------------------------------------------------- void Mus_Register(void) @@ -120,7 +102,7 @@ void Mus_Register(void) /** * Initialize the Mus module and choose the interfaces to use. * - * @return @c true, if no errors occur. + * @return @c true, if no errors occur. */ boolean Mus_Init(void) { @@ -135,69 +117,42 @@ boolean Mus_Init(void) return true; } - VERBOSE( Con_Message("Initializing Music subsystem...\n") ) + VERBOSE( Con_Message("Initializing Music subsystem...\n") ); - iMusic = NULL; - iCD = NULL; + interfaces[0].ip = (audiointerface_music_generic_t*) AudioDriver_Music(); + interfaces[1].ip = (audiointerface_music_generic_t*) AudioDriver_CD(); - // Use the external music playback facilities, if available. - if(audioDriver == &audiod_dummy) - { - // Nothing to do. - } -#ifndef DENG_DISABLE_SDLMIXER - else if(audioDriver == &audiod_sdlmixer) - { - iMusic = (audiointerface_music_t*) &audiod_sdlmixer_music; - } -#endif - else - { - // Use the external interface. - iMusic = (audiodExternalIMusic.gen.Init? &audiodExternalIMusic : 0); - iCD = (audiodExternalICD.gen.Init? &audiodExternalICD : 0); - } - -#ifdef MACOSX - if(!iMusic) - { - // On the Mac, use QuickTime as the fallback for music. - iMusic = &audiodQuickTimeMusic; - } -#endif - - // Initialize the chosen interfaces. for(i = 0; i < NUM_INTERFACES; ++i) { - if(*interfaces[i].ip && !(*interfaces[i].ip)->Init()) + if(interfaces[i].ip && !interfaces[i].ip->Init()) { Con_Message("Warning:Mus_Init: Failed to initialize %s interface.\n", interfaces[i].name); - *interfaces[i].ip = NULL; + interfaces[i].ip = NULL; } } - if(audioDriver->Set) - { - // Tell the audio driver about our soundfont config. - audioDriver->Set(AUDIOP_SOUNDFONT_FILENAME, soundFontPath); - } - - // Print a list of the chosen interfaces. + // Print a list of the available interfaces. if(verbose) { char buf[80]; Con_Message("Music configuration:\n"); for(i = 0; i < NUM_INTERFACES; ++i) { - if(!(*interfaces[i].ip)) + if(!interfaces[i].ip) strcpy(buf, "N/A"); - else if( !(*interfaces[i].ip)->Get(MUSIP_ID, buf)) + else if( !interfaces[i].ip->Get(MUSIP_ID, buf)) strcpy(buf, "?"); Con_Message(" %-5s: %s\n", interfaces[i].name, buf); } } + if(AudioDriver_Interface(AudioDriver_Music())->Set) + { + // Tell the audio driver about our soundfont config. + AudioDriver_Interface(AudioDriver_Music())->Set(AUDIOP_SOUNDFONT_FILENAME, soundFontPath); + } + currentSong = -1; musAvail = true; @@ -216,15 +171,12 @@ void Mus_Shutdown(void) // Shutdown interfaces. for(i = 0; i < NUM_INTERFACES; ++i) { - if(*interfaces[i].ip && (*interfaces[i].ip)->Shutdown) + if(interfaces[i].ip && interfaces[i].ip->Shutdown) { - (*interfaces[i].ip)->Shutdown(); + interfaces[i].ip->Shutdown(); } + interfaces[i].ip = 0; } - - // No more interfaces. - iMusic = 0; - iCD = 0; } /** @@ -240,8 +192,8 @@ void Mus_StartFrame(void) // Update all interfaces. for(i = 0; i < NUM_INTERFACES; ++i) { - if(*interfaces[i].ip) - (*interfaces[i].ip)->Update(); + if(interfaces[i].ip) + interfaces[i].ip->Update(); } } @@ -258,8 +210,8 @@ void Mus_SetVolume(float vol) // Set volume of all available interfaces. for(i = 0; i < NUM_INTERFACES; ++i) { - if(*interfaces[i].ip) - (*interfaces[i].ip)->Set(MUSIP_VOLUME, vol); + if(interfaces[i].ip) + interfaces[i].ip->Set(MUSIP_VOLUME, vol); } } @@ -276,8 +228,8 @@ void Mus_Pause(boolean doPause) // Pause all interfaces. for(i = 0; i < NUM_INTERFACES; ++i) { - if(*interfaces[i].ip) - (*interfaces[i].ip)->Pause(doPause); + if(interfaces[i].ip) + interfaces[i].ip->Pause(doPause); } } @@ -293,8 +245,8 @@ void Mus_Stop(void) // Stop all interfaces. for(i = 0; i < NUM_INTERFACES; ++i) { - if(*interfaces[i].ip) - (*interfaces[i].ip)->Stop(); + if(interfaces[i].ip) + interfaces[i].ip->Stop(); } } @@ -321,7 +273,7 @@ boolean Mus_IsMUSLump(lumpnum_t lumpNum) */ int Mus_GetExt(ded_music_t* def, ddstring_t* retPath) { - if(!musAvail || !iMusic) return false; + if(!musAvail || !AudioDriver_Music()) return false; // All external music files are specified relative to the base path. if(def->path && !Str_IsEmpty(Uri_Path(def->path))) @@ -351,7 +303,7 @@ int Mus_GetExt(ded_music_t* def, ddstring_t* retPath) */ int Mus_GetCD(ded_music_t* def) { - if(!musAvail || !iCD || !def) + if(!musAvail || !AudioDriver_CD() || !def) return 0; if(def->cdTrack) @@ -389,7 +341,7 @@ int Mus_StartLump(lumpnum_t lump, boolean looped, boolean canPlayMUS) size_t lumpLength; int lumpIdx; - if(!iMusic || lump < 0) return 0; + if(!AudioDriver_Music() || lump < 0) return 0; if(Mus_IsMUSLump(lump)) { @@ -422,7 +374,7 @@ int Mus_StartLump(lumpnum_t lump, boolean looped, boolean canPlayMUS) M_Mus2Midi((void*)buf, lumpLength, Str_Text(srcFile)); free(buf); } - else if(!iMusic->Play) + else if(!AudioDriver_Music()->Play) { // Music interface does not offer buffer playback. // Write this lump to disk and play from there. @@ -436,15 +388,15 @@ int Mus_StartLump(lumpnum_t lump, boolean looped, boolean canPlayMUS) if(srcFile) { - int result = iMusic->PlayFile(Str_Text(srcFile), looped); + int result = AudioDriver_Music()->PlayFile(Str_Text(srcFile), looped); Str_Delete(srcFile); return result; } fsObject = F_FindFileForLumpNum2(lump, &lumpIdx); lumpLength = F_LumpLength(lump); - F_ReadLumpSection(fsObject, lumpIdx, (uint8_t*)iMusic->SongBuffer(lumpLength), 0, lumpLength); - return iMusic->Play(looped); + F_ReadLumpSection(fsObject, lumpIdx, (uint8_t*)AudioDriver_Music()->SongBuffer(lumpLength), 0, lumpLength); + return AudioDriver_Music()->Play(looped); } /** @@ -465,8 +417,8 @@ int Mus_Start(ded_music_t* def, boolean looped) // We will not restart the currently playing song. if(songID == currentSong && - ((iMusic && iMusic->gen.Get(MUSIP_PLAYING, NULL)) || - (iCD && iCD->gen.Get(MUSIP_PLAYING, NULL)))) + ((AudioDriver_Music() && AudioDriver_Music()->gen.Get(MUSIP_PLAYING, NULL)) || + (AudioDriver_CD() && AudioDriver_CD()->gen.Get(MUSIP_PLAYING, NULL)))) return false; // Stop the currently playing song. @@ -505,7 +457,7 @@ int Mus_Start(ded_music_t* def, boolean looped) { case MUSP_CD: if(Mus_GetCD(def)) - return iCD->Play(Mus_GetCD(def), looped); + return AudioDriver_CD()->Play(Mus_GetCD(def), looped); break; case MUSP_EXT: @@ -517,7 +469,7 @@ int Mus_Start(ded_music_t* def, boolean looped) DFile* file = F_Open(Str_Text(&path), "rb"); size_t len = DFile_Length(file); - if(!iMusic->Play) + if(!AudioDriver_Music()->Play) { // Music interface does not offer buffer playback. // Write to disk and play from there. ddstring_t* fileName = composeBufferedMusicFilename(currentBufFile ^= 1, NULL); @@ -541,7 +493,7 @@ int Mus_Start(ded_music_t* def, boolean looped) free(buf); // Music maestro, if you please! - result = iMusic->PlayFile(Str_Text(fileName), looped); + result = AudioDriver_Music()->PlayFile(Str_Text(fileName), looped); Str_Delete(fileName); return result; } @@ -559,11 +511,11 @@ int Mus_Start(ded_music_t* def, boolean looped) VERBOSE( Con_Message("Mus_GetExt: Opened song '%s' (file \"%s\" %lu bytes).\n", def->id, F_PrettyPath(Str_Text(&path)), (unsigned long) len) ) - ptr = iMusic->SongBuffer(len); + ptr = AudioDriver_Music()->SongBuffer(len); DFile_Read(file, (uint8_t*)ptr, len); F_Delete(file); - return iMusic->Play(looped); + return AudioDriver_Music()->Play(looped); } } @@ -572,7 +524,7 @@ int Mus_Start(ded_music_t* def, boolean looped) // Fall through. case MUSP_MUS: - if(iMusic) + if(AudioDriver_Music()) { lumpnum_t lump; if(def->lumpName && (lump = F_CheckLumpNumForName2(def->lumpName, true)) >= 0) @@ -596,8 +548,9 @@ int Mus_Start(ded_music_t* def, boolean looped) static void Mus_UpdateSoundFont(void) { - if(!audioDriver || !audioDriver->Set) return; - audioDriver->Set(AUDIOP_SOUNDFONT_FILENAME, Con_GetString("music-soundfont")); + audiodriver_t* d = AudioDriver_Interface(AudioDriver_Music()); + if(!d || !d->Set) return; + d->Set(AUDIOP_SOUNDFONT_FILENAME, Con_GetString("music-soundfont")); } /** @@ -605,7 +558,6 @@ static void Mus_UpdateSoundFont(void) */ D_CMD(PlayMusic) { - if(!musAvail) { Con_Printf("The Music module is not available.\n"); @@ -638,7 +590,7 @@ D_CMD(PlayMusic) lumpnum_t lump = F_CheckLumpNumForName2(argv[2], true); if(lump < 0) return false; // No such lump. - if(iMusic) + if(AudioDriver_Music()) { return Mus_StartLump(lump, true, true); } @@ -653,7 +605,7 @@ D_CMD(PlayMusic) ddstring_t path; int result = 0; - if(!iMusic) + if(!AudioDriver_Music()) { Con_Printf("No music interface available.\n"); return false; @@ -666,7 +618,7 @@ D_CMD(PlayMusic) F_ExpandBasePath(&path, &path); Mus_Stop(); - result = iMusic->PlayFile(Str_Text(&path), true); + result = AudioDriver_Music()->PlayFile(Str_Text(&path), true); Str_Free(&path); return result; } @@ -674,14 +626,14 @@ D_CMD(PlayMusic) { // Perhaps a CD track? if(!stricmp(argv[1], "cd")) { - if(!iCD) + if(!AudioDriver_CD()) { Con_Printf("No CDAudio interface available.\n"); return false; } Mus_Stop(); - return iCD->Play(atoi(argv[2]), true); + return AudioDriver_CD()->Play(atoi(argv[2]), true); } } break; diff --git a/doomsday/engine/portable/src/s_sfx.c b/doomsday/engine/portable/src/s_sfx.c index bd34fe74bc..eacdbd0612 100644 --- a/doomsday/engine/portable/src/s_sfx.c +++ b/doomsday/engine/portable/src/s_sfx.c @@ -59,10 +59,6 @@ void Sfx_SampleFormat(int newBits, int newRate); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -// SFX playback functions loaded from a sound driver plugin. -extern audiodriver_t audiodExternal; -extern audiointerface_sfx_t audiodExternalISFX; - // PUBLIC DATA DEFINITIONS ------------------------------------------------- boolean sfxAvail = false; @@ -80,9 +76,6 @@ int sfxSampleRate = 11025; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -// The interfaces. -static audiointerface_sfx_generic_t* iSFX = NULL; - static int numChannels = 0; static sfxchannel_t* channels; static mobj_t* listener; @@ -132,7 +125,7 @@ int C_DECL Sfx_ChannelRefreshThread(void* parm) if(!ch->buffer || !(ch->buffer->flags & SFXBF_PLAYING)) continue; - iSFX->Refresh(ch->buffer); + AudioDriver_SFX()->Refresh(ch->buffer); } refreshing = false; @@ -197,7 +190,7 @@ void Sfx_StopSoundGroup(int group, mobj_t* emitter) continue; // This channel must stop. - iSFX->Stop(ch->buffer); + AudioDriver_SFX()->Stop(ch->buffer); } } @@ -235,7 +228,7 @@ int Sfx_StopSound(int id, mobj_t* emitter) } // This channel must be stopped! - iSFX->Stop(ch->buffer); + AudioDriver_SFX()->Stop(ch->buffer); ++stopCount; } @@ -292,7 +285,7 @@ void Sfx_UnloadSoundID(int id) continue; // Stop and unload. - iSFX->Reset(ch->buffer); + AudioDriver_SFX()->Reset(ch->buffer); } END_COP; @@ -413,25 +406,25 @@ void Sfx_ChannelUpdate(sfxchannel_t* ch) } // Frequency is common to both 2D and 3D sounds. - iSFX->Set(buf, SFXBP_FREQUENCY, ch->frequency); + AudioDriver_SFX()->Set(buf, SFXBP_FREQUENCY, ch->frequency); if(buf->flags & SFXBF_3D) { // Volume is affected only by maxvol. - iSFX->Set(buf, SFXBP_VOLUME, ch->volume * sfxVolume / 255.0f); + AudioDriver_SFX()->Set(buf, SFXBP_VOLUME, ch->volume * sfxVolume / 255.0f); if(ch->emitter && ch->emitter == listener) { // Emitted by the listener object. Go to relative position mode // and set the position to (0,0,0). vec[VX] = vec[VY] = vec[VZ] = 0; - iSFX->Set(buf, SFXBP_RELATIVE_MODE, true); - iSFX->Setv(buf, SFXBP_POSITION, vec); + AudioDriver_SFX()->Set(buf, SFXBP_RELATIVE_MODE, true); + AudioDriver_SFX()->Setv(buf, SFXBP_POSITION, vec); } else { // Use the channel's real position. - iSFX->Set(buf, SFXBP_RELATIVE_MODE, false); - iSFX->Setv(buf, SFXBP_POSITION, ch->pos); + AudioDriver_SFX()->Set(buf, SFXBP_RELATIVE_MODE, false); + AudioDriver_SFX()->Setv(buf, SFXBP_POSITION, ch->pos); } // If the sound is emitted by the listener, speed is zero. @@ -441,13 +434,13 @@ void Sfx_ChannelUpdate(sfxchannel_t* ch) vec[VX] = ch->emitter->mom[MX] * TICSPERSEC; vec[VY] = ch->emitter->mom[MY] * TICSPERSEC; vec[VZ] = ch->emitter->mom[MZ] * TICSPERSEC; - iSFX->Setv(buf, SFXBP_VELOCITY, vec); + AudioDriver_SFX()->Setv(buf, SFXBP_VELOCITY, vec); } else { // Not moving. vec[VX] = vec[VY] = vec[VZ] = 0; - iSFX->Setv(buf, SFXBP_VELOCITY, vec); + AudioDriver_SFX()->Setv(buf, SFXBP_VELOCITY, vec); } } else @@ -513,8 +506,8 @@ void Sfx_ChannelUpdate(sfxchannel_t* ch) } } - iSFX->Set(buf, SFXBP_VOLUME, ch->volume * dist * sfxVolume / 255.0f); - iSFX->Set(buf, SFXBP_PAN, pan); + AudioDriver_SFX()->Set(buf, SFXBP_VOLUME, ch->volume * dist * sfxVolume / 255.0f); + AudioDriver_SFX()->Set(buf, SFXBP_PAN, pan); } } @@ -534,19 +527,19 @@ void Sfx_ListenerUpdate(void) { // Position. At eye-level. Sfx_GetListenerXYZ(vec); - iSFX->Listenerv(SFXLP_POSITION, vec); + AudioDriver_SFX()->Listenerv(SFXLP_POSITION, vec); // Orientation. (0,0) will produce front=(1,0,0) and up=(0,0,1). vec[VX] = listener->angle / (float) ANGLE_MAX *360; vec[VY] = (listener->dPlayer? LOOKDIR2DEG(listener->dPlayer->lookDir) : 0); - iSFX->Listenerv(SFXLP_ORIENTATION, vec); + AudioDriver_SFX()->Listenerv(SFXLP_ORIENTATION, vec); // Velocity. The unit is world distance units per second. vec[VX] = listener->mom[MX] * TICSPERSEC; vec[VY] = listener->mom[MY] * TICSPERSEC; vec[VZ] = listener->mom[MZ] * TICSPERSEC; - iSFX->Listenerv(SFXLP_VELOCITY, vec); + AudioDriver_SFX()->Listenerv(SFXLP_VELOCITY, vec); // Reverb effects. Has the current sector changed? if(listenerSector != listener->subsector->sector) @@ -560,12 +553,12 @@ void Sfx_ListenerUpdate(void) vec[i] *= sfxReverbStrength; } - iSFX->Listenerv(SFXLP_REVERB, vec); + AudioDriver_SFX()->Listenerv(SFXLP_REVERB, vec); } } // Update all listener properties. - iSFX->Listener(SFXLP_UPDATE, 0); + AudioDriver_SFX()->Listener(SFXLP_UPDATE, 0); } void Sfx_ListenerNoReverb(void) @@ -576,8 +569,8 @@ void Sfx_ListenerNoReverb(void) return; listenerSector = NULL; - iSFX->Listenerv(SFXLP_REVERB, rev); - iSFX->Listener(SFXLP_UPDATE, 0); + AudioDriver_SFX()->Listenerv(SFXLP_REVERB, rev); + AudioDriver_SFX()->Listener(SFXLP_UPDATE, 0); } /** @@ -589,7 +582,7 @@ void Sfx_ChannelStop(sfxchannel_t* ch) if(!ch->buffer) return; - iSFX->Stop(ch->buffer); + AudioDriver_SFX()->Stop(ch->buffer); } void Sfx_GetChannelPriorities(float* prios) @@ -795,9 +788,9 @@ int Sfx_StartSound(sfxsample_t* sample, float volume, float freq, if(selCh->buffer->rate != sample->rate || selCh->buffer->bytes != sample->bytesPer) { - iSFX->Destroy(selCh->buffer); + AudioDriver_SFX()->Destroy(selCh->buffer); // Create a new buffer with the correct format. - selCh->buffer = iSFX->Create(play3D ? SFXBF_3D : 0, sample->bytesPer * 8, sample->rate); + selCh->buffer = AudioDriver_SFX()->Create(play3D ? SFXBF_3D : 0, sample->bytesPer * 8, sample->rate); } // Clear flags. @@ -839,7 +832,7 @@ int Sfx_StartSound(sfxsample_t* sample, float volume, float freq, */ if(!selCh->buffer->sample || selCh->buffer->sample->id != sample->id) { - iSFX->Load(selCh->buffer, sample); + AudioDriver_SFX()->Load(selCh->buffer, sample); } // Update channel properties. @@ -850,20 +843,20 @@ int Sfx_StartSound(sfxsample_t* sample, float volume, float freq, { // Init the buffer's min/max distances. // This is only done once, when the sound is started (i.e., here). - iSFX->Set(selCh->buffer, SFXBP_MIN_DISTANCE, + AudioDriver_SFX()->Set(selCh->buffer, SFXBP_MIN_DISTANCE, (selCh->flags & SFXCF_NO_ATTENUATION)? 10000 : soundMinDist); - iSFX->Set(selCh->buffer, SFXBP_MAX_DISTANCE, + AudioDriver_SFX()->Set(selCh->buffer, SFXBP_MAX_DISTANCE, (selCh->flags & SFXCF_NO_ATTENUATION)? 20000 : soundMaxDist); } // This'll commit all the deferred properties. - iSFX->Listener(SFXLP_UPDATE, 0); + AudioDriver_SFX()->Listener(SFXLP_UPDATE, 0); // Start playing. - iSFX->Play(selCh->buffer); + AudioDriver_SFX()->Play(selCh->buffer); END_COP; @@ -910,7 +903,7 @@ void Sfx_StartFrame(void) return; // Tell the audioDriver that the sound frame begins. - audioDriver->Event(SFXEV_BEGIN); + AudioDriver_Interface(AudioDriver_SFX())->Event(SFXEV_BEGIN); // Have there been changes to the cvar settings? Sfx_3DMode(sfx3D); @@ -945,7 +938,7 @@ void Sfx_EndFrame(void) } // The sound frame ends. - audioDriver->Event(SFXEV_END); + AudioDriver_Interface(AudioDriver_SFX())->Event(SFXEV_END); } /** @@ -962,12 +955,12 @@ void Sfx_CreateChannels(int num2D, int bits, int rate) // Change the primary buffer's format to match the channel format. parm[0] = bits; parm[1] = rate; - iSFX->Listenerv(SFXLP_PRIMARY_FORMAT, parm); + AudioDriver_SFX()->Listenerv(SFXLP_PRIMARY_FORMAT, parm); // Try to create a buffer for each channel. for(i = 0, ch = channels; i < numChannels; ++i, ch++) { - ch->buffer = iSFX->Create(num2D-- > 0 ? 0 : SFXBF_3D, bits, rate); + ch->buffer = AudioDriver_SFX()->Create(num2D-- > 0 ? 0 : SFXBF_3D, bits, rate); if(!ch->buffer) { Con_Message("Sfx_CreateChannels: Failed to create " @@ -990,7 +983,7 @@ void Sfx_DestroyChannels(void) Sfx_ChannelStop(channels + i); if(channels[i].buffer) - iSFX->Destroy(channels[i].buffer); + AudioDriver_SFX()->Destroy(channels[i].buffer); channels[i].buffer = NULL; } END_COP; @@ -1044,9 +1037,9 @@ void Sfx_StartRefresh(void) refreshing = false; allowRefresh = true; - if(!iSFX) goto noRefresh; // Nothing to refresh. + if(!AudioDriver_SFX()) goto noRefresh; // Nothing to refresh. - if(iSFX->Getv) iSFX->Getv(SFXIP_DISABLE_CHANNEL_REFRESH, &disableRefresh); + if(AudioDriver_SFX()->Getv) AudioDriver_SFX()->Getv(SFXIP_DISABLE_CHANNEL_REFRESH, &disableRefresh); if(!disableRefresh) { // Start the refresh thread. It will run until the Sfx module is shut down. @@ -1080,24 +1073,7 @@ boolean Sfx_Init(void) VERBOSE( Con_Message("Initializing Sound Effects subsystem...\n") ) - // Use the external SFX playback facilities, if available. - if(audioDriver == &audiod_dummy) - { - iSFX = (audiointerface_sfx_generic_t*) &audiod_dummy_sfx; - } -#ifndef DENG_DISABLE_SDLMIXER - else if(audioDriver == &audiod_sdlmixer) - { - iSFX = (audiointerface_sfx_generic_t*) &audiod_sdlmixer_sfx; - } -#endif - else - { - iSFX = (audiodExternalISFX.gen.Init? - (audiointerface_sfx_generic_t*) &audiodExternalISFX : 0); - } - - if(!iSFX) + if(!AudioDriver_SFX()) { // No interface for SFX playback. return false; } @@ -1105,8 +1081,8 @@ boolean Sfx_Init(void) // This is based on the scientific calculations that if the DOOM marine // is 56 units tall, 60 is about two meters. //// \fixme Derive from the viewheight. - iSFX->Listener(SFXLP_UNITS_PER_METER, 30); - iSFX->Listener(SFXLP_DOPPLER, 1.5f); + AudioDriver_SFX()->Listener(SFXLP_UNITS_PER_METER, 30); + AudioDriver_SFX()->Listener(SFXLP_DOPPLER, 1.5f); // The audioDriver is working, let's create the channels. Sfx_InitChannels(); diff --git a/doomsday/engine/unix/src/sys_audiod_loader.c b/doomsday/engine/unix/src/sys_audiod_loader.c deleted file mode 100644 index 1a20154029..0000000000 --- a/doomsday/engine/unix/src/sys_audiod_loader.c +++ /dev/null @@ -1,183 +0,0 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html - * - *\author Copyright © 2004-2012 Jaakko Keränen - *\author Copyright © 2007-2012 Daniel Swanson - *\author Copyright © 2006 Jamie Jones - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * sys_audiod_loader.c: Loader for ds*.so - */ - -// HEADER FILES ------------------------------------------------------------ - -#include - -#ifdef UNIX -# include "library.h" -#endif - -#include "de_console.h" - -#include "s_main.h" -#include "sys_audiod.h" -#include "sys_audiod_sfx.h" -#include "sys_audiod_mus.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -audiodriver_t audiodExternal; - -audiointerface_sfx_t audiodExternalISFX; -audiointerface_music_t audiodExternalIMusic; -audiointerface_cd_t audiodExternalICD; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static Library* handle = NULL; - -// CODE -------------------------------------------------------------------- - -static void* Imp(const char* fn) -{ - return Library_Symbol(handle, fn); -} - -void Sys_ShutdownAudioDriver(void) -{ - if(!audioDriver) - return; - - if(audioDriver->Shutdown) - audioDriver->Shutdown(); - - if(audioDriver == &audiodExternal) - { - Library_Delete(handle); - handle = NULL; - } -} - -static audiodriver_t* importExternal(void) -{ - audiodriver_t* d = &audiodExternal; - - // Clear everything. - memset(d, 0, sizeof(*d)); - - d->Init = Imp("DS_Init"); - d->Shutdown = Imp("DS_Shutdown"); - d->Event = Imp("DS_Event"); - d->Set = Imp("DS_Set"); - - // The driver may provide SFX playback functionality. - if(Imp("DS_SFX_Init")) - { // The driver offers a SFX playback interface. - audiointerface_sfx_t* i = &audiodExternalISFX; - - i->gen.Init = Imp("DS_SFX_Init"); - i->gen.Create = Imp("DS_SFX_CreateBuffer"); - i->gen.Destroy = Imp("DS_SFX_DestroyBuffer"); - i->gen.Load = Imp("DS_SFX_Load"); - i->gen.Reset = Imp("DS_SFX_Reset"); - i->gen.Play = Imp("DS_SFX_Play"); - i->gen.Stop = Imp("DS_SFX_Stop"); - i->gen.Refresh = Imp("DS_SFX_Refresh"); - - i->gen.Set = Imp("DS_SFX_Set"); - i->gen.Setv = Imp("DS_SFX_Setv"); - i->gen.Listener = Imp("DS_SFX_Listener"); - i->gen.Listenerv = Imp("DS_SFX_Listenerv"); - i->gen.Getv = Imp("DS_SFX_Getv"); - } - - // The driver may provide music playback functionality. - if(Imp("DM_Music_Init")) - { // The driver also offers a music playback interface. - audiointerface_music_t* i = &audiodExternalIMusic; - - i->gen.Init = Imp("DM_Music_Init"); - i->gen.Update = Imp("DM_Music_Update"); - i->gen.Get = Imp("DM_Music_Get"); - i->gen.Set = Imp("DM_Music_Set"); - i->gen.Pause = Imp("DM_Music_Pause"); - i->gen.Stop = Imp("DM_Music_Stop"); - i->SongBuffer = Imp("DM_Music_SongBuffer"); - i->Play = Imp("DM_Music_Play"); - i->PlayFile = Imp("DM_Music_PlayFile"); - } - - if(Imp("DM_CDAudio_Init")) - { // The driver also offers a CD audio (redbook) playback interface. - audiointerface_cd_t* i = &audiodExternalICD; - - i->gen.Init = Imp("DM_CDAudio_Init"); - i->gen.Update = Imp("DM_CDAudio_Update"); - i->gen.Set = Imp("DM_CDAudio_Set"); - i->gen.Get = Imp("DM_CDAudio_Get"); - i->gen.Pause = Imp("DM_CDAudio_Pause"); - i->gen.Stop = Imp("DM_CDAudio_Stop"); - i->Play = Imp("DM_CDAudio_Play"); - } - - return d; -} - -audiodriver_t* Sys_LoadAudioDriver(const char* name) -{ - audiodriver_t* ad = NULL; - if(NULL != name && name[0]) - { - ddstring_t libPath; - // Compose the name using the prefix "ds". - Str_Init(&libPath); -#ifdef MACOSX - Str_Appendf(&libPath, "ds%s.bundle", name); -#else - Str_Appendf(&libPath, "libds%s.so", name); -#endif - - // Load the audio driver library and import symbols. - handle = Library_New(Str_Text(&libPath)); - if(NULL != handle) - { - ad = importExternal(); - } - if(NULL == ad) - { - Con_Message("Warning: Sys_LoadAudioDriver: Loading of \"%s\" failed.\n", Str_Text(&libPath)); - } - Str_Free(&libPath); - } - return ad; -} diff --git a/doomsday/engine/win32/src/sys_audiod_loader.c b/doomsday/engine/win32/src/sys_audiod_loader.c deleted file mode 100644 index cd9be0e1b1..0000000000 --- a/doomsday/engine/win32/src/sys_audiod_loader.c +++ /dev/null @@ -1,177 +0,0 @@ -/**\file - *\section License - * License: GPL - * Online License Link: http://www.gnu.org/licenses/gpl.html - * - *\author Copyright © 2003-2012 Jaakko Keränen - *\author Copyright © 2006-2009 Daniel Swanson - * - * 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., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/** - * sys_audiod_loader.c: Audio Driver loader, Win32-specific. - * - * Loader for ds*.dll - */ - -// HEADER FILES ------------------------------------------------------------ - -#define WIN32_LEAN_AND_MEAN -#include - -#include "de_console.h" - -#include "s_main.h" -#include "sys_audiod.h" -#include "sys_audiod_sfx.h" -#include "sys_audiod_mus.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -audiodriver_t audiodExternal; - -audiointerface_sfx_t audiodExternalISFX; -audiointerface_music_t audiodExternalIMusic; -audiointerface_cd_t audiodExternalICD; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static HINSTANCE hInstExt = NULL; - -// CODE -------------------------------------------------------------------- - -static void* Imp(const char* fn) -{ - return GetProcAddress(hInstExt, fn); -} - -void Sys_ShutdownAudioDriver(void) -{ - if(!audioDriver) - return; - - if(audioDriver->Shutdown) - audioDriver->Shutdown(); - - if(audioDriver == &audiodExternal) - { - FreeLibrary(hInstExt); - hInstExt = NULL; - } -} - -static audiodriver_t* importExternal(void) -{ - audiodriver_t* d = &audiodExternal; - - // Clear everything. - memset(d, 0, sizeof(*d)); - - d->Init = Imp("DS_Init"); - d->Shutdown = Imp("DS_Shutdown"); - d->Event = Imp("DS_Event"); - d->Set = Imp("DS_Set"); - - // The driver may provide SFX playback functionality. - if(Imp("DS_SFX_Init")) - { // The driver offers a SFX playback interface. - audiointerface_sfx_t* i = &audiodExternalISFX; - - i->gen.Init = Imp("DS_SFX_Init"); - i->gen.Create = Imp("DS_SFX_CreateBuffer"); - i->gen.Destroy = Imp("DS_SFX_DestroyBuffer"); - i->gen.Load = Imp("DS_SFX_Load"); - i->gen.Reset = Imp("DS_SFX_Reset"); - i->gen.Play = Imp("DS_SFX_Play"); - i->gen.Stop = Imp("DS_SFX_Stop"); - i->gen.Refresh = Imp("DS_SFX_Refresh"); - - i->gen.Set = Imp("DS_SFX_Set"); - i->gen.Setv = Imp("DS_SFX_Setv"); - i->gen.Listener = Imp("DS_SFX_Listener"); - i->gen.Listenerv = Imp("DS_SFX_Listenerv"); - i->gen.Getv = Imp("DS_SFX_Getv"); - } - - // The driver may provide music playback functionality. - if(Imp("DM_Music_Init")) - { // The driver also offers a music playback interface. - audiointerface_music_t* i = &audiodExternalIMusic; - - i->gen.Init = Imp("DM_Music_Init"); - i->gen.Update = Imp("DM_Music_Update"); - i->gen.Get = Imp("DM_Music_Get"); - i->gen.Set = Imp("DM_Music_Set"); - i->gen.Pause = Imp("DM_Music_Pause"); - i->gen.Stop = Imp("DM_Music_Stop"); - i->SongBuffer = Imp("DM_Music_SongBuffer"); - i->Play = Imp("DM_Music_Play"); - i->PlayFile = Imp("DM_Music_PlayFile"); - } - - if(Imp("DM_CDAudio_Init")) - { // The driver also offers a CD audio (redbook) playback interface. - audiointerface_cd_t* i = &audiodExternalICD; - - i->gen.Init = Imp("DM_CDAudio_Init"); - i->gen.Update = Imp("DM_CDAudio_Update"); - i->gen.Set = Imp("DM_CDAudio_Set"); - i->gen.Get = Imp("DM_CDAudio_Get"); - i->gen.Pause = Imp("DM_CDAudio_Pause"); - i->gen.Stop = Imp("DM_CDAudio_Stop"); - i->Play = Imp("DM_CDAudio_Play"); - } - - return d; -} - -audiodriver_t* Sys_LoadAudioDriver(const char* name) -{ - audiodriver_t* ad = NULL; - if(NULL != name && name[0]) - { - ddstring_t libPath; - // Compose the name using the prefix "ds". - Str_Init(&libPath); - Str_Appendf(&libPath, "%sds%s.dll", ddBinPath, name); - - // Load the audio driver library and import symbols. - hInstExt = LoadLibrary(WIN_STRING(Str_Text(&libPath))); - if(NULL != hInstExt) - { - ad = importExternal(); - } - if(NULL == ad) - { - Con_Message("Warning: Sys_LoadAudioDriver: Loading of \"%s\" failed.\n", Str_Text(&libPath)); - } - Str_Free(&libPath); - } - return ad; -} diff --git a/doomsday/plugins/openal/src/driver_openal.c b/doomsday/plugins/openal/src/driver_openal.c index 13e68b6b6b..b403e188a3 100644 --- a/doomsday/plugins/openal/src/driver_openal.c +++ b/doomsday/plugins/openal/src/driver_openal.c @@ -23,7 +23,6 @@ * * \bug Not 64bit clean: In function 'DS_SFX_CreateBuffer': cast to pointer from integer of different size * \bug Not 64bit clean: In function 'DS_SFX_DestroyBuffer': cast to pointer from integer of different size - * \bug Not 64bit clean: In function 'Sys_LoadAudioDriver': cast to pointer from integer of different size * \bug Not 64bit clean: In function 'DS_SFX_Play': cast to pointer from integer of different size * \bug Not 64bit clean: In function 'DS_SFX_Stop': cast to pointer from integer of different size * \bug Not 64bit clean: In function 'DS_SFX_Refresh': cast to pointer from integer of different size