/ source / audiolib / src / drivers.cpp
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: