More fixes
[rtaudio-cdist.git] / include / asio.h
1 //---------------------------------------------------------------------------------------------------\r
2 //---------------------------------------------------------------------------------------------------\r
3 \r
4 /*\r
5         Steinberg Audio Stream I/O API\r
6         (c) 1997 - 2013, Steinberg Media Technologies GmbH\r
7 \r
8         ASIO Interface Specification v 2.3\r
9 \r
10         2005 - Added support for DSD sample data (in cooperation with Sony)\r
11         2012 - Added support for drop out detection\r
12                 \r
13         \r
14 \r
15         basic concept is an i/o synchronous double-buffer scheme:\r
16         \r
17         on bufferSwitch(index == 0), host will read/write:\r
18 \r
19                 after ASIOStart(), the\r
20   read  first input buffer A (index 0)\r
21         |   will be invalid (empty)\r
22         *   ------------------------\r
23         |------------------------|-----------------------|\r
24         |                        |                       |\r
25         |  Input Buffer A (0)    |   Input Buffer B (1)  |\r
26         |                        |                       |\r
27         |------------------------|-----------------------|\r
28         |                        |                       |\r
29         |  Output Buffer A (0)   |   Output Buffer B (1) |\r
30         |                        |                       |\r
31         |------------------------|-----------------------|\r
32         *                        -------------------------\r
33         |                        before calling ASIOStart(),\r
34   write                      host will have filled output\r
35                              buffer B (index 1) already\r
36 \r
37   *please* take special care of proper statement of input\r
38   and output latencies (see ASIOGetLatencies()), these\r
39   control sequencer sync accuracy\r
40 \r
41 */\r
42 \r
43 //---------------------------------------------------------------------------------------------------\r
44 //---------------------------------------------------------------------------------------------------\r
45 \r
46 /*\r
47 \r
48 prototypes summary:\r
49 \r
50 ASIOError ASIOInit(ASIODriverInfo *info);\r
51 ASIOError ASIOExit(void);\r
52 ASIOError ASIOStart(void);\r
53 ASIOError ASIOStop(void);\r
54 ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);\r
55 ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);\r
56 ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
57 ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);\r
58 ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);\r
59 ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);\r
60 ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);\r
61 ASIOError ASIOSetClockSource(long reference);\r
62 ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
63 ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);\r
64 ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
65         long bufferSize, ASIOCallbacks *callbacks);\r
66 ASIOError ASIODisposeBuffers(void);\r
67 ASIOError ASIOControlPanel(void);\r
68 void *ASIOFuture(long selector, void *params);\r
69 ASIOError ASIOOutputReady(void);\r
70 \r
71 */\r
72 \r
73 //---------------------------------------------------------------------------------------------------\r
74 //---------------------------------------------------------------------------------------------------\r
75 \r
76 #ifndef __ASIO_H\r
77 #define __ASIO_H\r
78 \r
79 // force 4 byte alignment\r
80 #if defined(_MSC_VER) && !defined(__MWERKS__) \r
81 #pragma pack(push,4)\r
82 #elif PRAGMA_ALIGN_SUPPORTED\r
83 #pragma options align = native\r
84 #endif\r
85 \r
86 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
87 // Type definitions\r
88 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
89 \r
90 // number of samples data type is 64 bit integer\r
91 #if NATIVE_INT64\r
92         typedef long long int ASIOSamples;\r
93 #else\r
94         typedef struct ASIOSamples {\r
95                 unsigned long hi;\r
96                 unsigned long lo;\r
97         } ASIOSamples;\r
98 #endif\r
99 \r
100 // Timestamp data type is 64 bit integer,\r
101 // Time format is Nanoseconds.\r
102 #if NATIVE_INT64\r
103         typedef long long int ASIOTimeStamp ;\r
104 #else\r
105         typedef struct ASIOTimeStamp {\r
106                 unsigned long hi;\r
107                 unsigned long lo;\r
108         } ASIOTimeStamp;\r
109 #endif\r
110 \r
111 // Samplerates are expressed in IEEE 754 64 bit double float,\r
112 // native format as host computer\r
113 #if IEEE754_64FLOAT\r
114         typedef double ASIOSampleRate;\r
115 #else\r
116         typedef struct ASIOSampleRate {\r
117                 char ieee[8];\r
118         } ASIOSampleRate;\r
119 #endif\r
120 \r
121 // Boolean values are expressed as long\r
122 typedef long ASIOBool;\r
123 enum {\r
124         ASIOFalse = 0,\r
125         ASIOTrue = 1\r
126 };\r
127 \r
128 // Sample Types are expressed as long\r
129 typedef long ASIOSampleType;\r
130 enum {\r
131         ASIOSTInt16MSB   = 0,\r
132         ASIOSTInt24MSB   = 1,           // used for 20 bits as well\r
133         ASIOSTInt32MSB   = 2,\r
134         ASIOSTFloat32MSB = 3,           // IEEE 754 32 bit float\r
135         ASIOSTFloat64MSB = 4,           // IEEE 754 64 bit double float\r
136 \r
137         // these are used for 32 bit data buffer, with different alignment of the data inside\r
138         // 32 bit PCI bus systems can be more easily used with these\r
139         ASIOSTInt32MSB16 = 8,           // 32 bit data with 16 bit alignment\r
140         ASIOSTInt32MSB18 = 9,           // 32 bit data with 18 bit alignment\r
141         ASIOSTInt32MSB20 = 10,          // 32 bit data with 20 bit alignment\r
142         ASIOSTInt32MSB24 = 11,          // 32 bit data with 24 bit alignment\r
143         \r
144         ASIOSTInt16LSB   = 16,\r
145         ASIOSTInt24LSB   = 17,          // used for 20 bits as well\r
146         ASIOSTInt32LSB   = 18,\r
147         ASIOSTFloat32LSB = 19,          // IEEE 754 32 bit float, as found on Intel x86 architecture\r
148         ASIOSTFloat64LSB = 20,          // IEEE 754 64 bit double float, as found on Intel x86 architecture\r
149 \r
150         // these are used for 32 bit data buffer, with different alignment of the data inside\r
151         // 32 bit PCI bus systems can more easily used with these\r
152         ASIOSTInt32LSB16 = 24,          // 32 bit data with 18 bit alignment\r
153         ASIOSTInt32LSB18 = 25,          // 32 bit data with 18 bit alignment\r
154         ASIOSTInt32LSB20 = 26,          // 32 bit data with 20 bit alignment\r
155         ASIOSTInt32LSB24 = 27,          // 32 bit data with 24 bit alignment\r
156 \r
157         //      ASIO DSD format.\r
158         ASIOSTDSDInt8LSB1   = 32,               // DSD 1 bit data, 8 samples per byte. First sample in Least significant bit.\r
159         ASIOSTDSDInt8MSB1   = 33,               // DSD 1 bit data, 8 samples per byte. First sample in Most significant bit.\r
160         ASIOSTDSDInt8NER8       = 40,           // DSD 8 bit data, 1 sample per byte. No Endianness required.\r
161 \r
162         ASIOSTLastEntry\r
163 };\r
164 \r
165 /*-----------------------------------------------------------------------------\r
166 // DSD operation and buffer layout\r
167 // Definition by Steinberg/Sony Oxford.\r
168 //\r
169 // We have tried to treat DSD as PCM and so keep a consistant structure across\r
170 // the ASIO interface.\r
171 //\r
172 // DSD's sample rate is normally referenced as a multiple of 44.1Khz, so\r
173 // the standard sample rate is refered to as 64Fs (or 2.8224Mhz). We looked\r
174 // at making a special case for DSD and adding a field to the ASIOFuture that\r
175 // would allow the user to select the Over Sampleing Rate (OSR) as a seperate\r
176 // entity but decided in the end just to treat it as a simple value of\r
177 // 2.8224Mhz and use the standard interface to set it.\r
178 //\r
179 // The second problem was the "word" size, in PCM the word size is always a\r
180 // greater than or equal to 8 bits (a byte). This makes life easy as we can\r
181 // then pack the samples into the "natural" size for the machine.\r
182 // In DSD the "word" size is 1 bit. This is not a major problem and can easily\r
183 // be dealt with if we ensure that we always deal with a multiple of 8 samples.\r
184 //\r
185 // DSD brings with it another twist to the Endianness religion. How are the\r
186 // samples packed into the byte. It would be nice to just say the most significant\r
187 // bit is always the first sample, however there would then be a performance hit\r
188 // on little endian machines. Looking at how some of the processing goes...\r
189 // Little endian machines like the first sample to be in the Least Significant Bit,\r
190 //   this is because when you write it to memory the data is in the correct format\r
191 //   to be shifted in and out of the words.\r
192 // Big endian machine prefer the first sample to be in the Most Significant Bit,\r
193 //   again for the same reasion.\r
194 //\r
195 // And just when things were looking really muddy there is a proposed extension to\r
196 // DSD that uses 8 bit word sizes. It does not care what endianness you use.\r
197 //\r
198 // Switching the driver between DSD and PCM mode\r
199 // ASIOFuture allows for extending the ASIO API quite transparently.\r
200 // See kAsioSetIoFormat, kAsioGetIoFormat, kAsioCanDoIoFormat\r
201 //\r
202 //-----------------------------------------------------------------------------*/\r
203 \r
204 \r
205 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
206 // Error codes\r
207 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
208 \r
209 typedef long ASIOError;\r
210 enum {\r
211         ASE_OK = 0,             // This value will be returned whenever the call succeeded\r
212         ASE_SUCCESS = 0x3f4847a0,       // unique success return value for ASIOFuture calls\r
213         ASE_NotPresent = -1000, // hardware input or output is not present or available\r
214         ASE_HWMalfunction,      // hardware is malfunctioning (can be returned by any ASIO function)\r
215         ASE_InvalidParameter,   // input parameter invalid\r
216         ASE_InvalidMode,        // hardware is in a bad mode or used in a bad mode\r
217         ASE_SPNotAdvancing,     // hardware is not running when sample position is inquired\r
218         ASE_NoClock,            // sample clock or rate cannot be determined or is not present\r
219         ASE_NoMemory            // not enough memory for completing the request\r
220 };\r
221 \r
222 //---------------------------------------------------------------------------------------------------\r
223 //---------------------------------------------------------------------------------------------------\r
224 \r
225 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
226 // Time Info support\r
227 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
228 \r
229 typedef struct ASIOTimeCode\r
230 {       \r
231         double          speed;                  // speed relation (fraction of nominal speed)\r
232                                                 // optional; set to 0. or 1. if not supported\r
233         ASIOSamples     timeCodeSamples;        // time in samples\r
234         unsigned long   flags;                  // some information flags (see below)\r
235         char future[64];\r
236 } ASIOTimeCode;\r
237 \r
238 typedef enum ASIOTimeCodeFlags\r
239 {\r
240         kTcValid                = 1,\r
241         kTcRunning              = 1 << 1,\r
242         kTcReverse              = 1 << 2,\r
243         kTcOnspeed              = 1 << 3,\r
244         kTcStill                = 1 << 4,\r
245         \r
246         kTcSpeedValid           = 1 << 8\r
247 }  ASIOTimeCodeFlags;\r
248 \r
249 typedef struct AsioTimeInfo\r
250 {\r
251         double          speed;                  // absolute speed (1. = nominal)\r
252         ASIOTimeStamp   systemTime;             // system time related to samplePosition, in nanoseconds\r
253                                                 // on mac, must be derived from Microseconds() (not UpTime()!)\r
254                                                 // on windows, must be derived from timeGetTime()\r
255         ASIOSamples     samplePosition;\r
256         ASIOSampleRate  sampleRate;             // current rate\r
257         unsigned long flags;                    // (see below)\r
258         char reserved[12];\r
259 } AsioTimeInfo;\r
260 \r
261 typedef enum AsioTimeInfoFlags\r
262 {\r
263         kSystemTimeValid        = 1,            // must always be valid\r
264         kSamplePositionValid    = 1 << 1,       // must always be valid\r
265         kSampleRateValid        = 1 << 2,\r
266         kSpeedValid             = 1 << 3,\r
267         \r
268         kSampleRateChanged      = 1 << 4,\r
269         kClockSourceChanged     = 1 << 5\r
270 } AsioTimeInfoFlags;\r
271 \r
272 typedef struct ASIOTime                          // both input/output\r
273 {\r
274         long reserved[4];                       // must be 0\r
275         struct AsioTimeInfo     timeInfo;       // required\r
276         struct ASIOTimeCode     timeCode;       // optional, evaluated if (timeCode.flags & kTcValid)\r
277 } ASIOTime;\r
278 \r
279 /*\r
280 \r
281 using time info:\r
282 it is recommended to use the new method with time info even if the asio\r
283 device does not support timecode; continuous calls to ASIOGetSamplePosition\r
284 and ASIOGetSampleRate are avoided, and there is a more defined relationship\r
285 between callback time and the time info.\r
286 \r
287 see the example below.\r
288 to initiate time info mode, after you have received the callbacks pointer in\r
289 ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo\r
290 as the argument. if this returns 1, host has accepted time info mode.\r
291 now host expects the new callback bufferSwitchTimeInfo to be used instead\r
292 of the old bufferSwitch method. the ASIOTime structure is assumed to be valid\r
293 and accessible until the callback returns.\r
294 \r
295 using time code:\r
296 if the device supports reading time code, it will call host's asioMessage callback\r
297 with kAsioSupportsTimeCode as the selector. it may then fill the according\r
298 fields and set the kTcValid flag.\r
299 host will call the future method with the kAsioEnableTimeCodeRead selector when\r
300 it wants to enable or disable tc reading by the device. you should also support\r
301 the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example).\r
302 \r
303 note:\r
304 the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions.\r
305 as a matter of convention, the relationship between the sample\r
306 position counter and the time code at buffer switch time is\r
307 (ignoring offset between tc and sample pos when tc is running):\r
308 \r
309 on input:       sample 0 -> input  buffer sample 0 -> time code 0\r
310 on output:      sample 0 -> output buffer sample 0 -> time code 0\r
311 \r
312 this means that for 'real' calculations, one has to take into account\r
313 the according latencies.\r
314 \r
315 example:\r
316 \r
317 ASIOTime asioTime;\r
318 \r
319 in createBuffers()\r
320 {\r
321         memset(&asioTime, 0, sizeof(ASIOTime));\r
322         AsioTimeInfo* ti = &asioTime.timeInfo;\r
323         ti->sampleRate = theSampleRate;\r
324         ASIOTimeCode* tc = &asioTime.timeCode;\r
325         tc->speed = 1.;\r
326         timeInfoMode = false;\r
327         canTimeCode = false;\r
328         if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1)\r
329         {\r
330                 timeInfoMode = true;\r
331 #if kCanTimeCode\r
332                 if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1)\r
333                         canTimeCode = true;\r
334 #endif\r
335         }\r
336 }\r
337 \r
338 void switchBuffers(long doubleBufferIndex, bool processNow)\r
339 {\r
340         if(timeInfoMode)\r
341         {\r
342                 AsioTimeInfo* ti = &asioTime.timeInfo;\r
343                 ti->flags =     kSystemTimeValid | kSamplePositionValid | kSampleRateValid;\r
344                 ti->systemTime = theNanoSeconds;\r
345                 ti->samplePosition = theSamplePosition;\r
346                 if(ti->sampleRate != theSampleRate)\r
347                         ti->flags |= kSampleRateChanged;\r
348                 ti->sampleRate = theSampleRate;\r
349 \r
350 #if kCanTimeCode\r
351                 if(canTimeCode && timeCodeEnabled)\r
352                 {\r
353                         ASIOTimeCode* tc = &asioTime.timeCode;\r
354                         tc->timeCodeSamples = tcSamples;                                                // tc in samples\r
355                         tc->flags = kTcValid | kTcRunning | kTcOnspeed;                 // if so...\r
356                 }\r
357                 ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);\r
358 #else\r
359                 callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse);\r
360 #endif\r
361         }\r
362         else\r
363                 callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse);\r
364 }\r
365 \r
366 ASIOError ASIOFuture(long selector, void *params)\r
367 {\r
368         switch(selector)\r
369         {\r
370                 case kAsioEnableTimeCodeRead:\r
371                         timeCodeEnabled = true;\r
372                         return ASE_SUCCESS;\r
373                 case kAsioDisableTimeCodeRead:\r
374                         timeCodeEnabled = false;\r
375                         return ASE_SUCCESS;\r
376                 case kAsioCanTimeInfo:\r
377                         return ASE_SUCCESS;\r
378                 #if kCanTimeCode\r
379                 case kAsioCanTimeCode:\r
380                         return ASE_SUCCESS;\r
381                 #endif\r
382         }\r
383         return ASE_NotPresent;\r
384 };\r
385 \r
386 */\r
387 \r
388 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
389 // application's audio stream handler callbacks\r
390 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
391 \r
392 typedef struct ASIOCallbacks\r
393 {\r
394         void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess);\r
395                 // bufferSwitch indicates that both input and output are to be processed.\r
396                 // the current buffer half index (0 for A, 1 for B) determines\r
397                 // - the output buffer that the host should start to fill. the other buffer\r
398                 //   will be passed to output hardware regardless of whether it got filled\r
399                 //   in time or not.\r
400                 // - the input buffer that is now filled with incoming data. Note that\r
401                 //   because of the synchronicity of i/o, the input always has at\r
402                 //   least one buffer latency in relation to the output.\r
403                 // directProcess suggests to the host whether it should immedeately\r
404                 // start processing (directProcess == ASIOTrue), or whether its process\r
405                 // should be deferred because the call comes from a very low level\r
406                 // (for instance, a high level priority interrupt), and direct processing\r
407                 // would cause timing instabilities for the rest of the system. If in doubt,\r
408                 // directProcess should be set to ASIOFalse.\r
409                 // Note: bufferSwitch may be called at interrupt time for highest efficiency.\r
410 \r
411         void (*sampleRateDidChange) (ASIOSampleRate sRate);\r
412                 // gets called when the AudioStreamIO detects a sample rate change\r
413                 // If sample rate is unknown, 0 is passed (for instance, clock loss\r
414                 // when externally synchronized).\r
415 \r
416         long (*asioMessage) (long selector, long value, void* message, double* opt);\r
417                 // generic callback for various purposes, see selectors below.\r
418                 // note this is only present if the asio version is 2 or higher\r
419 \r
420         ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess);\r
421                 // new callback with time info. makes ASIOGetSamplePosition() and various\r
422                 // calls to ASIOGetSampleRate obsolete,\r
423                 // and allows for timecode sync etc. to be preferred; will be used if\r
424                 // the driver calls asioMessage with selector kAsioSupportsTimeInfo.\r
425 } ASIOCallbacks;\r
426 \r
427 // asioMessage selectors\r
428 enum\r
429 {\r
430         kAsioSelectorSupported = 1,     // selector in <value>, returns 1L if supported,\r
431                                                                 // 0 otherwise\r
432     kAsioEngineVersion,                 // returns engine (host) asio implementation version,\r
433                                                                 // 2 or higher\r
434         kAsioResetRequest,                      // request driver reset. if accepted, this\r
435                                                                 // will close the driver (ASIO_Exit() ) and\r
436                                                                 // re-open it again (ASIO_Init() etc). some\r
437                                                                 // drivers need to reconfigure for instance\r
438                                                                 // when the sample rate changes, or some basic\r
439                                                                 // changes have been made in ASIO_ControlPanel().\r
440                                                                 // returns 1L; note the request is merely passed\r
441                                                                 // to the application, there is no way to determine\r
442                                                                 // if it gets accepted at this time (but it usually\r
443                                                                 // will be).\r
444         kAsioBufferSizeChange,          // not yet supported, will currently always return 0L.\r
445                                                                 // for now, use kAsioResetRequest instead.\r
446                                                                 // once implemented, the new buffer size is expected\r
447                                                                 // in <value>, and on success returns 1L\r
448         kAsioResyncRequest,                     // the driver went out of sync, such that\r
449                                                                 // the timestamp is no longer valid. this\r
450                                                                 // is a request to re-start the engine and\r
451                                                                 // slave devices (sequencer). returns 1 for ok,\r
452                                                                 // 0 if not supported.\r
453         kAsioLatenciesChanged,          // the drivers latencies have changed. The engine\r
454                                                                 // will refetch the latencies.\r
455         kAsioSupportsTimeInfo,          // if host returns true here, it will expect the\r
456                                                                 // callback bufferSwitchTimeInfo to be called instead\r
457                                                                 // of bufferSwitch\r
458         kAsioSupportsTimeCode,          // \r
459         kAsioMMCCommand,                        // unused - value: number of commands, message points to mmc commands\r
460         kAsioSupportsInputMonitor,      // kAsioSupportsXXX return 1 if host supports this\r
461         kAsioSupportsInputGain,     // unused and undefined\r
462         kAsioSupportsInputMeter,    // unused and undefined\r
463         kAsioSupportsOutputGain,    // unused and undefined\r
464         kAsioSupportsOutputMeter,   // unused and undefined\r
465         kAsioOverload,              // driver detected an overload\r
466 \r
467         kAsioNumMessageSelectors\r
468 };\r
469 \r
470 //---------------------------------------------------------------------------------------------------\r
471 //---------------------------------------------------------------------------------------------------\r
472 \r
473 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
474 // (De-)Construction\r
475 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
476 \r
477 typedef struct ASIODriverInfo\r
478 {\r
479         long asioVersion;               // currently, 2\r
480         long driverVersion;             // driver specific\r
481         char name[32];\r
482         char errorMessage[124];\r
483         void *sysRef;                   // on input: system reference\r
484                                                         // (Windows: application main window handle, Mac & SGI: 0)\r
485 } ASIODriverInfo;\r
486 \r
487 ASIOError ASIOInit(ASIODriverInfo *info);\r
488 /* Purpose:\r
489           Initialize the AudioStreamIO.\r
490         Parameter:\r
491           info: pointer to an ASIODriver structure:\r
492             - asioVersion:\r
493                         - on input, the host version. *** Note *** this is 0 for earlier asio\r
494                         implementations, and the asioMessage callback is implemeted\r
495                         only if asioVersion is 2 or greater. sorry but due to a design fault\r
496                         the driver doesn't have access to the host version in ASIOInit :-(\r
497                         added selector for host (engine) version in the asioMessage callback\r
498                         so we're ok from now on.\r
499                         - on return, asio implementation version.\r
500                           older versions are 1\r
501                           if you support this version (namely, ASIO_outputReady() )\r
502                           this should be 2 or higher. also see the note in\r
503                           ASIO_getTimeStamp() !\r
504             - version: on return, the driver version (format is driver specific)\r
505             - name: on return, a null-terminated string containing the driver's name\r
506                 - error message: on return, should contain a user message describing\r
507                   the type of error that occured during ASIOInit(), if any.\r
508                 - sysRef: platform specific\r
509         Returns:\r
510           If neither input nor output is present ASE_NotPresent\r
511           will be returned.\r
512           ASE_NoMemory, ASE_HWMalfunction are other possible error conditions\r
513 */\r
514 \r
515 ASIOError ASIOExit(void);\r
516 /* Purpose:\r
517           Terminates the AudioStreamIO.\r
518         Parameter:\r
519           None.\r
520         Returns:\r
521           If neither input nor output is present ASE_NotPresent\r
522           will be returned.\r
523         Notes: this implies ASIOStop() and ASIODisposeBuffers(),\r
524           meaning that no host callbacks must be accessed after ASIOExit().\r
525 */\r
526 \r
527 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
528 // Start/Stop\r
529 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
530 \r
531 ASIOError ASIOStart(void);\r
532 /* Purpose:\r
533           Start input and output processing synchronously.\r
534           This will\r
535           - reset the sample counter to zero\r
536           - start the hardware (both input and output)\r
537             The first call to the hosts' bufferSwitch(index == 0) then tells\r
538             the host to read from input buffer A (index 0), and start\r
539             processing to output buffer A while output buffer B (which\r
540             has been filled by the host prior to calling ASIOStart())\r
541             is possibly sounding (see also ASIOGetLatencies()) \r
542         Parameter:\r
543           None.\r
544         Returns:\r
545           If neither input nor output is present, ASE_NotPresent\r
546           will be returned.\r
547           If the hardware fails to start, ASE_HWMalfunction will be returned.\r
548         Notes:\r
549           There is no restriction on the time that ASIOStart() takes\r
550           to perform (that is, it is not considered a realtime trigger).\r
551 */\r
552 \r
553 ASIOError ASIOStop(void);\r
554 /* Purpose:\r
555           Stops input and output processing altogether.\r
556         Parameter:\r
557           None.\r
558         Returns:\r
559           If neither input nor output is present ASE_NotPresent\r
560           will be returned.\r
561         Notes:\r
562           On return from ASIOStop(), the driver must in no\r
563           case call the hosts' bufferSwitch() routine.\r
564 */\r
565 \r
566 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
567 // Inquiry methods and sample rate\r
568 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
569 \r
570 ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels);\r
571 /* Purpose:\r
572           Returns number of individual input/output channels.\r
573         Parameter:\r
574           numInputChannels will hold the number of available input channels\r
575           numOutputChannels will hold the number of available output channels\r
576         Returns:\r
577           If no input/output is present ASE_NotPresent will be returned.\r
578           If only inputs, or only outputs are available, the according\r
579           other parameter will be zero, and ASE_OK is returned.\r
580 */\r
581 \r
582 ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency);\r
583 /* Purpose:\r
584           Returns the input and output latencies. This includes\r
585           device specific delays, like FIFOs etc.\r
586         Parameter:\r
587           inputLatency will hold the 'age' of the first sample frame\r
588           in the input buffer when the hosts reads it in bufferSwitch()\r
589           (this is theoretical, meaning it does not include the overhead\r
590           and delay between the actual physical switch, and the time\r
591           when bufferSitch() enters).\r
592           This will usually be the size of one block in sample frames, plus\r
593           device specific latencies.\r
594 \r
595           outputLatency will specify the time between the buffer switch,\r
596           and the time when the next play buffer will start to sound.\r
597           The next play buffer is defined as the one the host starts\r
598           processing after (or at) bufferSwitch(), indicated by the\r
599           index parameter (0 for buffer A, 1 for buffer B).\r
600           It will usually be either one block, if the host writes directly\r
601           to a dma buffer, or two or more blocks if the buffer is 'latched' by\r
602           the driver. As an example, on ASIOStart(), the host will have filled\r
603           the play buffer at index 1 already; when it gets the callback (with\r
604           the parameter index == 0), this tells it to read from the input\r
605           buffer 0, and start to fill the play buffer 0 (assuming that now\r
606           play buffer 1 is already sounding). In this case, the output\r
607           latency is one block. If the driver decides to copy buffer 1\r
608           at that time, and pass it to the hardware at the next slot (which\r
609           is most commonly done, but should be avoided), the output latency\r
610           becomes two blocks instead, resulting in a total i/o latency of at least\r
611           3 blocks. As memory access is the main bottleneck in native dsp processing,\r
612           and to acheive less latency, it is highly recommended to try to avoid\r
613           copying (this is also why the driver is the owner of the buffers). To\r
614           summarize, the minimum i/o latency can be acheived if the input buffer\r
615           is processed by the host into the output buffer which will physically\r
616           start to sound on the next time slice. Also note that the host expects\r
617           the bufferSwitch() callback to be accessed for each time slice in order\r
618           to retain sync, possibly recursively; if it fails to process a block in\r
619           time, it will suspend its operation for some time in order to recover.\r
620         Returns:\r
621           If no input/output is present ASE_NotPresent will be returned.\r
622 */\r
623 \r
624 ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);\r
625 /* Purpose:\r
626           Returns min, max, and preferred buffer sizes for input/output\r
627         Parameter:\r
628           minSize will hold the minimum buffer size\r
629           maxSize will hold the maxium possible buffer size\r
630           preferredSize will hold the preferred buffer size (a size which\r
631           best fits performance and hardware requirements)\r
632           granularity will hold the granularity at which buffer sizes\r
633           may differ. Usually, the buffer size will be a power of 2;\r
634           in this case, granularity will hold -1 on return, signalling\r
635           possible buffer sizes starting from minSize, increased in\r
636           powers of 2 up to maxSize.\r
637         Returns:\r
638           If no input/output is present ASE_NotPresent will be returned.\r
639         Notes:\r
640           When minimum and maximum buffer size are equal,\r
641           the preferred buffer size has to be the same value as well; granularity\r
642           should be 0 in this case.\r
643 */\r
644 \r
645 ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate);\r
646 /* Purpose:\r
647           Inquires the hardware for the available sample rates.\r
648         Parameter:\r
649           sampleRate is the rate in question.\r
650         Returns:\r
651           If the inquired sample rate is not supported, ASE_NoClock will be returned.\r
652           If no input/output is present ASE_NotPresent will be returned.\r
653 */\r
654 ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate);\r
655 /* Purpose:\r
656           Get the current sample Rate.\r
657         Parameter:\r
658           currentRate will hold the current sample rate on return.\r
659         Returns:\r
660           If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned.\r
661           If no input/output is present ASE_NotPresent will be returned.\r
662         Notes:\r
663 */\r
664 \r
665 ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate);\r
666 /* Purpose:\r
667           Set the hardware to the requested sample Rate. If sampleRate == 0,\r
668           enable external sync.\r
669         Parameter:\r
670           sampleRate: on input, the requested rate\r
671         Returns:\r
672           If sampleRate is unknown ASE_NoClock will be returned.\r
673           If the current clock is external, and sampleRate is != 0,\r
674           ASE_InvalidMode will be returned\r
675           If no input/output is present ASE_NotPresent will be returned.\r
676         Notes:\r
677 */\r
678 \r
679 typedef struct ASIOClockSource\r
680 {\r
681         long index;                                     // as used for ASIOSetClockSource()\r
682         long associatedChannel;         // for instance, S/PDIF or AES/EBU\r
683         long associatedGroup;           // see channel groups (ASIOGetChannelInfo())\r
684         ASIOBool isCurrentSource;       // ASIOTrue if this is the current clock source\r
685         char name[32];                          // for user selection\r
686 } ASIOClockSource;\r
687 \r
688 ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources);\r
689 /* Purpose:\r
690           Get the available external audio clock sources\r
691         Parameter:\r
692           clocks points to an array of ASIOClockSource structures:\r
693                 - index: this is used to identify the clock source\r
694                   when ASIOSetClockSource() is accessed, should be\r
695                   an index counting from zero\r
696                 - associatedInputChannel: the first channel of an associated\r
697                   input group, if any.\r
698                 - associatedGroup: the group index of that channel.\r
699                   groups of channels are defined to seperate for\r
700                   instance analog, S/PDIF, AES/EBU, ADAT connectors etc,\r
701                   when present simultaniously. Note that associated channel\r
702                   is enumerated according to numInputs/numOutputs, means it\r
703                   is independant from a group (see also ASIOGetChannelInfo())\r
704                   inputs are associated to a clock if the physical connection\r
705                   transfers both data and clock (like S/PDIF, AES/EBU, or\r
706                   ADAT inputs). if there is no input channel associated with\r
707                   the clock source (like Word Clock, or internal oscillator), both\r
708                   associatedChannel and associatedGroup should be set to -1.\r
709                 - isCurrentSource: on exit, ASIOTrue if this is the current clock\r
710                   source, ASIOFalse else\r
711                 - name: a null-terminated string for user selection of the available sources.\r
712           numSources:\r
713               on input: the number of allocated array members\r
714               on output: the number of available clock sources, at least\r
715               1 (internal clock generator).\r
716         Returns:\r
717           If no input/output is present ASE_NotPresent will be returned.\r
718         Notes:\r
719 */\r
720 \r
721 ASIOError ASIOSetClockSource(long index);\r
722 /* Purpose:\r
723           Set the audio clock source\r
724         Parameter:\r
725           index as obtained from an inquiry to ASIOGetClockSources()\r
726         Returns:\r
727           If no input/output is present ASE_NotPresent will be returned.\r
728           If the clock can not be selected because an input channel which\r
729           carries the current clock source is active, ASE_InvalidMode\r
730           *may* be returned (this depends on the properties of the driver\r
731           and/or hardware).\r
732         Notes:\r
733           Should *not* return ASE_NoClock if there is no clock signal present\r
734           at the selected source; this will be inquired via ASIOGetSampleRate().\r
735           It should call the host callback procedure sampleRateHasChanged(),\r
736           if the switch causes a sample rate change, or if no external clock\r
737           is present at the selected source.\r
738 */\r
739 \r
740 ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp);\r
741 /* Purpose:\r
742           Inquires the sample position/time stamp pair.\r
743         Parameter:\r
744           sPos will hold the sample position on return. The sample\r
745           position is reset to zero when ASIOStart() gets called.\r
746           tStamp will hold the system time when the sample position\r
747           was latched.\r
748         Returns:\r
749           If no input/output is present, ASE_NotPresent will be returned.\r
750           If there is no clock, ASE_SPNotAdvancing will be returned.\r
751         Notes:\r
752 \r
753           in order to be able to synchronise properly,\r
754           the sample position / time stamp pair must refer to the current block,\r
755           that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch()\r
756           callback and expect the time for the current block. thus, when requested\r
757           in the very first bufferSwitch after ASIO_Start(), the sample position\r
758           should be zero, and the time stamp should refer to the very time where\r
759           the stream was started. it also means that the sample position must be\r
760           block aligned. the driver must ensure proper interpolation if the system\r
761           time can not be determined for the block position. the driver is responsible\r
762           for precise time stamps as it usually has most direct access to lower\r
763           level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies()\r
764           are essential for precise media synchronization!\r
765 */\r
766 \r
767 typedef struct ASIOChannelInfo\r
768 {\r
769         long channel;                   // on input, channel index\r
770         ASIOBool isInput;               // on input\r
771         ASIOBool isActive;              // on exit\r
772         long channelGroup;              // dto\r
773         ASIOSampleType type;    // dto\r
774         char name[32];                  // dto\r
775 } ASIOChannelInfo;\r
776 \r
777 ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info);\r
778 /* Purpose:\r
779           retreive information about the nature of a channel\r
780         Parameter:\r
781           info: pointer to a ASIOChannelInfo structure with\r
782                 - channel: on input, the channel index of the channel in question.\r
783                 - isInput: on input, ASIOTrue if info for an input channel is\r
784                   requested, else output\r
785                 - channelGroup: on return, the channel group that the channel\r
786                   belongs to. For drivers which support different types of\r
787                   channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces,\r
788                   there should be a reasonable grouping of these types. Groups\r
789                   are always independant form a channel index, that is, a channel\r
790                   index always counts from 0 to numInputs/numOutputs regardless\r
791                   of the group it may belong to.\r
792                   There will always be at least one group (group 0). Please\r
793                   also note that by default, the host may decide to activate\r
794                   channels 0 and 1; thus, these should belong to the most\r
795                   useful type (analog i/o, if present).\r
796                 - type: on return, contains the sample type of the channel\r
797                 - isActive: on return, ASIOTrue if channel is active as it was\r
798                   installed by ASIOCreateBuffers(), ASIOFalse else\r
799                 - name:  describing the type of channel in question. Used to allow\r
800                   for user selection, and enabling of specific channels. examples:\r
801               "Analog In", "SPDIF Out" etc\r
802         Returns:\r
803           If no input/output is present ASE_NotPresent will be returned.\r
804         Notes:\r
805           If possible, the string should be organised such that the first\r
806           characters are most significantly describing the nature of the\r
807           port, to allow for identification even if the view showing the\r
808           port name is too small to display more than 8 characters, for\r
809           instance.\r
810 */\r
811 \r
812 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
813 // Buffer preparation\r
814 //- - - - - - - - - - - - - - - - - - - - - - - - -\r
815 \r
816 typedef struct ASIOBufferInfo\r
817 {\r
818         ASIOBool isInput;                       // on input:  ASIOTrue: input, else output\r
819         long channelNum;                        // on input:  channel index\r
820         void *buffers[2];                       // on output: double buffer addresses\r
821 } ASIOBufferInfo;\r
822 \r
823 ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels,\r
824         long bufferSize, ASIOCallbacks *callbacks);\r
825 \r
826 /* Purpose:\r
827           Allocates input/output buffers for all input and output channels to be activated.\r
828         Parameter:\r
829           bufferInfos is a pointer to an array of ASIOBufferInfo structures:\r
830             - isInput: on input, ASIOTrue if the buffer is to be allocated\r
831               for an input, output buffer else\r
832             - channelNum: on input, the index of the channel in question\r
833               (counting from 0)\r
834             - buffers: on exit, 2 pointers to the halves of the channels' double-buffer.\r
835               the size of the buffer(s) of course depend on both the ASIOSampleType\r
836               as obtained from ASIOGetChannelInfo(), and bufferSize\r
837           numChannels is the sum of all input and output channels to be created;\r
838           thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo\r
839           structures.\r
840           bufferSize selects one of the possible buffer sizes as obtained from\r
841           ASIOGetBufferSizes().\r
842           callbacks is a pointer to an ASIOCallbacks structure.\r
843         Returns:\r
844           If not enough memory is available ASE_NoMemory will be returned.\r
845           If no input/output is present ASE_NotPresent will be returned.\r
846           If bufferSize is not supported, or one or more of the bufferInfos elements\r
847           contain invalid settings, ASE_InvalidMode will be returned.\r
848         Notes:\r
849           If individual channel selection is not possible but requested,\r
850           the driver has to handle this. namely, bufferSwitch() will only\r
851           have filled buffers of enabled outputs. If possible, processing\r
852           and buss activities overhead should be avoided for channels which\r
853           were not enabled here.\r
854 */\r
855 \r
856 ASIOError ASIODisposeBuffers(void);\r
857 /* Purpose:\r
858           Releases all buffers for the device.\r
859         Parameter:\r
860           None.\r
861         Returns:\r
862           If no buffer were ever prepared, ASE_InvalidMode will be returned.\r
863           If no input/output is present ASE_NotPresent will be returned.\r
864         Notes:\r
865           This implies ASIOStop().\r
866 */\r
867 \r
868 ASIOError ASIOControlPanel(void);\r
869 /* Purpose:\r
870           request the driver to start a control panel component\r
871           for device specific user settings. This will not be\r
872           accessed on some platforms (where the component is accessed\r
873           instead).\r
874         Parameter:\r
875           None.\r
876         Returns:\r
877           If no panel is available ASE_NotPresent will be returned.\r
878           Actually, the return code is ignored.\r
879         Notes:\r
880           if the user applied settings which require a re-configuration\r
881           of parts or all of the enigine and/or driver (such as a change of\r
882           the block size), the asioMessage callback can be used (see\r
883           ASIO_Callbacks).\r
884 */\r
885 \r
886 ASIOError ASIOFuture(long selector, void *params);\r
887 /* Purpose:\r
888           various\r
889         Parameter:\r
890           selector: operation Code as to be defined. zero is reserved for\r
891           testing purposes.\r
892           params: depends on the selector; usually pointer to a structure\r
893           for passing and retreiving any type and amount of parameters.\r
894         Returns:\r
895           the return value is also selector dependant. if the selector\r
896           is unknown, ASE_InvalidParameter should be returned to prevent\r
897           further calls with this selector. on success, ASE_SUCCESS\r
898           must be returned (note: ASE_OK is *not* sufficient!)\r
899         Notes:\r
900           see selectors defined below.    \r
901 */\r
902 \r
903 enum\r
904 {\r
905         kAsioEnableTimeCodeRead = 1,    // no arguments\r
906         kAsioDisableTimeCodeRead,               // no arguments\r
907         kAsioSetInputMonitor,                   // ASIOInputMonitor* in params\r
908         kAsioTransport,                                 // ASIOTransportParameters* in params\r
909         kAsioSetInputGain,                              // ASIOChannelControls* in params, apply gain\r
910         kAsioGetInputMeter,                             // ASIOChannelControls* in params, fill meter\r
911         kAsioSetOutputGain,                             // ASIOChannelControls* in params, apply gain\r
912         kAsioGetOutputMeter,                    // ASIOChannelControls* in params, fill meter\r
913         kAsioCanInputMonitor,                   // no arguments for kAsioCanXXX selectors\r
914         kAsioCanTimeInfo,\r
915         kAsioCanTimeCode,\r
916         kAsioCanTransport,\r
917         kAsioCanInputGain,\r
918         kAsioCanInputMeter,\r
919         kAsioCanOutputGain,\r
920         kAsioCanOutputMeter,\r
921         kAsioOptionalOne,\r
922         \r
923         //      DSD support\r
924         //      The following extensions are required to allow switching\r
925         //      and control of the DSD subsystem.\r
926         kAsioSetIoFormat                        = 0x23111961,           /* ASIOIoFormat * in params.                    */\r
927         kAsioGetIoFormat                        = 0x23111983,           /* ASIOIoFormat * in params.                    */\r
928         kAsioCanDoIoFormat                      = 0x23112004,           /* ASIOIoFormat * in params.                    */\r
929         \r
930         // Extension for drop out detection\r
931         kAsioCanReportOverload                  = 0x24042012,   /* return ASE_SUCCESS if driver can detect and report overloads */\r
932         \r
933         kAsioGetInternalBufferSamples   = 0x25042012    /* ASIOInternalBufferInfo * in params. Deliver size of driver internal buffering, return ASE_SUCCESS if supported */\r
934 };\r
935 \r
936 typedef struct ASIOInputMonitor\r
937 {\r
938         long input;             // this input was set to monitor (or off), -1: all\r
939         long output;    // suggested output for monitoring the input (if so)\r
940         long gain;              // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB)\r
941         ASIOBool state; // ASIOTrue => on, ASIOFalse => off\r
942         long pan;               // suggested pan, 0 => all left, 0x7fffffff => right\r
943 } ASIOInputMonitor;\r
944 \r
945 typedef struct ASIOChannelControls\r
946 {\r
947         long channel;                   // on input, channel index\r
948         ASIOBool isInput;               // on input\r
949         long gain;                              // on input,  ranges 0 thru 0x7fffffff\r
950         long meter;                             // on return, ranges 0 thru 0x7fffffff\r
951         char future[32];\r
952 } ASIOChannelControls;\r
953 \r
954 typedef struct ASIOTransportParameters\r
955 {\r
956         long command;           // see enum below\r
957         ASIOSamples samplePosition;\r
958         long track;\r
959         long trackSwitches[16];         // 512 tracks on/off\r
960         char future[64];\r
961 } ASIOTransportParameters;\r
962 \r
963 enum\r
964 {\r
965         kTransStart = 1,\r
966         kTransStop,\r
967         kTransLocate,           // to samplePosition\r
968         kTransPunchIn,\r
969         kTransPunchOut,\r
970         kTransArmOn,            // track\r
971         kTransArmOff,           // track\r
972         kTransMonitorOn,        // track\r
973         kTransMonitorOff,       // track\r
974         kTransArm,                      // trackSwitches\r
975         kTransMonitor           // trackSwitches\r
976 };\r
977 \r
978 /*\r
979 // DSD support\r
980 //      Some notes on how to use ASIOIoFormatType.\r
981 //\r
982 //      The caller will fill the format with the request types.\r
983 //      If the board can do the request then it will leave the\r
984 //      values unchanged. If the board does not support the\r
985 //      request then it will change that entry to Invalid (-1)\r
986 //\r
987 //      So to request DSD then\r
988 //\r
989 //      ASIOIoFormat NeedThis={kASIODSDFormat};\r
990 //\r
991 //      if(ASE_SUCCESS != ASIOFuture(kAsioSetIoFormat,&NeedThis) ){\r
992 //              // If the board did not accept one of the parameters then the\r
993 //              // whole call will fail and the failing parameter will\r
994 //              // have had its value changes to -1.\r
995 //      }\r
996 //\r
997 // Note: Switching between the formats need to be done before the "prepared"\r
998 // state (see ASIO 2 documentation) is entered.\r
999 */\r
1000 typedef long int ASIOIoFormatType;\r
1001 enum ASIOIoFormatType_e\r
1002 {\r
1003         kASIOFormatInvalid = -1,\r
1004         kASIOPCMFormat = 0,\r
1005         kASIODSDFormat = 1,\r
1006 };\r
1007 \r
1008 typedef struct ASIOIoFormat_s\r
1009 {\r
1010         ASIOIoFormatType        FormatType;\r
1011         char                            future[512-sizeof(ASIOIoFormatType)];\r
1012 } ASIOIoFormat;\r
1013 \r
1014 // Extension for drop detection\r
1015 // Note: Refers to buffering that goes beyond the double buffer e.g. used by USB driver designs\r
1016 typedef struct ASIOInternalBufferInfo\r
1017 {\r
1018         long inputSamples;                      // size of driver's internal input buffering which is included in getLatencies\r
1019         long outputSamples;                     // size of driver's internal output buffering which is included in getLatencies\r
1020 } ASIOInternalBufferInfo;\r
1021 \r
1022 \r
1023 ASIOError ASIOOutputReady(void);\r
1024 /* Purpose:\r
1025           this tells the driver that the host has completed processing\r
1026           the output buffers. if the data format required by the hardware\r
1027           differs from the supported asio formats, but the hardware\r
1028           buffers are DMA buffers, the driver will have to convert\r
1029           the audio stream data; as the bufferSwitch callback is\r
1030           usually issued at dma block switch time, the driver will\r
1031           have to convert the *previous* host buffer, which increases\r
1032           the output latency by one block.\r
1033           when the host finds out that ASIOOutputReady() returns\r
1034           true, it will issue this call whenever it completed\r
1035           output processing. then the driver can convert the\r
1036           host data directly to the dma buffer to be played next,\r
1037           reducing output latency by one block.\r
1038           another way to look at it is, that the buffer switch is called\r
1039           in order to pass the *input* stream to the host, so that it can\r
1040           process the input into the output, and the output stream is passed\r
1041           to the driver when the host has completed its process.\r
1042         Parameter:\r
1043                 None\r
1044         Returns:\r
1045           only if the above mentioned scenario is given, and a reduction\r
1046           of output latency can be acheived by this mechanism, should\r
1047           ASE_OK be returned. otherwise (and usually), ASE_NotPresent\r
1048           should be returned in order to prevent further calls to this\r
1049           function. note that the host may want to determine if it is\r
1050           to use this when the system is not yet fully initialized, so\r
1051           ASE_OK should always be returned if the mechanism makes sense.          \r
1052         Notes:\r
1053           please remeber to adjust ASIOGetLatencies() according to\r
1054           whether ASIOOutputReady() was ever called or not, if your\r
1055           driver supports this scenario.\r
1056           also note that the engine may fail to call ASIO_OutputReady()\r
1057           in time in overload cases. as already mentioned, bufferSwitch\r
1058       should be called for every block regardless of whether a block\r
1059       could be processed in time.\r
1060 */\r
1061 \r
1062 // restore old alignment\r
1063 #if defined(_MSC_VER) && !defined(__MWERKS__) \r
1064 #pragma pack(pop)\r
1065 #elif PRAGMA_ALIGN_SUPPORTED\r
1066 #pragma options align = reset\r
1067 #endif\r
1068 \r
1069 #endif\r
1070 \r