/[svn]/linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceAsio.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/audio/AudioOutputDeviceAsio.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2509 - (show annotations) (download)
Sat Jan 18 18:10:49 2014 UTC (10 years, 3 months ago) by schoenebeck
File size: 41403 byte(s)
* ASIO driver: be more verbose when no ASIO card could be found
  (fixes #203)
* ignore missing LADSPA paths without ignoring valid LADSPA paths
  (fixes #208)
* updated linuxsampler man page

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2014 Christian Schoenebeck *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21 * MA 02111-1307 USA *
22 ***************************************************************************/
23
24 #include "AudioOutputDeviceAsio.h"
25 #include "AudioOutputDeviceFactory.h"
26
27 #define kMaxInputChannels 32
28 #define kMaxOutputChannels 32
29 #define ASIO_MAX_DEVICE_INFO 32
30
31 #define NUM_STANDARDSAMPLINGRATES 3 // 11.025, 22.05, 44.1
32 #define NUM_CUSTOMSAMPLINGRATES 9 // must be the same number of elements as in the array below
33 #define MAX_NUMSAMPLINGRATES (NUM_STANDARDSAMPLINGRATES + NUM_CUSTOMSAMPLINGRATES)
34
35 // internal data storage
36 struct DriverInfo {
37 // ASIOInit()
38 ASIODriverInfo driverInfo;
39
40 // ASIOGetChannels()
41 long numInputChannels;
42 long numOutputChannels;
43
44 // ASIOGetBufferSize()
45 long minBufSize;
46 long maxBufSize;
47 long preferredBufSize;
48 long bufGranularity;
49 long chosenBufSize;
50
51 // ASIOGetSampleRate()
52 ASIOSampleRate sampleRate;
53 std::vector<int> sampleRates;
54
55 // ASIOOutputReady()
56 bool ASIOOutputReadySupported;
57
58 // ASIOGetLatencies ()
59 long inputLatency;
60 long outputLatency;
61
62 // ASIOCreateBuffers ()
63 long numInputBuffers; // becomes number of actual created input buffers
64 long numOutputBuffers; // becomes number of actual created output buffers
65 ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels];
66
67 // ASIOGetChannelInfo()
68 ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels];
69 // The above two arrays share the same indexing, as the data in them are linked together
70
71 // Information from ASIOGetSamplePosition()
72 // data is converted to double floats for easier use, however 64 bit integer can be used, too
73 double nanoSeconds;
74 double samples;
75 double tcSamples; // time code samples
76
77 // bufferSwitchTimeInfo()
78 ASIOTime tInfo; // time info state
79 unsigned long sysRefTime; // system reference time, when bufferSwitch() was called
80
81 // Signal the end of processing in this example
82 bool stopped;
83 };
84
85 extern AsioDrivers* asioDrivers;
86 extern bool loadAsioDriver(char* name);
87
88 static DriverInfo asioDriverInfo = { { 0 }, 0 };
89
90 static bool asioDriverOpened = false;
91 static bool AudioOutputDeviceAsioInstantiated = false;
92 static String currentAsioDriverName;
93 static std::vector<String> asioDriverList;
94 static bool asioDriverListLoaded = false;
95
96 namespace LinuxSampler {
97
98 // callback prototypes
99
100 ASIOCallbacks asioCallbacks;
101 AudioOutputDeviceAsio* GlobalAudioOutputDeviceAsioThisPtr;
102
103 template<int bitres>
104 static void floatToASIOSTInt32LSBXX(float* in, void* dest, int numSamples) {
105 double pos_max_value = (1 << bitres) -1.0;
106 double neg_max_value = -pos_max_value;
107 int32_t* out = (int32_t*)dest;
108 for (int i = 0; i < numSamples ; i++) {
109 double sample_point = in[i] * pos_max_value;
110 if (sample_point < neg_max_value) sample_point = neg_max_value;
111 if (sample_point > pos_max_value) sample_point = pos_max_value;
112 out[i] = (int16_t)sample_point;
113 }
114 }
115
116 static void floatToASIOSTInt16LSB(float* in, void* dest, int numSamples) {
117 int16_t* out = (int16_t*)dest;
118 for (int i = 0; i < numSamples ; i++) {
119 float sample_point = in[i] * 32768.0f;
120 if (sample_point < -32768.0) sample_point = -32768.0;
121 if (sample_point > 32767.0) sample_point = 32767.0;
122 out[i] = (int16_t)sample_point;
123 }
124 }
125
126 static void floatToASIOSTInt32LSB(float* in, void* dest, int numSamples) {
127 int32_t* out = (int32_t*)dest;
128 for (int i = 0; i < numSamples ; i++) {
129 double sample_point = in[i] * 2147483648.0;
130 if (sample_point < - 2147483648.0) sample_point = -2147483648.0;
131 if (sample_point > 2147483647.0) sample_point = 2147483647.0;
132 out[i] = (int32_t)(sample_point);
133 }
134 }
135
136 std::vector<String> getAsioDriverNames();
137
138 static bool ASIO_loadAsioDriver(const char* name) {
139 dmsg(2,("ASIO_loadAsioDriver: trying to load '%s'\n", name));
140 #ifdef WINDOWS
141 CoInitialize(0);
142 #endif
143 return loadAsioDriver(const_cast<char*>(name));
144 }
145
146 int ASIO_OpenAndQueryDeviceInfo(String driverName, DriverInfo* driverInfo) {
147 ASIOSampleRate possibleSampleRates[] =
148 { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0,
149 32000.0, 44100.0, 48000.0, 88200.0, 96000.0 };
150
151 ASIOError asioError;
152
153 // Call this function in order to fill the internal vector
154 // containing the list of ASIO cards.
155
156 // Since the reading of the list is performed only one time,
157 // subsequent calls to this function will be automatically
158 // ignored.
159
160 // Calling getAsioDriverNames() is needed in the case of a
161 // LinuxSampler client application first creating an ASIO device,
162 // which calls ASIO_OpenAndQueryDeviceInfo(), and afterwards
163 // retrieve the list of available ASIO cards, since
164 // getAsioDriverNames() unloads the current driver and loads the
165 // driver 'dummy' this would cause the audio stopping and forcing
166 // the create the audio output device again.
167 getAsioDriverNames();
168
169 dmsg(2,("ASIO_OpenAndQueryDeviceInfo driverName='%s' current='%s'\n",
170 driverName.c_str(), currentAsioDriverName.c_str()));
171 if (driverName == currentAsioDriverName) {
172 // if the given ASIO driver name == current ASIO driver name
173 // and the driver was already opened then do nothing
174 if (asioDriverOpened) {
175 dmsg(2,("asioDriver already opened, doing nothing\n"));
176 return 0;
177 }
178 }
179 else {
180 dmsg(2,("driverName != currentAsioDriverName, new asio driver specified, opening device...\n"));
181 // if a new ASIO driver name was specified then first check if
182 // we need to close the old one
183 if (asioDriverOpened) {
184 dmsg(2,("different asioDriver already opened, closing old one\n"));
185 asioDriverOpened = false;
186 ASIOExit(); // close the old ASIO driver
187 }
188 }
189 currentAsioDriverName = driverName;
190
191 memset(&driverInfo->driverInfo, 0, sizeof(ASIODriverInfo));
192 driverInfo->driverInfo.asioVersion = 1;
193 driverInfo->driverInfo.sysRef = NULL;
194
195 // MUST BE CHECKED : to force fragments loading on Mac
196 // ASIO_loadAsioDriver("dummy");
197
198 dmsg(2,("Before ASIO_loadAsioDriver('%s')\n", driverName.c_str()));
199 if (!ASIO_loadAsioDriver(driverName.c_str())) {
200 dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not loadAsioDriver %s\n", driverName.c_str()));
201 return -1;
202 }
203 dmsg(2,("Before ASIOInit()\n"));
204 if ((asioError = ASIOInit(&driverInfo->driverInfo)) != ASE_OK) {
205 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n",
206 int(asioError), driverName.c_str()));
207 return asioError;
208 }
209 dmsg(2,("Before ASIOGetChannels()\n"));
210 if ((asioError = ASIOGetChannels(&driverInfo->numInputChannels,
211 &driverInfo->numOutputChannels)) != ASE_OK) {
212 dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetChannels for %s: %d\n",
213 driverName.c_str(), int(asioError)));
214 return asioError;
215 }
216
217 dmsg(2,("Before ASIOGetBufferSize()\n"));
218 if ((asioError = ASIOGetBufferSize(&driverInfo->minBufSize,
219 &driverInfo->maxBufSize,
220 &driverInfo->preferredBufSize,
221 &driverInfo->bufGranularity)) != ASE_OK) {
222 dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetBufferSize for %s: %d\n",
223 driverName.c_str(), int(asioError)));
224 return asioError;
225 }
226
227 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %ld\n", driverInfo->numInputChannels));
228 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %ld\n", driverInfo->numOutputChannels));
229
230 // Loop through the possible sampling rates and check each to see
231 // if the device supports it.
232 driverInfo->sampleRates.clear();
233 for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) {
234 if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) {
235 dmsg(2,("ASIOCanSampleRate: possible sample rate = %ld\n",
236 (long)possibleSampleRates[index]));
237 driverInfo->sampleRates.push_back((int)possibleSampleRates[index]);
238 }
239 }
240
241 // get the channel infos for each output channel (including sample format)
242 for (int i = 0; i < driverInfo->numOutputChannels; i++) {
243 driverInfo->channelInfos[i].channel = i;
244 driverInfo->channelInfos[i].isInput = ASIOFalse;
245 ASIOGetChannelInfo(&driverInfo->channelInfos[i]);
246 dmsg(2,("channelInfos[%d].type (sampleformat) = %d\n",
247 i, int(driverInfo->channelInfos[i].type)));
248 }
249
250 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n"));
251 asioDriverOpened = true;
252 return ASE_OK;
253 }
254
255
256 std::vector<String> getAsioDriverNames() {
257 char* names[ASIO_MAX_DEVICE_INFO];
258 int numDrivers;
259
260 if (asioDriverListLoaded) {
261 dmsg(2,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n"));
262 return asioDriverList;
263 }
264
265 // MUST BE CHECKED : to force fragments loading on Mac
266 ASIO_loadAsioDriver("dummy");
267
268 #if MAC
269 numDrivers = asioDrivers->getNumFragments();
270 #elif WINDOWS
271 numDrivers = asioDrivers->asioGetNumDev();
272 #endif
273
274 for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
275 names[i] = new char[32];
276 memset(names[i], 0, 32);
277 }
278
279 // Get names of all available ASIO drivers
280 asioDrivers->getDriverNames(names, ASIO_MAX_DEVICE_INFO);
281 dmsg(2,("getAsioDriverNames: numDrivers=%d\n", numDrivers));
282
283 for (int i = 0; i < numDrivers; i++) {
284 dmsg(2,("ASIO DRIVERLIST: i=%d name='%s'\n", i, names[i]));
285
286 #if 1
287 asioDriverList.push_back(names[i]);
288 #else
289 // FIXME: We currently try what is the best method to exclude
290 // not connected devices or not working drivers. The code
291 // below is for testing only, it tries to load each ASIO
292 // driver and if it gives an error it is not included in the
293 // list of available drivers (asioDriverList).
294 if (ASIO_loadAsioDriver(names[i])) {
295 ASIOError asioError;
296 if ((asioError = ASIOInit(&asioDriverInfo.driverInfo)) == ASE_OK) {
297 asioDriverList.push_back(names[i]);
298 }
299 else {
300 dmsg(2,("getDriverList: ASIOInit of driver %s gave Error %d! ignoring it.\n",
301 names[i], int(asioError)));
302 }
303 }
304 else {
305 dmsg(2,("getDriverList: load driver %s failed! ignoring it.\n", names[i]));
306 }
307 // FIXME: we need to check this ASIOExit is needed (gave a
308 // crash on a ASIO ADSP24(WDM) card so we commented it out)
309 // ASIOExit();
310 #endif
311 //currentAsioDriverName = "";
312 }
313
314 for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
315 delete[] names[i];
316 }
317
318 dmsg(2,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n",
319 int(asioDriverList.size())));
320 asioDriverListLoaded = true;
321 return asioDriverList;
322 }
323
324 // currently not unsed
325 unsigned long get_sys_reference_time() {
326 // get the system reference time
327 #if WINDOWS
328 return timeGetTime();
329 #elif MAC
330 static const double twoRaisedTo32 = 4294967296.;
331 UnsignedWide ys;
332 Microseconds(&ys);
333 double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo);
334 return (unsigned long)(r / 1000.);
335 #endif
336 }
337
338
339 //----------------------------------------------------------------------------------
340 // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
341 #if NATIVE_INT64
342 #define ASIO64toDouble(a) (a)
343 #else
344 const double twoRaisedTo32 = 4294967296.;
345 #define ASIO64toDouble(a) ((a).lo + (a).hi * twoRaisedTo32)
346 #endif
347
348
349 ASIOTime* AudioOutputDeviceAsio::bufferSwitchTimeInfo(ASIOTime *timeInfo, long index,
350 ASIOBool processNow) {
351 static long processedSamples = 0;
352 // store the timeInfo for later use
353 asioDriverInfo.tInfo = *timeInfo;
354
355 // get the time stamp of the buffer, not necessary if no
356 // synchronization to other media is required
357 if (timeInfo->timeInfo.flags & kSystemTimeValid)
358 asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
359 else
360 asioDriverInfo.nanoSeconds = 0;
361
362 if (timeInfo->timeInfo.flags & kSamplePositionValid)
363 asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
364 else
365 asioDriverInfo.samples = 0;
366
367 if (timeInfo->timeCode.flags & kTcValid)
368 asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
369 else
370 asioDriverInfo.tcSamples = 0;
371
372 // TODO: ignore for now. get the system reference time
373 // asioDriverInfo.sysRefTime = get_sys_reference_time();
374
375 // buffer size in samples
376 long buffSize = asioDriverInfo.chosenBufSize;
377
378 // tell LinuxSampler to render a fragment of buffSize samples
379 GlobalAudioOutputDeviceAsioThisPtr->RenderAudio(buffSize);
380
381 // now write and convert the samples to the ASIO buffer
382 for (int i = 0; i < asioDriverInfo.numOutputBuffers; i++)
383 {
384 // do processing for the outputs only
385 switch (asioDriverInfo.channelInfos[i].type)
386 {
387 case ASIOSTInt16LSB:
388 floatToASIOSTInt16LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
389 (int16_t*)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);
390 break;
391 case ASIOSTInt24LSB: // used for 20 bits as well
392 memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3);
393 break;
394 case ASIOSTInt32LSB:
395 floatToASIOSTInt32LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
396 (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);
397 break;
398 case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
399 throw AudioOutputException("ASIO Error: ASIOSTFloat32LSB not yet supported! report to LinuxSampler developers.");
400 break;
401 case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
402 throw AudioOutputException("ASIO Error: ASIOSTFloat64LSB not yet supported! report to LinuxSampler developers.");
403 break;
404
405 // These are used for 32 bit data buffer, with different
406 // alignment of the data inside. 32 bit PCI bus systems
407 // can more easily used with these.
408
409 case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment
410 floatToASIOSTInt32LSBXX<16>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
411 (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
412 buffSize);
413 break;
414 case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment
415 floatToASIOSTInt32LSBXX<18>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
416 (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
417 buffSize);
418 break;
419 case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment
420 floatToASIOSTInt32LSBXX<20>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
421 (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
422 buffSize);
423 break;
424 case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
425 floatToASIOSTInt32LSBXX<24>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
426 (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
427 buffSize);
428 break;
429 case ASIOSTInt16MSB:
430 throw AudioOutputException("ASIO Error: ASIOSTInt16MSB not yet supported! report to LinuxSampler developers.");
431 break;
432 case ASIOSTInt24MSB: // used for 20 bits as well
433 throw AudioOutputException("ASIO Error: ASIOSTInt24MSB not yet supported! report to LinuxSampler developers.");
434 break;
435 case ASIOSTInt32MSB:
436 throw AudioOutputException("ASIO Error: ASIOSTInt32MSB not yet supported! report to LinuxSampler developers.");
437 break;
438 case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on bigendian architecture
439 throw AudioOutputException("ASIO Error: ASIOSTFloat32MSB not yet supported! report to LinuxSampler developers.");
440 break;
441 case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on bigendian architecture
442 throw AudioOutputException("ASIO Error: ASIOSTFloat64MSB not yet supported! report to LinuxSampler developers.");
443 break;
444
445 // These are used for 32 bit data buffer, with different
446 // alignment of the data inside. 32 bit PCI bus systems
447 // can more easily used with these.
448
449 case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment
450 throw AudioOutputException("ASIO Error: ASIOSTInt32MSB16 not yet supported! report to LinuxSampler developers.");
451 break;
452 case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment
453 throw AudioOutputException("ASIO Error: ASIOSTInt32MSB18 not yet supported! report to LinuxSampler developers.");
454 break;
455 case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
456 throw AudioOutputException("ASIO Error: ASIOSTInt32MSB20 not yet supported! report to LinuxSampler developers.");
457 break;
458 case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
459 throw AudioOutputException("ASIO Error: ASIOSTInt32MSB24 not yet supported! report to LinuxSampler developers.");
460 break;
461 default:
462 throw AudioOutputException("ASIO Error: unknown ASIOST sample format. report error.");
463 break;
464 }
465 }
466
467 // finally if the driver supports the ASIOOutputReady()
468 // optimization, do it here, all data are in place
469 if (asioDriverInfo.ASIOOutputReadySupported)
470 ASIOOutputReady();
471
472 processedSamples += buffSize;
473 return 0L;
474 }
475
476 void AudioOutputDeviceAsio::bufferSwitch(long index, ASIOBool processNow) {
477 // The actual processing callback.
478
479 // As this is a "back door" into the bufferSwitchTimeInfo, a
480 // timeInfo needs to be created, though it will only set the
481 // timeInfo.samplePosition and timeInfo.systemTime fields and the
482 // according flags.
483 ASIOTime timeInfo;
484 memset(&timeInfo, 0, sizeof(timeInfo));
485
486 // Get the time stamp of the buffer. Not necessary if no
487 // synchronization to other media is required.
488 if (ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition,
489 &timeInfo.timeInfo.systemTime) == ASE_OK)
490 timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
491
492 bufferSwitchTimeInfo(&timeInfo, index, processNow);
493 }
494
495 void sampleRateChanged(ASIOSampleRate sRate) {
496 // Do whatever you need to do if the sample rate changed.
497 // Usually this only happens during external sync.
498 // Audio processing is not stopped by the driver, actual sample rate
499 // might not have even changed, maybe only the sample rate status of an
500 // AES/EBU or S/PDIF digital input at the audio device.
501 // You might have to update time/sample related conversion routines, etc.
502 }
503
504 long asioMessages(long selector, long value, void* message, double* opt) {
505 dmsg(2,("asioMessages selector=%ld value=%ld\n", selector, value));
506 // currently the parameters "value", "message" and "opt" are not used.
507 long ret = 0;
508 switch (selector)
509 {
510 case kAsioSelectorSupported:
511 if (value == kAsioResetRequest ||
512 value == kAsioEngineVersion ||
513 value == kAsioResyncRequest ||
514 value == kAsioLatenciesChanged ||
515 // the following three were added for ASIO 2.0, we don't necessarily have to support them
516 value == kAsioSupportsTimeInfo ||
517 value == kAsioSupportsTimeCode ||
518 value == kAsioSupportsInputMonitor)
519 ret = 1L;
520 break;
521 case kAsioResetRequest:
522 // Defer the task and perform the reset of the driver during the next "safe" situation.
523 // You cannot reset the driver right now, as this code is called from the driver.
524 // Reset the driver is done by completely destruct is. I.e. ASIOStop(),
525 // ASIODisposeBuffers(), Destruction
526 // Afterwards you initialize the driver again.
527
528 //GlobalAudioOutputDeviceAsioThisPtr->asioDriverInfo.stopped; // In this sample the processing will just stop
529 ret = 1L;
530 break;
531 case kAsioResyncRequest:
532 // This informs the application, that the driver encountered some non fatal data loss.
533 // It is used for synchronization purposes of different media.
534 // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
535 // Windows Multimedia system, which could loose data because the Mutex was hold too long
536 // by another thread.
537 // However a driver can issue it in other situations, too.
538 ret = 1L;
539 break;
540 case kAsioLatenciesChanged:
541 // This will inform the host application that the drivers were latencies changed.
542 // Beware, it this does not mean that the buffer sizes have changed!
543 // You might need to update internal delay data.
544 ret = 1L;
545 break;
546 case kAsioEngineVersion:
547 // Return the supported ASIO version of the host application.
548 // If a host applications does not implement this selector, ASIO 1.0 is assumed
549 // by the driver
550 ret = 2L;
551 break;
552 case kAsioSupportsTimeInfo:
553 // Informs the driver whether the asioCallbacks.bufferSwitchTimeInfo() callback
554 // is supported.
555 // For compatibility with ASIO 1.0 drivers the host application should always support
556 // the "old" bufferSwitch method, too.
557 ret = 1;
558 break;
559 case kAsioSupportsTimeCode:
560 // Informs the driver whether application is interested in time code info.
561 // If an application does not need to know about time code, the driver has less work
562 // to do.
563 ret = 0;
564 break;
565 }
566 return ret;
567 }
568
569
570 // *************** ParameterCard ***************
571 // *
572
573 AudioOutputDeviceAsio::ParameterCard::ParameterCard() : DeviceCreationParameterString() {
574 InitWithDefault(); // use default card
575 }
576
577 AudioOutputDeviceAsio::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {
578 }
579
580 String AudioOutputDeviceAsio::ParameterCard::Description() {
581 return "Sound card to be used";
582 }
583
584 bool AudioOutputDeviceAsio::ParameterCard::Fix() {
585 return true;
586 }
587
588 bool AudioOutputDeviceAsio::ParameterCard::Mandatory() {
589 return false;
590 }
591
592 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterCard::DependsAsParameters() {
593 return std::map<String,DeviceCreationParameter*>(); // no dependencies
594 }
595
596 optional<String> AudioOutputDeviceAsio::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
597 std::vector<String> cards = PossibilitiesAsString(Parameters);
598 if (cards.empty()) throw Exception(
599 "AudioOutputDeviceAsio: Can't find any ASIO-capable sound card. Make "
600 "sure you have an ASIO driver installed for your sound device. If you "
601 "are using a consumer sound card that does not provide an ASIO driver "
602 "to be installed, then consider installing an alternative like ASIO4ALL."
603 );
604
605 // If currentAsioDriverName is empty then return the first card,
606 // otherwise return the currentAsioDriverName. This avoids closing
607 // the current ASIO driver when the LSCP client calls commands
608 // like GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO ASIO CARD, which
609 // would load the default card (without this check it would always
610 // be the same which would cause the above problem).
611 if (currentAsioDriverName == "") {
612 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s' (first card by default)\n", cards[0].c_str()));
613 return cards[0]; // first card by default
614 }
615 else {
616 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n", currentAsioDriverName.c_str()));
617 return currentAsioDriverName;
618 }
619
620 }
621
622 std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {
623 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n"));
624 return getAsioDriverNames();
625 }
626
627 void AudioOutputDeviceAsio::ParameterCard::OnSetValue(String s) throw (Exception) {
628 // not posssible, as parameter is fix
629 }
630
631 String AudioOutputDeviceAsio::ParameterCard::Name() {
632 return "CARD";
633 }
634
635
636
637 // *************** ParameterSampleRate ***************
638 // *
639
640 AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate() : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {
641 }
642
643 AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate(String s) : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {
644 }
645
646 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterSampleRate::DependsAsParameters() {
647 static ParameterCard card;
648 std::map<String,DeviceCreationParameter*> dependencies;
649 dependencies[card.Name()] = &card;
650 return dependencies;
651 }
652
653 optional<int> AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {
654 if (!Parameters.count("CARD")) {
655 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing (parameter CARD not supplied)\n"));
656 return optional<int>::nothing;
657 }
658
659 // return the default samplerate. first try 44100 then 48000, then
660 // the first samplerate found in the list
661 ParameterCard card(Parameters["CARD"]);
662 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
663 for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
664 if (asioDriverInfo.sampleRates[i] == 44100) {
665 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n"));
666 return 44100;
667 }
668 if (asioDriverInfo.sampleRates[i] == 48000) {
669 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n"));
670 return 48000;
671 }
672 }
673 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",
674 asioDriverInfo.sampleRates[0]));
675 return asioDriverInfo.sampleRates[0];
676 }
677
678 std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {
679 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n"));
680 if (!Parameters.count("CARD")) {
681 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector (parameter CARD not supplied)\n"));
682 return std::vector<int>();
683 }
684
685 ParameterCard card(Parameters["CARD"]);
686 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return std::vector<int>();
687
688 for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
689 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt samplerate[%d]=%d\n", i, asioDriverInfo.sampleRates[i]));
690 }
691
692 return asioDriverInfo.sampleRates;
693 }
694
695
696
697 // *************** ParameterChannels ***************
698 // *
699
700 AudioOutputDeviceAsio::ParameterChannels::ParameterChannels() : AudioOutputDevice::ParameterChannels::ParameterChannels() {
701 //InitWithDefault();
702 // could not determine default value? ...
703 //if (ValueAsInt() == 0) SetValue(2); // ... then (try) a common value
704 }
705
706 AudioOutputDeviceAsio::ParameterChannels::ParameterChannels(String s) : AudioOutputDevice::ParameterChannels::ParameterChannels(s) {
707 }
708
709 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterChannels::DependsAsParameters() {
710 static ParameterCard card;
711 std::map<String,DeviceCreationParameter*> dependencies;
712 dependencies[card.Name()] = &card;
713 return dependencies;
714 }
715
716 optional<int> AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {
717 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt\n"));
718 if (!Parameters.count("CARD")) {
719 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
720 return optional<int>::nothing;
721 }
722
723 ParameterCard card(Parameters["CARD"]);
724 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
725 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %ld\n",
726 asioDriverInfo.numOutputChannels));
727 return asioDriverInfo.numOutputChannels;
728 }
729
730 optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
731 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt\n"));
732 if (!Parameters.count("CARD")) {
733 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
734 return optional<int>::nothing;
735 }
736 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n"));
737 return 1;
738 }
739
740 optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
741 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt\n"));
742 if (!Parameters.count("CARD")) {
743 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
744 return optional<int>::nothing;
745 }
746
747 ParameterCard card(Parameters["CARD"]);
748 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
749 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %ld\n",
750 asioDriverInfo.numOutputChannels));
751 return asioDriverInfo.numOutputChannels;
752 }
753
754
755
756 // *************** ParameterFragmentSize ***************
757 // *
758
759 AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {
760 InitWithDefault();
761 }
762
763 AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {
764 }
765
766 String AudioOutputDeviceAsio::ParameterFragmentSize::Description() {
767 return "Size of each buffer fragment";
768 }
769
770 bool AudioOutputDeviceAsio::ParameterFragmentSize::Fix() {
771 return true;
772 }
773
774 bool AudioOutputDeviceAsio::ParameterFragmentSize::Mandatory() {
775 return false;
776 }
777
778 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterFragmentSize::DependsAsParameters() {
779 static ParameterCard card;
780 std::map<String,DeviceCreationParameter*> dependencies;
781 dependencies[card.Name()] = &card;
782 return dependencies;
783 }
784
785 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {
786 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt\n"));
787 if (!Parameters.count("CARD")) {
788 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
789 return optional<int>::nothing;
790 }
791
792 ParameterCard card(Parameters["CARD"]);
793 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
794 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %ld\n",
795 asioDriverInfo.preferredBufSize));
796 return asioDriverInfo.preferredBufSize;
797 }
798
799 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
800 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt\n"));
801 if (!Parameters.count("CARD")) {
802 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
803 return optional<int>::nothing;
804 }
805
806 ParameterCard card(Parameters["CARD"]);
807 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
808 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %ld\n",
809 asioDriverInfo.minBufSize));
810 return asioDriverInfo.minBufSize;
811 }
812
813 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
814 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt\n"));
815 if (!Parameters.count("CARD")) {
816 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
817 return optional<int>::nothing;
818 }
819
820 ParameterCard card(Parameters["CARD"]);
821 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
822 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %ld\n",
823 asioDriverInfo.maxBufSize));
824 return asioDriverInfo.maxBufSize;
825 }
826
827 std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
828 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt\n"));
829 return std::vector<int>();
830 }
831
832 void AudioOutputDeviceAsio::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {
833 // not posssible, as parameter is fix
834 }
835
836 String AudioOutputDeviceAsio::ParameterFragmentSize::Name() {
837 return "FRAGMENTSIZE";
838 }
839
840
841
842 // *************** AudioOutputDeviceAsio ***************
843 // *
844
845 /**
846 * Create and initialize Asio audio output device with given parameters.
847 *
848 * @param Parameters - optional parameters
849 * @throws AudioOutputException if output device cannot be opened
850 */
851 AudioOutputDeviceAsio::AudioOutputDeviceAsio(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {
852 if (AudioOutputDeviceAsioInstantiated) throw Exception("AudioOutputDeviceAsio: Sorry, only one ASIO card at time can be opened");
853 AudioOutputDeviceAsioInstantiated = true;
854 this->uiAsioChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
855 this->uiSamplerate = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
856 this->FragmentSize = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
857 String card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
858
859
860 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor channels=%d samplerate=%d fragmentsize=%d card=%s\n",
861 uiAsioChannels, uiSamplerate, FragmentSize, card.c_str()));
862
863 asioIsPlaying = false;
864
865 if (ASIO_OpenAndQueryDeviceInfo(card, &asioDriverInfo) != 0) {
866 throw AudioOutputException("Error: ASIO Initialization error");
867 }
868 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n"));
869
870 ASIOError asioError;
871 if ((asioError = ASIOSetSampleRate(uiSamplerate)) != ASE_OK) {
872 dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: ASIOSetSampleRate failed: %d\n", int(asioError)));
873 throw AudioOutputException("Error: ASIOSetSampleRate: cannot set samplerate.");
874 }
875 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n"));
876
877 asioDriverInfo.ASIOOutputReadySupported = (ASIOOutputReady() == ASE_OK);
878 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady: %d\n",
879 asioDriverInfo.ASIOOutputReadySupported));
880
881 asioDriverInfo.numInputBuffers = 0;
882 asioDriverInfo.numOutputBuffers = uiAsioChannels;
883 asioDriverInfo.chosenBufSize = FragmentSize;
884
885 for (uint i = 0; i < uiAsioChannels; i++) {
886 asioDriverInfo.bufferInfos[i].isInput = ASIOFalse;
887 asioDriverInfo.bufferInfos[i].channelNum = i;
888 }
889
890 asioCallbacks.bufferSwitch = &bufferSwitch;
891 asioCallbacks.sampleRateDidChange = &sampleRateChanged;
892 asioCallbacks.asioMessage = &asioMessages;
893 asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
894
895 if ((asioError = ASIOCreateBuffers(asioDriverInfo.bufferInfos,
896 asioDriverInfo.numOutputBuffers,
897 asioDriverInfo.chosenBufSize,
898 &asioCallbacks)) != ASE_OK) {
899 dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: ASIOCreateBuffers failed: %d\n", int(asioError)));
900 throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.");
901 }
902 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n"));
903
904 // create audio channels for this audio device to which the sampler engines can write to
905 for (uint i = 0; i < uiAsioChannels; i++) {
906 Channels.push_back(new AudioChannel(i, FragmentSize));
907 }
908
909 // FIXME: temporary global variable used to store the this pointer
910 // for the ASIO callbacks wanting to access the AudioOutputDeviceAsio
911 // methods
912 GlobalAudioOutputDeviceAsioThisPtr = this;
913
914 if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
915 Play();
916 }
917 }
918
919 AudioOutputDeviceAsio::~AudioOutputDeviceAsio() {
920 ASIOExit();
921 asioDriverOpened = false;
922 AudioOutputDeviceAsioInstantiated = false;
923 }
924
925 void AudioOutputDeviceAsio::Play() {
926 dmsg(2,("AudioOutputDeviceAsio::Play()\n"));
927 ASIOError asioError;
928 if ((asioError = ASIOStart()) != ASE_OK) {
929 asioIsPlaying = false;
930 dmsg(1,("AudioOutputDeviceAsio::Play: ASIOStart failed: %d\n", int(asioError)));
931 throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOStart failed");
932 }
933 else asioIsPlaying = true;
934 }
935
936 bool AudioOutputDeviceAsio::IsPlaying() {
937 return asioIsPlaying;
938 }
939
940 void AudioOutputDeviceAsio::Stop() {
941 dmsg(2,("AudioOutputDeviceAsio::Stop()\n"));
942 ASIOStop();
943 asioIsPlaying = false;
944 }
945
946 AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) {
947 dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d uiAsioChannels=%d\n",
948 ChannelNr, uiAsioChannels));
949 // just create a mix channel
950 return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels));
951 }
952
953 uint AudioOutputDeviceAsio::MaxSamplesPerCycle() {
954 dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n", FragmentSize));
955 return FragmentSize;
956 }
957
958 uint AudioOutputDeviceAsio::SampleRate() {
959 dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n", uiSamplerate)); fflush(stdout);
960 return uiSamplerate;
961 }
962
963 String AudioOutputDeviceAsio::Name() {
964 return "ASIO";
965 }
966
967 String AudioOutputDeviceAsio::Driver() {
968 return Name();
969 }
970
971 String AudioOutputDeviceAsio::Description() {
972 return "Audio Streaming Input Output 2.2";
973 }
974
975 String AudioOutputDeviceAsio::Version() {
976 String s = "$Revision$";
977 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
978 }
979
980 } // namespace LinuxSampler

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC