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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2509 - (hide 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 senoner 1500 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 2509 * Copyright (C) 2005 - 2014 Christian Schoenebeck *
7 senoner 1500 * *
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 persson 1948 #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 senoner 1500
35     // internal data storage
36 persson 1948 struct DriverInfo {
37 senoner 1500 // 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 persson 1948 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 senoner 1500
67     // ASIOGetChannelInfo()
68 persson 1948 ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels];
69 senoner 1500 // 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 persson 1948 double tcSamples; // time code samples
76 senoner 1500
77     // bufferSwitchTimeInfo()
78 persson 1948 ASIOTime tInfo; // time info state
79     unsigned long sysRefTime; // system reference time, when bufferSwitch() was called
80 senoner 1500
81     // Signal the end of processing in this example
82     bool stopped;
83 persson 1948 };
84 senoner 1500
85     extern AsioDrivers* asioDrivers;
86 persson 1948 extern bool loadAsioDriver(char* name);
87    
88     static DriverInfo asioDriverInfo = { { 0 }, 0 };
89 senoner 1500
90 persson 1888 static bool asioDriverOpened = false;
91 senoner 1500 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 persson 1948 AudioOutputDeviceAsio* GlobalAudioOutputDeviceAsioThisPtr;
102 senoner 1500
103 persson 1888 template<int bitres>
104 persson 1948 static void floatToASIOSTInt32LSBXX(float* in, void* dest, int numSamples) {
105 persson 1888 double pos_max_value = (1 << bitres) -1.0;
106     double neg_max_value = -pos_max_value;
107 persson 1948 int32_t* out = (int32_t*)dest;
108     for (int i = 0; i < numSamples ; i++) {
109 persson 1888 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 persson 1948 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 senoner 1500 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 persson 1948 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 senoner 1500 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 persson 1888 std::vector<String> getAsioDriverNames();
137    
138 persson 1948 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 senoner 1500 }
145    
146 persson 1951 int ASIO_OpenAndQueryDeviceInfo(String driverName, DriverInfo* driverInfo) {
147 persson 1948 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 senoner 1500
151 persson 1948 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 persson 1888 getAsioDriverNames();
168    
169 persson 1948 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 persson 1951 dmsg(2,("asioDriver already opened, doing nothing\n"));
176     return 0;
177 senoner 1500 }
178     }
179     else {
180 persson 1951 dmsg(2,("driverName != currentAsioDriverName, new asio driver specified, opening device...\n"));
181 persson 1948 // if a new ASIO driver name was specified then first check if
182     // we need to close the old one
183     if (asioDriverOpened) {
184 persson 1951 dmsg(2,("different asioDriver already opened, closing old one\n"));
185 senoner 1500 asioDriverOpened = false;
186     ASIOExit(); // close the old ASIO driver
187     }
188     }
189     currentAsioDriverName = driverName;
190    
191 persson 1951 memset(&driverInfo->driverInfo, 0, sizeof(ASIODriverInfo));
192     driverInfo->driverInfo.asioVersion = 1;
193     driverInfo->driverInfo.sysRef = NULL;
194 senoner 1500
195 persson 1948 // MUST BE CHECKED : to force fragments loading on Mac
196     // ASIO_loadAsioDriver("dummy");
197 senoner 1500
198 persson 1948 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 persson 1951 return -1;
202 senoner 1500 }
203 persson 1888 dmsg(2,("Before ASIOInit()\n"));
204 persson 1951 if ((asioError = ASIOInit(&driverInfo->driverInfo)) != ASE_OK) {
205     dmsg(2,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n",
206 persson 1948 int(asioError), driverName.c_str()));
207 persson 1951 return asioError;
208 senoner 1500 }
209 persson 1888 dmsg(2,("Before ASIOGetChannels()\n"));
210 persson 1948 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 persson 1951 return asioError;
215 senoner 1500 }
216    
217 persson 1888 dmsg(2,("Before ASIOGetBufferSize()\n"));
218 persson 1948 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 persson 1951 return asioError;
225 senoner 1500 }
226    
227 persson 1948 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %ld\n", driverInfo->numInputChannels));
228     dmsg(2,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %ld\n", driverInfo->numOutputChannels));
229 senoner 1500
230 persson 1948 // Loop through the possible sampling rates and check each to see
231     // if the device supports it.
232 senoner 1500 driverInfo->sampleRates.clear();
233     for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) {
234     if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) {
235 persson 1948 dmsg(2,("ASIOCanSampleRate: possible sample rate = %ld\n",
236     (long)possibleSampleRates[index]));
237     driverInfo->sampleRates.push_back((int)possibleSampleRates[index]);
238 senoner 1500 }
239     }
240    
241 persson 1948 // get the channel infos for each output channel (including sample format)
242     for (int i = 0; i < driverInfo->numOutputChannels; i++) {
243 senoner 1500 driverInfo->channelInfos[i].channel = i;
244     driverInfo->channelInfos[i].isInput = ASIOFalse;
245     ASIOGetChannelInfo(&driverInfo->channelInfos[i]);
246 persson 1948 dmsg(2,("channelInfos[%d].type (sampleformat) = %d\n",
247     i, int(driverInfo->channelInfos[i].type)));
248 senoner 1500 }
249    
250 persson 1888 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n"));
251 senoner 1500 asioDriverOpened = true;
252 persson 1951 return ASE_OK;
253 senoner 1500 }
254    
255    
256     std::vector<String> getAsioDriverNames() {
257     char* names[ASIO_MAX_DEVICE_INFO];
258     int numDrivers;
259    
260 persson 1948 if (asioDriverListLoaded) {
261 persson 1888 dmsg(2,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n"));
262 senoner 1500 return asioDriverList;
263     }
264    
265 persson 1948 // MUST BE CHECKED : to force fragments loading on Mac
266 senoner 1500 ASIO_loadAsioDriver("dummy");
267    
268 persson 1948 #if MAC
269 senoner 1500 numDrivers = asioDrivers->getNumFragments();
270 persson 1948 #elif WINDOWS
271 senoner 1500 numDrivers = asioDrivers->asioGetNumDev();
272 persson 1948 #endif
273 senoner 1500
274 persson 1948 for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
275 senoner 1500 names[i] = new char[32];
276 persson 1948 memset(names[i], 0, 32);
277 senoner 1500 }
278    
279 persson 1948 // Get names of all available ASIO drivers
280     asioDrivers->getDriverNames(names, ASIO_MAX_DEVICE_INFO);
281     dmsg(2,("getAsioDriverNames: numDrivers=%d\n", numDrivers));
282 senoner 1500
283 persson 1948 for (int i = 0; i < numDrivers; i++) {
284     dmsg(2,("ASIO DRIVERLIST: i=%d name='%s'\n", i, names[i]));
285 senoner 1500
286 persson 1948 #if 1
287 senoner 1500 asioDriverList.push_back(names[i]);
288 persson 1948 #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 persson 1951 ASIOError asioError;
296     if ((asioError = ASIOInit(&asioDriverInfo.driverInfo)) == ASE_OK) {
297 senoner 1500 asioDriverList.push_back(names[i]);
298     }
299     else {
300 persson 1948 dmsg(2,("getDriverList: ASIOInit of driver %s gave Error %d! ignoring it.\n",
301 persson 1951 names[i], int(asioError)));
302 senoner 1500 }
303     }
304     else {
305 persson 1888 dmsg(2,("getDriverList: load driver %s failed! ignoring it.\n", names[i]));
306 senoner 1500 }
307 persson 1948 // 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 senoner 1500 }
313    
314 persson 1948 for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
315 persson 1644 delete[] names[i];
316 senoner 1500 }
317    
318 persson 1948 dmsg(2,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n",
319     int(asioDriverList.size())));
320 senoner 1500 asioDriverListLoaded = true;
321 persson 1948 return asioDriverList;
322 senoner 1500 }
323    
324 persson 1948 // 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 senoner 1500 }
337    
338    
339     //----------------------------------------------------------------------------------
340     // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
341     #if NATIVE_INT64
342 persson 1948 #define ASIO64toDouble(a) (a)
343 senoner 1500 #else
344 persson 1948 const double twoRaisedTo32 = 4294967296.;
345     #define ASIO64toDouble(a) ((a).lo + (a).hi * twoRaisedTo32)
346 senoner 1500 #endif
347    
348    
349 persson 1948 ASIOTime* AudioOutputDeviceAsio::bufferSwitchTimeInfo(ASIOTime *timeInfo, long index,
350     ASIOBool processNow) {
351 senoner 1500 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 persson 1948 // TODO: ignore for now. get the system reference time
373 persson 1888 // asioDriverInfo.sysRefTime = get_sys_reference_time();
374 senoner 1500
375 persson 1948 // buffer size in samples
376     long buffSize = asioDriverInfo.chosenBufSize;
377 senoner 1500
378 persson 1948 // tell LinuxSampler to render a fragment of buffSize samples
379 senoner 1500 GlobalAudioOutputDeviceAsioThisPtr->RenderAudio(buffSize);
380    
381 persson 1948 // now write and convert the samples to the ASIO buffer
382     for (int i = 0; i < asioDriverInfo.numOutputBuffers; i++)
383     {
384 senoner 1500 // do processing for the outputs only
385     switch (asioDriverInfo.channelInfos[i].type)
386     {
387 persson 1948 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 senoner 1500
405 persson 1948 // 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 senoner 1500
409 persson 1948 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 senoner 1500 }
465 persson 1948 }
466 senoner 1500
467 persson 1948 // finally if the driver supports the ASIOOutputReady()
468     // optimization, do it here, all data are in place
469     if (asioDriverInfo.ASIOOutputReadySupported)
470     ASIOOutputReady();
471 senoner 1500
472     processedSamples += buffSize;
473 persson 1948 return 0L;
474 senoner 1500 }
475    
476 persson 1948 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 persson 1951 ASIOTime timeInfo;
484 persson 1948 memset(&timeInfo, 0, sizeof(timeInfo));
485 senoner 1500
486 persson 1948 // 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 senoner 1500 timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
491    
492 persson 1948 bufferSwitchTimeInfo(&timeInfo, index, processNow);
493 senoner 1500 }
494    
495 persson 1948 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 senoner 1500 }
503    
504 persson 1948 long asioMessages(long selector, long value, void* message, double* opt) {
505     dmsg(2,("asioMessages selector=%ld value=%ld\n", selector, value));
506 senoner 1500 // currently the parameters "value", "message" and "opt" are not used.
507     long ret = 0;
508 persson 1948 switch (selector)
509 senoner 1500 {
510 persson 1948 case kAsioSelectorSupported:
511     if (value == kAsioResetRequest ||
512     value == kAsioEngineVersion ||
513     value == kAsioResyncRequest ||
514     value == kAsioLatenciesChanged ||
515 senoner 1500 // the following three were added for ASIO 2.0, we don't necessarily have to support them
516 persson 1948 value == kAsioSupportsTimeInfo ||
517     value == kAsioSupportsTimeCode ||
518     value == kAsioSupportsInputMonitor)
519 senoner 1500 ret = 1L;
520 persson 1948 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 senoner 1500 }
566     return ret;
567     }
568    
569    
570     // *************** ParameterCard ***************
571     // *
572    
573 persson 1948 AudioOutputDeviceAsio::ParameterCard::ParameterCard() : DeviceCreationParameterString() {
574     InitWithDefault(); // use default card
575     }
576 senoner 1500
577 persson 1948 AudioOutputDeviceAsio::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {
578     }
579 senoner 1500
580 persson 1948 String AudioOutputDeviceAsio::ParameterCard::Description() {
581     return "Sound card to be used";
582     }
583 senoner 1500
584 persson 1948 bool AudioOutputDeviceAsio::ParameterCard::Fix() {
585     return true;
586     }
587 senoner 1500
588 persson 1948 bool AudioOutputDeviceAsio::ParameterCard::Mandatory() {
589     return false;
590     }
591 senoner 1500
592 persson 1948 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterCard::DependsAsParameters() {
593     return std::map<String,DeviceCreationParameter*>(); // no dependencies
594     }
595 senoner 1500
596 persson 1948 optional<String> AudioOutputDeviceAsio::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
597     std::vector<String> cards = PossibilitiesAsString(Parameters);
598 schoenebeck 2509 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 senoner 1500
605 persson 1948 // 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 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s' (first card by default)\n", cards[0].c_str()));
613 persson 1948 return cards[0]; // first card by default
614     }
615     else {
616 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n", currentAsioDriverName.c_str()));
617 persson 1948 return currentAsioDriverName;
618     }
619 persson 1888
620 persson 1948 }
621 persson 1888
622 persson 1948 std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {
623     dmsg(2,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n"));
624     return getAsioDriverNames();
625     }
626 senoner 1500
627 persson 1948 void AudioOutputDeviceAsio::ParameterCard::OnSetValue(String s) throw (Exception) {
628     // not posssible, as parameter is fix
629     }
630 senoner 1500
631 persson 1948 String AudioOutputDeviceAsio::ParameterCard::Name() {
632     return "CARD";
633     }
634 senoner 1500
635    
636    
637     // *************** ParameterSampleRate ***************
638     // *
639    
640 persson 1948 AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate() : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {
641     }
642 senoner 1500
643 persson 1948 AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate(String s) : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {
644     }
645 senoner 1500
646 persson 1948 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 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing (parameter CARD not supplied)\n"));
656 persson 1948 return optional<int>::nothing;
657 senoner 1500 }
658    
659 persson 1948 // return the default samplerate. first try 44100 then 48000, then
660     // the first samplerate found in the list
661     ParameterCard card(Parameters["CARD"]);
662 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
663 persson 1948 for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
664     if (asioDriverInfo.sampleRates[i] == 44100) {
665 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n"));
666 persson 1948 return 44100;
667 senoner 1500 }
668 persson 1948 if (asioDriverInfo.sampleRates[i] == 48000) {
669     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n"));
670     return 48000;
671 senoner 1500 }
672     }
673 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",
674     asioDriverInfo.sampleRates[0]));
675     return asioDriverInfo.sampleRates[0];
676     }
677 senoner 1500
678 persson 1948 std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {
679     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n"));
680     if (!Parameters.count("CARD")) {
681 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector (parameter CARD not supplied)\n"));
682 persson 1948 return std::vector<int>();
683     }
684 senoner 1500
685 persson 1948 ParameterCard card(Parameters["CARD"]);
686 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return std::vector<int>();
687 senoner 1500
688 persson 1948 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 senoner 1500
692 persson 1948 return asioDriverInfo.sampleRates;
693     }
694 senoner 1500
695    
696    
697     // *************** ParameterChannels ***************
698     // *
699    
700 persson 1948 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 senoner 1500
706 persson 1948 AudioOutputDeviceAsio::ParameterChannels::ParameterChannels(String s) : AudioOutputDevice::ParameterChannels::ParameterChannels(s) {
707     }
708 senoner 1500
709 persson 1948 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 senoner 1500 }
722    
723 persson 1948 ParameterCard card(Parameters["CARD"]);
724 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
725 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %ld\n",
726     asioDriverInfo.numOutputChannels));
727     return asioDriverInfo.numOutputChannels;
728     }
729 senoner 1500
730 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
731 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt\n"));
732 persson 1948 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 senoner 1500 }
736 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n"));
737     return 1;
738     }
739 senoner 1500
740 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
741 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt\n"));
742 persson 1948 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 senoner 1500 }
746    
747 persson 1948 ParameterCard card(Parameters["CARD"]);
748 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
749 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %ld\n",
750     asioDriverInfo.numOutputChannels));
751     return asioDriverInfo.numOutputChannels;
752     }
753 senoner 1500
754    
755    
756     // *************** ParameterFragmentSize ***************
757     // *
758    
759 persson 1948 AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {
760     InitWithDefault();
761     }
762 senoner 1500
763 persson 1948 AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {
764     }
765 senoner 1500
766 persson 1948 String AudioOutputDeviceAsio::ParameterFragmentSize::Description() {
767     return "Size of each buffer fragment";
768     }
769 senoner 1500
770 persson 1948 bool AudioOutputDeviceAsio::ParameterFragmentSize::Fix() {
771     return true;
772     }
773 senoner 1500
774 persson 1948 bool AudioOutputDeviceAsio::ParameterFragmentSize::Mandatory() {
775     return false;
776     }
777 senoner 1500
778 persson 1948 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 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt\n"));
787 persson 1948 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 senoner 1500 }
791    
792 persson 1948 ParameterCard card(Parameters["CARD"]);
793 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
794 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %ld\n",
795     asioDriverInfo.preferredBufSize));
796     return asioDriverInfo.preferredBufSize;
797     }
798 senoner 1500
799 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
800 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt\n"));
801 persson 1948 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 senoner 1500 }
805    
806 persson 1948 ParameterCard card(Parameters["CARD"]);
807 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
808 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %ld\n",
809     asioDriverInfo.minBufSize));
810     return asioDriverInfo.minBufSize;
811     }
812 senoner 1500
813 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
814 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt\n"));
815 persson 1948 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 senoner 1500 }
819    
820 persson 1948 ParameterCard card(Parameters["CARD"]);
821 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
822 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %ld\n",
823     asioDriverInfo.maxBufSize));
824     return asioDriverInfo.maxBufSize;
825     }
826 senoner 1500
827 persson 1948 std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
828 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt\n"));
829 persson 1948 return std::vector<int>();
830     }
831 senoner 1500
832 persson 1948 void AudioOutputDeviceAsio::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {
833     // not posssible, as parameter is fix
834     }
835 senoner 1500
836 persson 1948 String AudioOutputDeviceAsio::ParameterFragmentSize::Name() {
837     return "FRAGMENTSIZE";
838     }
839 senoner 1500
840    
841    
842     // *************** AudioOutputDeviceAsio ***************
843     // *
844    
845 persson 1948 /**
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 senoner 1500
859    
860 persson 1951 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor channels=%d samplerate=%d fragmentsize=%d card=%s\n",
861     uiAsioChannels, uiSamplerate, FragmentSize, card.c_str()));
862 senoner 1500
863 persson 1948 asioIsPlaying = false;
864 senoner 1500
865 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card, &asioDriverInfo) != 0) {
866     throw AudioOutputException("Error: ASIO Initialization error");
867     }
868 persson 1948 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n"));
869 senoner 1500
870 persson 1951 ASIOError asioError;
871     if ((asioError = ASIOSetSampleRate(uiSamplerate)) != ASE_OK) {
872     dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: ASIOSetSampleRate failed: %d\n", int(asioError)));
873 persson 1948 throw AudioOutputException("Error: ASIOSetSampleRate: cannot set samplerate.");
874     }
875     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n"));
876 senoner 1500
877 persson 1951 asioDriverInfo.ASIOOutputReadySupported = (ASIOOutputReady() == ASE_OK);
878     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady: %d\n",
879     asioDriverInfo.ASIOOutputReadySupported));
880 senoner 1500
881 persson 1948 asioDriverInfo.numInputBuffers = 0;
882     asioDriverInfo.numOutputBuffers = uiAsioChannels;
883     asioDriverInfo.chosenBufSize = FragmentSize;
884 senoner 1500
885 persson 1948 for (uint i = 0; i < uiAsioChannels; i++) {
886     asioDriverInfo.bufferInfos[i].isInput = ASIOFalse;
887     asioDriverInfo.bufferInfos[i].channelNum = i;
888     }
889 senoner 1500
890 persson 1948 asioCallbacks.bufferSwitch = &bufferSwitch;
891     asioCallbacks.sampleRateDidChange = &sampleRateChanged;
892     asioCallbacks.asioMessage = &asioMessages;
893     asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
894 senoner 1500
895 persson 1951 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 persson 1948 throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.");
901 senoner 1500 }
902 persson 1948 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n"));
903 senoner 1500
904 persson 1948 // 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 senoner 1500 }
908    
909 persson 1948 // 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 senoner 1500
914 persson 1948 if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
915     Play();
916 senoner 1500 }
917 persson 1948 }
918 senoner 1500
919 persson 1948 AudioOutputDeviceAsio::~AudioOutputDeviceAsio() {
920     ASIOExit();
921     asioDriverOpened = false;
922     AudioOutputDeviceAsioInstantiated = false;
923     }
924    
925     void AudioOutputDeviceAsio::Play() {
926 persson 1951 dmsg(2,("AudioOutputDeviceAsio::Play()\n"));
927     ASIOError asioError;
928     if ((asioError = ASIOStart()) != ASE_OK) {
929 senoner 1500 asioIsPlaying = false;
930 persson 1951 dmsg(1,("AudioOutputDeviceAsio::Play: ASIOStart failed: %d\n", int(asioError)));
931     throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOStart failed");
932 senoner 1500 }
933 persson 1948 else asioIsPlaying = true;
934     }
935 senoner 1500
936 persson 1948 bool AudioOutputDeviceAsio::IsPlaying() {
937     return asioIsPlaying;
938     }
939 senoner 1500
940 persson 1948 void AudioOutputDeviceAsio::Stop() {
941 persson 1951 dmsg(2,("AudioOutputDeviceAsio::Stop()\n"));
942 persson 1948 ASIOStop();
943     asioIsPlaying = false;
944     }
945 senoner 1500
946 persson 1948 AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) {
947 persson 1951 dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d uiAsioChannels=%d\n",
948 persson 1948 ChannelNr, uiAsioChannels));
949     // just create a mix channel
950     return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels));
951     }
952 senoner 1500
953 persson 1948 uint AudioOutputDeviceAsio::MaxSamplesPerCycle() {
954     dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n", FragmentSize));
955     return FragmentSize;
956     }
957 senoner 1500
958 persson 1948 uint AudioOutputDeviceAsio::SampleRate() {
959     dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n", uiSamplerate)); fflush(stdout);
960     return uiSamplerate;
961     }
962 senoner 1500
963 persson 1948 String AudioOutputDeviceAsio::Name() {
964     return "ASIO";
965     }
966 senoner 1500
967 persson 1948 String AudioOutputDeviceAsio::Driver() {
968     return Name();
969     }
970 senoner 1500
971 persson 1948 String AudioOutputDeviceAsio::Description() {
972     return "Audio Streaming Input Output 2.2";
973     }
974    
975     String AudioOutputDeviceAsio::Version() {
976 schoenebeck 2494 String s = "$Revision$";
977 persson 1948 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
978     }
979    
980 senoner 1500 } // namespace LinuxSampler

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC