drivers.cpp
1 /* 2 Copyright (C) 2009 Jonathon Fowler <jf@jonof.id.au> 3 Copyright (C) EDuke32 developers and contributors 4 5 This program is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 2 8 of the License, or (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 See the GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 */ 21 22 /** 23 * Abstraction layer for hiding the various supported sound devices 24 * behind a common and opaque interface called on by MultiVoc. 25 */ 26 27 #include "drivers.h" 28 29 #include "driver_adlib.h" 30 #include "driver_sf2.h" 31 #include "_midi.h" 32 33 #ifdef RENDERTYPESDL 34 # include "driver_sdl.h" 35 #endif 36 37 #ifdef _WIN32 38 # include "driver_directsound.h" 39 # include "driver_winmm.h" 40 #endif 41 42 #ifdef __linux__ 43 # include "driver_alsa.h" 44 #endif 45 46 int ASS_PCMSoundDriver = ASS_AutoDetect; 47 int ASS_MIDISoundDriver = ASS_AutoDetect; 48 int ASS_EMIDICard = -1; 49 50 #define UNSUPPORTED_PCM nullptr,nullptr,nullptr,nullptr,nullptr,nullptr 51 #define UNSUPPORTED_MIDI EMIDI_GeneralMIDI,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr 52 #define UNSUPPORTED_COMPLETELY nullptr,nullptr,UNSUPPORTED_PCM,UNSUPPORTED_MIDI 53 54 static struct 55 { 56 const char *DriverName; 57 58 int (*GetError)(void); 59 const char *(*ErrorString)(int); 60 61 int (*PCM_Init)(int *, int *, void *); 62 void (*PCM_Shutdown)(void); 63 int (*PCM_BeginPlayback)(char *, int, int, void (*)(void)); 64 void (*PCM_StopPlayback)(void); 65 void (*PCM_Lock)(void); 66 void (*PCM_Unlock)(void); 67 68 int EMIDICardType; 69 int (*MIDI_Init)(midifuncs *); 70 void (*MIDI_Shutdown)(void); 71 int (*MIDI_StartPlayback)(void); 72 void (*MIDI_HaltPlayback)(void); 73 void (*MIDI_SetTempo)(int tempo, int division); 74 void (*MIDI_Lock)(void); 75 void (*MIDI_Unlock)(void); 76 void (*MIDI_Service)(void); 77 } SoundDrivers[ASS_NumSoundCards] = { 78 79 // Simple DirectMedia Layer 80 { 81 "SDL", 82 #ifdef RENDERTYPESDL 83 SDLDrv_GetError, 84 SDLDrv_ErrorString, 85 SDLDrv_PCM_Init, 86 SDLDrv_PCM_Shutdown, 87 SDLDrv_PCM_BeginPlayback, 88 SDLDrv_PCM_StopPlayback, 89 SDLDrv_PCM_Lock, 90 SDLDrv_PCM_Unlock, 91 UNSUPPORTED_MIDI, 92 #else 93 UNSUPPORTED_COMPLETELY 94 #endif 95 }, 96 97 // Windows DirectSound 98 { 99 "DirectSound", 100 #ifdef RENDERTYPEWIN 101 DirectSoundDrv_GetError, 102 DirectSoundDrv_ErrorString, 103 DirectSoundDrv_PCM_Init, 104 DirectSoundDrv_PCM_Shutdown, 105 DirectSoundDrv_PCM_BeginPlayback, 106 DirectSoundDrv_PCM_StopPlayback, 107 DirectSoundDrv_PCM_Lock, 108 DirectSoundDrv_PCM_Unlock, 109 UNSUPPORTED_MIDI, 110 #else 111 UNSUPPORTED_COMPLETELY 112 #endif 113 }, 114 115 // OPL3 emulation 116 { 117 "AdLib OPL3 emulation", 118 AdLibDrv_GetError, 119 AdLibDrv_ErrorString, 120 121 UNSUPPORTED_PCM, 122 123 EMIDI_AdLib, 124 AdLibDrv_MIDI_Init, 125 AdLibDrv_MIDI_Shutdown, 126 AdLibDrv_MIDI_StartPlayback, 127 AdLibDrv_MIDI_HaltPlayback, 128 AdLibDrv_MIDI_SetTempo, 129 nullptr, 130 nullptr, 131 AdLibDrv_MIDI_Service, 132 }, 133 134 // Windows MultiMedia system 135 { 136 "Windows MME", 137 #ifdef _WIN32 138 WinMMDrv_GetError, 139 WinMMDrv_ErrorString, 140 141 UNSUPPORTED_PCM, 142 143 EMIDI_GeneralMIDI, 144 WinMMDrv_MIDI_Init, 145 WinMMDrv_MIDI_Shutdown, 146 WinMMDrv_MIDI_StartPlayback, 147 WinMMDrv_MIDI_HaltPlayback, 148 WinMMDrv_MIDI_SetTempo, 149 WinMMDrv_MIDI_Lock, 150 WinMMDrv_MIDI_Unlock, 151 WinMMDrv_MIDI_Service, 152 #else 153 UNSUPPORTED_COMPLETELY 154 #endif 155 }, 156 157 // TinySoundFont 158 { 159 "SoundFont2 synthesizer", 160 SF2Drv_GetError, 161 SF2Drv_ErrorString, 162 163 UNSUPPORTED_PCM, 164 165 EMIDI_GeneralMIDI, 166 SF2Drv_MIDI_Init, 167 SF2Drv_MIDI_Shutdown, 168 SF2Drv_MIDI_StartPlayback, 169 SF2Drv_MIDI_HaltPlayback, 170 SF2Drv_MIDI_SetTempo, 171 nullptr, 172 nullptr, 173 SF2Drv_MIDI_Service, 174 }, 175 176 // ALSA MIDI synthesiser 177 { 178 "ALSA", 179 #ifdef __linux__ 180 ALSADrv_GetError, 181 ALSADrv_ErrorString, 182 183 UNSUPPORTED_PCM, 184 185 EMIDI_GeneralMIDI, 186 ALSADrv_MIDI_Init, 187 ALSADrv_MIDI_Shutdown, 188 ALSADrv_MIDI_StartPlayback, 189 ALSADrv_MIDI_HaltPlayback, 190 ALSADrv_MIDI_SetTempo, 191 ALSADrv_MIDI_Lock, 192 ALSADrv_MIDI_Unlock, 193 ALSADrv_MIDI_Service, 194 #else 195 UNSUPPORTED_COMPLETELY 196 #endif 197 }, 198 }; 199 200 201 int SoundDriver_IsPCMSupported(int driver) { return (SoundDrivers[driver].PCM_Init != 0); } 202 int SoundDriver_IsMIDISupported(int driver) { return (SoundDrivers[driver].MIDI_Init != 0); } 203 const char *SoundDriver_GetName(int driver) { return SoundDrivers[driver].DriverName; } 204 205 int SoundDriver_PCM_GetError(void) 206 { 207 if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) 208 return -1; 209 210 return SoundDrivers[ASS_PCMSoundDriver].GetError(); 211 } 212 213 const char * SoundDriver_PCM_ErrorString( int ErrorNumber ) 214 { 215 if (ASS_PCMSoundDriver < 0 || ASS_PCMSoundDriver >= ASS_NumSoundCards) 216 return "No sound driver selected."; 217 218 if (!SoundDriver_IsPCMSupported(ASS_PCMSoundDriver)) 219 return "Unsupported sound driver selected."; 220 221 return SoundDrivers[ASS_PCMSoundDriver].ErrorString(ErrorNumber); 222 } 223 224 int SoundDriver_MIDI_GetError(void) 225 { 226 if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) 227 return -1; 228 229 return SoundDrivers[ASS_MIDISoundDriver].GetError(); 230 } 231 232 const char * SoundDriver_MIDI_ErrorString( int ErrorNumber ) 233 { 234 if (ASS_MIDISoundDriver < 0 || ASS_MIDISoundDriver >= ASS_NumSoundCards) 235 return "No sound driver selected."; 236 237 if (!SoundDriver_IsMIDISupported(ASS_MIDISoundDriver)) 238 return "Unsupported sound driver selected."; 239 240 return SoundDrivers[ASS_MIDISoundDriver].ErrorString(ErrorNumber); 241 } 242 243 int SoundDriver_PCM_Init(int *mixrate, int *numchannels, void *initdata) 244 { 245 return SoundDrivers[ASS_PCMSoundDriver].PCM_Init(mixrate, numchannels, initdata); 246 } 247 248 int SoundDriver_PCM_BeginPlayback(char *BufferStart, int BufferSize, int NumDivisions, void (*CallBackFunc)(void)) 249 { 250 return SoundDrivers[ASS_PCMSoundDriver].PCM_BeginPlayback(BufferStart, BufferSize, NumDivisions, CallBackFunc); 251 } 252 253 void SoundDriver_PCM_Shutdown(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_Shutdown(); } 254 void SoundDriver_PCM_StopPlayback(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_StopPlayback(); } 255 void SoundDriver_PCM_Lock(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_Lock(); } 256 void SoundDriver_PCM_Unlock(void) { SoundDrivers[ASS_PCMSoundDriver].PCM_Unlock(); } 257 int SoundDriver_MIDI_Init(midifuncs *funcs) { return SoundDrivers[ASS_MIDISoundDriver].MIDI_Init(funcs); } 258 int SoundDriver_MIDI_StartPlayback(void) { return SoundDrivers[ASS_MIDISoundDriver].MIDI_StartPlayback(); } 259 void SoundDriver_MIDI_Shutdown(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_Shutdown(); } 260 void SoundDriver_MIDI_HaltPlayback(void) { SoundDrivers[ASS_MIDISoundDriver].MIDI_HaltPlayback(); } 261 void SoundDriver_MIDI_SetTempo(int tempo, int division) { SoundDrivers[ASS_MIDISoundDriver].MIDI_SetTempo(tempo, division); } 262 void SoundDriver_MIDI_Lock(void) { if (SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock) SoundDrivers[ASS_MIDISoundDriver].MIDI_Lock(); } 263 void SoundDriver_MIDI_Unlock(void) { if (SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock) SoundDrivers[ASS_MIDISoundDriver].MIDI_Unlock(); } 264 int SoundDriver_MIDI_GetCardType(void) { return SoundDrivers[ASS_MIDISoundDriver].EMIDICardType; } 265 266 // vim:ts=4:sw=4:expandtab: