1 /*
2 * Copyright (c) 2009, The MilkyTracker Team.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * - Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * - Neither the name of the <ORGANIZATION> nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "AudioDriverManager.h"
31 #include "AudioDriverBase.h"
32 #include "MilkyPlayCommon.h"
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #define ALLOC_DRIVERLIST(NUMDRIVERS) \
38 enumerationIndex = -1; \
39 numDrivers = (NUMDRIVERS); \
40 driverList = new AudioDriverInterface*[numDrivers]; \
41 memset(driverList, 0, numDrivers*sizeof(AudioDriverInterface*));
42
43 #define CLEANUP_DRIVERLIST \
44 for (mp_sint32 i = 0; i < numDrivers; i++) \
45 delete driverList[i]; \
46 delete[] driverList;
47
48 #if defined(DRIVER_WIN32)
49 //////////////////////////////////////////////////////////////////
50 // Windows implementation
51 //////////////////////////////////////////////////////////////////
52 #include "AudioDriver_MMSYSTEM.h"
53
54 #if !defined(_WIN32_WCE) && !defined(__SKIPRTAUDIO__)
55 #include "AudioDriver_RTAUDIO.h"
56
57 /* Taken from VersionHelpers.h in the Windows 8 SDK; not present in the XP-compatible SDKs */
IsWindowsVistaOrGreater()58 static bool IsWindowsVistaOrGreater()
59 {
60 OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 };
61 DWORDLONG const dwlConditionMask = VerSetConditionMask(
62 VerSetConditionMask(
63 VerSetConditionMask(
64 0, VER_MAJORVERSION, VER_GREATER_EQUAL),
65 VER_MINORVERSION, VER_GREATER_EQUAL),
66 VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
67
68 osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA);
69 osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA);
70 osvi.wServicePackMajor = 0;
71
72 return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
73 }
74
75 #endif
76 #if !defined(_WIN32_WCE) && defined(__WASAPI__)
77 #include "AudioDriver_PORTAUDIO.h"
78 #endif
79
AudioDriverManager()80 AudioDriverManager::AudioDriverManager() :
81 defaultDriverIndex(0)
82 {
83 mp_sint32 driverListSize = 1;
84 #if !defined(_WIN32_WCE) && !defined(__SKIPRTAUDIO__)
85 driverListSize+=4;
86 #endif
87 #if !defined(_WIN32_WCE) && defined(__WASAPI__)
88 driverListSize++;
89 #endif
90
91 mp_sint32 i = 0;
92 ALLOC_DRIVERLIST(driverListSize);
93 driverList[i++] = new AudioDriver_MMSYSTEM();
94 #if !defined(_WIN32_WCE) && !defined(__SKIPRTAUDIO__)
95 driverList[i++] = new AudioDriver_RTAUDIO();
96 driverList[i++] = new AudioDriver_RTAUDIO(AudioDriver_RTAUDIO::WINDOWS_ASIO);
97 driverList[i++] = new AudioDriver_RTAUDIO(AudioDriver_RTAUDIO::WINDOWS_DS);
98 driverList[i++] = new AudioDriver_RTAUDIO(AudioDriver_RTAUDIO::WINDOWS_WASAPI);
99
100 #ifndef _WIN32_WCE
101 // On Windows Vista we set the DS driver to be the default
102 if (IsWindowsVistaOrGreater())
103 defaultDriverIndex = i-2;
104 #endif
105
106 #endif
107 #if !defined(_WIN32_WCE) && defined(__WASAPI__)
108 driverList[i++] = new AudioDriver_PORTAUDIO();
109 #endif
110 }
111
112 #elif defined(DRIVER_OSX)
113 //////////////////////////////////////////////////////////////////
114 // Mac OS X implementation
115 //////////////////////////////////////////////////////////////////
116 #include "AudioDriver_COREAUDIO.h"
117
AudioDriverManager()118 AudioDriverManager::AudioDriverManager() :
119 defaultDriverIndex(0)
120 {
121 mp_uint32 deviceCount = 0;
122 AudioObjectID* deviceIDs = NULL;
123 OSStatus err = AudioDriver_COREAUDIO::getAudioDevices(deviceCount, deviceIDs);
124
125 if (err)
126 fprintf(stderr, "Core Audio: Error while enumerating devices (%d)\n", err);
127
128 ALLOC_DRIVERLIST(deviceCount + 1);
129
130 // First device: system default output
131 driverList[0] = new AudioDriver_COREAUDIO();
132
133 // List all output devices
134 int i;
135 for (i = 0; i < deviceCount; i++)
136 {
137 driverList[i + 1] = new AudioDriver_COREAUDIO(deviceIDs[i]);
138 }
139
140 if (deviceIDs)
141 delete[] deviceIDs;
142 }
143
144 #elif defined(DRIVER_UNIX)
145 //////////////////////////////////////////////////////////////////
146 // UNIX implementation
147 //////////////////////////////////////////////////////////////////
148 #include "AudioDriver_SDL.h"
149 // #include "AudioDriver_RTAUDIO.h"
150 #ifdef HAVE_LIBASOUND
151 #include "drivers/alsa/AudioDriver_ALSA.h"
152 #endif
153 #ifdef HAVE_JACK_JACK_H
154 #include "AudioDriver_JACK.h"
155 #endif
156
AudioDriverManager()157 AudioDriverManager::AudioDriverManager() :
158 defaultDriverIndex(0)
159 {
160 int count = 1;
161 #ifdef HAVE_LIBASOUND
162 count++;
163 #endif
164 #ifdef HAVE_JACK_JACK_H
165 count++;
166 #endif
167 ALLOC_DRIVERLIST(count);
168 count = 0;
169 driverList[count++] = new AudioDriver_SDL();
170 #ifdef HAVE_LIBASOUND
171 driverList[count++] = new AudioDriver_ALSA();
172 #endif
173 #if HAVE_JACK_JACK_H
174 driverList[count++] = new AudioDriver_JACK();
175 #endif
176 }
177
178 #elif defined(DRIVER_SDL)
179 //////////////////////////////////////////////////////////////////
180 // SDL implementation
181 //////////////////////////////////////////////////////////////////
182 #include "AudioDriver_SDL.h"
183
AudioDriverManager()184 AudioDriverManager::AudioDriverManager() :
185 defaultDriverIndex(0)
186 {
187 ALLOC_DRIVERLIST(1);
188 driverList[0] = new AudioDriver_SDL();
189 }
190
191 #elif defined(DRIVER_PSP)
192 //////////////////////////////////////////////////////////////////
193 // PSP implementation
194 //////////////////////////////////////////////////////////////////
195 #include "AudioDriver_PSP.h"
196
AudioDriverManager()197 AudioDriverManager::AudioDriverManager() :
198 defaultDriverIndex(0)
199 {
200 ALLOC_DRIVERLIST(1);
201 driverList[0] = new AudioDriver_PSP();
202 }
203
204 #elif defined(DRIVER_HAIKU)
205 //////////////////////////////////////////////////////////////////
206 // Haiku implementation
207 //////////////////////////////////////////////////////////////////
208 #include "AudioDriver_Haiku.h"
209
AudioDriverManager()210 AudioDriverManager::AudioDriverManager() :
211 defaultDriverIndex(0)
212 {
213 ALLOC_DRIVERLIST(1);
214 driverList[0] = new AudioDriver_Haiku();
215 }
216
217 #endif
218
getPreferredAudioDriver()219 AudioDriverInterface* AudioDriverManager::getPreferredAudioDriver()
220 {
221 return driverList[defaultDriverIndex];
222 }
223
~AudioDriverManager()224 AudioDriverManager::~AudioDriverManager()
225 {
226 CLEANUP_DRIVERLIST;
227 }
228
getAudioDriverByName(const char * name)229 AudioDriverInterface* AudioDriverManager::getAudioDriverByName(const char* name)
230 {
231 if (name == NULL)
232 return NULL;
233
234 for (mp_sint32 i = 0; i < numDrivers; i++)
235 {
236 if (strcmp(driverList[i]->getDriverID(), name) == 0)
237 return driverList[i];
238 }
239
240 return NULL;
241 }
242
getFirstDriverName() const243 const char* AudioDriverManager::getFirstDriverName() const
244 {
245 enumerationIndex = 0;
246 if (enumerationIndex < numDrivers)
247 return driverList[enumerationIndex]->getDriverID();
248 else
249 return NULL;
250 }
251
getNextDriverName() const252 const char* AudioDriverManager::getNextDriverName() const
253 {
254 enumerationIndex++;
255 if (enumerationIndex >= numDrivers)
256 {
257 enumerationIndex = -1;
258 return NULL;
259 }
260
261 return driverList[enumerationIndex]->getDriverID();
262 }
263
getPreferredAudioDriverSampleRate() const264 mp_sint32 AudioDriverManager::getPreferredAudioDriverSampleRate() const
265 {
266 return driverList[defaultDriverIndex]->getPreferredSampleRate();
267 }
268
getPreferredAudioDriverBufferSize() const269 mp_sint32 AudioDriverManager::getPreferredAudioDriverBufferSize() const
270 {
271 return driverList[defaultDriverIndex]->getPreferredBufferSize();
272 }
273