89 |
static ASIODriverInfo MyAsioDriverInfo; |
static ASIODriverInfo MyAsioDriverInfo; |
90 |
static DriverInfo asioDriverInfo = {0}; |
static DriverInfo asioDriverInfo = {0}; |
91 |
|
|
92 |
static bool asioDriverOpened; |
static bool asioDriverOpened = false; |
93 |
static bool AudioOutputDeviceAsioInstantiated = false; |
static bool AudioOutputDeviceAsioInstantiated = false; |
94 |
static String currentAsioDriverName; |
static String currentAsioDriverName; |
95 |
static std::vector<String> asioDriverList; |
static std::vector<String> asioDriverList; |
103 |
ASIOBufferInfo bufferInfos[2]; |
ASIOBufferInfo bufferInfos[2]; |
104 |
AudioOutputDeviceAsio *GlobalAudioOutputDeviceAsioThisPtr; |
AudioOutputDeviceAsio *GlobalAudioOutputDeviceAsioThisPtr; |
105 |
|
|
106 |
void floatToASIOSTInt16LSB(float *in, void *dest, int numSamples) { |
template<int bitres> |
107 |
|
static void floatToASIOSTInt32LSBXX(float *in, void *dest, int numSamples) { |
108 |
|
double pos_max_value = (1 << bitres) -1.0; |
109 |
|
double neg_max_value = -pos_max_value; |
110 |
|
int32_t *out = (int32_t *)dest; |
111 |
|
for(int i=0; i < numSamples ; i++) { |
112 |
|
double sample_point = in[i] * pos_max_value; |
113 |
|
if (sample_point < neg_max_value) sample_point = neg_max_value; |
114 |
|
if (sample_point > pos_max_value) sample_point = pos_max_value; |
115 |
|
out[i] = (int16_t)sample_point; |
116 |
|
} |
117 |
|
} |
118 |
|
|
119 |
|
static void floatToASIOSTInt16LSB(float *in, void *dest, int numSamples) { |
120 |
int16_t *out = (int16_t *)dest; |
int16_t *out = (int16_t *)dest; |
121 |
for(int i=0; i < numSamples ; i++) { |
for(int i=0; i < numSamples ; i++) { |
122 |
float sample_point = in[i] * 32768.0f; |
float sample_point = in[i] * 32768.0f; |
126 |
} |
} |
127 |
} |
} |
128 |
|
|
129 |
void floatToASIOSTInt32LSB(float *in, void *dest, int numSamples) { |
static void floatToASIOSTInt32LSB(float *in, void *dest, int numSamples) { |
130 |
int32_t *out = (int32_t *)dest; |
int32_t *out = (int32_t *)dest; |
131 |
for(int i=0; i < numSamples ; i++) { |
for(int i=0; i < numSamples ; i++) { |
132 |
double sample_point = in[i] * 2147483648.0; |
double sample_point = in[i] * 2147483648.0; |
136 |
} |
} |
137 |
} |
} |
138 |
|
|
139 |
|
std::vector<String> getAsioDriverNames(); |
140 |
|
|
141 |
static bool ASIO_loadAsioDriver(char *name) |
static bool ASIO_loadAsioDriver(char *name) |
142 |
{ |
{ |
143 |
dmsg(1,("ASIO_loadAsioDriver: trying to load '%s'\n",name)); |
dmsg(2,("ASIO_loadAsioDriver: trying to load '%s'\n",name)); |
144 |
#ifdef WINDOWS |
#ifdef WINDOWS |
145 |
CoInitialize(0); |
CoInitialize(0); |
146 |
#endif |
#endif |
155 |
ASIOChannelInfo channelInfos; |
ASIOChannelInfo channelInfos; |
156 |
ASIOError asioError; |
ASIOError asioError; |
157 |
|
|
158 |
dmsg(1,("ASIO_OpenAndQueryDeviceInfo driverName='%s' current='%s'\n",driverName, currentAsioDriverName.c_str() )); |
// call this function in order to fill the internal vector containing the list of ASIO cards |
159 |
|
// since the reading of the list is performed only one time subsequent calls to this function will be automatically ignored |
160 |
|
// calling getAsioDriverNames() is needed in the case of a LinuxSampler client application first creating an ASIO device |
161 |
|
// which calls ASIO_OpenAndQueryDeviceInfo() and afterwards retrieve the list of available ASIO cards |
162 |
|
// since getAsioDriverNames() unloads the current driver and loads the driver 'dummy' this would cause |
163 |
|
// the audio stopping and forcing the create the audio output device again |
164 |
|
getAsioDriverNames(); |
165 |
|
|
166 |
|
dmsg(2,("ASIO_OpenAndQueryDeviceInfo driverName='%s' current='%s'\n",driverName, currentAsioDriverName.c_str() )); |
167 |
if(!strcmp(driverName, currentAsioDriverName.c_str() )) { |
if(!strcmp(driverName, currentAsioDriverName.c_str() )) { |
168 |
// if the given ASIO driver name == current ASIO driver name and the driver |
// if the given ASIO driver name == current ASIO driver name and the driver |
169 |
// was already opened then do nothing |
// was already opened then do nothing |
170 |
if(asioDriverOpened) { |
if(asioDriverOpened) { |
171 |
dmsg(0,("asioDriver ALREADY OPENED, DOING NOTHING !\n")); |
dmsg(2,("asioDriver ALREADY OPENED, DOING NOTHING !\n")); |
172 |
return 0; |
return 0; |
173 |
} |
} |
174 |
} |
} |
175 |
else { |
else { |
176 |
dmsg(1,("driverName != currentAsioDriverName , new asio driver specified, opening device ....\n")); |
dmsg(2,("driverName != currentAsioDriverName , new asio driver specified, opening device ....\n")); |
177 |
// if a new ASIO driver name was specified then first check if we need to close |
// if a new ASIO driver name was specified then first check if we need to close |
178 |
// the old one |
// the old one |
179 |
if(asioDriverOpened) { |
if(asioDriverOpened) { |
180 |
dmsg(0,("different asioDriver ALREADY OPENED, closing old one !\n")); |
dmsg(2,("different asioDriver ALREADY OPENED, closing old one !\n")); |
181 |
asioDriverOpened = false; |
asioDriverOpened = false; |
182 |
ASIOExit(); // close the old ASIO driver |
ASIOExit(); // close the old ASIO driver |
183 |
} |
} |
191 |
/* MUST BE CHECKED : to force fragments loading on Mac */ |
/* MUST BE CHECKED : to force fragments loading on Mac */ |
192 |
//ASIO_loadAsioDriver("dummy"); |
//ASIO_loadAsioDriver("dummy"); |
193 |
|
|
194 |
dmsg(1,("Before ASIO_loadAsioDriver('%s')\n",driverName)); |
dmsg(2,("Before ASIO_loadAsioDriver('%s')\n",driverName)); |
195 |
if ( !ASIO_loadAsioDriver(driverName) ) { |
if ( !ASIO_loadAsioDriver(driverName) ) { |
196 |
dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not loadAsioDriver %s\n", driverName)); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not loadAsioDriver %s\n", driverName)); |
197 |
return -1; |
return -1; |
198 |
} |
} |
199 |
dmsg(1,("Before ASIOInit()\n")); |
dmsg(2,("Before ASIOInit()\n")); |
200 |
if( (asioError = ASIOInit(asioDriverInfo)) != ASE_OK ) { |
if( (asioError = ASIOInit(asioDriverInfo)) != ASE_OK ) { |
201 |
dmsg(1,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n", asioError, driverName)); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n", asioError, driverName)); |
202 |
return asioError; |
return asioError; |
203 |
} |
} |
204 |
dmsg(1,("Before ASIOGetChannels()\n")); |
dmsg(2,("Before ASIOGetChannels()\n")); |
205 |
if( (asioError = ASIOGetChannels(&driverInfo->numInputChannels, &driverInfo->numOutputChannels) != ASE_OK)) { |
if( (asioError = ASIOGetChannels(&driverInfo->numInputChannels, &driverInfo->numOutputChannels) != ASE_OK)) { |
206 |
dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetChannels for %s\n", driverName)); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetChannels for %s\n", driverName)); |
207 |
return asioError; |
return asioError; |
208 |
} |
} |
209 |
|
|
210 |
dmsg(1,("Before ASIOGetBufferSize()\n")); |
dmsg(2,("Before ASIOGetBufferSize()\n")); |
211 |
if( (asioError = ASIOGetBufferSize(&driverInfo->minBufSize,&driverInfo->maxBufSize,&driverInfo->preferredBufSize,&driverInfo->bufGranularity) != ASE_OK)) { |
if( (asioError = ASIOGetBufferSize(&driverInfo->minBufSize,&driverInfo->maxBufSize,&driverInfo->preferredBufSize,&driverInfo->bufGranularity) != ASE_OK)) { |
212 |
dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetBufferSize for %s\n", driverName)); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetBufferSize for %s\n", driverName)); |
213 |
return asioError; |
return asioError; |
214 |
} |
} |
215 |
|
|
216 |
dmsg(0,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %d\n", driverInfo->numInputChannels )); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %d\n", driverInfo->numInputChannels )); |
217 |
dmsg(0,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %d\n", driverInfo->numOutputChannels )); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %d\n", driverInfo->numOutputChannels )); |
218 |
|
|
219 |
/* Loop through the possible sampling rates and check each to see if the device supports it. */ |
/* Loop through the possible sampling rates and check each to see if the device supports it. */ |
220 |
driverInfo->numSampleRates = 0; |
driverInfo->numSampleRates = 0; |
221 |
driverInfo->sampleRates.clear(); |
driverInfo->sampleRates.clear(); |
222 |
for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) { |
for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) { |
223 |
if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) { |
if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) { |
224 |
dmsg(1,("ASIOCanSampleRate: possible sample rate = %d\n", (long)possibleSampleRates[index])); |
dmsg(2,("ASIOCanSampleRate: possible sample rate = %d\n", (long)possibleSampleRates[index])); |
225 |
driverInfo->sampleRates.push_back( (int)possibleSampleRates[index] ); |
driverInfo->sampleRates.push_back( (int)possibleSampleRates[index] ); |
226 |
driverInfo->numSampleRates++; |
driverInfo->numSampleRates++; |
227 |
} |
} |
232 |
driverInfo->channelInfos[i].channel = i; |
driverInfo->channelInfos[i].channel = i; |
233 |
driverInfo->channelInfos[i].isInput = ASIOFalse; |
driverInfo->channelInfos[i].isInput = ASIOFalse; |
234 |
ASIOGetChannelInfo(&driverInfo->channelInfos[i]); |
ASIOGetChannelInfo(&driverInfo->channelInfos[i]); |
235 |
dmsg(1,("channelInfos[%d].type (sampleformat) = %d\n", i, driverInfo->channelInfos[i].type)); |
dmsg(2,("channelInfos[%d].type (sampleformat) = %d\n", i, driverInfo->channelInfos[i].type)); |
236 |
} |
} |
237 |
|
|
238 |
dmsg(1,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n")); |
dmsg(2,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n")); |
239 |
asioDriverOpened = true; |
asioDriverOpened = true; |
240 |
return ASE_OK; |
return ASE_OK; |
241 |
} |
} |
247 |
int numDrivers; |
int numDrivers; |
248 |
|
|
249 |
if(asioDriverListLoaded) { |
if(asioDriverListLoaded) { |
250 |
dmsg(1,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n")); |
dmsg(2,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n")); |
251 |
return asioDriverList; |
return asioDriverList; |
252 |
} |
} |
253 |
|
|
267 |
|
|
268 |
/* Get names of all available ASIO drivers */ |
/* Get names of all available ASIO drivers */ |
269 |
asioDrivers->getDriverNames(names,ASIO_MAX_DEVICE_INFO); |
asioDrivers->getDriverNames(names,ASIO_MAX_DEVICE_INFO); |
270 |
dmsg(1,("getAsioDriverNames: numDrivers=%d\n",numDrivers)); |
dmsg(2,("getAsioDriverNames: numDrivers=%d\n",numDrivers)); |
271 |
|
|
272 |
for (int i = 0 ; i < numDrivers ; i++) { |
for (int i = 0 ; i < numDrivers ; i++) { |
273 |
dmsg(1,("ASIO DRIVERLIST: i=%d name='%s'\n",i,names[i])); |
dmsg(2,("ASIO DRIVERLIST: i=%d name='%s'\n",i,names[i])); |
274 |
|
|
275 |
#if 1 |
#if 1 |
276 |
asioDriverList.push_back(names[i]); |
asioDriverList.push_back(names[i]); |
284 |
asioDriverList.push_back(names[i]); |
asioDriverList.push_back(names[i]); |
285 |
} |
} |
286 |
else { |
else { |
287 |
dmsg(0,("getDriverList: ASIOInit of driver %s gave Error %d ! ignoring it.\n", names[i],asioError)); |
dmsg(2,("getDriverList: ASIOInit of driver %s gave Error %d ! ignoring it.\n", names[i],asioError)); |
288 |
} |
} |
289 |
} |
} |
290 |
else { |
else { |
291 |
dmsg(0,("getDriverList: load driver %s failed! ignoring it.\n", names[i])); |
dmsg(2,("getDriverList: load driver %s failed! ignoring it.\n", names[i])); |
292 |
} |
} |
293 |
// FIXME: we need to check this ASIOExit is needed (gave a crash on a ASIO ADSP24(WDM) card so we commented it out) |
// FIXME: we need to check this ASIOExit is needed (gave a crash on a ASIO ADSP24(WDM) card so we commented it out) |
294 |
//ASIOExit(); |
//ASIOExit(); |
295 |
#endif |
#endif |
296 |
currentAsioDriverName=""; |
//currentAsioDriverName=""; |
297 |
|
|
298 |
} |
} |
299 |
|
|
301 |
delete[] names[i]; |
delete[] names[i]; |
302 |
} |
} |
303 |
|
|
304 |
dmsg(1,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n", asioDriverList.size() )); |
dmsg(2,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n", asioDriverList.size() )); |
305 |
asioDriverListLoaded = true; |
asioDriverListLoaded = true; |
306 |
return asioDriverList; |
return asioDriverList; |
307 |
} |
} |
355 |
else |
else |
356 |
asioDriverInfo.tcSamples = 0; |
asioDriverInfo.tcSamples = 0; |
357 |
|
|
358 |
// get the system reference time |
// TODO: ignore for now. get the system reference time |
359 |
asioDriverInfo.sysRefTime = get_sys_reference_time(); |
// asioDriverInfo.sysRefTime = get_sys_reference_time(); |
360 |
|
|
361 |
// buffer size in samples |
// buffer size in samples |
362 |
long buffSize = asioDriverInfo.chosenBufSize; |
long buffSize = asioDriverInfo.chosenBufSize; |
372 |
switch (asioDriverInfo.channelInfos[i].type) |
switch (asioDriverInfo.channelInfos[i].type) |
373 |
{ |
{ |
374 |
case ASIOSTInt16LSB: |
case ASIOSTInt16LSB: |
375 |
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 2); |
floatToASIOSTInt16LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), |
376 |
|
(int16_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize); |
377 |
break; |
break; |
378 |
case ASIOSTInt24LSB: // used for 20 bits as well |
case ASIOSTInt24LSB: // used for 20 bits as well |
379 |
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3); |
memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3); |
380 |
break; |
break; |
381 |
case ASIOSTInt32LSB: |
case ASIOSTInt32LSB: |
382 |
p = (int32_t *)asioDriverInfo.bufferInfos[i].buffers[index]; |
floatToASIOSTInt32LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), |
383 |
floatToASIOSTInt32LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), p, buffSize); |
(int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize); |
384 |
break; |
break; |
385 |
case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture |
case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture |
386 |
throw AudioOutputException(String("ASIO Error: ASIOSTFloat32LSB not yet supported! report to LinuxSampler developers.") ); |
throw AudioOutputException(String("ASIO Error: ASIOSTFloat32LSB not yet supported! report to LinuxSampler developers.") ); |
391 |
|
|
392 |
// these are used for 32 bit data buffer, with different alignment of the data inside |
// these are used for 32 bit data buffer, with different alignment of the data inside |
393 |
// 32 bit PCI bus systems can more easily used with these |
// 32 bit PCI bus systems can more easily used with these |
394 |
case ASIOSTInt32LSB16: // 32 bit data with 18 bit alignment |
case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment |
395 |
throw AudioOutputException(String("ASIO Error: ASIOSTInt32LSB16 not yet supported! report to LinuxSampler developers.") ); |
floatToASIOSTInt32LSBXX<16>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), |
396 |
|
(int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize); |
397 |
break; |
break; |
398 |
case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment |
case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment |
399 |
throw AudioOutputException(String("ASIO Error: ASIOSTInt32LSB18 not yet supported! report to LinuxSampler developers.") ); |
floatToASIOSTInt32LSBXX<18>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), |
400 |
|
(int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize); |
401 |
break; |
break; |
402 |
case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment |
case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment |
403 |
throw AudioOutputException(String("ASIO Error: ASIOSTInt32LSB20 not yet supported! report to LinuxSampler developers.") ); |
floatToASIOSTInt32LSBXX<20>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), |
404 |
|
(int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize); |
405 |
break; |
break; |
406 |
case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment |
case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment |
407 |
throw AudioOutputException(String("ASIO Error: ASIOSTInt32LSB24 not yet supported! report to LinuxSampler developers.") ); |
floatToASIOSTInt32LSBXX<24>( GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(), |
408 |
|
(int32_t *)asioDriverInfo.bufferInfos[i].buffers[index], buffSize); |
409 |
break; |
break; |
410 |
case ASIOSTInt16MSB: |
case ASIOSTInt16MSB: |
411 |
throw AudioOutputException(String("ASIO Error: ASIOSTInt16MSB not yet supported! report to LinuxSampler developers.") ); |
throw AudioOutputException(String("ASIO Error: ASIOSTInt16MSB not yet supported! report to LinuxSampler developers.") ); |
479 |
|
|
480 |
long asioMessages(long selector, long value, void* message, double* opt) |
long asioMessages(long selector, long value, void* message, double* opt) |
481 |
{ |
{ |
482 |
dmsg(1,("asioMessages selector=%d value=%d\n",selector,value)); |
dmsg(2,("asioMessages selector=%d value=%d\n",selector,value)); |
483 |
// currently the parameters "value", "message" and "opt" are not used. |
// currently the parameters "value", "message" and "opt" are not used. |
484 |
long ret = 0; |
long ret = 0; |
485 |
switch(selector) |
switch(selector) |
572 |
|
|
573 |
std::vector<String> cards = PossibilitiesAsString(Parameters); |
std::vector<String> cards = PossibilitiesAsString(Parameters); |
574 |
if (cards.empty()) throw Exception("AudioOutputDeviceAsio: Can't find any card"); |
if (cards.empty()) throw Exception("AudioOutputDeviceAsio: Can't find any card"); |
575 |
dmsg(1,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n",cards[0].c_str() )); |
dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n",cards[0].c_str() )); |
576 |
return cards[0]; // first card by default |
|
577 |
|
// if currentAsioDriverName is empty then return the first card |
578 |
|
// otherwise return the currentAsioDriverName. this avoids closing the current ASIO driver |
579 |
|
// when the LSCP client calls commands like GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO ASIO CARD |
580 |
|
// which would load the default card (without this check it would always be the same which would cause the above problem) |
581 |
|
if( currentAsioDriverName == "" ) { |
582 |
|
return cards[0]; // first card by default |
583 |
|
} |
584 |
|
else { |
585 |
|
return currentAsioDriverName; |
586 |
|
} |
587 |
|
|
588 |
} |
} |
589 |
|
|
590 |
std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) { |
std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) { |
591 |
dmsg(1,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n")); |
592 |
return getAsioDriverNames(); |
return getAsioDriverNames(); |
593 |
} |
} |
594 |
|
|
620 |
|
|
621 |
optional<int> AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) { |
622 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
623 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing (parameter CARD not supplied)\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing (parameter CARD not supplied)\n")); |
624 |
return optional<int>::nothing; |
return optional<int>::nothing; |
625 |
} |
} |
626 |
|
|
632 |
for(int i = 0 ; i < asioDriverInfo.sampleRates.size() ; i++) { |
for(int i = 0 ; i < asioDriverInfo.sampleRates.size() ; i++) { |
633 |
if(asioDriverInfo.sampleRates[i] == 44100) { |
if(asioDriverInfo.sampleRates[i] == 44100) { |
634 |
return 44100; |
return 44100; |
635 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n")); |
636 |
} |
} |
637 |
if(asioDriverInfo.sampleRates[i] == 48000) { |
if(asioDriverInfo.sampleRates[i] == 48000) { |
638 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n")); |
639 |
return 48000; |
return 48000; |
640 |
} |
} |
641 |
} |
} |
642 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",asioDriverInfo.sampleRates[0])); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",asioDriverInfo.sampleRates[0])); |
643 |
return asioDriverInfo.sampleRates[0]; |
return asioDriverInfo.sampleRates[0]; |
644 |
} |
} |
645 |
|
|
646 |
std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) { |
std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) { |
647 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n")); |
648 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
649 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector (parameter CARD not supplied)\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector (parameter CARD not supplied)\n")); |
650 |
return std::vector<int>(); |
return std::vector<int>(); |
651 |
} |
} |
652 |
|
|
656 |
} |
} |
657 |
|
|
658 |
for(int i=0;i<asioDriverInfo.sampleRates.size();i++) { |
for(int i=0;i<asioDriverInfo.sampleRates.size();i++) { |
659 |
dmsg(1,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt samplerate[%d]=%d\n",i,asioDriverInfo.sampleRates[i])); |
dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt samplerate[%d]=%d\n",i,asioDriverInfo.sampleRates[i])); |
660 |
} |
} |
661 |
|
|
662 |
return asioDriverInfo.sampleRates; |
return asioDriverInfo.sampleRates; |
684 |
} |
} |
685 |
|
|
686 |
optional<int> AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) { |
687 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt\n")); |
688 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
689 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning optional<int>::nothing (CARD parameter not supplied)\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning optional<int>::nothing (CARD parameter not supplied)\n")); |
690 |
return optional<int>::nothing; |
return optional<int>::nothing; |
691 |
} |
} |
692 |
|
|
694 |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
695 |
throw AudioOutputException(String("Error: ASIO Initialization Error") ); |
throw AudioOutputException(String("Error: ASIO Initialization Error") ); |
696 |
} |
} |
697 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %d\n",asioDriverInfo.numOutputChannels)); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %d\n",asioDriverInfo.numOutputChannels)); |
698 |
return asioDriverInfo.numOutputChannels; |
return asioDriverInfo.numOutputChannels; |
699 |
} |
} |
700 |
|
|
701 |
optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) { |
702 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt!\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt!\n")); |
703 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
704 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n")); |
705 |
return optional<int>::nothing; |
return optional<int>::nothing; |
706 |
} |
} |
707 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n")); |
708 |
return 1; |
return 1; |
709 |
} |
} |
710 |
|
|
711 |
optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) { |
712 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt!\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt!\n")); |
713 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
714 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n")); |
715 |
return optional<int>::nothing; |
return optional<int>::nothing; |
716 |
} |
} |
717 |
|
|
719 |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
720 |
throw AudioOutputException(String("Error: ASIO Init Error") ); |
throw AudioOutputException(String("Error: ASIO Init Error") ); |
721 |
} |
} |
722 |
dmsg(1,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %d\n",asioDriverInfo.numOutputChannels)); |
dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %d\n",asioDriverInfo.numOutputChannels)); |
723 |
return asioDriverInfo.numOutputChannels; |
return asioDriverInfo.numOutputChannels; |
724 |
} |
} |
725 |
|
|
755 |
} |
} |
756 |
|
|
757 |
optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) { |
758 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt!\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt!\n")); |
759 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
760 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n")); |
761 |
return optional<int>::nothing; |
return optional<int>::nothing; |
762 |
} |
} |
763 |
|
|
765 |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
766 |
throw AudioOutputException(String("Error: ASIO Initialization Error") ); |
throw AudioOutputException(String("Error: ASIO Initialization Error") ); |
767 |
} |
} |
768 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %d\n",asioDriverInfo.preferredBufSize)); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %d\n",asioDriverInfo.preferredBufSize)); |
769 |
return asioDriverInfo.preferredBufSize; |
return asioDriverInfo.preferredBufSize; |
770 |
} |
} |
771 |
|
|
772 |
optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) { |
773 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt!\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt!\n")); |
774 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
775 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n")); |
776 |
return optional<int>::nothing; |
return optional<int>::nothing; |
777 |
} |
} |
778 |
|
|
780 |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
781 |
throw AudioOutputException(String("Error: ASIO Initalization Error") ); |
throw AudioOutputException(String("Error: ASIO Initalization Error") ); |
782 |
} |
} |
783 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %d\n",asioDriverInfo.minBufSize)); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %d\n",asioDriverInfo.minBufSize)); |
784 |
return asioDriverInfo.minBufSize; |
return asioDriverInfo.minBufSize; |
785 |
} |
} |
786 |
|
|
787 |
optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) { |
optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) { |
788 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt!\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt!\n")); |
789 |
if (!Parameters.count("CARD")) { |
if (!Parameters.count("CARD")) { |
790 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n")); |
791 |
return optional<int>::nothing; |
return optional<int>::nothing; |
792 |
} |
} |
793 |
|
|
795 |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
if( ASIO_OpenAndQueryDeviceInfo((char *)card.ValueAsString().c_str(), &asioDriverInfo, &MyAsioDriverInfo) != ASE_OK) { |
796 |
throw AudioOutputException(String("Error: ASIO Initialization Error") ); |
throw AudioOutputException(String("Error: ASIO Initialization Error") ); |
797 |
} |
} |
798 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %d\n",asioDriverInfo.maxBufSize)); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %d\n",asioDriverInfo.maxBufSize)); |
799 |
return asioDriverInfo.maxBufSize; |
return asioDriverInfo.maxBufSize; |
800 |
} |
} |
801 |
|
|
802 |
std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) { |
std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) { |
803 |
dmsg(1,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt!\n")); |
dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt!\n")); |
804 |
return std::vector<int>(); |
return std::vector<int>(); |
805 |
} |
} |
806 |
|
|
833 |
String Card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString(); |
String Card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString(); |
834 |
|
|
835 |
|
|
836 |
dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor\n")); |
dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor\n")); |
837 |
|
|
838 |
asioIsPlaying = false; |
asioIsPlaying = false; |
839 |
|
|
840 |
ASIO_OpenAndQueryDeviceInfo((char *)Card.c_str(), &asioDriverInfo, &MyAsioDriverInfo); |
ASIO_OpenAndQueryDeviceInfo((char *)Card.c_str(), &asioDriverInfo, &MyAsioDriverInfo); |
841 |
dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n")); |
dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n")); |
842 |
|
|
843 |
if( ASIOSetSampleRate(uiSamplerate) != ASE_OK ) { |
if( ASIOSetSampleRate(uiSamplerate) != ASE_OK ) { |
844 |
throw AudioOutputException(String("Error: ASIOSetSampleRate: cannot set samplerate. ") ); |
throw AudioOutputException(String("Error: ASIOSetSampleRate: cannot set samplerate. ") ); |
845 |
} |
} |
846 |
dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n")); |
dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n")); |
847 |
|
|
848 |
if(ASIOOutputReady() == ASE_OK) asioDriverInfo.ASIOOutputReadySupported = true; |
if(ASIOOutputReady() == ASE_OK) asioDriverInfo.ASIOOutputReadySupported = true; |
849 |
else asioDriverInfo.ASIOOutputReadySupported = false; |
else asioDriverInfo.ASIOOutputReadySupported = false; |
850 |
dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady\n")); |
dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady\n")); |
851 |
|
|
852 |
asioDriverInfo.numInputBuffers = 0; |
asioDriverInfo.numInputBuffers = 0; |
853 |
asioDriverInfo.numOutputBuffers = uiAsioChannels; |
asioDriverInfo.numOutputBuffers = uiAsioChannels; |
866 |
if ( ASIOCreateBuffers(asioDriverInfo.bufferInfos, asioDriverInfo.numOutputBuffers, asioDriverInfo.chosenBufSize = FragmentSize, &asioCallbacks) != ASE_OK ){ |
if ( ASIOCreateBuffers(asioDriverInfo.bufferInfos, asioDriverInfo.numOutputBuffers, asioDriverInfo.chosenBufSize = FragmentSize, &asioCallbacks) != ASE_OK ){ |
867 |
throw AudioOutputException(String("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.") ); |
throw AudioOutputException(String("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.") ); |
868 |
} |
} |
869 |
dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n")); |
dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n")); |
870 |
|
|
871 |
// create audio channels for this audio device to which the sampler engines can write to |
// create audio channels for this audio device to which the sampler engines can write to |
872 |
for (int i = 0; i < uiAsioChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize)); |
for (int i = 0; i < uiAsioChannels; i++) this->Channels.push_back(new AudioChannel(i, FragmentSize)); |
886 |
} |
} |
887 |
|
|
888 |
void AudioOutputDeviceAsio::Play() { |
void AudioOutputDeviceAsio::Play() { |
889 |
dmsg(1,("AudioOutputDeviceAsio::Play() !\n")); |
dmsg(2,("AudioOutputDeviceAsio::Play() !\n")); |
890 |
if ( ASIOStart() != ASE_OK ){ |
if ( ASIOStart() != ASE_OK ){ |
891 |
asioIsPlaying = false; |
asioIsPlaying = false; |
892 |
throw AudioOutputException(String("AudioOutputDeviceAsio: Error: ASIOStart failed.") ); |
throw AudioOutputException(String("AudioOutputDeviceAsio: Error: ASIOStart failed.") ); |
899 |
} |
} |
900 |
|
|
901 |
void AudioOutputDeviceAsio::Stop() { |
void AudioOutputDeviceAsio::Stop() { |
902 |
dmsg(1,("AudioOutputDeviceAsio::Stop() !\n")); |
dmsg(2,("AudioOutputDeviceAsio::Stop() !\n")); |
903 |
ASIOStop(); |
ASIOStop(); |
904 |
asioIsPlaying = false; |
asioIsPlaying = false; |
905 |
} |
} |
906 |
|
|
907 |
AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) { |
AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) { |
908 |
dmsg(1,("AudioOutputDeviceAsio::CreateChannel value=%d uiAsioChannels=%d\n",ChannelNr,uiAsioChannels)); |
dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d uiAsioChannels=%d\n",ChannelNr,uiAsioChannels)); |
909 |
// just create a mix channel |
// just create a mix channel |
910 |
return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels)); |
return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels)); |
911 |
} |
} |
912 |
|
|
913 |
uint AudioOutputDeviceAsio::MaxSamplesPerCycle() { |
uint AudioOutputDeviceAsio::MaxSamplesPerCycle() { |
914 |
dmsg(3,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n",FragmentSize)); |
dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n",FragmentSize)); |
915 |
return FragmentSize; |
return FragmentSize; |
916 |
} |
} |
917 |
|
|
918 |
uint AudioOutputDeviceAsio::SampleRate() { |
uint AudioOutputDeviceAsio::SampleRate() { |
919 |
dmsg(1,("AudioOutputDeviceAsio::SampleRate value=%d\n",uiSamplerate)); fflush(stdout); |
dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n",uiSamplerate)); fflush(stdout); |
920 |
return uiSamplerate; |
return uiSamplerate; |
921 |
} |
} |
922 |
|
|
933 |
} |
} |
934 |
|
|
935 |
String AudioOutputDeviceAsio::Version() { |
String AudioOutputDeviceAsio::Version() { |
936 |
String s = "$Revision: 1.2 $"; |
String s = "$Revision: 1.3 $"; |
937 |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword |
938 |
} |
} |
939 |
|
|