/[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 1948 - (hide annotations) (download)
Sun Jul 19 11:12:13 2009 UTC (14 years, 9 months ago) by persson
File size: 40604 byte(s)
* code cleanup of the ASIO driver
* minor Makefile fix for parallel make

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 persson 1948 int numSampleRates;
54 senoner 1500 std::vector<int> sampleRates;
55    
56     // ASIOOutputReady()
57     bool ASIOOutputReadySupported;
58    
59     // ASIOGetLatencies ()
60     long inputLatency;
61     long outputLatency;
62    
63     // ASIOCreateBuffers ()
64 persson 1948 long numInputBuffers; // becomes number of actual created input buffers
65     long numOutputBuffers; // becomes number of actual created output buffers
66     ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels];
67 senoner 1500
68     // ASIOGetChannelInfo()
69 persson 1948 ASIOChannelInfo channelInfos[kMaxInputChannels + kMaxOutputChannels];
70 senoner 1500 // The above two arrays share the same indexing, as the data in them are linked together
71    
72     // Information from ASIOGetSamplePosition()
73     // data is converted to double floats for easier use, however 64 bit integer can be used, too
74     double nanoSeconds;
75     double samples;
76 persson 1948 double tcSamples; // time code samples
77 senoner 1500
78     // bufferSwitchTimeInfo()
79 persson 1948 ASIOTime tInfo; // time info state
80     unsigned long sysRefTime; // system reference time, when bufferSwitch() was called
81 senoner 1500
82     // Signal the end of processing in this example
83     bool stopped;
84 persson 1948 };
85 senoner 1500
86     extern AsioDrivers* asioDrivers;
87 persson 1948 extern bool loadAsioDriver(char* name);
88    
89 senoner 1500 static ASIODriverInfo MyAsioDriverInfo;
90 persson 1948 static DriverInfo asioDriverInfo = { { 0 }, 0 };
91 senoner 1500
92 persson 1888 static bool asioDriverOpened = false;
93 senoner 1500 static bool AudioOutputDeviceAsioInstantiated = false;
94     static String currentAsioDriverName;
95     static std::vector<String> asioDriverList;
96     static bool asioDriverListLoaded = false;
97    
98     namespace LinuxSampler {
99    
100     // callback prototypes
101    
102     ASIOCallbacks asioCallbacks;
103 persson 1948 AudioOutputDeviceAsio* GlobalAudioOutputDeviceAsioThisPtr;
104 senoner 1500
105 persson 1888 template<int bitres>
106 persson 1948 static void floatToASIOSTInt32LSBXX(float* in, void* dest, int numSamples) {
107 persson 1888 double pos_max_value = (1 << bitres) -1.0;
108     double neg_max_value = -pos_max_value;
109 persson 1948 int32_t* out = (int32_t*)dest;
110     for (int i = 0; i < numSamples ; i++) {
111 persson 1888 double sample_point = in[i] * pos_max_value;
112     if (sample_point < neg_max_value) sample_point = neg_max_value;
113     if (sample_point > pos_max_value) sample_point = pos_max_value;
114     out[i] = (int16_t)sample_point;
115     }
116     }
117    
118 persson 1948 static void floatToASIOSTInt16LSB(float* in, void* dest, int numSamples) {
119     int16_t* out = (int16_t*)dest;
120     for (int i = 0; i < numSamples ; i++) {
121 senoner 1500 float sample_point = in[i] * 32768.0f;
122     if (sample_point < -32768.0) sample_point = -32768.0;
123     if (sample_point > 32767.0) sample_point = 32767.0;
124     out[i] = (int16_t)sample_point;
125     }
126     }
127    
128 persson 1948 static void floatToASIOSTInt32LSB(float* in, void* dest, int numSamples) {
129     int32_t* out = (int32_t*)dest;
130     for (int i = 0; i < numSamples ; i++) {
131 senoner 1500 double sample_point = in[i] * 2147483648.0;
132     if (sample_point < - 2147483648.0) sample_point = -2147483648.0;
133     if (sample_point > 2147483647.0) sample_point = 2147483647.0;
134     out[i] = (int32_t)(sample_point);
135     }
136     }
137    
138 persson 1888 std::vector<String> getAsioDriverNames();
139    
140 persson 1948 static bool ASIO_loadAsioDriver(const char* name) {
141     dmsg(2,("ASIO_loadAsioDriver: trying to load '%s'\n", name));
142     #ifdef WINDOWS
143     CoInitialize(0);
144     #endif
145     return loadAsioDriver(const_cast<char*>(name));
146 senoner 1500 }
147    
148 persson 1948 void ASIO_OpenAndQueryDeviceInfo(String driverName, DriverInfo* driverInfo,
149     ASIODriverInfo* asioDriverInfo) throw (AudioOutputException) {
150     static const char* errmsg = "Error: ASIO Initalization Error";
151 senoner 1500
152 persson 1948 ASIOSampleRate possibleSampleRates[] =
153     { 8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0,
154     32000.0, 44100.0, 48000.0, 88200.0, 96000.0 };
155 senoner 1500
156 persson 1948 ASIOError asioError;
157    
158     // Call this function in order to fill the internal vector
159     // containing the list of ASIO cards.
160    
161     // Since the reading of the list is performed only one time,
162     // subsequent calls to this function will be automatically
163     // ignored.
164    
165     // Calling getAsioDriverNames() is needed in the case of a
166     // LinuxSampler client application first creating an ASIO device,
167     // which calls ASIO_OpenAndQueryDeviceInfo(), and afterwards
168     // retrieve the list of available ASIO cards, since
169     // getAsioDriverNames() unloads the current driver and loads the
170     // driver 'dummy' this would cause the audio stopping and forcing
171     // the create the audio output device again.
172 persson 1888 getAsioDriverNames();
173    
174 persson 1948 dmsg(2,("ASIO_OpenAndQueryDeviceInfo driverName='%s' current='%s'\n",
175     driverName.c_str(), currentAsioDriverName.c_str()));
176     if (driverName == currentAsioDriverName) {
177     // if the given ASIO driver name == current ASIO driver name
178     // and the driver was already opened then do nothing
179     if (asioDriverOpened) {
180 persson 1888 dmsg(2,("asioDriver ALREADY OPENED, DOING NOTHING !\n"));
181 persson 1948 return;
182 senoner 1500 }
183     }
184     else {
185 persson 1948 dmsg(2,("driverName != currentAsioDriverName, new asio driver specified, opening device ....\n"));
186     // if a new ASIO driver name was specified then first check if
187     // we need to close the old one
188     if (asioDriverOpened) {
189 persson 1888 dmsg(2,("different asioDriver ALREADY OPENED, closing old one !\n"));
190 senoner 1500 asioDriverOpened = false;
191     ASIOExit(); // close the old ASIO driver
192     }
193     }
194     currentAsioDriverName = driverName;
195    
196 persson 1948 memset((void*)asioDriverInfo, 0, sizeof(ASIODriverInfo));
197     asioDriverInfo->asioVersion = 1;
198 senoner 1500 asioDriverInfo->sysRef = NULL;
199    
200 persson 1948 // MUST BE CHECKED : to force fragments loading on Mac
201     // ASIO_loadAsioDriver("dummy");
202 senoner 1500
203 persson 1948 dmsg(2,("Before ASIO_loadAsioDriver('%s')\n", driverName.c_str()));
204     if (!ASIO_loadAsioDriver(driverName.c_str())) {
205     dmsg(2,("ASIO_OpenAndQueryDeviceInfo could not loadAsioDriver %s\n", driverName.c_str()));
206     throw AudioOutputException(errmsg);
207 senoner 1500 }
208 persson 1888 dmsg(2,("Before ASIOInit()\n"));
209 persson 1948 if ((asioError = ASIOInit(asioDriverInfo)) != ASE_OK) {
210     dmsg(1,("ASIO_OpenAndQueryDeviceInfo: ASIOInit returned %d for %s\n",
211     int(asioError), driverName.c_str()));
212     throw AudioOutputException(errmsg);
213 senoner 1500 }
214 persson 1888 dmsg(2,("Before ASIOGetChannels()\n"));
215 persson 1948 if ((asioError = ASIOGetChannels(&driverInfo->numInputChannels,
216     &driverInfo->numOutputChannels)) != ASE_OK) {
217     dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetChannels for %s: %d\n",
218     driverName.c_str(), int(asioError)));
219     throw AudioOutputException(errmsg);
220 senoner 1500 }
221    
222 persson 1888 dmsg(2,("Before ASIOGetBufferSize()\n"));
223 persson 1948 if ((asioError = ASIOGetBufferSize(&driverInfo->minBufSize,
224     &driverInfo->maxBufSize,
225     &driverInfo->preferredBufSize,
226     &driverInfo->bufGranularity)) != ASE_OK) {
227     dmsg(1,("ASIO_OpenAndQueryDeviceInfo could not ASIOGetBufferSize for %s: %d\n",
228     driverName.c_str(), int(asioError)));
229     throw AudioOutputException(errmsg);
230 senoner 1500 }
231    
232 persson 1948 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: InputChannels = %ld\n", driverInfo->numInputChannels));
233     dmsg(2,("ASIO_OpenAndQueryDeviceInfo: OutputChannels = %ld\n", driverInfo->numOutputChannels));
234 senoner 1500
235 persson 1948 // Loop through the possible sampling rates and check each to see
236     // if the device supports it.
237 senoner 1500 driverInfo->numSampleRates = 0;
238     driverInfo->sampleRates.clear();
239     for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) {
240     if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) {
241 persson 1948 dmsg(2,("ASIOCanSampleRate: possible sample rate = %ld\n",
242     (long)possibleSampleRates[index]));
243     driverInfo->sampleRates.push_back((int)possibleSampleRates[index]);
244 senoner 1500 driverInfo->numSampleRates++;
245     }
246     }
247    
248 persson 1948 // get the channel infos for each output channel (including sample format)
249     for (int i = 0; i < driverInfo->numOutputChannels; i++) {
250 senoner 1500 driverInfo->channelInfos[i].channel = i;
251     driverInfo->channelInfos[i].isInput = ASIOFalse;
252     ASIOGetChannelInfo(&driverInfo->channelInfos[i]);
253 persson 1948 dmsg(2,("channelInfos[%d].type (sampleformat) = %d\n",
254     i, int(driverInfo->channelInfos[i].type)));
255 senoner 1500 }
256    
257 persson 1888 dmsg(2,("ASIO_OpenAndQueryDeviceInfo: driver opened.\n"));
258 senoner 1500 asioDriverOpened = true;
259     }
260    
261    
262     std::vector<String> getAsioDriverNames() {
263     char* names[ASIO_MAX_DEVICE_INFO];
264     int numDrivers;
265    
266 persson 1948 if (asioDriverListLoaded) {
267 persson 1888 dmsg(2,("getAsioDriverNames: ASIO driver list already loaded, doing returning cached list.\n"));
268 senoner 1500 return asioDriverList;
269     }
270    
271 persson 1948 // MUST BE CHECKED : to force fragments loading on Mac
272 senoner 1500 ASIO_loadAsioDriver("dummy");
273    
274 persson 1948 #if MAC
275 senoner 1500 numDrivers = asioDrivers->getNumFragments();
276 persson 1948 #elif WINDOWS
277 senoner 1500 numDrivers = asioDrivers->asioGetNumDev();
278 persson 1948 #endif
279 senoner 1500
280 persson 1948 for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
281 senoner 1500 names[i] = new char[32];
282 persson 1948 memset(names[i], 0, 32);
283 senoner 1500 }
284    
285 persson 1948 // Get names of all available ASIO drivers
286     asioDrivers->getDriverNames(names, ASIO_MAX_DEVICE_INFO);
287     dmsg(2,("getAsioDriverNames: numDrivers=%d\n", numDrivers));
288 senoner 1500
289 persson 1948 for (int i = 0; i < numDrivers; i++) {
290     dmsg(2,("ASIO DRIVERLIST: i=%d name='%s'\n", i, names[i]));
291 senoner 1500
292 persson 1948 #if 1
293 senoner 1500 asioDriverList.push_back(names[i]);
294 persson 1948 #else
295 senoner 1500 int asioError;
296 persson 1948 // FIXME: We currently try what is the best method to exclude
297     // not connected devices or not working drivers. The code
298     // below is for testing only, it tries to load each ASIO
299     // driver and if it gives an error it is not included in the
300     // list of available drivers (asioDriverList).
301     if (ASIO_loadAsioDriver(names[i])) {
302     if ((asioError = ASIOInit(&MyAsioDriverInfo)) == ASE_OK) {
303 senoner 1500 asioDriverList.push_back(names[i]);
304     }
305     else {
306 persson 1948 dmsg(2,("getDriverList: ASIOInit of driver %s gave Error %d! ignoring it.\n",
307     names[i], asioError));
308 senoner 1500 }
309     }
310     else {
311 persson 1888 dmsg(2,("getDriverList: load driver %s failed! ignoring it.\n", names[i]));
312 senoner 1500 }
313 persson 1948 // FIXME: we need to check this ASIOExit is needed (gave a
314     // crash on a ASIO ADSP24(WDM) card so we commented it out)
315     // ASIOExit();
316     #endif
317     //currentAsioDriverName = "";
318 senoner 1500 }
319    
320 persson 1948 for (int i = 0; i < ASIO_MAX_DEVICE_INFO; i++) {
321 persson 1644 delete[] names[i];
322 senoner 1500 }
323    
324 persson 1948 dmsg(2,("getAsioDriverNames: returing from function. asioDriverList.size()=%d\n",
325     int(asioDriverList.size())));
326 senoner 1500 asioDriverListLoaded = true;
327 persson 1948 return asioDriverList;
328 senoner 1500 }
329    
330 persson 1948 // currently not unsed
331     unsigned long get_sys_reference_time() {
332     // get the system reference time
333     #if WINDOWS
334     return timeGetTime();
335     #elif MAC
336     static const double twoRaisedTo32 = 4294967296.;
337     UnsignedWide ys;
338     Microseconds(&ys);
339     double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo);
340     return (unsigned long)(r / 1000.);
341     #endif
342 senoner 1500 }
343    
344    
345     //----------------------------------------------------------------------------------
346     // conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
347     #if NATIVE_INT64
348 persson 1948 #define ASIO64toDouble(a) (a)
349 senoner 1500 #else
350 persson 1948 const double twoRaisedTo32 = 4294967296.;
351     #define ASIO64toDouble(a) ((a).lo + (a).hi * twoRaisedTo32)
352 senoner 1500 #endif
353    
354    
355 persson 1948 ASIOTime* AudioOutputDeviceAsio::bufferSwitchTimeInfo(ASIOTime *timeInfo, long index,
356     ASIOBool processNow) {
357 senoner 1500 static long processedSamples = 0;
358     // store the timeInfo for later use
359     asioDriverInfo.tInfo = *timeInfo;
360    
361     // get the time stamp of the buffer, not necessary if no
362     // synchronization to other media is required
363     if (timeInfo->timeInfo.flags & kSystemTimeValid)
364     asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
365     else
366     asioDriverInfo.nanoSeconds = 0;
367    
368     if (timeInfo->timeInfo.flags & kSamplePositionValid)
369     asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
370     else
371     asioDriverInfo.samples = 0;
372    
373     if (timeInfo->timeCode.flags & kTcValid)
374     asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
375     else
376     asioDriverInfo.tcSamples = 0;
377    
378 persson 1948 // TODO: ignore for now. get the system reference time
379 persson 1888 // asioDriverInfo.sysRefTime = get_sys_reference_time();
380 senoner 1500
381 persson 1948 // buffer size in samples
382     long buffSize = asioDriverInfo.chosenBufSize;
383 senoner 1500
384 persson 1948 // tell LinuxSampler to render a fragment of buffSize samples
385 senoner 1500 GlobalAudioOutputDeviceAsioThisPtr->RenderAudio(buffSize);
386    
387 persson 1948 // now write and convert the samples to the ASIO buffer
388     for (int i = 0; i < asioDriverInfo.numOutputBuffers; i++)
389     {
390 senoner 1500 // do processing for the outputs only
391     switch (asioDriverInfo.channelInfos[i].type)
392     {
393 persson 1948 case ASIOSTInt16LSB:
394     floatToASIOSTInt16LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
395     (int16_t*)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);
396     break;
397     case ASIOSTInt24LSB: // used for 20 bits as well
398     memset (asioDriverInfo.bufferInfos[i].buffers[index], 0, buffSize * 3);
399     break;
400     case ASIOSTInt32LSB:
401     floatToASIOSTInt32LSB(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
402     (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index], buffSize);
403     break;
404     case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
405     throw AudioOutputException("ASIO Error: ASIOSTFloat32LSB not yet supported! report to LinuxSampler developers.");
406     break;
407     case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
408     throw AudioOutputException("ASIO Error: ASIOSTFloat64LSB not yet supported! report to LinuxSampler developers.");
409     break;
410 senoner 1500
411 persson 1948 // These are used for 32 bit data buffer, with different
412     // alignment of the data inside. 32 bit PCI bus systems
413     // can more easily used with these.
414 senoner 1500
415 persson 1948 case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment
416     floatToASIOSTInt32LSBXX<16>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
417     (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
418     buffSize);
419     break;
420     case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment
421     floatToASIOSTInt32LSBXX<18>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
422     (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
423     buffSize);
424     break;
425     case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment
426     floatToASIOSTInt32LSBXX<20>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
427     (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
428     buffSize);
429     break;
430     case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
431     floatToASIOSTInt32LSBXX<24>(GlobalAudioOutputDeviceAsioThisPtr->Channels[i]->Buffer(),
432     (int32_t*)asioDriverInfo.bufferInfos[i].buffers[index],
433     buffSize);
434     break;
435     case ASIOSTInt16MSB:
436     throw AudioOutputException("ASIO Error: ASIOSTInt16MSB not yet supported! report to LinuxSampler developers.");
437     break;
438     case ASIOSTInt24MSB: // used for 20 bits as well
439     throw AudioOutputException("ASIO Error: ASIOSTInt24MSB not yet supported! report to LinuxSampler developers.");
440     break;
441     case ASIOSTInt32MSB:
442     throw AudioOutputException("ASIO Error: ASIOSTInt32MSB not yet supported! report to LinuxSampler developers.");
443     break;
444     case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on bigendian architecture
445     throw AudioOutputException("ASIO Error: ASIOSTFloat32MSB not yet supported! report to LinuxSampler developers.");
446     break;
447     case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on bigendian architecture
448     throw AudioOutputException("ASIO Error: ASIOSTFloat64MSB not yet supported! report to LinuxSampler developers.");
449     break;
450    
451     // These are used for 32 bit data buffer, with different
452     // alignment of the data inside. 32 bit PCI bus systems
453     // can more easily used with these.
454    
455     case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment
456     throw AudioOutputException("ASIO Error: ASIOSTInt32MSB16 not yet supported! report to LinuxSampler developers.");
457     break;
458     case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment
459     throw AudioOutputException("ASIO Error: ASIOSTInt32MSB18 not yet supported! report to LinuxSampler developers.");
460     break;
461     case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
462     throw AudioOutputException("ASIO Error: ASIOSTInt32MSB20 not yet supported! report to LinuxSampler developers.");
463     break;
464     case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
465     throw AudioOutputException("ASIO Error: ASIOSTInt32MSB24 not yet supported! report to LinuxSampler developers.");
466     break;
467     default:
468     throw AudioOutputException("ASIO Error: unknown ASIOST sample format. report error.");
469     break;
470 senoner 1500 }
471 persson 1948 }
472 senoner 1500
473 persson 1948 // finally if the driver supports the ASIOOutputReady()
474     // optimization, do it here, all data are in place
475     if (asioDriverInfo.ASIOOutputReadySupported)
476     ASIOOutputReady();
477 senoner 1500
478     processedSamples += buffSize;
479 persson 1948 return 0L;
480 senoner 1500 }
481    
482 persson 1948 void AudioOutputDeviceAsio::bufferSwitch(long index, ASIOBool processNow) {
483     // The actual processing callback.
484    
485     // As this is a "back door" into the bufferSwitchTimeInfo, a
486     // timeInfo needs to be created, though it will only set the
487     // timeInfo.samplePosition and timeInfo.systemTime fields and the
488     // according flags.
489 senoner 1500 ASIOTime timeInfo;
490 persson 1948 memset(&timeInfo, 0, sizeof(timeInfo));
491 senoner 1500
492 persson 1948 // Get the time stamp of the buffer. Not necessary if no
493     // synchronization to other media is required.
494     if (ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition,
495     &timeInfo.timeInfo.systemTime) == ASE_OK)
496 senoner 1500 timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
497    
498 persson 1948 bufferSwitchTimeInfo(&timeInfo, index, processNow);
499 senoner 1500 }
500    
501 persson 1948 void sampleRateChanged(ASIOSampleRate sRate) {
502     // Do whatever you need to do if the sample rate changed.
503     // Usually this only happens during external sync.
504     // Audio processing is not stopped by the driver, actual sample rate
505     // might not have even changed, maybe only the sample rate status of an
506     // AES/EBU or S/PDIF digital input at the audio device.
507     // You might have to update time/sample related conversion routines, etc.
508 senoner 1500 }
509    
510 persson 1948 long asioMessages(long selector, long value, void* message, double* opt) {
511     dmsg(2,("asioMessages selector=%ld value=%ld\n", selector, value));
512 senoner 1500 // currently the parameters "value", "message" and "opt" are not used.
513     long ret = 0;
514 persson 1948 switch (selector)
515 senoner 1500 {
516 persson 1948 case kAsioSelectorSupported:
517     if (value == kAsioResetRequest ||
518     value == kAsioEngineVersion ||
519     value == kAsioResyncRequest ||
520     value == kAsioLatenciesChanged ||
521 senoner 1500 // the following three were added for ASIO 2.0, we don't necessarily have to support them
522 persson 1948 value == kAsioSupportsTimeInfo ||
523     value == kAsioSupportsTimeCode ||
524     value == kAsioSupportsInputMonitor)
525 senoner 1500 ret = 1L;
526 persson 1948 break;
527     case kAsioResetRequest:
528     // Defer the task and perform the reset of the driver during the next "safe" situation.
529     // You cannot reset the driver right now, as this code is called from the driver.
530     // Reset the driver is done by completely destruct is. I.e. ASIOStop(),
531     // ASIODisposeBuffers(), Destruction
532     // Afterwards you initialize the driver again.
533    
534     //GlobalAudioOutputDeviceAsioThisPtr->asioDriverInfo.stopped; // In this sample the processing will just stop
535     ret = 1L;
536     break;
537     case kAsioResyncRequest:
538     // This informs the application, that the driver encountered some non fatal data loss.
539     // It is used for synchronization purposes of different media.
540     // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
541     // Windows Multimedia system, which could loose data because the Mutex was hold too long
542     // by another thread.
543     // However a driver can issue it in other situations, too.
544     ret = 1L;
545     break;
546     case kAsioLatenciesChanged:
547     // This will inform the host application that the drivers were latencies changed.
548     // Beware, it this does not mean that the buffer sizes have changed!
549     // You might need to update internal delay data.
550     ret = 1L;
551     break;
552     case kAsioEngineVersion:
553     // Return the supported ASIO version of the host application.
554     // If a host applications does not implement this selector, ASIO 1.0 is assumed
555     // by the driver
556     ret = 2L;
557     break;
558     case kAsioSupportsTimeInfo:
559     // Informs the driver whether the asioCallbacks.bufferSwitchTimeInfo() callback
560     // is supported.
561     // For compatibility with ASIO 1.0 drivers the host application should always support
562     // the "old" bufferSwitch method, too.
563     ret = 1;
564     break;
565     case kAsioSupportsTimeCode:
566     // Informs the driver whether application is interested in time code info.
567     // If an application does not need to know about time code, the driver has less work
568     // to do.
569     ret = 0;
570     break;
571 senoner 1500 }
572     return ret;
573     }
574    
575    
576     // *************** ParameterCard ***************
577     // *
578    
579 persson 1948 AudioOutputDeviceAsio::ParameterCard::ParameterCard() : DeviceCreationParameterString() {
580     InitWithDefault(); // use default card
581     }
582 senoner 1500
583 persson 1948 AudioOutputDeviceAsio::ParameterCard::ParameterCard(String s) throw (Exception) : DeviceCreationParameterString(s) {
584     }
585 senoner 1500
586 persson 1948 String AudioOutputDeviceAsio::ParameterCard::Description() {
587     return "Sound card to be used";
588     }
589 senoner 1500
590 persson 1948 bool AudioOutputDeviceAsio::ParameterCard::Fix() {
591     return true;
592     }
593 senoner 1500
594 persson 1948 bool AudioOutputDeviceAsio::ParameterCard::Mandatory() {
595     return false;
596     }
597 senoner 1500
598 persson 1948 std::map<String,DeviceCreationParameter*> AudioOutputDeviceAsio::ParameterCard::DependsAsParameters() {
599     return std::map<String,DeviceCreationParameter*>(); // no dependencies
600     }
601 senoner 1500
602 persson 1948 optional<String> AudioOutputDeviceAsio::ParameterCard::DefaultAsString(std::map<String,String> Parameters) {
603     std::vector<String> cards = PossibilitiesAsString(Parameters);
604     if (cards.empty()) throw Exception("AudioOutputDeviceAsio: Can't find any card");
605     dmsg(2,("AudioOutputDeviceAsio::ParameterCard::DefaultAsString='%s'\n", cards[0].c_str()));
606 senoner 1500
607 persson 1948 // If currentAsioDriverName is empty then return the first card,
608     // otherwise return the currentAsioDriverName. This avoids closing
609     // the current ASIO driver when the LSCP client calls commands
610     // like GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO ASIO CARD, which
611     // would load the default card (without this check it would always
612     // be the same which would cause the above problem).
613     if (currentAsioDriverName == "") {
614     return cards[0]; // first card by default
615     }
616     else {
617     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     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning optional<int>::nothing (parameter CARD not supplied)\n"));
656     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     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
663     for (uint i = 0; i < asioDriverInfo.sampleRates.size(); i++) {
664     if (asioDriverInfo.sampleRates[i] == 44100) {
665     return 44100;
666     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::DefaultAsInt returning 44100\n"));
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     dmsg(2,("AudioOutputDeviceAsio::ParameterSampleRate::PossibilitiesAsInt returning empty vector (parameter CARD not supplied)\n"));
682     return std::vector<int>();
683     }
684 senoner 1500
685 persson 1948 ParameterCard card(Parameters["CARD"]);
686     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
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     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
725     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     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt!\n"));
732     if (!Parameters.count("CARD")) {
733     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMinAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
734     return optional<int>::nothing;
735 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     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt!\n"));
742     if (!Parameters.count("CARD")) {
743     dmsg(2,("AudioOutputDeviceAsio::ParameterChannels::RangeMaxAsInt returning optional<int>::nothing (CARD parameter not supplied)\n"));
744     return optional<int>::nothing;
745 senoner 1500 }
746    
747 persson 1948 ParameterCard card(Parameters["CARD"]);
748     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
749     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     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt!\n"));
787     if (!Parameters.count("CARD")) {
788     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::DefaultAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
789     return optional<int>::nothing;
790 senoner 1500 }
791    
792 persson 1948 ParameterCard card(Parameters["CARD"]);
793     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
794     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     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt!\n"));
801     if (!Parameters.count("CARD")) {
802     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMinAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
803     return optional<int>::nothing;
804 senoner 1500 }
805    
806 persson 1948 ParameterCard card(Parameters["CARD"]);
807     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
808     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     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt!\n"));
815     if (!Parameters.count("CARD")) {
816     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::RangeMaxAsInt returning optional<int>::nothing (no CARD parameter supplied\n"));
817     return optional<int>::nothing;
818 senoner 1500 }
819    
820 persson 1948 ParameterCard card(Parameters["CARD"]);
821     ASIO_OpenAndQueryDeviceInfo(card.ValueAsString(), &asioDriverInfo, &MyAsioDriverInfo);
822     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     dmsg(2,("AudioOutputDeviceAsio::ParameterFragmentSize::PossibilitiesAsInt!\n"));
829     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     asioDriverOpened = false;
855     this->uiAsioChannels = ((DeviceCreationParameterInt*)Parameters["CHANNELS"])->ValueAsInt();
856     this->uiSamplerate = ((DeviceCreationParameterInt*)Parameters["SAMPLERATE"])->ValueAsInt();
857     this->FragmentSize = ((DeviceCreationParameterInt*)Parameters["FRAGMENTSIZE"])->ValueAsInt();
858     String card = ((DeviceCreationParameterString*)Parameters["CARD"])->ValueAsString();
859 senoner 1500
860    
861 persson 1948 dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio constructor\n"));
862 senoner 1500
863 persson 1948 asioIsPlaying = false;
864 senoner 1500
865 persson 1948 ASIO_OpenAndQueryDeviceInfo(card, &asioDriverInfo, &MyAsioDriverInfo);
866     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIO_OpenAndQueryDeviceInfo\n"));
867 senoner 1500
868 persson 1948 if (ASIOSetSampleRate(uiSamplerate) != ASE_OK) {
869     throw AudioOutputException("Error: ASIOSetSampleRate: cannot set samplerate.");
870     }
871     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOSetSampleRate\n"));
872 senoner 1500
873 persson 1948 if (ASIOOutputReady() == ASE_OK) asioDriverInfo.ASIOOutputReadySupported = true;
874     else asioDriverInfo.ASIOOutputReadySupported = false;
875     dmsg(2,("AudioOutputDeviceAsio::AudioOutputDeviceAsio: after ASIOOutputReady\n"));
876 senoner 1500
877 persson 1948 asioDriverInfo.numInputBuffers = 0;
878     asioDriverInfo.numOutputBuffers = uiAsioChannels;
879     asioDriverInfo.chosenBufSize = FragmentSize;
880 senoner 1500
881 persson 1948 for (uint i = 0; i < uiAsioChannels; i++) {
882     asioDriverInfo.bufferInfos[i].isInput = ASIOFalse;
883     asioDriverInfo.bufferInfos[i].channelNum = i;
884     }
885 senoner 1500
886 persson 1948 asioCallbacks.bufferSwitch = &bufferSwitch;
887     asioCallbacks.sampleRateDidChange = &sampleRateChanged;
888     asioCallbacks.asioMessage = &asioMessages;
889     asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo;
890 senoner 1500
891 persson 1948 if (ASIOCreateBuffers(asioDriverInfo.bufferInfos,
892     asioDriverInfo.numOutputBuffers,
893     asioDriverInfo.chosenBufSize = FragmentSize,
894     &asioCallbacks) != ASE_OK) {
895     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     dmsg(2,("AudioOutputDeviceAsio::Play() !\n"));
922     if (ASIOStart() != ASE_OK) {
923 senoner 1500 asioIsPlaying = false;
924 persson 1948 throw AudioOutputException("AudioOutputDeviceAsio: Error: ASIOStart failed.");
925 senoner 1500 }
926 persson 1948 else asioIsPlaying = true;
927     }
928 senoner 1500
929 persson 1948 bool AudioOutputDeviceAsio::IsPlaying() {
930     return asioIsPlaying;
931     }
932 senoner 1500
933 persson 1948 void AudioOutputDeviceAsio::Stop() {
934     dmsg(2,("AudioOutputDeviceAsio::Stop() !\n"));
935     ASIOStop();
936     asioIsPlaying = false;
937     }
938 senoner 1500
939 persson 1948 AudioChannel* AudioOutputDeviceAsio::CreateChannel(uint ChannelNr) {
940     dmsg(2,("AudioOutputDeviceAsio::CreateChannel value=%d uiAsioChannels=%d\n",
941     ChannelNr, uiAsioChannels));
942     // just create a mix channel
943     return new AudioChannel(ChannelNr, Channel(ChannelNr % uiAsioChannels));
944     }
945 senoner 1500
946 persson 1948 uint AudioOutputDeviceAsio::MaxSamplesPerCycle() {
947     dmsg(2,("AudioOutputDeviceAsio::MaxSamplesPerCycle value=%d\n", FragmentSize));
948     return FragmentSize;
949     }
950 senoner 1500
951 persson 1948 uint AudioOutputDeviceAsio::SampleRate() {
952     dmsg(2,("AudioOutputDeviceAsio::SampleRate value=%d\n", uiSamplerate)); fflush(stdout);
953     return uiSamplerate;
954     }
955 senoner 1500
956 persson 1948 String AudioOutputDeviceAsio::Name() {
957     return "ASIO";
958     }
959 senoner 1500
960 persson 1948 String AudioOutputDeviceAsio::Driver() {
961     return Name();
962     }
963 senoner 1500
964 persson 1948 String AudioOutputDeviceAsio::Description() {
965     return "Audio Streaming Input Output 2.2";
966     }
967    
968     String AudioOutputDeviceAsio::Version() {
969     String s = "$Revision: 1.5 $";
970     return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
971     }
972    
973 senoner 1500 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC