/[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 2494 - (hide annotations) (download)
Wed Jan 1 17:48:01 2014 UTC (10 years, 3 months ago) by schoenebeck
File size: 41121 byte(s)
* Enabled automatic svn "Revision" macro expansion on certain files.
* Bumped version to 1.0.0.svn24.

1 senoner 1500 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 persson 1644 * Copyright (C) 2005 - 2008 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     if (cards.empty()) throw Exception("AudioOutputDeviceAsio: Can't find any card");
599 senoner 1500
600 persson 1948 // If currentAsioDriverName is empty then return the first card,
601     // otherwise return the currentAsioDriverName. This avoids closing
602     // the current ASIO driver when the LSCP client calls commands
603     // like GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO ASIO CARD, which
604     // would load the default card (without this check it would always
605     // be the same which would cause the above problem).
606     if (currentAsioDriverName == "") {
607 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s' (first card by default)\n", cards[0].c_str()));
608 persson 1948 return cards[0]; // first card by default
609     }
610     else {
611 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n", currentAsioDriverName.c_str()));
612 persson 1948 return currentAsioDriverName;
613     }
614 persson 1888
615 persson 1948 }
616 persson 1888
617 persson 1948 std::vector<String> AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString(std::map<String,String> Parameters) {
618     dmsg(2,("AudioOutputDeviceAsio::ParameterCard::PossibilitiesAsString:\n"));
619     return getAsioDriverNames();
620     }
621 senoner 1500
622 persson 1948 void AudioOutputDeviceAsio::ParameterCard::OnSetValue(String s) throw (Exception) {
623     // not posssible, as parameter is fix
624     }
625 senoner 1500
626 persson 1948 String AudioOutputDeviceAsio::ParameterCard::Name() {
627     return "CARD";
628     }
629 senoner 1500
630    
631    
632     // *************** ParameterSampleRate ***************
633     // *
634    
635 persson 1948 AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate() : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate() {
636     }
637 senoner 1500
638 persson 1948 AudioOutputDeviceAsio::ParameterSampleRate::ParameterSampleRate(String s) : AudioOutputDevice::ParameterSampleRate::ParameterSampleRate(s) {
639     }
640 senoner 1500
641 persson 1948 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterSampleRate::DependsAsParameters() {
642     static ParameterCard card;
643     std::map<String,DeviceCreationParameter*> dependencies;
644     dependencies[card.Name()] = &card;
645     return dependencies;
646     }
647    
648     optional<int> AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt(std::map<String,String> Parameters) {
649     if (!Parameters.count("CARD")) {
650 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing (parameter CARD not supplied)\n"));
651 persson 1948 return optional<int>::nothing;
652 senoner 1500 }
653    
654 persson 1948 // return the default samplerate. first try 44100 then 48000, then
655     // the first samplerate found in the list
656     ParameterCard card(Parameters["CARD"]);
657 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
658 persson 1948 for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
659     if (asioDriverInfo.sampleRates[i] == 44100) {
660 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n"));
661 persson 1948 return 44100;
662 senoner 1500 }
663 persson 1948 if (asioDriverInfo.sampleRates[i] == 48000) {
664     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 48000\n"));
665     return 48000;
666 senoner 1500 }
667     }
668 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning %d\n",
669     asioDriverInfo.sampleRates[0]));
670     return asioDriverInfo.sampleRates[0];
671     }
672 senoner 1500
673 persson 1948 std::vector<int> AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt(std::map<String,String> Parameters) {
674     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt\n"));
675     if (!Parameters.count("CARD")) {
676 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector (parameter CARD not supplied)\n"));
677 persson 1948 return std::vector<int>();
678     }
679 senoner 1500
680 persson 1948 ParameterCard card(Parameters["CARD"]);
681 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return std::vector<int>();
682 senoner 1500
683 persson 1948 for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
684     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt samplerate[%d]=%d\n", i, asioDriverInfo.sampleRates[i]));
685     }
686 senoner 1500
687 persson 1948 return asioDriverInfo.sampleRates;
688     }
689 senoner 1500
690    
691    
692     // *************** ParameterChannels ***************
693     // *
694    
695 persson 1948 AudioOutputDeviceAsio::ParameterChannels::ParameterChannels() : AudioOutputDevice::ParameterChannels::ParameterChannels() {
696     //InitWithDefault();
697     // could not determine default value? ...
698     //if (ValueAsInt() == 0) SetValue(2); // ... then (try) a common value
699     }
700 senoner 1500
701 persson 1948 AudioOutputDeviceAsio::ParameterChannels::ParameterChannels(String s) : AudioOutputDevice::ParameterChannels::ParameterChannels(s) {
702     }
703 senoner 1500
704 persson 1948 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterChannels::DependsAsParameters() {
705     static ParameterCard card;
706     std::map<String,DeviceCreationParameter*> dependencies;
707     dependencies[card.Name()] = &card;
708     return dependencies;
709     }
710    
711     optional<int> AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt(std::map<String,String> Parameters) {
712     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt\n"));
713     if (!Parameters.count("CARD")) {
714     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
715     return optional<int>::nothing;
716 senoner 1500 }
717    
718 persson 1948 ParameterCard card(Parameters["CARD"]);
719 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
720 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::DefaultAsInt returning %ld\n",
721     asioDriverInfo.numOutputChannels));
722     return asioDriverInfo.numOutputChannels;
723     }
724 senoner 1500
725 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt(std::map<String,String> Parameters) {
726 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt\n"));
727 persson 1948 if (!Parameters.count("CARD")) {
728     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
729     return optional<int>::nothing;
730 senoner 1500 }
731 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning 1\n"));
732     return 1;
733     }
734 senoner 1500
735 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt(std::map<String,String> Parameters) {
736 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt\n"));
737 persson 1948 if (!Parameters.count("CARD")) {
738     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
739     return optional<int>::nothing;
740 senoner 1500 }
741    
742 persson 1948 ParameterCard card(Parameters["CARD"]);
743 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
744 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning %ld\n",
745     asioDriverInfo.numOutputChannels));
746     return asioDriverInfo.numOutputChannels;
747     }
748 senoner 1500
749    
750    
751     // *************** ParameterFragmentSize ***************
752     // *
753    
754 persson 1948 AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize() : DeviceCreationParameterInt() {
755     InitWithDefault();
756     }
757 senoner 1500
758 persson 1948 AudioOutputDeviceAsio::ParameterFragmentSize::ParameterFragmentSize(String s) throw (Exception) : DeviceCreationParameterInt(s) {
759     }
760 senoner 1500
761 persson 1948 String AudioOutputDeviceAsio::ParameterFragmentSize::Description() {
762     return "Size of each buffer fragment";
763     }
764 senoner 1500
765 persson 1948 bool AudioOutputDeviceAsio::ParameterFragmentSize::Fix() {
766     return true;
767     }
768 senoner 1500
769 persson 1948 bool AudioOutputDeviceAsio::ParameterFragmentSize::Mandatory() {
770     return false;
771     }
772 senoner 1500
773 persson 1948 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterFragmentSize::DependsAsParameters() {
774     static ParameterCard card;
775     std::map<String,DeviceCreationParameter*> dependencies;
776     dependencies[card.Name()] = &card;
777     return dependencies;
778     }
779    
780     optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt(std::map<String,String> Parameters) {
781 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt\n"));
782 persson 1948 if (!Parameters.count("CARD")) {
783     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
784     return optional<int>::nothing;
785 senoner 1500 }
786    
787 persson 1948 ParameterCard card(Parameters["CARD"]);
788 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
789 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning %ld\n",
790     asioDriverInfo.preferredBufSize));
791     return asioDriverInfo.preferredBufSize;
792     }
793 senoner 1500
794 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt(std::map<String,String> Parameters) {
795 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt\n"));
796 persson 1948 if (!Parameters.count("CARD")) {
797     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
798     return optional<int>::nothing;
799 senoner 1500 }
800    
801 persson 1948 ParameterCard card(Parameters["CARD"]);
802 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
803 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning %ld\n",
804     asioDriverInfo.minBufSize));
805     return asioDriverInfo.minBufSize;
806     }
807 senoner 1500
808 persson 1948 optional<int> AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt(std::map<String,String> Parameters) {
809 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt\n"));
810 persson 1948 if (!Parameters.count("CARD")) {
811     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
812     return optional<int>::nothing;
813 senoner 1500 }
814    
815 persson 1948 ParameterCard card(Parameters["CARD"]);
816 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo) != 0) return optional<int>::nothing;
817 persson 1948 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning %ld\n",
818     asioDriverInfo.maxBufSize));
819     return asioDriverInfo.maxBufSize;
820     }
821 senoner 1500
822 persson 1948 std::vector<int> AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt(std::map<String,String> Parameters) {
823 persson 1951 dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt\n"));
824 persson 1948 return std::vector<int>();
825     }
826 senoner 1500
827 persson 1948 void AudioOutputDeviceAsio::ParameterFragmentSize::OnSetValue(int i) throw (Exception) {
828     // not posssible, as parameter is fix
829     }
830 senoner 1500
831 persson 1948 String AudioOutputDeviceAsio::ParameterFragmentSize::Name() {
832     return "FRAGMENTSIZE";
833     }
834 senoner 1500
835    
836    
837     // *************** AudioOutputDeviceAsio ***************
838     // *
839    
840 persson 1948 /**
841     * Create and initialize Asio audio output device with given parameters.
842     *
843     * @param Parameters - optional parameters
844     * @throws AudioOutputException if output device cannot be opened
845     */
846     AudioOutputDeviceAsio::AudioOutputDeviceAsio(std::map<String,DeviceCreationParameter*> Parameters) : AudioOutputDevice(Parameters) {
847     if (AudioOutputDeviceAsioInstantiated) throw Exception("AudioOutputDeviceAsio: Sorry, only one ASIO card at time can be opened");
848     AudioOutputDeviceAsioInstantiated = true;
849     this->uiAsioChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
850     this->uiSamplerate = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
851     this->FragmentSize = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
852     String card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
853 senoner 1500
854    
855 persson 1951 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor channels=%d samplerate=%d fragmentsize=%d card=%s\n",
856     uiAsioChannels, uiSamplerate, FragmentSize, card.c_str()));
857 senoner 1500
858 persson 1948 asioIsPlaying = false;
859 senoner 1500
860 persson 1951 if (ASIO_OpenAndQueryDeviceInfo(card, &asioDriverInfo) != 0) {
861     throw AudioOutputException("Error: ASIO Initialization error");
862     }
863 persson 1948 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n"));
864 senoner 1500
865 persson 1951 ASIOError asioError;
866     if ((asioError = ASIOSetSampleRate(uiSamplerate)) != ASE_OK) {
867     dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: ASIOSetSampleRate failed: %d\n", int(asioError)));
868 persson 1948 throw AudioOutputException("Error: ASIOSetSampleRate: cannot set samplerate.");
869     }
870     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n"));
871 senoner 1500
872 persson 1951 asioDriverInfo.ASIOOutputReadySupported = (ASIOOutputReady() == ASE_OK);
873     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady: %d\n",
874     asioDriverInfo.ASIOOutputReadySupported));
875 senoner 1500
876 persson 1948 asioDriverInfo.numInputBuffers = 0;
877     asioDriverInfo.numOutputBuffers = uiAsioChannels;
878     asioDriverInfo.chosenBufSize = FragmentSize;
879 senoner 1500
880 persson 1948 for (uint i = 0; i < uiAsioChannels; i++) {
881     asioDriverInfo.bufferInfos[i].isInput = ASIOFalse;
882     asioDriverInfo.bufferInfos[i].channelNum = i;
883     }
884 senoner 1500
885 persson 1948 asioCallbacks.bufferSwitch = &bufferSwitch;
886     asioCallbacks.sampleRateDidChange = &sampleRateChanged;
887     asioCallbacks.asioMessage = &asioMessages;
888     asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
889 senoner 1500
890 persson 1951 if ((asioError = ASIOCreateBuffers(asioDriverInfo.bufferInfos,
891     asioDriverInfo.numOutputBuffers,
892     asioDriverInfo.chosenBufSize,
893     &asioCallbacks)) != ASE_OK) {
894     dmsg(1,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: ASIOCreateBuffers failed: %d\n", int(asioError)));
895 persson 1948 throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOCreateBuffers failed.");
896 senoner 1500 }
897 persson 1948 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOCreateBuffers\n"));
898 senoner 1500
899 persson 1948 // create audio channels for this audio device to which the sampler engines can write to
900     for (uint i = 0; i < uiAsioChannels; i++) {
901     Channels.push_back(new AudioChannel(i, FragmentSize));
902 senoner 1500 }
903    
904 persson 1948 // FIXME: temporary global variable used to store the this pointer
905     // for the ASIO callbacks wanting to access the AudioOutputDeviceAsio
906     // methods
907     GlobalAudioOutputDeviceAsioThisPtr = this;
908 senoner 1500
909 persson 1948 if (((DeviceCreationParameterBool*)Parameters["ACTIVE"])->ValueAsBool()) {
910     Play();
911 senoner 1500 }
912 persson 1948 }
913 senoner 1500
914 persson 1948 AudioOutputDeviceAsio::~AudioOutputDeviceAsio() {
915     ASIOExit();
916     asioDriverOpened = false;
917     AudioOutputDeviceAsioInstantiated = false;
918     }
919    
920     void AudioOutputDeviceAsio::Play() {
921 persson 1951 dmsg(2,("AudioOutputDeviceAsio::Play()\n"));
922     ASIOError asioError;
923     if ((asioError = ASIOStart()) != ASE_OK) {
924 senoner 1500 asioIsPlaying = false;
925 persson 1951 dmsg(1,("AudioOutputDeviceAsio::Play: ASIOStart failed: %d\n", int(asioError)));
926     throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOStart failed");
927 senoner 1500 }
928 persson 1948 else asioIsPlaying = true;
929     }
930 senoner 1500
931 persson 1948 bool AudioOutputDeviceAsio::IsPlaying() {
932     return asioIsPlaying;
933     }
934 senoner 1500
935 persson 1948 void AudioOutputDeviceAsio::Stop() {
936 persson 1951 dmsg(2,("AudioOutputDeviceAsio::Stop()\n"));
937 persson 1948 ASIOStop();
938     asioIsPlaying = false;
939     }
940 senoner 1500
941 persson 1948 AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) {
942 persson 1951 dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d uiAsioChannels=%d\n",
943 persson 1948 ChannelNr, uiAsioChannels));
944     // just create a mix channel
945     return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels));
946     }
947 senoner 1500
948 persson 1948 uint AudioOutputDeviceAsio::MaxSamplesPerCycle() {
949     dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n", FragmentSize));
950     return FragmentSize;
951     }
952 senoner 1500
953 persson 1948 uint AudioOutputDeviceAsio::SampleRate() {
954     dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n", uiSamplerate)); fflush(stdout);
955     return uiSamplerate;
956     }
957 senoner 1500
958 persson 1948 String AudioOutputDeviceAsio::Name() {
959     return "ASIO";
960     }
961 senoner 1500
962 persson 1948 String AudioOutputDeviceAsio::Driver() {
963     return Name();
964     }
965 senoner 1500
966 persson 1948 String AudioOutputDeviceAsio::Description() {
967     return "Audio Streaming Input Output 2.2";
968     }
969    
970     String AudioOutputDeviceAsio::Version() {
971 schoenebeck 2494 String s = "$Revision$";
972 persson 1948 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
973     }
974    
975 senoner 1500 } // namespace LinuxSampler

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC