~ubuntu-branches/ubuntu/saucy/sflphone/saucy

« back to all changes in this revision

Viewing changes to sflphone-common/libs/pjproject/third_party/portaudio/src/hostapi/asio/pa_asio.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Francois Marier
  • Date: 2010-12-24 16:33:55 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20101224163355-tkvvikqxbrbav6up
Tags: 0.9.11-1
* New upstream release
* Add new build dependencies on libwebkit-dev and libyaml-dev

* Bump Standards-Version up to 3.9.1
* Bump debhelper compatibility to 8
* Patch another typo in the upstream code (lintian notice)

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 */
30
30
 
31
31
/*
32
 
 * The text above constitutes the entire PortAudio license; however, 
 
32
 * The text above constitutes the entire PortAudio license; however,
33
33
 * the PortAudio community also makes the following non-binding requests:
34
34
 *
35
35
 * Any person wishing to distribute modifications to the Software is
36
36
 * requested to send the modifications to the original developer so that
37
 
 * they can be incorporated into the canonical version. It is also 
38
 
 * requested that these non-binding requests be included along with the 
 
37
 * they can be incorporated into the canonical version. It is also
 
38
 * requested that these non-binding requests be included along with the
39
39
 * license above.
40
40
 */
41
41
 
83
83
 
84
84
    @todo review ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable
85
85
 
86
 
    @todo review Blocking i/o latency computations in OpenStream(), changing ring 
 
86
    @todo review Blocking i/o latency computations in OpenStream(), changing ring
87
87
          buffer to a non-power-of-two structure could reduce blocking i/o latency.
88
88
 
89
89
    @todo implement IsFormatSupported
171
171
 
172
172
/* external reference to ASIO SDK's asioDrivers.
173
173
 
174
 
 This is a bit messy because we want to explicitly manage 
175
 
 allocation/deallocation of this structure, but some layers of the SDK 
 
174
 This is a bit messy because we want to explicitly manage
 
175
 allocation/deallocation of this structure, but some layers of the SDK
176
176
 which we currently use (eg the implementation in asio.cpp) still
177
177
 use this global version.
178
178
 
190
190
 
191
191
/* prototypes for functions declared in this file */
192
192
 
193
 
extern "C" PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex );
194
 
static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
195
 
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
 
193
extern "C" PaError PaAsio_Initialize (PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex);
 
194
static void Terminate (struct PaUtilHostApiRepresentation *hostApi);
 
195
static PaError OpenStream (struct PaUtilHostApiRepresentation *hostApi,
196
196
                           PaStream** s,
197
197
                           const PaStreamParameters *inputParameters,
198
198
                           const PaStreamParameters *outputParameters,
200
200
                           unsigned long framesPerBuffer,
201
201
                           PaStreamFlags streamFlags,
202
202
                           PaStreamCallback *streamCallback,
203
 
                           void *userData );
204
 
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
 
203
                           void *userData);
 
204
static PaError IsFormatSupported (struct PaUtilHostApiRepresentation *hostApi,
205
205
                                  const PaStreamParameters *inputParameters,
206
206
                                  const PaStreamParameters *outputParameters,
207
 
                                  double sampleRate );
208
 
static PaError CloseStream( PaStream* stream );
209
 
static PaError StartStream( PaStream *stream );
210
 
static PaError StopStream( PaStream *stream );
211
 
static PaError AbortStream( PaStream *stream );
212
 
static PaError IsStreamStopped( PaStream *s );
213
 
static PaError IsStreamActive( PaStream *stream );
214
 
static PaTime GetStreamTime( PaStream *stream );
215
 
static double GetStreamCpuLoad( PaStream* stream );
216
 
static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
217
 
static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
218
 
static signed long GetStreamReadAvailable( PaStream* stream );
219
 
static signed long GetStreamWriteAvailable( PaStream* stream );
 
207
                                  double sampleRate);
 
208
static PaError CloseStream (PaStream* stream);
 
209
static PaError StartStream (PaStream *stream);
 
210
static PaError StopStream (PaStream *stream);
 
211
static PaError AbortStream (PaStream *stream);
 
212
static PaError IsStreamStopped (PaStream *s);
 
213
static PaError IsStreamActive (PaStream *stream);
 
214
static PaTime GetStreamTime (PaStream *stream);
 
215
static double GetStreamCpuLoad (PaStream* stream);
 
216
static PaError ReadStream (PaStream* stream, void *buffer, unsigned long frames);
 
217
static PaError WriteStream (PaStream* stream, const void *buffer, unsigned long frames);
 
218
static signed long GetStreamReadAvailable (PaStream* stream);
 
219
static signed long GetStreamWriteAvailable (PaStream* stream);
220
220
 
221
221
/* Blocking i/o callback function. */
222
 
static int BlockingIoPaCallback(const void                     *inputBuffer    ,
223
 
                                      void                     *outputBuffer   ,
224
 
                                      unsigned long             framesPerBuffer,
225
 
                                const PaStreamCallbackTimeInfo *timeInfo       ,
226
 
                                      PaStreamCallbackFlags     statusFlags    ,
227
 
                                      void                     *userData       );
 
222
static int BlockingIoPaCallback (const void                     *inputBuffer    ,
 
223
                                 void                     *outputBuffer   ,
 
224
                                 unsigned long             framesPerBuffer,
 
225
                                 const PaStreamCallbackTimeInfo *timeInfo       ,
 
226
                                 PaStreamCallbackFlags     statusFlags    ,
 
227
                                 void                     *userData);
228
228
 
229
229
/* our ASIO callback functions */
230
230
 
231
 
static void bufferSwitch(long index, ASIOBool processNow);
232
 
static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
233
 
static void sampleRateChanged(ASIOSampleRate sRate);
234
 
static long asioMessages(long selector, long value, void* message, double* opt);
 
231
static void bufferSwitch (long index, ASIOBool processNow);
 
232
static ASIOTime *bufferSwitchTimeInfo (ASIOTime *timeInfo, long index, ASIOBool processNow);
 
233
static void sampleRateChanged (ASIOSampleRate sRate);
 
234
static long asioMessages (long selector, long value, void* message, double* opt);
235
235
 
236
 
static ASIOCallbacks asioCallbacks_ =
237
 
    { bufferSwitch, sampleRateChanged, asioMessages, bufferSwitchTimeInfo };
 
236
static ASIOCallbacks asioCallbacks_ = { bufferSwitch, sampleRateChanged, asioMessages, bufferSwitchTimeInfo };
238
237
 
239
238
 
240
239
#define PA_ASIO_SET_LAST_HOST_ERROR( errorCode, errorText ) \
241
240
    PaUtil_SetLastHostErrorInfo( paASIO, errorCode, errorText )
242
241
 
243
242
 
244
 
static void PaAsio_SetLastSystemError( DWORD errorCode )
 
243
static void PaAsio_SetLastSystemError (DWORD errorCode)
245
244
{
246
245
    LPVOID lpMsgBuf;
247
 
    FormatMessage(
 
246
    FormatMessage (
248
247
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
249
248
        NULL,
250
249
        errorCode,
251
 
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
 
250
        MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
252
251
        (LPTSTR) &lpMsgBuf,
253
252
        0,
254
253
        NULL
255
254
    );
256
 
    PaUtil_SetLastHostErrorInfo( paASIO, errorCode, (const char*)lpMsgBuf );
257
 
    LocalFree( lpMsgBuf );
 
255
    PaUtil_SetLastHostErrorInfo (paASIO, errorCode, (const char*) lpMsgBuf);
 
256
    LocalFree (lpMsgBuf);
258
257
}
259
258
 
260
259
#define PA_ASIO_SET_LAST_SYSTEM_ERROR( errorCode ) \
261
260
    PaAsio_SetLastSystemError( errorCode )
262
261
 
263
262
 
264
 
static const char* PaAsio_GetAsioErrorText( ASIOError asioError )
 
263
static const char* PaAsio_GetAsioErrorText (ASIOError asioError)
265
264
{
266
265
    const char *result;
267
266
 
268
 
    switch( asioError ){
 
267
    switch (asioError) {
269
268
        case ASE_OK:
270
 
        case ASE_SUCCESS:           result = "Success"; break;
271
 
        case ASE_NotPresent:        result = "Hardware input or output is not present or available"; break;
272
 
        case ASE_HWMalfunction:     result = "Hardware is malfunctioning"; break;
273
 
        case ASE_InvalidParameter:  result = "Input parameter invalid"; break;
274
 
        case ASE_InvalidMode:       result = "Hardware is in a bad mode or used in a bad mode"; break;
275
 
        case ASE_SPNotAdvancing:    result = "Hardware is not running when sample position is inquired"; break;
276
 
        case ASE_NoClock:           result = "Sample clock or rate cannot be determined or is not present"; break;
277
 
        case ASE_NoMemory:          result = "Not enough memory for completing the request"; break;
278
 
        default:                    result = "Unknown ASIO error"; break;
 
269
        case ASE_SUCCESS:
 
270
            result = "Success";
 
271
            break;
 
272
        case ASE_NotPresent:
 
273
            result = "Hardware input or output is not present or available";
 
274
            break;
 
275
        case ASE_HWMalfunction:
 
276
            result = "Hardware is malfunctioning";
 
277
            break;
 
278
        case ASE_InvalidParameter:
 
279
            result = "Input parameter invalid";
 
280
            break;
 
281
        case ASE_InvalidMode:
 
282
            result = "Hardware is in a bad mode or used in a bad mode";
 
283
            break;
 
284
        case ASE_SPNotAdvancing:
 
285
            result = "Hardware is not running when sample position is inquired";
 
286
            break;
 
287
        case ASE_NoClock:
 
288
            result = "Sample clock or rate cannot be determined or is not present";
 
289
            break;
 
290
        case ASE_NoMemory:
 
291
            result = "Not enough memory for completing the request";
 
292
            break;
 
293
        default:
 
294
            result = "Unknown ASIO error";
 
295
            break;
279
296
    }
280
297
 
281
298
    return result;
290
307
 
291
308
// Atomic increment and decrement operations
292
309
#if MAC
293
 
    /* need to be implemented on Mac */
294
 
    inline long PaAsio_AtomicIncrement(volatile long* v) {return ++(*const_cast<long*>(v));}
295
 
    inline long PaAsio_AtomicDecrement(volatile long* v) {return --(*const_cast<long*>(v));}
 
310
/* need to be implemented on Mac */
 
311
inline long PaAsio_AtomicIncrement (volatile long* v)
 
312
{
 
313
    return ++ (*const_cast<long*> (v));
 
314
}
 
315
inline long PaAsio_AtomicDecrement (volatile long* v)
 
316
{
 
317
    return -- (*const_cast<long*> (v));
 
318
}
296
319
#elif WINDOWS
297
 
    inline long PaAsio_AtomicIncrement(volatile long* v) {return InterlockedIncrement(const_cast<long*>(v));}
298
 
    inline long PaAsio_AtomicDecrement(volatile long* v) {return InterlockedDecrement(const_cast<long*>(v));}
 
320
inline long PaAsio_AtomicIncrement (volatile long* v)
 
321
{
 
322
    return InterlockedIncrement (const_cast<long*> (v));
 
323
}
 
324
inline long PaAsio_AtomicDecrement (volatile long* v)
 
325
{
 
326
    return InterlockedDecrement (const_cast<long*> (v));
 
327
}
299
328
#endif
300
329
 
301
330
 
302
331
 
303
 
typedef struct PaAsioDriverInfo
304
 
{
 
332
typedef struct PaAsioDriverInfo {
305
333
    ASIODriverInfo asioDriverInfo;
306
334
    long inputChannelCount, outputChannelCount;
307
335
    long bufferMinSize, bufferMaxSize, bufferPreferredSize, bufferGranularity;
312
340
 
313
341
/* PaAsioHostApiRepresentation - host api datastructure specific to this implementation */
314
342
 
315
 
typedef struct
316
 
{
 
343
typedef struct {
317
344
    PaUtilHostApiRepresentation inheritedHostApiRep;
318
345
    PaUtilStreamInterface callbackStreamInterface;
319
346
    PaUtilStreamInterface blockingStreamInterface;
322
349
 
323
350
    AsioDrivers *asioDrivers;
324
351
    void *systemSpecific;
325
 
    
 
352
 
326
353
    /* the ASIO C API only allows one ASIO driver to be open at a time,
327
354
        so we keep track of whether we have the driver open here, and
328
355
        use this information to return errors from OpenStream if the
344
371
    Retrieve <driverCount> driver names from ASIO, returned in a char**
345
372
    allocated in <group>.
346
373
*/
347
 
static char **GetAsioDriverNames( PaAsioHostApiRepresentation *asioHostApi, PaUtilAllocationGroup *group, long driverCount )
 
374
static char **GetAsioDriverNames (PaAsioHostApiRepresentation *asioHostApi, PaUtilAllocationGroup *group, long driverCount)
348
375
{
349
376
    char **result = 0;
350
377
    int i;
351
378
 
352
 
    result =(char**)PaUtil_GroupAllocateMemory(
353
 
            group, sizeof(char*) * driverCount );
354
 
    if( !result )
355
 
        goto error;
356
 
 
357
 
    result[0] = (char*)PaUtil_GroupAllocateMemory(
358
 
            group, 32 * driverCount );
359
 
    if( !result[0] )
360
 
        goto error;
361
 
 
362
 
    for( i=0; i<driverCount; ++i )
 
379
    result = (char**) PaUtil_GroupAllocateMemory (
 
380
                 group, sizeof (char*) * driverCount);
 
381
 
 
382
    if (!result)
 
383
        goto error;
 
384
 
 
385
    result[0] = (char*) PaUtil_GroupAllocateMemory (
 
386
                    group, 32 * driverCount);
 
387
 
 
388
    if (!result[0])
 
389
        goto error;
 
390
 
 
391
    for (i=0; i<driverCount; ++i)
363
392
        result[i] = result[0] + (32 * i);
364
393
 
365
 
    asioHostApi->asioDrivers->getDriverNames( result, driverCount );
 
394
    asioHostApi->asioDrivers->getDriverNames (result, driverCount);
366
395
 
367
396
error:
368
397
    return result;
369
398
}
370
399
 
371
400
 
372
 
static PaSampleFormat AsioSampleTypeToPaNativeSampleFormat(ASIOSampleType type)
373
 
{
374
 
    switch (type) {
375
 
        case ASIOSTInt16MSB:
376
 
        case ASIOSTInt16LSB:
377
 
                return paInt16;
378
 
 
379
 
        case ASIOSTFloat32MSB:
380
 
        case ASIOSTFloat32LSB:
381
 
        case ASIOSTFloat64MSB:
382
 
        case ASIOSTFloat64LSB:
383
 
                return paFloat32;
384
 
 
385
 
        case ASIOSTInt32MSB:
386
 
        case ASIOSTInt32LSB:
387
 
        case ASIOSTInt32MSB16:
388
 
        case ASIOSTInt32LSB16:
389
 
        case ASIOSTInt32MSB18:
390
 
        case ASIOSTInt32MSB20:
391
 
        case ASIOSTInt32MSB24:
392
 
        case ASIOSTInt32LSB18:
393
 
        case ASIOSTInt32LSB20:
394
 
        case ASIOSTInt32LSB24:
395
 
                return paInt32;
396
 
 
397
 
        case ASIOSTInt24MSB:
398
 
        case ASIOSTInt24LSB:
399
 
                return paInt24;
400
 
 
401
 
        default:
402
 
                return paCustomFormat;
403
 
    }
404
 
}
405
 
 
406
 
void AsioSampleTypeLOG(ASIOSampleType type)
407
 
{
408
 
    switch (type) {
409
 
        case ASIOSTInt16MSB:  PA_DEBUG(("ASIOSTInt16MSB\n"));  break;
410
 
        case ASIOSTInt16LSB:  PA_DEBUG(("ASIOSTInt16LSB\n"));  break;
411
 
        case ASIOSTFloat32MSB:PA_DEBUG(("ASIOSTFloat32MSB\n"));break;
412
 
        case ASIOSTFloat32LSB:PA_DEBUG(("ASIOSTFloat32LSB\n"));break;
413
 
        case ASIOSTFloat64MSB:PA_DEBUG(("ASIOSTFloat64MSB\n"));break;
414
 
        case ASIOSTFloat64LSB:PA_DEBUG(("ASIOSTFloat64LSB\n"));break;
415
 
        case ASIOSTInt32MSB:  PA_DEBUG(("ASIOSTInt32MSB\n"));  break;
416
 
        case ASIOSTInt32LSB:  PA_DEBUG(("ASIOSTInt32LSB\n"));  break;
417
 
        case ASIOSTInt32MSB16:PA_DEBUG(("ASIOSTInt32MSB16\n"));break;
418
 
        case ASIOSTInt32LSB16:PA_DEBUG(("ASIOSTInt32LSB16\n"));break;
419
 
        case ASIOSTInt32MSB18:PA_DEBUG(("ASIOSTInt32MSB18\n"));break;
420
 
        case ASIOSTInt32MSB20:PA_DEBUG(("ASIOSTInt32MSB20\n"));break;
421
 
        case ASIOSTInt32MSB24:PA_DEBUG(("ASIOSTInt32MSB24\n"));break;
422
 
        case ASIOSTInt32LSB18:PA_DEBUG(("ASIOSTInt32LSB18\n"));break;
423
 
        case ASIOSTInt32LSB20:PA_DEBUG(("ASIOSTInt32LSB20\n"));break;
424
 
        case ASIOSTInt32LSB24:PA_DEBUG(("ASIOSTInt32LSB24\n"));break;
425
 
        case ASIOSTInt24MSB:  PA_DEBUG(("ASIOSTInt24MSB\n"));  break;
426
 
        case ASIOSTInt24LSB:  PA_DEBUG(("ASIOSTInt24LSB\n"));  break;
427
 
        default:              PA_DEBUG(("Custom Format%d\n",type));break;
428
 
 
429
 
    }
430
 
}
431
 
 
432
 
static int BytesPerAsioSample( ASIOSampleType sampleType )
 
401
static PaSampleFormat AsioSampleTypeToPaNativeSampleFormat (ASIOSampleType type)
 
402
{
 
403
    switch (type) {
 
404
        case ASIOSTInt16MSB:
 
405
        case ASIOSTInt16LSB:
 
406
            return paInt16;
 
407
 
 
408
        case ASIOSTFloat32MSB:
 
409
        case ASIOSTFloat32LSB:
 
410
        case ASIOSTFloat64MSB:
 
411
        case ASIOSTFloat64LSB:
 
412
            return paFloat32;
 
413
 
 
414
        case ASIOSTInt32MSB:
 
415
        case ASIOSTInt32LSB:
 
416
        case ASIOSTInt32MSB16:
 
417
        case ASIOSTInt32LSB16:
 
418
        case ASIOSTInt32MSB18:
 
419
        case ASIOSTInt32MSB20:
 
420
        case ASIOSTInt32MSB24:
 
421
        case ASIOSTInt32LSB18:
 
422
        case ASIOSTInt32LSB20:
 
423
        case ASIOSTInt32LSB24:
 
424
            return paInt32;
 
425
 
 
426
        case ASIOSTInt24MSB:
 
427
        case ASIOSTInt24LSB:
 
428
            return paInt24;
 
429
 
 
430
        default:
 
431
            return paCustomFormat;
 
432
    }
 
433
}
 
434
 
 
435
void AsioSampleTypeLOG (ASIOSampleType type)
 
436
{
 
437
    switch (type) {
 
438
        case ASIOSTInt16MSB:
 
439
            PA_DEBUG ( ("ASIOSTInt16MSB\n"));
 
440
            break;
 
441
        case ASIOSTInt16LSB:
 
442
            PA_DEBUG ( ("ASIOSTInt16LSB\n"));
 
443
            break;
 
444
        case ASIOSTFloat32MSB:
 
445
            PA_DEBUG ( ("ASIOSTFloat32MSB\n"));
 
446
            break;
 
447
        case ASIOSTFloat32LSB:
 
448
            PA_DEBUG ( ("ASIOSTFloat32LSB\n"));
 
449
            break;
 
450
        case ASIOSTFloat64MSB:
 
451
            PA_DEBUG ( ("ASIOSTFloat64MSB\n"));
 
452
            break;
 
453
        case ASIOSTFloat64LSB:
 
454
            PA_DEBUG ( ("ASIOSTFloat64LSB\n"));
 
455
            break;
 
456
        case ASIOSTInt32MSB:
 
457
            PA_DEBUG ( ("ASIOSTInt32MSB\n"));
 
458
            break;
 
459
        case ASIOSTInt32LSB:
 
460
            PA_DEBUG ( ("ASIOSTInt32LSB\n"));
 
461
            break;
 
462
        case ASIOSTInt32MSB16:
 
463
            PA_DEBUG ( ("ASIOSTInt32MSB16\n"));
 
464
            break;
 
465
        case ASIOSTInt32LSB16:
 
466
            PA_DEBUG ( ("ASIOSTInt32LSB16\n"));
 
467
            break;
 
468
        case ASIOSTInt32MSB18:
 
469
            PA_DEBUG ( ("ASIOSTInt32MSB18\n"));
 
470
            break;
 
471
        case ASIOSTInt32MSB20:
 
472
            PA_DEBUG ( ("ASIOSTInt32MSB20\n"));
 
473
            break;
 
474
        case ASIOSTInt32MSB24:
 
475
            PA_DEBUG ( ("ASIOSTInt32MSB24\n"));
 
476
            break;
 
477
        case ASIOSTInt32LSB18:
 
478
            PA_DEBUG ( ("ASIOSTInt32LSB18\n"));
 
479
            break;
 
480
        case ASIOSTInt32LSB20:
 
481
            PA_DEBUG ( ("ASIOSTInt32LSB20\n"));
 
482
            break;
 
483
        case ASIOSTInt32LSB24:
 
484
            PA_DEBUG ( ("ASIOSTInt32LSB24\n"));
 
485
            break;
 
486
        case ASIOSTInt24MSB:
 
487
            PA_DEBUG ( ("ASIOSTInt24MSB\n"));
 
488
            break;
 
489
        case ASIOSTInt24LSB:
 
490
            PA_DEBUG ( ("ASIOSTInt24LSB\n"));
 
491
            break;
 
492
        default:
 
493
            PA_DEBUG ( ("Custom Format%d\n",type));
 
494
            break;
 
495
 
 
496
    }
 
497
}
 
498
 
 
499
static int BytesPerAsioSample (ASIOSampleType sampleType)
433
500
{
434
501
    switch (sampleType) {
435
502
        case ASIOSTInt16MSB:
464
531
}
465
532
 
466
533
 
467
 
static void Swap16( void *buffer, long shift, long count )
 
534
static void Swap16 (void *buffer, long shift, long count)
468
535
{
469
 
    unsigned short *p = (unsigned short*)buffer;
 
536
    unsigned short *p = (unsigned short*) buffer;
470
537
    unsigned short temp;
471
538
    (void) shift; /* unused parameter */
472
539
 
473
 
    while( count-- )
474
 
    {
 
540
    while (count--) {
475
541
        temp = *p;
476
 
        *p++ = (unsigned short)((temp<<8) | (temp>>8));
 
542
        *p++ = (unsigned short) ( (temp<<8) | (temp>>8));
477
543
    }
478
544
}
479
545
 
480
 
static void Swap24( void *buffer, long shift, long count )
 
546
static void Swap24 (void *buffer, long shift, long count)
481
547
{
482
 
    unsigned char *p = (unsigned char*)buffer;
 
548
    unsigned char *p = (unsigned char*) buffer;
483
549
    unsigned char temp;
484
550
    (void) shift; /* unused parameter */
485
551
 
486
 
    while( count-- )
487
 
    {
 
552
    while (count--) {
488
553
        temp = *p;
489
 
        *p = *(p+2);
490
 
        *(p+2) = temp;
 
554
        *p = * (p+2);
 
555
        * (p+2) = temp;
491
556
        p += 3;
492
557
    }
493
558
}
494
559
 
495
560
#define PA_SWAP32_( x ) ((x>>24) | ((x>>8)&0xFF00) | ((x<<8)&0xFF0000) | (x<<24));
496
561
 
497
 
static void Swap32( void *buffer, long shift, long count )
 
562
static void Swap32 (void *buffer, long shift, long count)
498
563
{
499
 
    unsigned long *p = (unsigned long*)buffer;
 
564
    unsigned long *p = (unsigned long*) buffer;
500
565
    unsigned long temp;
501
566
    (void) shift; /* unused parameter */
502
567
 
503
 
    while( count-- )
504
 
    {
 
568
    while (count--) {
505
569
        temp = *p;
506
 
        *p++ = PA_SWAP32_( temp);
 
570
        *p++ = PA_SWAP32_ (temp);
507
571
    }
508
572
}
509
573
 
510
 
static void SwapShiftLeft32( void *buffer, long shift, long count )
 
574
static void SwapShiftLeft32 (void *buffer, long shift, long count)
511
575
{
512
 
    unsigned long *p = (unsigned long*)buffer;
 
576
    unsigned long *p = (unsigned long*) buffer;
513
577
    unsigned long temp;
514
578
 
515
 
    while( count-- )
516
 
    {
 
579
    while (count--) {
517
580
        temp = *p;
518
 
        temp = PA_SWAP32_( temp);
 
581
        temp = PA_SWAP32_ (temp);
519
582
        *p++ = temp << shift;
520
583
    }
521
584
}
522
585
 
523
 
static void ShiftRightSwap32( void *buffer, long shift, long count )
 
586
static void ShiftRightSwap32 (void *buffer, long shift, long count)
524
587
{
525
 
    unsigned long *p = (unsigned long*)buffer;
 
588
    unsigned long *p = (unsigned long*) buffer;
526
589
    unsigned long temp;
527
590
 
528
 
    while( count-- )
529
 
    {
 
591
    while (count--) {
530
592
        temp = *p >> shift;
531
 
        *p++ = PA_SWAP32_( temp);
 
593
        *p++ = PA_SWAP32_ (temp);
532
594
    }
533
595
}
534
596
 
535
 
static void ShiftLeft32( void *buffer, long shift, long count )
 
597
static void ShiftLeft32 (void *buffer, long shift, long count)
536
598
{
537
 
    unsigned long *p = (unsigned long*)buffer;
 
599
    unsigned long *p = (unsigned long*) buffer;
538
600
    unsigned long temp;
539
601
 
540
 
    while( count-- )
541
 
    {
 
602
    while (count--) {
542
603
        temp = *p;
543
604
        *p++ = temp << shift;
544
605
    }
545
606
}
546
607
 
547
 
static void ShiftRight32( void *buffer, long shift, long count )
 
608
static void ShiftRight32 (void *buffer, long shift, long count)
548
609
{
549
 
    unsigned long *p = (unsigned long*)buffer;
 
610
    unsigned long *p = (unsigned long*) buffer;
550
611
    unsigned long temp;
551
612
 
552
 
    while( count-- )
553
 
    {
 
613
    while (count--) {
554
614
        temp = *p;
555
615
        *p++ = temp >> shift;
556
616
    }
558
618
 
559
619
#define PA_SWAP_( x, y ) temp=x; x = y; y = temp;
560
620
 
561
 
static void Swap64ConvertFloat64ToFloat32( void *buffer, long shift, long count )
 
621
static void Swap64ConvertFloat64ToFloat32 (void *buffer, long shift, long count)
562
622
{
563
 
    double *in = (double*)buffer;
564
 
    float *out = (float*)buffer;
 
623
    double *in = (double*) buffer;
 
624
    float *out = (float*) buffer;
565
625
    unsigned char *p;
566
626
    unsigned char temp;
567
627
    (void) shift; /* unused parameter */
568
628
 
569
 
    while( count-- )
570
 
    {
571
 
        p = (unsigned char*)in;
572
 
        PA_SWAP_( p[0], p[7] );
573
 
        PA_SWAP_( p[1], p[6] );
574
 
        PA_SWAP_( p[2], p[5] );
575
 
        PA_SWAP_( p[3], p[4] );
 
629
    while (count--) {
 
630
        p = (unsigned char*) in;
 
631
        PA_SWAP_ (p[0], p[7]);
 
632
        PA_SWAP_ (p[1], p[6]);
 
633
        PA_SWAP_ (p[2], p[5]);
 
634
        PA_SWAP_ (p[3], p[4]);
576
635
 
577
636
        *out++ = (float) (*in++);
578
637
    }
579
638
}
580
639
 
581
 
static void ConvertFloat64ToFloat32( void *buffer, long shift, long count )
 
640
static void ConvertFloat64ToFloat32 (void *buffer, long shift, long count)
582
641
{
583
 
    double *in = (double*)buffer;
584
 
    float *out = (float*)buffer;
 
642
    double *in = (double*) buffer;
 
643
    float *out = (float*) buffer;
585
644
    (void) shift; /* unused parameter */
586
645
 
587
 
    while( count-- )
 
646
    while (count--)
588
647
        *out++ = (float) (*in++);
589
648
}
590
649
 
591
 
static void ConvertFloat32ToFloat64Swap64( void *buffer, long shift, long count )
 
650
static void ConvertFloat32ToFloat64Swap64 (void *buffer, long shift, long count)
592
651
{
593
 
    float *in = ((float*)buffer) + (count-1);
594
 
    double *out = ((double*)buffer) + (count-1);
 
652
    float *in = ( (float*) buffer) + (count-1);
 
653
    double *out = ( (double*) buffer) + (count-1);
595
654
    unsigned char *p;
596
655
    unsigned char temp;
597
656
    (void) shift; /* unused parameter */
598
657
 
599
 
    while( count-- )
600
 
    {
 
658
    while (count--) {
601
659
        *out = *in--;
602
660
 
603
 
        p = (unsigned char*)out;
604
 
        PA_SWAP_( p[0], p[7] );
605
 
        PA_SWAP_( p[1], p[6] );
606
 
        PA_SWAP_( p[2], p[5] );
607
 
        PA_SWAP_( p[3], p[4] );
 
661
        p = (unsigned char*) out;
 
662
        PA_SWAP_ (p[0], p[7]);
 
663
        PA_SWAP_ (p[1], p[6]);
 
664
        PA_SWAP_ (p[2], p[5]);
 
665
        PA_SWAP_ (p[3], p[4]);
608
666
 
609
667
        out--;
610
668
    }
611
669
}
612
670
 
613
 
static void ConvertFloat32ToFloat64( void *buffer, long shift, long count )
 
671
static void ConvertFloat32ToFloat64 (void *buffer, long shift, long count)
614
672
{
615
 
    float *in = ((float*)buffer) + (count-1);
616
 
    double *out = ((double*)buffer) + (count-1);
 
673
    float *in = ( (float*) buffer) + (count-1);
 
674
    double *out = ( (double*) buffer) + (count-1);
617
675
    (void) shift; /* unused parameter */
618
676
 
619
 
    while( count-- )
 
677
    while (count--)
620
678
        *out-- = *in--;
621
679
}
622
680
 
630
688
#define PA_LSB_IS_NATIVE_
631
689
#endif
632
690
 
633
 
typedef void PaAsioBufferConverter( void *, long, long );
634
 
 
635
 
static void SelectAsioToPaConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift )
636
 
{
637
 
    *shift = 0;
638
 
    *converter = 0;
639
 
 
640
 
    switch (type) {
641
 
        case ASIOSTInt16MSB:
642
 
            /* dest: paInt16, no conversion necessary, possible byte swap*/
643
 
            #ifdef PA_LSB_IS_NATIVE_
644
 
                *converter = Swap16;
645
 
            #endif
646
 
            break;
647
 
        case ASIOSTInt16LSB:
648
 
            /* dest: paInt16, no conversion necessary, possible byte swap*/
649
 
            #ifdef PA_MSB_IS_NATIVE_
650
 
                *converter = Swap16;
651
 
            #endif
652
 
            break;
653
 
        case ASIOSTFloat32MSB:
654
 
            /* dest: paFloat32, no conversion necessary, possible byte swap*/
655
 
            #ifdef PA_LSB_IS_NATIVE_
656
 
                *converter = Swap32;
657
 
            #endif
658
 
            break;
659
 
        case ASIOSTFloat32LSB:
660
 
            /* dest: paFloat32, no conversion necessary, possible byte swap*/
661
 
            #ifdef PA_MSB_IS_NATIVE_
662
 
                *converter = Swap32;
663
 
            #endif
664
 
            break;
665
 
        case ASIOSTFloat64MSB:
666
 
            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
667
 
            #ifdef PA_LSB_IS_NATIVE_
668
 
                *converter = Swap64ConvertFloat64ToFloat32;
669
 
            #else
670
 
                *converter = ConvertFloat64ToFloat32;
671
 
            #endif
672
 
            break;
673
 
        case ASIOSTFloat64LSB:
674
 
            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
675
 
            #ifdef PA_MSB_IS_NATIVE_
676
 
                *converter = Swap64ConvertFloat64ToFloat32;
677
 
            #else
678
 
                *converter = ConvertFloat64ToFloat32;
679
 
            #endif
680
 
            break;
681
 
        case ASIOSTInt32MSB:
682
 
            /* dest: paInt32, no conversion necessary, possible byte swap */
683
 
            #ifdef PA_LSB_IS_NATIVE_
684
 
                *converter = Swap32;
685
 
            #endif
686
 
            break;
687
 
        case ASIOSTInt32LSB:
688
 
            /* dest: paInt32, no conversion necessary, possible byte swap */
689
 
            #ifdef PA_MSB_IS_NATIVE_
690
 
                *converter = Swap32;
691
 
            #endif
692
 
            break;
693
 
        case ASIOSTInt32MSB16:
694
 
            /* dest: paInt32, 16 bit shift, possible byte swap */
695
 
            #ifdef PA_LSB_IS_NATIVE_
696
 
                *converter = SwapShiftLeft32;
697
 
            #else
698
 
                *converter = ShiftLeft32;
699
 
            #endif
700
 
            *shift = 16;
701
 
            break;
702
 
        case ASIOSTInt32MSB18:
703
 
            /* dest: paInt32, 14 bit shift, possible byte swap */
704
 
            #ifdef PA_LSB_IS_NATIVE_
705
 
                *converter = SwapShiftLeft32;
706
 
            #else
707
 
                *converter = ShiftLeft32;
708
 
            #endif
709
 
            *shift = 14;
710
 
            break;
711
 
        case ASIOSTInt32MSB20:
712
 
            /* dest: paInt32, 12 bit shift, possible byte swap */
713
 
            #ifdef PA_LSB_IS_NATIVE_
714
 
                *converter = SwapShiftLeft32;
715
 
            #else
716
 
                *converter = ShiftLeft32;
717
 
            #endif
718
 
            *shift = 12;
719
 
            break;
720
 
        case ASIOSTInt32MSB24:
721
 
            /* dest: paInt32, 8 bit shift, possible byte swap */
722
 
            #ifdef PA_LSB_IS_NATIVE_
723
 
                *converter = SwapShiftLeft32;
724
 
            #else
725
 
                *converter = ShiftLeft32;
726
 
            #endif
727
 
            *shift = 8;
728
 
            break;
729
 
        case ASIOSTInt32LSB16:
730
 
            /* dest: paInt32, 16 bit shift, possible byte swap */
731
 
            #ifdef PA_MSB_IS_NATIVE_
732
 
                *converter = SwapShiftLeft32;
733
 
            #else
734
 
                *converter = ShiftLeft32;
735
 
            #endif
736
 
            *shift = 16;
737
 
            break;
738
 
        case ASIOSTInt32LSB18:
739
 
            /* dest: paInt32, 14 bit shift, possible byte swap */
740
 
            #ifdef PA_MSB_IS_NATIVE_
741
 
                *converter = SwapShiftLeft32;
742
 
            #else
743
 
                *converter = ShiftLeft32;
744
 
            #endif
745
 
            *shift = 14;
746
 
            break;
747
 
        case ASIOSTInt32LSB20:
748
 
            /* dest: paInt32, 12 bit shift, possible byte swap */
749
 
            #ifdef PA_MSB_IS_NATIVE_
750
 
                *converter = SwapShiftLeft32;
751
 
            #else
752
 
                *converter = ShiftLeft32;
753
 
            #endif
754
 
            *shift = 12;
755
 
            break;
756
 
        case ASIOSTInt32LSB24:
757
 
            /* dest: paInt32, 8 bit shift, possible byte swap */
758
 
            #ifdef PA_MSB_IS_NATIVE_
759
 
                *converter = SwapShiftLeft32;
760
 
            #else
761
 
                *converter = ShiftLeft32;
762
 
            #endif
763
 
            *shift = 8;
764
 
            break;
765
 
        case ASIOSTInt24MSB:
766
 
            /* dest: paInt24, no conversion necessary, possible byte swap */
767
 
            #ifdef PA_LSB_IS_NATIVE_
768
 
                *converter = Swap24;
769
 
            #endif
770
 
            break;
771
 
        case ASIOSTInt24LSB:
772
 
            /* dest: paInt24, no conversion necessary, possible byte swap */
773
 
            #ifdef PA_MSB_IS_NATIVE_
774
 
                *converter = Swap24;
775
 
            #endif
776
 
            break;
777
 
    }
778
 
}
779
 
 
780
 
 
781
 
static void SelectPaToAsioConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift )
782
 
{
783
 
    *shift = 0;
784
 
    *converter = 0;
785
 
 
786
 
    switch (type) {
787
 
        case ASIOSTInt16MSB:
788
 
            /* src: paInt16, no conversion necessary, possible byte swap*/
789
 
            #ifdef PA_LSB_IS_NATIVE_
790
 
                *converter = Swap16;
791
 
            #endif
792
 
            break;
793
 
        case ASIOSTInt16LSB:
794
 
            /* src: paInt16, no conversion necessary, possible byte swap*/
795
 
            #ifdef PA_MSB_IS_NATIVE_
796
 
                *converter = Swap16;
797
 
            #endif
798
 
            break;
799
 
        case ASIOSTFloat32MSB:
800
 
            /* src: paFloat32, no conversion necessary, possible byte swap*/
801
 
            #ifdef PA_LSB_IS_NATIVE_
802
 
                *converter = Swap32;
803
 
            #endif
804
 
            break;
805
 
        case ASIOSTFloat32LSB:
806
 
            /* src: paFloat32, no conversion necessary, possible byte swap*/
807
 
            #ifdef PA_MSB_IS_NATIVE_
808
 
                *converter = Swap32;
809
 
            #endif
810
 
            break;
811
 
        case ASIOSTFloat64MSB:
812
 
            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
813
 
            #ifdef PA_LSB_IS_NATIVE_
814
 
                *converter = ConvertFloat32ToFloat64Swap64;
815
 
            #else
816
 
                *converter = ConvertFloat32ToFloat64;
817
 
            #endif
818
 
            break;
819
 
        case ASIOSTFloat64LSB:
820
 
            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
821
 
            #ifdef PA_MSB_IS_NATIVE_
822
 
                *converter = ConvertFloat32ToFloat64Swap64;
823
 
            #else
824
 
                *converter = ConvertFloat32ToFloat64;
825
 
            #endif
826
 
            break;
827
 
        case ASIOSTInt32MSB:
828
 
            /* src: paInt32, no conversion necessary, possible byte swap */
829
 
            #ifdef PA_LSB_IS_NATIVE_
830
 
                *converter = Swap32;
831
 
            #endif
832
 
            break;
833
 
        case ASIOSTInt32LSB:
834
 
            /* src: paInt32, no conversion necessary, possible byte swap */
835
 
            #ifdef PA_MSB_IS_NATIVE_
836
 
                *converter = Swap32;
837
 
            #endif
838
 
            break;
839
 
        case ASIOSTInt32MSB16:
840
 
            /* src: paInt32, 16 bit shift, possible byte swap */
841
 
            #ifdef PA_LSB_IS_NATIVE_
842
 
                *converter = ShiftRightSwap32;
843
 
            #else
844
 
                *converter = ShiftRight32;
845
 
            #endif
846
 
            *shift = 16;
847
 
            break;
848
 
        case ASIOSTInt32MSB18:
849
 
            /* src: paInt32, 14 bit shift, possible byte swap */
850
 
            #ifdef PA_LSB_IS_NATIVE_
851
 
                *converter = ShiftRightSwap32;
852
 
            #else
853
 
                *converter = ShiftRight32;
854
 
            #endif
855
 
            *shift = 14;
856
 
            break;
857
 
        case ASIOSTInt32MSB20:
858
 
            /* src: paInt32, 12 bit shift, possible byte swap */
859
 
            #ifdef PA_LSB_IS_NATIVE_
860
 
                *converter = ShiftRightSwap32;
861
 
            #else
862
 
                *converter = ShiftRight32;
863
 
            #endif
864
 
            *shift = 12;
865
 
            break;
866
 
        case ASIOSTInt32MSB24:
867
 
            /* src: paInt32, 8 bit shift, possible byte swap */
868
 
            #ifdef PA_LSB_IS_NATIVE_
869
 
                *converter = ShiftRightSwap32;
870
 
            #else
871
 
                *converter = ShiftRight32;
872
 
            #endif
873
 
            *shift = 8;
874
 
            break;
875
 
        case ASIOSTInt32LSB16:
876
 
            /* src: paInt32, 16 bit shift, possible byte swap */
877
 
            #ifdef PA_MSB_IS_NATIVE_
878
 
                *converter = ShiftRightSwap32;
879
 
            #else
880
 
                *converter = ShiftRight32;
881
 
            #endif
882
 
            *shift = 16;
883
 
            break;
884
 
        case ASIOSTInt32LSB18:
885
 
            /* src: paInt32, 14 bit shift, possible byte swap */
886
 
            #ifdef PA_MSB_IS_NATIVE_
887
 
                *converter = ShiftRightSwap32;
888
 
            #else
889
 
                *converter = ShiftRight32;
890
 
            #endif
891
 
            *shift = 14;
892
 
            break;
893
 
        case ASIOSTInt32LSB20:
894
 
            /* src: paInt32, 12 bit shift, possible byte swap */
895
 
            #ifdef PA_MSB_IS_NATIVE_
896
 
                *converter = ShiftRightSwap32;
897
 
            #else
898
 
                *converter = ShiftRight32;
899
 
            #endif
900
 
            *shift = 12;
901
 
            break;
902
 
        case ASIOSTInt32LSB24:
903
 
            /* src: paInt32, 8 bit shift, possible byte swap */
904
 
            #ifdef PA_MSB_IS_NATIVE_
905
 
                *converter = ShiftRightSwap32;
906
 
            #else
907
 
                *converter = ShiftRight32;
908
 
            #endif
909
 
            *shift = 8;
910
 
            break;
911
 
        case ASIOSTInt24MSB:
912
 
            /* src: paInt24, no conversion necessary, possible byte swap */
913
 
            #ifdef PA_LSB_IS_NATIVE_
914
 
                *converter = Swap24;
915
 
            #endif
916
 
            break;
917
 
        case ASIOSTInt24LSB:
918
 
            /* src: paInt24, no conversion necessary, possible byte swap */
919
 
            #ifdef PA_MSB_IS_NATIVE_
920
 
                *converter = Swap24;
921
 
            #endif
922
 
            break;
923
 
    }
924
 
}
925
 
 
926
 
 
927
 
typedef struct PaAsioDeviceInfo
928
 
{
 
691
typedef void PaAsioBufferConverter (void *, long, long);
 
692
 
 
693
static void SelectAsioToPaConverter (ASIOSampleType type, PaAsioBufferConverter **converter, long *shift)
 
694
{
 
695
    *shift = 0;
 
696
    *converter = 0;
 
697
 
 
698
    switch (type) {
 
699
        case ASIOSTInt16MSB:
 
700
            /* dest: paInt16, no conversion necessary, possible byte swap*/
 
701
#ifdef PA_LSB_IS_NATIVE_
 
702
            *converter = Swap16;
 
703
#endif
 
704
            break;
 
705
        case ASIOSTInt16LSB:
 
706
            /* dest: paInt16, no conversion necessary, possible byte swap*/
 
707
#ifdef PA_MSB_IS_NATIVE_
 
708
            *converter = Swap16;
 
709
#endif
 
710
            break;
 
711
        case ASIOSTFloat32MSB:
 
712
            /* dest: paFloat32, no conversion necessary, possible byte swap*/
 
713
#ifdef PA_LSB_IS_NATIVE_
 
714
            *converter = Swap32;
 
715
#endif
 
716
            break;
 
717
        case ASIOSTFloat32LSB:
 
718
            /* dest: paFloat32, no conversion necessary, possible byte swap*/
 
719
#ifdef PA_MSB_IS_NATIVE_
 
720
            *converter = Swap32;
 
721
#endif
 
722
            break;
 
723
        case ASIOSTFloat64MSB:
 
724
            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
 
725
#ifdef PA_LSB_IS_NATIVE_
 
726
            *converter = Swap64ConvertFloat64ToFloat32;
 
727
#else
 
728
            *converter = ConvertFloat64ToFloat32;
 
729
#endif
 
730
            break;
 
731
        case ASIOSTFloat64LSB:
 
732
            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
 
733
#ifdef PA_MSB_IS_NATIVE_
 
734
            *converter = Swap64ConvertFloat64ToFloat32;
 
735
#else
 
736
            *converter = ConvertFloat64ToFloat32;
 
737
#endif
 
738
            break;
 
739
        case ASIOSTInt32MSB:
 
740
            /* dest: paInt32, no conversion necessary, possible byte swap */
 
741
#ifdef PA_LSB_IS_NATIVE_
 
742
            *converter = Swap32;
 
743
#endif
 
744
            break;
 
745
        case ASIOSTInt32LSB:
 
746
            /* dest: paInt32, no conversion necessary, possible byte swap */
 
747
#ifdef PA_MSB_IS_NATIVE_
 
748
            *converter = Swap32;
 
749
#endif
 
750
            break;
 
751
        case ASIOSTInt32MSB16:
 
752
            /* dest: paInt32, 16 bit shift, possible byte swap */
 
753
#ifdef PA_LSB_IS_NATIVE_
 
754
            *converter = SwapShiftLeft32;
 
755
#else
 
756
            *converter = ShiftLeft32;
 
757
#endif
 
758
            *shift = 16;
 
759
            break;
 
760
        case ASIOSTInt32MSB18:
 
761
            /* dest: paInt32, 14 bit shift, possible byte swap */
 
762
#ifdef PA_LSB_IS_NATIVE_
 
763
            *converter = SwapShiftLeft32;
 
764
#else
 
765
            *converter = ShiftLeft32;
 
766
#endif
 
767
            *shift = 14;
 
768
            break;
 
769
        case ASIOSTInt32MSB20:
 
770
            /* dest: paInt32, 12 bit shift, possible byte swap */
 
771
#ifdef PA_LSB_IS_NATIVE_
 
772
            *converter = SwapShiftLeft32;
 
773
#else
 
774
            *converter = ShiftLeft32;
 
775
#endif
 
776
            *shift = 12;
 
777
            break;
 
778
        case ASIOSTInt32MSB24:
 
779
            /* dest: paInt32, 8 bit shift, possible byte swap */
 
780
#ifdef PA_LSB_IS_NATIVE_
 
781
            *converter = SwapShiftLeft32;
 
782
#else
 
783
            *converter = ShiftLeft32;
 
784
#endif
 
785
            *shift = 8;
 
786
            break;
 
787
        case ASIOSTInt32LSB16:
 
788
            /* dest: paInt32, 16 bit shift, possible byte swap */
 
789
#ifdef PA_MSB_IS_NATIVE_
 
790
            *converter = SwapShiftLeft32;
 
791
#else
 
792
            *converter = ShiftLeft32;
 
793
#endif
 
794
            *shift = 16;
 
795
            break;
 
796
        case ASIOSTInt32LSB18:
 
797
            /* dest: paInt32, 14 bit shift, possible byte swap */
 
798
#ifdef PA_MSB_IS_NATIVE_
 
799
            *converter = SwapShiftLeft32;
 
800
#else
 
801
            *converter = ShiftLeft32;
 
802
#endif
 
803
            *shift = 14;
 
804
            break;
 
805
        case ASIOSTInt32LSB20:
 
806
            /* dest: paInt32, 12 bit shift, possible byte swap */
 
807
#ifdef PA_MSB_IS_NATIVE_
 
808
            *converter = SwapShiftLeft32;
 
809
#else
 
810
            *converter = ShiftLeft32;
 
811
#endif
 
812
            *shift = 12;
 
813
            break;
 
814
        case ASIOSTInt32LSB24:
 
815
            /* dest: paInt32, 8 bit shift, possible byte swap */
 
816
#ifdef PA_MSB_IS_NATIVE_
 
817
            *converter = SwapShiftLeft32;
 
818
#else
 
819
            *converter = ShiftLeft32;
 
820
#endif
 
821
            *shift = 8;
 
822
            break;
 
823
        case ASIOSTInt24MSB:
 
824
            /* dest: paInt24, no conversion necessary, possible byte swap */
 
825
#ifdef PA_LSB_IS_NATIVE_
 
826
            *converter = Swap24;
 
827
#endif
 
828
            break;
 
829
        case ASIOSTInt24LSB:
 
830
            /* dest: paInt24, no conversion necessary, possible byte swap */
 
831
#ifdef PA_MSB_IS_NATIVE_
 
832
            *converter = Swap24;
 
833
#endif
 
834
            break;
 
835
    }
 
836
}
 
837
 
 
838
 
 
839
static void SelectPaToAsioConverter (ASIOSampleType type, PaAsioBufferConverter **converter, long *shift)
 
840
{
 
841
    *shift = 0;
 
842
    *converter = 0;
 
843
 
 
844
    switch (type) {
 
845
        case ASIOSTInt16MSB:
 
846
            /* src: paInt16, no conversion necessary, possible byte swap*/
 
847
#ifdef PA_LSB_IS_NATIVE_
 
848
            *converter = Swap16;
 
849
#endif
 
850
            break;
 
851
        case ASIOSTInt16LSB:
 
852
            /* src: paInt16, no conversion necessary, possible byte swap*/
 
853
#ifdef PA_MSB_IS_NATIVE_
 
854
            *converter = Swap16;
 
855
#endif
 
856
            break;
 
857
        case ASIOSTFloat32MSB:
 
858
            /* src: paFloat32, no conversion necessary, possible byte swap*/
 
859
#ifdef PA_LSB_IS_NATIVE_
 
860
            *converter = Swap32;
 
861
#endif
 
862
            break;
 
863
        case ASIOSTFloat32LSB:
 
864
            /* src: paFloat32, no conversion necessary, possible byte swap*/
 
865
#ifdef PA_MSB_IS_NATIVE_
 
866
            *converter = Swap32;
 
867
#endif
 
868
            break;
 
869
        case ASIOSTFloat64MSB:
 
870
            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
 
871
#ifdef PA_LSB_IS_NATIVE_
 
872
            *converter = ConvertFloat32ToFloat64Swap64;
 
873
#else
 
874
            *converter = ConvertFloat32ToFloat64;
 
875
#endif
 
876
            break;
 
877
        case ASIOSTFloat64LSB:
 
878
            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
 
879
#ifdef PA_MSB_IS_NATIVE_
 
880
            *converter = ConvertFloat32ToFloat64Swap64;
 
881
#else
 
882
            *converter = ConvertFloat32ToFloat64;
 
883
#endif
 
884
            break;
 
885
        case ASIOSTInt32MSB:
 
886
            /* src: paInt32, no conversion necessary, possible byte swap */
 
887
#ifdef PA_LSB_IS_NATIVE_
 
888
            *converter = Swap32;
 
889
#endif
 
890
            break;
 
891
        case ASIOSTInt32LSB:
 
892
            /* src: paInt32, no conversion necessary, possible byte swap */
 
893
#ifdef PA_MSB_IS_NATIVE_
 
894
            *converter = Swap32;
 
895
#endif
 
896
            break;
 
897
        case ASIOSTInt32MSB16:
 
898
            /* src: paInt32, 16 bit shift, possible byte swap */
 
899
#ifdef PA_LSB_IS_NATIVE_
 
900
            *converter = ShiftRightSwap32;
 
901
#else
 
902
            *converter = ShiftRight32;
 
903
#endif
 
904
            *shift = 16;
 
905
            break;
 
906
        case ASIOSTInt32MSB18:
 
907
            /* src: paInt32, 14 bit shift, possible byte swap */
 
908
#ifdef PA_LSB_IS_NATIVE_
 
909
            *converter = ShiftRightSwap32;
 
910
#else
 
911
            *converter = ShiftRight32;
 
912
#endif
 
913
            *shift = 14;
 
914
            break;
 
915
        case ASIOSTInt32MSB20:
 
916
            /* src: paInt32, 12 bit shift, possible byte swap */
 
917
#ifdef PA_LSB_IS_NATIVE_
 
918
            *converter = ShiftRightSwap32;
 
919
#else
 
920
            *converter = ShiftRight32;
 
921
#endif
 
922
            *shift = 12;
 
923
            break;
 
924
        case ASIOSTInt32MSB24:
 
925
            /* src: paInt32, 8 bit shift, possible byte swap */
 
926
#ifdef PA_LSB_IS_NATIVE_
 
927
            *converter = ShiftRightSwap32;
 
928
#else
 
929
            *converter = ShiftRight32;
 
930
#endif
 
931
            *shift = 8;
 
932
            break;
 
933
        case ASIOSTInt32LSB16:
 
934
            /* src: paInt32, 16 bit shift, possible byte swap */
 
935
#ifdef PA_MSB_IS_NATIVE_
 
936
            *converter = ShiftRightSwap32;
 
937
#else
 
938
            *converter = ShiftRight32;
 
939
#endif
 
940
            *shift = 16;
 
941
            break;
 
942
        case ASIOSTInt32LSB18:
 
943
            /* src: paInt32, 14 bit shift, possible byte swap */
 
944
#ifdef PA_MSB_IS_NATIVE_
 
945
            *converter = ShiftRightSwap32;
 
946
#else
 
947
            *converter = ShiftRight32;
 
948
#endif
 
949
            *shift = 14;
 
950
            break;
 
951
        case ASIOSTInt32LSB20:
 
952
            /* src: paInt32, 12 bit shift, possible byte swap */
 
953
#ifdef PA_MSB_IS_NATIVE_
 
954
            *converter = ShiftRightSwap32;
 
955
#else
 
956
            *converter = ShiftRight32;
 
957
#endif
 
958
            *shift = 12;
 
959
            break;
 
960
        case ASIOSTInt32LSB24:
 
961
            /* src: paInt32, 8 bit shift, possible byte swap */
 
962
#ifdef PA_MSB_IS_NATIVE_
 
963
            *converter = ShiftRightSwap32;
 
964
#else
 
965
            *converter = ShiftRight32;
 
966
#endif
 
967
            *shift = 8;
 
968
            break;
 
969
        case ASIOSTInt24MSB:
 
970
            /* src: paInt24, no conversion necessary, possible byte swap */
 
971
#ifdef PA_LSB_IS_NATIVE_
 
972
            *converter = Swap24;
 
973
#endif
 
974
            break;
 
975
        case ASIOSTInt24LSB:
 
976
            /* src: paInt24, no conversion necessary, possible byte swap */
 
977
#ifdef PA_MSB_IS_NATIVE_
 
978
            *converter = Swap24;
 
979
#endif
 
980
            break;
 
981
    }
 
982
}
 
983
 
 
984
 
 
985
typedef struct PaAsioDeviceInfo {
929
986
    PaDeviceInfo commonDeviceInfo;
930
987
    long minBufferSize;
931
988
    long maxBufferSize;
937
994
PaAsioDeviceInfo;
938
995
 
939
996
 
940
 
PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device,
941
 
        long *minLatency, long *maxLatency, long *preferredLatency, long *granularity )
 
997
PaError PaAsio_GetAvailableLatencyValues (PaDeviceIndex device,
 
998
        long *minLatency, long *maxLatency, long *preferredLatency, long *granularity)
942
999
{
943
1000
    PaError result;
944
1001
    PaUtilHostApiRepresentation *hostApi;
945
1002
    PaDeviceIndex hostApiDevice;
946
1003
 
947
 
    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
948
 
 
949
 
    if( result == paNoError )
950
 
    {
951
 
        result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
952
 
 
953
 
        if( result == paNoError )
954
 
        {
 
1004
    result = PaUtil_GetHostApiRepresentation (&hostApi, paASIO);
 
1005
 
 
1006
    if (result == paNoError) {
 
1007
        result = PaUtil_DeviceIndexToHostApiDeviceIndex (&hostApiDevice, device, hostApi);
 
1008
 
 
1009
        if (result == paNoError) {
955
1010
            PaAsioDeviceInfo *asioDeviceInfo =
956
 
                    (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
 
1011
                (PaAsioDeviceInfo*) hostApi->deviceInfos[hostApiDevice];
957
1012
 
958
1013
            *minLatency = asioDeviceInfo->minBufferSize;
959
1014
            *maxLatency = asioDeviceInfo->maxBufferSize;
968
1023
/* Unload whatever we loaded in LoadAsioDriver().
969
1024
   Also balance the call to CoInitialize(0).
970
1025
*/
971
 
static void UnloadAsioDriver( void )
 
1026
static void UnloadAsioDriver (void)
972
1027
{
973
 
        ASIOExit();
974
 
        CoUninitialize();
 
1028
    ASIOExit();
 
1029
    CoUninitialize();
975
1030
}
976
1031
 
977
1032
/*
980
1035
    and must be closed by the called by calling UnloadAsioDriver() - if an error
981
1036
    is returned the driver will already be unloaded.
982
1037
*/
983
 
static PaError LoadAsioDriver( PaAsioHostApiRepresentation *asioHostApi, const char *driverName,
984
 
        PaAsioDriverInfo *driverInfo, void *systemSpecific )
 
1038
static PaError LoadAsioDriver (PaAsioHostApiRepresentation *asioHostApi, const char *driverName,
 
1039
                               PaAsioDriverInfo *driverInfo, void *systemSpecific)
985
1040
{
986
1041
    PaError result = paNoError;
987
1042
    ASIOError asioError;
988
1043
    int asioIsInitialized = 0;
989
1044
 
990
 
    /* 
991
 
        ASIO uses CoCreateInstance() to load a driver. That requires that
992
 
        CoInitialize(0) be called for every thread that loads a driver.
993
 
        It is OK to call CoInitialize(0) multiple times form one thread as long
994
 
        as it is balanced by a call to CoUninitialize(). See UnloadAsioDriver().
 
1045
    /*
 
1046
    ASIO uses CoCreateInstance() to load a driver. That requires that
 
1047
    CoInitialize(0) be called for every thread that loads a driver.
 
1048
    It is OK to call CoInitialize(0) multiple times form one thread as long
 
1049
    as it is balanced by a call to CoUninitialize(). See UnloadAsioDriver().
995
1050
 
996
 
        The V18 version called CoInitialize() starting on 2/19/02.
997
 
        That was removed from PA V19 for unknown reasons.
998
 
        Phil Burk added it back on 6/27/08 so that JSyn would work.
 
1051
    The V18 version called CoInitialize() starting on 2/19/02.
 
1052
    That was removed from PA V19 for unknown reasons.
 
1053
    Phil Burk added it back on 6/27/08 so that JSyn would work.
999
1054
    */
1000
 
        CoInitialize( 0 );
 
1055
    CoInitialize (0);
1001
1056
 
1002
 
    if( !asioHostApi->asioDrivers->loadDriver( const_cast<char*>(driverName) ) )
1003
 
    {
1004
 
                /* If this returns an error then it might be because CoInitialize(0) was removed.
1005
 
                  It should be called right before this.
1006
 
            */
 
1057
    if (!asioHostApi->asioDrivers->loadDriver (const_cast<char*> (driverName))) {
 
1058
        /* If this returns an error then it might be because CoInitialize(0) was removed.
 
1059
          It should be called right before this.
 
1060
        */
1007
1061
        result = paUnanticipatedHostError;
1008
 
        PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" );
 
1062
        PA_ASIO_SET_LAST_HOST_ERROR (0, "Failed to load ASIO driver");
1009
1063
        goto error;
1010
1064
    }
1011
1065
 
1012
 
    memset( &driverInfo->asioDriverInfo, 0, sizeof(ASIODriverInfo) );
 
1066
    memset (&driverInfo->asioDriverInfo, 0, sizeof (ASIODriverInfo));
1013
1067
    driverInfo->asioDriverInfo.asioVersion = 2;
1014
1068
    driverInfo->asioDriverInfo.sysRef = systemSpecific;
1015
 
    if( (asioError = ASIOInit( &driverInfo->asioDriverInfo )) != ASE_OK )
1016
 
    {
 
1069
 
 
1070
    if ( (asioError = ASIOInit (&driverInfo->asioDriverInfo)) != ASE_OK) {
1017
1071
        result = paUnanticipatedHostError;
1018
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
1072
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
1019
1073
        goto error;
1020
 
    }
1021
 
    else
1022
 
    {
 
1074
    } else {
1023
1075
        asioIsInitialized = 1;
1024
1076
    }
1025
1077
 
1026
 
    if( (asioError = ASIOGetChannels(&driverInfo->inputChannelCount,
1027
 
            &driverInfo->outputChannelCount)) != ASE_OK )
1028
 
    {
1029
 
        result = paUnanticipatedHostError;
1030
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
1031
 
        goto error;
1032
 
    }
1033
 
 
1034
 
    if( (asioError = ASIOGetBufferSize(&driverInfo->bufferMinSize,
1035
 
            &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize,
1036
 
            &driverInfo->bufferGranularity)) != ASE_OK )
1037
 
    {
1038
 
        result = paUnanticipatedHostError;
1039
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
1040
 
        goto error;
1041
 
    }
1042
 
 
1043
 
    if( ASIOOutputReady() == ASE_OK )
 
1078
    if ( (asioError = ASIOGetChannels (&driverInfo->inputChannelCount,
 
1079
                                       &driverInfo->outputChannelCount)) != ASE_OK) {
 
1080
        result = paUnanticipatedHostError;
 
1081
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
 
1082
        goto error;
 
1083
    }
 
1084
 
 
1085
    if ( (asioError = ASIOGetBufferSize (&driverInfo->bufferMinSize,
 
1086
                                         &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize,
 
1087
                                         &driverInfo->bufferGranularity)) != ASE_OK) {
 
1088
        result = paUnanticipatedHostError;
 
1089
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
 
1090
        goto error;
 
1091
    }
 
1092
 
 
1093
    if (ASIOOutputReady() == ASE_OK)
1044
1094
        driverInfo->postOutput = true;
1045
1095
    else
1046
1096
        driverInfo->postOutput = false;
1048
1098
    return result;
1049
1099
 
1050
1100
error:
1051
 
    if( asioIsInitialized )
1052
 
        {
1053
 
                ASIOExit();
1054
 
        }
1055
 
        CoUninitialize();
 
1101
 
 
1102
    if (asioIsInitialized) {
 
1103
        ASIOExit();
 
1104
    }
 
1105
 
 
1106
    CoUninitialize();
1056
1107
    return result;
1057
1108
}
1058
1109
 
1059
1110
 
1060
1111
#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_     13   /* must be the same number of elements as in the array below */
1061
1112
static ASIOSampleRate defaultSampleRateSearchOrder_[]
1062
 
     = {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0,
1063
 
        192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
 
1113
= {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0,
 
1114
   192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0
 
1115
  };
1064
1116
 
1065
1117
 
1066
1118
/* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */
1067
 
typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID);
 
1119
typedef BOOL (WINAPI *IsDebuggerPresentPtr) (VOID);
1068
1120
IsDebuggerPresentPtr IsDebuggerPresent_ = 0;
1069
1121
//FARPROC IsDebuggerPresent_ = 0; // this is the current way to do it apparently according to davidv
1070
1122
 
1071
 
PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
 
1123
PaError PaAsio_Initialize (PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex)
1072
1124
{
1073
1125
    PaError result = paNoError;
1074
1126
    int i, driverCount;
1077
1129
    char **names;
1078
1130
    PaAsioDriverInfo paAsioDriverInfo;
1079
1131
 
1080
 
    asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) );
1081
 
    if( !asioHostApi )
1082
 
    {
 
1132
    asioHostApi = (PaAsioHostApiRepresentation*) PaUtil_AllocateMemory (sizeof (PaAsioHostApiRepresentation));
 
1133
 
 
1134
    if (!asioHostApi) {
1083
1135
        result = paInsufficientMemory;
1084
1136
        goto error;
1085
1137
    }
1087
1139
    asioHostApi->asioDrivers = 0; /* avoid surprises in our error handler below */
1088
1140
 
1089
1141
    asioHostApi->allocations = PaUtil_CreateAllocationGroup();
1090
 
    if( !asioHostApi->allocations )
1091
 
    {
 
1142
 
 
1143
    if (!asioHostApi->allocations) {
1092
1144
        result = paInsufficientMemory;
1093
1145
        goto error;
1094
1146
    }
1095
1147
 
1096
1148
    /* Allocate the AsioDrivers() driver list (class from ASIO SDK) */
1097
 
    try
1098
 
    {
 
1149
    try {
1099
1150
        asioHostApi->asioDrivers = new AsioDrivers(); /* calls CoInitialize(0) */
1100
 
    } 
1101
 
    catch (std::bad_alloc)
1102
 
    {
 
1151
    } catch (std::bad_alloc) {
1103
1152
        asioHostApi->asioDrivers = 0;
1104
1153
    }
 
1154
 
1105
1155
    /* some implementations of new (ie MSVC, see http://support.microsoft.com/?kbid=167733)
1106
1156
       don't throw std::bad_alloc, so we also explicitly test for a null return. */
1107
 
    if( asioHostApi->asioDrivers == 0 )
1108
 
    {
 
1157
    if (asioHostApi->asioDrivers == 0) {
1109
1158
        result = paInsufficientMemory;
1110
1159
        goto error;
1111
1160
    }
1122
1171
    (*hostApi)->info.name = "ASIO";
1123
1172
    (*hostApi)->info.deviceCount = 0;
1124
1173
 
1125
 
    #ifdef WINDOWS
1126
 
        /* use desktop window as system specific ptr */
1127
 
        asioHostApi->systemSpecific = GetDesktopWindow();
1128
 
    #endif
 
1174
#ifdef WINDOWS
 
1175
    /* use desktop window as system specific ptr */
 
1176
    asioHostApi->systemSpecific = GetDesktopWindow();
 
1177
#endif
1129
1178
 
1130
1179
    /* driverCount is the number of installed drivers - not necessarily
1131
1180
        the number of installed physical devices. */
1132
 
    #if MAC
1133
 
        driverCount = asioHostApi->asioDrivers->getNumFragments();
1134
 
    #elif WINDOWS
1135
 
        driverCount = asioHostApi->asioDrivers->asioGetNumDev();
1136
 
    #endif
1137
 
 
1138
 
    if( driverCount > 0 )
1139
 
    {
1140
 
        names = GetAsioDriverNames( asioHostApi, asioHostApi->allocations, driverCount );
1141
 
        if( !names )
1142
 
        {
 
1181
#if MAC
 
1182
    driverCount = asioHostApi->asioDrivers->getNumFragments();
 
1183
#elif WINDOWS
 
1184
    driverCount = asioHostApi->asioDrivers->asioGetNumDev();
 
1185
#endif
 
1186
 
 
1187
    if (driverCount > 0) {
 
1188
        names = GetAsioDriverNames (asioHostApi, asioHostApi->allocations, driverCount);
 
1189
 
 
1190
        if (!names) {
1143
1191
            result = paInsufficientMemory;
1144
1192
            goto error;
1145
1193
        }
1147
1195
 
1148
1196
        /* allocate enough space for all drivers, even if some aren't installed */
1149
1197
 
1150
 
        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
1151
 
                asioHostApi->allocations, sizeof(PaDeviceInfo*) * driverCount );
1152
 
        if( !(*hostApi)->deviceInfos )
1153
 
        {
 
1198
        (*hostApi)->deviceInfos = (PaDeviceInfo**) PaUtil_GroupAllocateMemory (
 
1199
                                      asioHostApi->allocations, sizeof (PaDeviceInfo*) * driverCount);
 
1200
 
 
1201
        if (! (*hostApi)->deviceInfos) {
1154
1202
            result = paInsufficientMemory;
1155
1203
            goto error;
1156
1204
        }
1157
1205
 
1158
1206
        /* allocate all device info structs in a contiguous block */
1159
 
        deviceInfoArray = (PaAsioDeviceInfo*)PaUtil_GroupAllocateMemory(
1160
 
                asioHostApi->allocations, sizeof(PaAsioDeviceInfo) * driverCount );
1161
 
        if( !deviceInfoArray )
1162
 
        {
 
1207
        deviceInfoArray = (PaAsioDeviceInfo*) PaUtil_GroupAllocateMemory (
 
1208
                              asioHostApi->allocations, sizeof (PaAsioDeviceInfo) * driverCount);
 
1209
 
 
1210
        if (!deviceInfoArray) {
1163
1211
            result = paInsufficientMemory;
1164
1212
            goto error;
1165
1213
        }
1166
1214
 
1167
 
        IsDebuggerPresent_ = GetProcAddress( LoadLibrary( "Kernel32.dll" ), "IsDebuggerPresent" );
1168
 
 
1169
 
        for( i=0; i < driverCount; ++i )
1170
 
        {
1171
 
 
1172
 
            PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i]));
 
1215
        IsDebuggerPresent_ = GetProcAddress (LoadLibrary ("Kernel32.dll"), "IsDebuggerPresent");
 
1216
 
 
1217
        for (i=0; i < driverCount; ++i) {
 
1218
 
 
1219
            PA_DEBUG ( ("ASIO names[%d]:%s\n",i,names[i]));
1173
1220
 
1174
1221
            // Since portaudio opens ALL ASIO drivers, and no one else does that,
1175
1222
            // we face fact that some drivers were not meant for it, drivers which act
1176
1223
            // like shells on top of REAL drivers, for instance.
1177
1224
            // so we get duplicate handles, locks and other problems.
1178
 
            // so lets NOT try to load any such wrappers. 
 
1225
            // so lets NOT try to load any such wrappers.
1179
1226
            // The ones i [davidv] know of so far are:
1180
1227
 
1181
 
            if (   strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0
1182
 
                || strcmp (names[i],"ASIO Multimedia Driver")          == 0
1183
 
                || strncmp(names[i],"Premiere",8)                      == 0   //"Premiere Elements Windows Sound 1.0"
1184
 
                || strncmp(names[i],"Adobe",5)                         == 0   //"Adobe Default Windows Sound 1.5"
1185
 
               )
1186
 
            {
1187
 
                PA_DEBUG(("BLACKLISTED!!!\n"));
 
1228
            if (strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0
 
1229
                    || strcmp (names[i],"ASIO Multimedia Driver")          == 0
 
1230
                    || strncmp (names[i],"Premiere",8)                      == 0  //"Premiere Elements Windows Sound 1.0"
 
1231
                    || strncmp (names[i],"Adobe",5)                         == 0  //"Adobe Default Windows Sound 1.5"
 
1232
               ) {
 
1233
                PA_DEBUG ( ("BLACKLISTED!!!\n"));
1188
1234
                continue;
1189
1235
            }
1190
1236
 
1191
1237
 
1192
 
            if( IsDebuggerPresent_ && IsDebuggerPresent_() )  
1193
 
            {
 
1238
            if (IsDebuggerPresent_ && IsDebuggerPresent_()) {
1194
1239
                /* ASIO Digidesign Driver uses PACE copy protection which quits out
1195
1240
                   if a debugger is running. So we don't load it if a debugger is running. */
1196
 
                if( strcmp(names[i], "ASIO Digidesign Driver") == 0 )  
1197
 
                {
1198
 
                    PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n"));  
1199
 
                    continue;  
1200
 
                }  
1201
 
            }  
 
1241
                if (strcmp (names[i], "ASIO Digidesign Driver") == 0) {
 
1242
                    PA_DEBUG ( ("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n"));
 
1243
                    continue;
 
1244
                }
 
1245
            }
1202
1246
 
1203
1247
 
1204
1248
            /* Attempt to load the asio driver... */
1205
 
            if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError )
1206
 
            {
 
1249
            if (LoadAsioDriver (asioHostApi, names[i], &paAsioDriverInfo, asioHostApi->systemSpecific) == paNoError) {
1207
1250
                PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
1208
1251
                PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
1209
1252
 
1211
1254
                deviceInfo->hostApi = hostApiIndex;
1212
1255
 
1213
1256
                deviceInfo->name = names[i];
1214
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n",  i,deviceInfo->name));
1215
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels       = %d\n", i, paAsioDriverInfo.inputChannelCount));
1216
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels      = %d\n", i, paAsioDriverInfo.outputChannelCount));
1217
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize       = %d\n", i, paAsioDriverInfo.bufferMinSize));
1218
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize       = %d\n", i, paAsioDriverInfo.bufferMaxSize));
1219
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize));
1220
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity   = %d\n", i, paAsioDriverInfo.bufferGranularity));
 
1257
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d name = %s\n",  i,deviceInfo->name));
 
1258
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d inputChannels       = %d\n", i, paAsioDriverInfo.inputChannelCount));
 
1259
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d outputChannels      = %d\n", i, paAsioDriverInfo.outputChannelCount));
 
1260
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d bufferMinSize       = %d\n", i, paAsioDriverInfo.bufferMinSize));
 
1261
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d bufferMaxSize       = %d\n", i, paAsioDriverInfo.bufferMaxSize));
 
1262
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize));
 
1263
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d bufferGranularity   = %d\n", i, paAsioDriverInfo.bufferGranularity));
1221
1264
 
1222
1265
                deviceInfo->maxInputChannels  = paAsioDriverInfo.inputChannelCount;
1223
1266
                deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
1224
1267
 
1225
1268
                deviceInfo->defaultSampleRate = 0.;
1226
1269
                bool foundDefaultSampleRate = false;
1227
 
                for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
1228
 
                {
1229
 
                    ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
1230
 
                    if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
1231
 
                    {
 
1270
 
 
1271
                for (int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j) {
 
1272
                    ASIOError asioError = ASIOCanSampleRate (defaultSampleRateSearchOrder_[j]);
 
1273
 
 
1274
                    if (asioError != ASE_NoClock && asioError != ASE_NotPresent) {
1232
1275
                        deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
1233
1276
                        foundDefaultSampleRate = true;
1234
1277
                        break;
1235
1278
                    }
1236
1279
                }
1237
1280
 
1238
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate));
 
1281
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate));
1239
1282
 
1240
 
                if( foundDefaultSampleRate ){
 
1283
                if (foundDefaultSampleRate) {
1241
1284
 
1242
1285
                    /* calculate default latency values from bufferPreferredSize
1243
1286
                        for default low latency, and bufferPreferredSize * 3
1248
1291
                    */
1249
1292
 
1250
1293
                    double defaultLowLatency =
1251
 
                            paAsioDriverInfo.bufferPreferredSize / deviceInfo->defaultSampleRate;
 
1294
                        paAsioDriverInfo.bufferPreferredSize / deviceInfo->defaultSampleRate;
1252
1295
 
1253
1296
                    deviceInfo->defaultLowInputLatency = defaultLowLatency;
1254
1297
                    deviceInfo->defaultLowOutputLatency = defaultLowLatency;
1255
1298
 
1256
1299
                    long defaultHighLatencyBufferSize =
1257
 
                            paAsioDriverInfo.bufferPreferredSize * 3;
 
1300
                        paAsioDriverInfo.bufferPreferredSize * 3;
1258
1301
 
1259
 
                    if( defaultHighLatencyBufferSize > paAsioDriverInfo.bufferMaxSize )
 
1302
                    if (defaultHighLatencyBufferSize > paAsioDriverInfo.bufferMaxSize)
1260
1303
                        defaultHighLatencyBufferSize = paAsioDriverInfo.bufferMaxSize;
1261
1304
 
1262
1305
                    double defaultHighLatency =
1263
 
                            defaultHighLatencyBufferSize / deviceInfo->defaultSampleRate;
1264
 
 
1265
 
                    if( defaultHighLatency < defaultLowLatency )
1266
 
                        defaultHighLatency = defaultLowLatency; /* just incase the driver returns something strange */ 
1267
 
                            
 
1306
                        defaultHighLatencyBufferSize / deviceInfo->defaultSampleRate;
 
1307
 
 
1308
                    if (defaultHighLatency < defaultLowLatency)
 
1309
                        defaultHighLatency = defaultLowLatency; /* just incase the driver returns something strange */
 
1310
 
1268
1311
                    deviceInfo->defaultHighInputLatency = defaultHighLatency;
1269
1312
                    deviceInfo->defaultHighOutputLatency = defaultHighLatency;
1270
 
                    
1271
 
                }else{
 
1313
 
 
1314
                } else {
1272
1315
 
1273
1316
                    deviceInfo->defaultLowInputLatency = 0.;
1274
1317
                    deviceInfo->defaultLowOutputLatency = 0.;
1276
1319
                    deviceInfo->defaultHighOutputLatency = 0.;
1277
1320
                }
1278
1321
 
1279
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
1280
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
1281
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
1282
 
                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
 
1322
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
 
1323
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
 
1324
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
 
1325
                PA_DEBUG ( ("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
1283
1326
 
1284
1327
                asioDeviceInfo->minBufferSize = paAsioDriverInfo.bufferMinSize;
1285
1328
                asioDeviceInfo->maxBufferSize = paAsioDriverInfo.bufferMaxSize;
1287
1330
                asioDeviceInfo->bufferGranularity = paAsioDriverInfo.bufferGranularity;
1288
1331
 
1289
1332
 
1290
 
                asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
1291
 
                        asioHostApi->allocations,
1292
 
                        sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
1293
 
                                + deviceInfo->maxOutputChannels) );
1294
 
                if( !asioDeviceInfo->asioChannelInfos )
1295
 
                {
 
1333
                asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*) PaUtil_GroupAllocateMemory (
 
1334
                                                       asioHostApi->allocations,
 
1335
                                                       sizeof (ASIOChannelInfo) * (deviceInfo->maxInputChannels
 
1336
                                                                                   + deviceInfo->maxOutputChannels));
 
1337
 
 
1338
                if (!asioDeviceInfo->asioChannelInfos) {
1296
1339
                    result = paInsufficientMemory;
1297
1340
                    goto error_unload;
1298
1341
                }
1299
1342
 
1300
1343
                int a;
1301
1344
 
1302
 
                for( a=0; a < deviceInfo->maxInputChannels; ++a ){
 
1345
                for (a=0; a < deviceInfo->maxInputChannels; ++a) {
1303
1346
                    asioDeviceInfo->asioChannelInfos[a].channel = a;
1304
1347
                    asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
1305
 
                    ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
1306
 
                    if( asioError != ASE_OK )
1307
 
                    {
 
1348
                    ASIOError asioError = ASIOGetChannelInfo (&asioDeviceInfo->asioChannelInfos[a]);
 
1349
 
 
1350
                    if (asioError != ASE_OK) {
1308
1351
                        result = paUnanticipatedHostError;
1309
 
                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
1352
                        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
1310
1353
                        goto error_unload;
1311
1354
                    }
1312
1355
                }
1313
1356
 
1314
 
                for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
 
1357
                for (a=0; a < deviceInfo->maxOutputChannels; ++a) {
1315
1358
                    int b = deviceInfo->maxInputChannels + a;
1316
1359
                    asioDeviceInfo->asioChannelInfos[b].channel = a;
1317
1360
                    asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
1318
 
                    ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
1319
 
                    if( asioError != ASE_OK )
1320
 
                    {
 
1361
                    ASIOError asioError = ASIOGetChannelInfo (&asioDeviceInfo->asioChannelInfos[b]);
 
1362
 
 
1363
                    if (asioError != ASE_OK) {
1321
1364
                        result = paUnanticipatedHostError;
1322
 
                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
1365
                        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
1323
1366
                        goto error_unload;
1324
1367
                    }
1325
1368
                }
1329
1372
                UnloadAsioDriver();
1330
1373
 
1331
1374
                (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
1332
 
                ++(*hostApi)->info.deviceCount;
 
1375
                ++ (*hostApi)->info.deviceCount;
1333
1376
            }
1334
1377
        }
1335
1378
    }
1336
1379
 
1337
 
    if( (*hostApi)->info.deviceCount > 0 )
1338
 
    {
 
1380
    if ( (*hostApi)->info.deviceCount > 0) {
1339
1381
        (*hostApi)->info.defaultInputDevice = 0;
1340
1382
        (*hostApi)->info.defaultOutputDevice = 0;
1341
 
    }
1342
 
    else
1343
 
    {
 
1383
    } else {
1344
1384
        (*hostApi)->info.defaultInputDevice = paNoDevice;
1345
1385
        (*hostApi)->info.defaultOutputDevice = paNoDevice;
1346
1386
    }
1350
1390
    (*hostApi)->OpenStream = OpenStream;
1351
1391
    (*hostApi)->IsFormatSupported = IsFormatSupported;
1352
1392
 
1353
 
    PaUtil_InitializeStreamInterface( &asioHostApi->callbackStreamInterface, CloseStream, StartStream,
 
1393
    PaUtil_InitializeStreamInterface (&asioHostApi->callbackStreamInterface, CloseStream, StartStream,
1354
1394
                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
1355
1395
                                      GetStreamTime, GetStreamCpuLoad,
1356
1396
                                      PaUtil_DummyRead, PaUtil_DummyWrite,
1357
 
                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
 
1397
                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable);
1358
1398
 
1359
 
    PaUtil_InitializeStreamInterface( &asioHostApi->blockingStreamInterface, CloseStream, StartStream,
 
1399
    PaUtil_InitializeStreamInterface (&asioHostApi->blockingStreamInterface, CloseStream, StartStream,
1360
1400
                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
1361
1401
                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
1362
 
                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
 
1402
                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable);
1363
1403
 
1364
1404
    return result;
1365
1405
 
1366
1406
error_unload:
1367
 
        UnloadAsioDriver();
 
1407
    UnloadAsioDriver();
1368
1408
 
1369
1409
error:
1370
 
    if( asioHostApi )
1371
 
    {
1372
 
        if( asioHostApi->allocations )
1373
 
        {
1374
 
            PaUtil_FreeAllAllocations( asioHostApi->allocations );
1375
 
            PaUtil_DestroyAllocationGroup( asioHostApi->allocations );
 
1410
 
 
1411
    if (asioHostApi) {
 
1412
        if (asioHostApi->allocations) {
 
1413
            PaUtil_FreeAllAllocations (asioHostApi->allocations);
 
1414
            PaUtil_DestroyAllocationGroup (asioHostApi->allocations);
1376
1415
        }
1377
1416
 
1378
1417
        delete asioHostApi->asioDrivers;
1379
1418
        asioDrivers = 0; /* keep SDK global in sync until we stop depending on it */
1380
1419
 
1381
 
        PaUtil_FreeMemory( asioHostApi );
 
1420
        PaUtil_FreeMemory (asioHostApi);
1382
1421
    }
 
1422
 
1383
1423
    return result;
1384
1424
}
1385
1425
 
1386
1426
 
1387
 
static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
 
1427
static void Terminate (struct PaUtilHostApiRepresentation *hostApi)
1388
1428
{
1389
 
    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
 
1429
    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*) hostApi;
1390
1430
 
1391
1431
    /*
1392
1432
        IMPLEMENT ME:
1393
1433
            - clean up any resources not handled by the allocation group (need to review if there are any)
1394
1434
    */
1395
1435
 
1396
 
    if( asioHostApi->allocations )
1397
 
    {
1398
 
        PaUtil_FreeAllAllocations( asioHostApi->allocations );
1399
 
        PaUtil_DestroyAllocationGroup( asioHostApi->allocations );
 
1436
    if (asioHostApi->allocations) {
 
1437
        PaUtil_FreeAllAllocations (asioHostApi->allocations);
 
1438
        PaUtil_DestroyAllocationGroup (asioHostApi->allocations);
1400
1439
    }
1401
1440
 
1402
1441
    delete asioHostApi->asioDrivers; /* calls CoUninitialize() */
1403
1442
    asioDrivers = 0; /* keep SDK global in sync until we stop depending on it */
1404
1443
 
1405
 
    PaUtil_FreeMemory( asioHostApi );
 
1444
    PaUtil_FreeMemory (asioHostApi);
1406
1445
}
1407
1446
 
1408
1447
 
1409
 
static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
 
1448
static PaError IsFormatSupported (struct PaUtilHostApiRepresentation *hostApi,
1410
1449
                                  const PaStreamParameters *inputParameters,
1411
1450
                                  const PaStreamParameters *outputParameters,
1412
 
                                  double sampleRate )
 
1451
                                  double sampleRate)
1413
1452
{
1414
1453
    PaError result = paNoError;
1415
 
    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
 
1454
    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*) hostApi;
1416
1455
    PaAsioDriverInfo *driverInfo = &asioHostApi->openAsioDriverInfo;
1417
1456
    int inputChannelCount, outputChannelCount;
1418
1457
    PaSampleFormat inputSampleFormat, outputSampleFormat;
1419
 
    PaDeviceIndex asioDeviceIndex;                                  
 
1458
    PaDeviceIndex asioDeviceIndex;
1420
1459
    ASIOError asioError;
1421
 
    
1422
 
    if( inputParameters && outputParameters )
1423
 
    {
 
1460
 
 
1461
    if (inputParameters && outputParameters) {
1424
1462
        /* full duplex ASIO stream must use the same device for input and output */
1425
1463
 
1426
 
        if( inputParameters->device != outputParameters->device )
 
1464
        if (inputParameters->device != outputParameters->device)
1427
1465
            return paBadIODeviceCombination;
1428
1466
    }
1429
 
    
1430
 
    if( inputParameters )
1431
 
    {
 
1467
 
 
1468
    if (inputParameters) {
1432
1469
        inputChannelCount = inputParameters->channelCount;
1433
1470
        inputSampleFormat = inputParameters->sampleFormat;
1434
1471
 
1435
1472
        /* all standard sample formats are supported by the buffer adapter,
1436
1473
            this implementation doesn't support any custom sample formats */
1437
 
        if( inputSampleFormat & paCustomFormat )
 
1474
        if (inputSampleFormat & paCustomFormat)
1438
1475
            return paSampleFormatNotSupported;
1439
 
            
 
1476
 
1440
1477
        /* unless alternate device specification is supported, reject the use of
1441
1478
            paUseHostApiSpecificDeviceSpecification */
1442
1479
 
1443
 
        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
 
1480
        if (inputParameters->device == paUseHostApiSpecificDeviceSpecification)
1444
1481
            return paInvalidDevice;
1445
1482
 
1446
1483
        asioDeviceIndex = inputParameters->device;
1449
1486
        /** @todo do more validation here */
1450
1487
        // if( inputParameters->hostApiSpecificStreamInfo )
1451
1488
        //    return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
1452
 
    }
1453
 
    else
1454
 
    {
 
1489
    } else {
1455
1490
        inputChannelCount = 0;
1456
1491
    }
1457
1492
 
1458
 
    if( outputParameters )
1459
 
    {
 
1493
    if (outputParameters) {
1460
1494
        outputChannelCount = outputParameters->channelCount;
1461
1495
        outputSampleFormat = outputParameters->sampleFormat;
1462
1496
 
1463
1497
        /* all standard sample formats are supported by the buffer adapter,
1464
1498
            this implementation doesn't support any custom sample formats */
1465
 
        if( outputSampleFormat & paCustomFormat )
 
1499
        if (outputSampleFormat & paCustomFormat)
1466
1500
            return paSampleFormatNotSupported;
1467
 
            
 
1501
 
1468
1502
        /* unless alternate device specification is supported, reject the use of
1469
1503
            paUseHostApiSpecificDeviceSpecification */
1470
1504
 
1471
 
        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
 
1505
        if (outputParameters->device == paUseHostApiSpecificDeviceSpecification)
1472
1506
            return paInvalidDevice;
1473
1507
 
1474
1508
        asioDeviceIndex = outputParameters->device;
1477
1511
        /** @todo do more validation here */
1478
1512
        // if( outputParameters->hostApiSpecificStreamInfo )
1479
1513
        //    return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
1480
 
    }
1481
 
    else
1482
 
    {
 
1514
    } else {
1483
1515
        outputChannelCount = 0;
1484
1516
    }
1485
1517
 
1487
1519
 
1488
1520
    /* if an ASIO device is open we can only get format information for the currently open device */
1489
1521
 
1490
 
    if( asioHostApi->openAsioDeviceIndex != paNoDevice 
1491
 
            && asioHostApi->openAsioDeviceIndex != asioDeviceIndex )
1492
 
    {
 
1522
    if (asioHostApi->openAsioDeviceIndex != paNoDevice
 
1523
            && asioHostApi->openAsioDeviceIndex != asioDeviceIndex) {
1493
1524
        return paDeviceUnavailable;
1494
1525
    }
1495
1526
 
1498
1529
        rather than the ones in our device info structure which may be stale */
1499
1530
 
1500
1531
    /* open the device if it's not already open */
1501
 
    if( asioHostApi->openAsioDeviceIndex == paNoDevice )
1502
 
    {
1503
 
        result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
1504
 
                driverInfo, asioHostApi->systemSpecific );
1505
 
        if( result != paNoError )
 
1532
    if (asioHostApi->openAsioDeviceIndex == paNoDevice) {
 
1533
        result = LoadAsioDriver (asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
 
1534
                                 driverInfo, asioHostApi->systemSpecific);
 
1535
 
 
1536
        if (result != paNoError)
1506
1537
            return result;
1507
1538
    }
1508
1539
 
1509
1540
    /* check that input device can support inputChannelCount */
1510
 
    if( inputChannelCount > 0 )
1511
 
    {
1512
 
        if( inputChannelCount > driverInfo->inputChannelCount )
1513
 
        {
 
1541
    if (inputChannelCount > 0) {
 
1542
        if (inputChannelCount > driverInfo->inputChannelCount) {
1514
1543
            result = paInvalidChannelCount;
1515
1544
            goto done;
1516
1545
        }
1517
1546
    }
1518
1547
 
1519
1548
    /* check that output device can support outputChannelCount */
1520
 
    if( outputChannelCount )
1521
 
    {
1522
 
        if( outputChannelCount > driverInfo->outputChannelCount )
1523
 
        {
 
1549
    if (outputChannelCount) {
 
1550
        if (outputChannelCount > driverInfo->outputChannelCount) {
1524
1551
            result = paInvalidChannelCount;
1525
1552
            goto done;
1526
1553
        }
1527
1554
    }
1528
 
    
 
1555
 
1529
1556
    /* query for sample rate support */
1530
 
    asioError = ASIOCanSampleRate( sampleRate );
1531
 
    if( asioError == ASE_NoClock || asioError == ASE_NotPresent )
1532
 
    {
 
1557
    asioError = ASIOCanSampleRate (sampleRate);
 
1558
 
 
1559
    if (asioError == ASE_NoClock || asioError == ASE_NotPresent) {
1533
1560
        result = paInvalidSampleRate;
1534
1561
        goto done;
1535
1562
    }
1536
1563
 
1537
1564
done:
 
1565
 
1538
1566
    /* close the device if it wasn't already open */
1539
 
    if( asioHostApi->openAsioDeviceIndex == paNoDevice )
1540
 
    {
 
1567
    if (asioHostApi->openAsioDeviceIndex == paNoDevice) {
1541
1568
        UnloadAsioDriver(); /* not sure if we should check for errors here */
1542
1569
    }
1543
1570
 
1544
 
    if( result == paNoError )
 
1571
    if (result == paNoError)
1545
1572
        return paFormatIsSupported;
1546
1573
    else
1547
1574
        return result;
1550
1577
 
1551
1578
 
1552
1579
/** A data structure specifically for storing blocking i/o related data. */
1553
 
typedef struct PaAsioStreamBlockingState
1554
 
{
 
1580
typedef struct PaAsioStreamBlockingState {
1555
1581
    int stopFlag; /**< Flag indicating that block processing is to be stopped. */
1556
1582
 
1557
1583
    unsigned long writeBuffersRequested; /**< The number of available output buffers, requested by the #WriteStream() function. */
1585
1611
 
1586
1612
/* PaAsioStream - a stream data structure specifically for this implementation */
1587
1613
 
1588
 
typedef struct PaAsioStream
1589
 
{
 
1614
typedef struct PaAsioStream {
1590
1615
    PaUtilStreamRepresentation streamRepresentation;
1591
1616
    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
1592
1617
    PaUtilBufferProcessor bufferProcessor;
1635
1660
static PaAsioStream *theAsioStream = 0; /* due to ASIO sdk limitations there can be only one stream */
1636
1661
 
1637
1662
 
1638
 
static void ZeroOutputBuffers( PaAsioStream *stream, long index )
 
1663
static void ZeroOutputBuffers (PaAsioStream *stream, long index)
1639
1664
{
1640
1665
    int i;
1641
1666
 
1642
 
    for( i=0; i < stream->outputChannelCount; ++i )
1643
 
    {
 
1667
    for (i=0; i < stream->outputChannelCount; ++i) {
1644
1668
        void *buffer = stream->asioBufferInfos[ i + stream->inputChannelCount ].buffers[index];
1645
1669
 
1646
 
        int bytesPerSample = BytesPerAsioSample( stream->asioChannelInfos[ i + stream->inputChannelCount ].type );
 
1670
        int bytesPerSample = BytesPerAsioSample (stream->asioChannelInfos[ i + stream->inputChannelCount ].type);
1647
1671
 
1648
 
        memset( buffer, 0, stream->framesPerHostCallback * bytesPerSample );
 
1672
        memset (buffer, 0, stream->framesPerHostCallback * bytesPerSample);
1649
1673
    }
1650
1674
}
1651
1675
 
1652
1676
 
1653
 
static unsigned long SelectHostBufferSize( unsigned long suggestedLatencyFrames,
1654
 
        PaAsioDriverInfo *driverInfo )
 
1677
static unsigned long SelectHostBufferSize (unsigned long suggestedLatencyFrames,
 
1678
        PaAsioDriverInfo *driverInfo)
1655
1679
{
1656
1680
    unsigned long result;
1657
1681
 
1658
 
    if( suggestedLatencyFrames == 0 )
1659
 
    {
 
1682
    if (suggestedLatencyFrames == 0) {
1660
1683
        result = driverInfo->bufferPreferredSize;
1661
 
    }
1662
 
    else{
1663
 
        if( suggestedLatencyFrames <= (unsigned long)driverInfo->bufferMinSize )
1664
 
        {
 
1684
    } else {
 
1685
        if (suggestedLatencyFrames <= (unsigned long) driverInfo->bufferMinSize) {
1665
1686
            result = driverInfo->bufferMinSize;
1666
 
        }
1667
 
        else if( suggestedLatencyFrames >= (unsigned long)driverInfo->bufferMaxSize )
1668
 
        {
 
1687
        } else if (suggestedLatencyFrames >= (unsigned long) driverInfo->bufferMaxSize) {
1669
1688
            result = driverInfo->bufferMaxSize;
1670
 
        }
1671
 
        else
1672
 
        {
1673
 
            if( driverInfo->bufferGranularity == -1 )
1674
 
            {
 
1689
        } else {
 
1690
            if (driverInfo->bufferGranularity == -1) {
1675
1691
                /* power-of-two */
1676
1692
                result = 2;
1677
1693
 
1678
 
                while( result < suggestedLatencyFrames )
 
1694
                while (result < suggestedLatencyFrames)
1679
1695
                    result *= 2;
1680
1696
 
1681
 
                if( result < (unsigned long)driverInfo->bufferMinSize )
 
1697
                if (result < (unsigned long) driverInfo->bufferMinSize)
1682
1698
                    result = driverInfo->bufferMinSize;
1683
1699
 
1684
 
                if( result > (unsigned long)driverInfo->bufferMaxSize )
 
1700
                if (result > (unsigned long) driverInfo->bufferMaxSize)
1685
1701
                    result = driverInfo->bufferMaxSize;
1686
 
            }
1687
 
            else if( driverInfo->bufferGranularity == 0 )
1688
 
            {
 
1702
            } else if (driverInfo->bufferGranularity == 0) {
1689
1703
                /* the documentation states that bufferGranularity should be
1690
1704
                    zero when bufferMinSize, bufferMaxSize and
1691
1705
                    bufferPreferredSize are the same. We assume that is the case.
1692
1706
                */
1693
1707
 
1694
1708
                result = driverInfo->bufferPreferredSize;
1695
 
            }
1696
 
            else
1697
 
            {
 
1709
            } else {
1698
1710
                /* modulo granularity */
1699
1711
 
1700
1712
                unsigned long remainder =
1701
 
                        suggestedLatencyFrames % driverInfo->bufferGranularity;
 
1713
                    suggestedLatencyFrames % driverInfo->bufferGranularity;
1702
1714
 
1703
 
                if( remainder == 0 )
1704
 
                {
 
1715
                if (remainder == 0) {
1705
1716
                    result = suggestedLatencyFrames;
1706
 
                }
1707
 
                else
1708
 
                {
 
1717
                } else {
1709
1718
                    result = suggestedLatencyFrames
1710
 
                            + (driverInfo->bufferGranularity - remainder);
 
1719
                             + (driverInfo->bufferGranularity - remainder);
1711
1720
 
1712
 
                    if( result > (unsigned long)driverInfo->bufferMaxSize )
 
1721
                    if (result > (unsigned long) driverInfo->bufferMaxSize)
1713
1722
                        result = driverInfo->bufferMaxSize;
1714
1723
                }
1715
1724
            }
1722
1731
 
1723
1732
/* returns channelSelectors if present */
1724
1733
 
1725
 
static PaError ValidateAsioSpecificStreamInfo(
1726
 
        const PaStreamParameters *streamParameters,
1727
 
        const PaAsioStreamInfo *streamInfo,
1728
 
        int deviceChannelCount,
1729
 
        int **channelSelectors )
 
1734
static PaError ValidateAsioSpecificStreamInfo (
 
1735
    const PaStreamParameters *streamParameters,
 
1736
    const PaAsioStreamInfo *streamInfo,
 
1737
    int deviceChannelCount,
 
1738
    int **channelSelectors)
1730
1739
{
1731
 
    if( streamInfo )
1732
 
    {
1733
 
        if( streamInfo->size != sizeof( PaAsioStreamInfo )
1734
 
                || streamInfo->version != 1 )
1735
 
        {
 
1740
    if (streamInfo) {
 
1741
        if (streamInfo->size != sizeof (PaAsioStreamInfo)
 
1742
                || streamInfo->version != 1) {
1736
1743
            return paIncompatibleHostApiSpecificStreamInfo;
1737
1744
        }
1738
1745
 
1739
 
        if( streamInfo->flags & paAsioUseChannelSelectors )
 
1746
        if (streamInfo->flags & paAsioUseChannelSelectors)
1740
1747
            *channelSelectors = streamInfo->channelSelectors;
1741
1748
 
1742
 
        if( !(*channelSelectors) )
 
1749
        if (! (*channelSelectors))
1743
1750
            return paIncompatibleHostApiSpecificStreamInfo;
1744
1751
 
1745
 
        for( int i=0; i < streamParameters->channelCount; ++i ){
1746
 
             if( (*channelSelectors)[i] < 0
1747
 
                    || (*channelSelectors)[i] >= deviceChannelCount ){
 
1752
        for (int i=0; i < streamParameters->channelCount; ++i) {
 
1753
            if ( (*channelSelectors) [i] < 0
 
1754
                    || (*channelSelectors) [i] >= deviceChannelCount) {
1748
1755
                return paInvalidChannelCount;
1749
 
             }           
 
1756
            }
1750
1757
        }
1751
1758
    }
1752
1759
 
1764
1771
    /* davidv: listing ASIO Clock sources. there is an ongoing investigation by
1765
1772
       me about whether or not to call ASIOSetSampleRate if an external Clock is
1766
1773
       used. A few drivers expected different things here */
1767
 
    
1768
 
    asioError = ASIOGetClockSources(clocks, &numSources);
1769
 
    if( asioError != ASE_OK ){
1770
 
        PA_DEBUG(("ERROR: ASIOGetClockSources: %s\n", PaAsio_GetAsioErrorText(asioError) ));
1771
 
    }else{
1772
 
        PA_DEBUG(("INFO ASIOGetClockSources listing %d clocks\n", numSources ));
1773
 
        for (int i=0;i<numSources;++i){
1774
 
            PA_DEBUG(("ASIOClockSource%d %s current:%d\n", i, clocks[i].name, clocks[i].isCurrentSource ));
1775
 
           
 
1774
 
 
1775
    asioError = ASIOGetClockSources (clocks, &numSources);
 
1776
 
 
1777
    if (asioError != ASE_OK) {
 
1778
        PA_DEBUG ( ("ERROR: ASIOGetClockSources: %s\n", PaAsio_GetAsioErrorText (asioError)));
 
1779
    } else {
 
1780
        PA_DEBUG ( ("INFO ASIOGetClockSources listing %d clocks\n", numSources));
 
1781
 
 
1782
        for (int i=0; i<numSources; ++i) {
 
1783
            PA_DEBUG ( ("ASIOClockSource%d %s current:%d\n", i, clocks[i].name, clocks[i].isCurrentSource));
 
1784
 
1776
1785
            if (clocks[i].isCurrentSource)
1777
1786
                result = true;
1778
1787
        }
1782
1791
}
1783
1792
 
1784
1793
 
1785
 
static PaError ValidateAndSetSampleRate( double sampleRate )
 
1794
static PaError ValidateAndSetSampleRate (double sampleRate)
1786
1795
{
1787
1796
    PaError result = paNoError;
1788
1797
    ASIOError asioError;
1789
1798
 
1790
 
    // check that the device supports the requested sample rate 
1791
 
 
1792
 
    asioError = ASIOCanSampleRate( sampleRate );
1793
 
    PA_DEBUG(("ASIOCanSampleRate(%f):%d\n", sampleRate, asioError ));
1794
 
 
1795
 
    if( asioError != ASE_OK )
1796
 
    {
 
1799
    // check that the device supports the requested sample rate
 
1800
 
 
1801
    asioError = ASIOCanSampleRate (sampleRate);
 
1802
    PA_DEBUG ( ("ASIOCanSampleRate(%f):%d\n", sampleRate, asioError));
 
1803
 
 
1804
    if (asioError != ASE_OK) {
1797
1805
        result = paInvalidSampleRate;
1798
 
        PA_DEBUG(("ERROR: ASIOCanSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
1806
        PA_DEBUG ( ("ERROR: ASIOCanSampleRate: %s\n", PaAsio_GetAsioErrorText (asioError)));
1799
1807
        goto error;
1800
1808
    }
1801
1809
 
1803
1811
    // sample rate if the device is not already in that rate.
1804
1812
 
1805
1813
    ASIOSampleRate oldRate;
1806
 
    asioError = ASIOGetSampleRate(&oldRate);
1807
 
    if( asioError != ASE_OK )
1808
 
    {
 
1814
    asioError = ASIOGetSampleRate (&oldRate);
 
1815
 
 
1816
    if (asioError != ASE_OK) {
1809
1817
        result = paInvalidSampleRate;
1810
 
        PA_DEBUG(("ERROR: ASIOGetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
1818
        PA_DEBUG ( ("ERROR: ASIOGetSampleRate: %s\n", PaAsio_GetAsioErrorText (asioError)));
1811
1819
        goto error;
1812
1820
    }
1813
 
    PA_DEBUG(("ASIOGetSampleRate:%f\n",oldRate));
1814
 
 
1815
 
    if (oldRate != sampleRate){
 
1821
 
 
1822
    PA_DEBUG ( ("ASIOGetSampleRate:%f\n",oldRate));
 
1823
 
 
1824
    if (oldRate != sampleRate) {
1816
1825
        /* Set sample rate */
1817
1826
 
1818
 
        PA_DEBUG(("before ASIOSetSampleRate(%f)\n",sampleRate));
 
1827
        PA_DEBUG ( ("before ASIOSetSampleRate(%f)\n",sampleRate));
1819
1828
 
1820
1829
        /*
1821
 
            If you have problems with some drivers when externally clocked, 
 
1830
            If you have problems with some drivers when externally clocked,
1822
1831
            try switching on the following line and commenting out the one after it.
1823
1832
            See IsUsingExternalClockSource() for more info.
1824
1833
        */
 
1834
 
1825
1835
        //if( IsUsingExternalClockSource() ){
1826
 
        if( false ){
1827
 
            asioError = ASIOSetSampleRate( 0 );
1828
 
        }else{
1829
 
            asioError = ASIOSetSampleRate( sampleRate );
 
1836
        if (false) {
 
1837
            asioError = ASIOSetSampleRate (0);
 
1838
        } else {
 
1839
            asioError = ASIOSetSampleRate (sampleRate);
1830
1840
        }
1831
 
        if( asioError != ASE_OK )
1832
 
        {
 
1841
 
 
1842
        if (asioError != ASE_OK) {
1833
1843
            result = paInvalidSampleRate;
1834
 
            PA_DEBUG(("ERROR: ASIOSetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
1844
            PA_DEBUG ( ("ERROR: ASIOSetSampleRate: %s\n", PaAsio_GetAsioErrorText (asioError)));
1835
1845
            goto error;
1836
1846
        }
1837
 
        PA_DEBUG(("after ASIOSetSampleRate(%f)\n",sampleRate));
1838
 
    }
1839
 
    else
1840
 
    {
1841
 
        PA_DEBUG(("No Need to change SR\n"));
 
1847
 
 
1848
        PA_DEBUG ( ("after ASIOSetSampleRate(%f)\n",sampleRate));
 
1849
    } else {
 
1850
        PA_DEBUG ( ("No Need to change SR\n"));
1842
1851
    }
1843
1852
 
1844
1853
error:
1848
1857
 
1849
1858
/* see pa_hostapi.h for a list of validity guarantees made about OpenStream  parameters */
1850
1859
 
1851
 
static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
 
1860
static PaError OpenStream (struct PaUtilHostApiRepresentation *hostApi,
1852
1861
                           PaStream** s,
1853
1862
                           const PaStreamParameters *inputParameters,
1854
1863
                           const PaStreamParameters *outputParameters,
1856
1865
                           unsigned long framesPerBuffer,
1857
1866
                           PaStreamFlags streamFlags,
1858
1867
                           PaStreamCallback *streamCallback,
1859
 
                           void *userData )
 
1868
                           void *userData)
1860
1869
{
1861
1870
    PaError result = paNoError;
1862
 
    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
 
1871
    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*) hostApi;
1863
1872
    PaAsioStream *stream = 0;
1864
1873
    PaAsioStreamInfo *inputStreamInfo, *outputStreamInfo;
1865
1874
    unsigned long framesPerHostBuffer;
1879
1888
    int *outputChannelSelectors = 0;
1880
1889
 
1881
1890
    /* Are we using blocking i/o interface? */
1882
 
    int usingBlockingIo = ( !streamCallback ) ? TRUE : FALSE;
 
1891
    int usingBlockingIo = (!streamCallback) ? TRUE : FALSE;
1883
1892
    /* Blocking i/o stuff */
1884
1893
    long lBlockingBufferSize     = 0; /* Desired ring buffer size in samples. */
1885
1894
    long lBlockingBufferSizePow2 = 0; /* Power-of-2 rounded ring buffer size. */
1892
1901
 
1893
1902
    /* unless we move to using lower level ASIO calls, we can only have
1894
1903
        one device open at a time */
1895
 
    if( asioHostApi->openAsioDeviceIndex != paNoDevice )
1896
 
    {
1897
 
        PA_DEBUG(("OpenStream paDeviceUnavailable\n"));
 
1904
    if (asioHostApi->openAsioDeviceIndex != paNoDevice) {
 
1905
        PA_DEBUG ( ("OpenStream paDeviceUnavailable\n"));
1898
1906
        return paDeviceUnavailable;
1899
1907
    }
1900
1908
 
1901
 
    assert( theAsioStream == 0 );
 
1909
    assert (theAsioStream == 0);
1902
1910
 
1903
 
    if( inputParameters && outputParameters )
1904
 
    {
 
1911
    if (inputParameters && outputParameters) {
1905
1912
        /* full duplex ASIO stream must use the same device for input and output */
1906
1913
 
1907
 
        if( inputParameters->device != outputParameters->device )
1908
 
        {
1909
 
            PA_DEBUG(("OpenStream paBadIODeviceCombination\n"));
 
1914
        if (inputParameters->device != outputParameters->device) {
 
1915
            PA_DEBUG ( ("OpenStream paBadIODeviceCombination\n"));
1910
1916
            return paBadIODeviceCombination;
1911
1917
        }
1912
1918
    }
1913
1919
 
1914
 
    if( inputParameters )
1915
 
    {
 
1920
    if (inputParameters) {
1916
1921
        inputChannelCount = inputParameters->channelCount;
1917
1922
        inputSampleFormat = inputParameters->sampleFormat;
1918
 
        suggestedInputLatencyFrames = (unsigned long)((inputParameters->suggestedLatency * sampleRate)+0.5f);
 
1923
        suggestedInputLatencyFrames = (unsigned long) ( (inputParameters->suggestedLatency * sampleRate) +0.5f);
1919
1924
 
1920
1925
        /* unless alternate device specification is supported, reject the use of
1921
1926
            paUseHostApiSpecificDeviceSpecification */
1922
 
        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
 
1927
        if (inputParameters->device == paUseHostApiSpecificDeviceSpecification)
1923
1928
            return paInvalidDevice;
1924
1929
 
1925
1930
        asioDeviceIndex = inputParameters->device;
1926
1931
 
1927
 
        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex];
 
1932
        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*) hostApi->deviceInfos[asioDeviceIndex];
1928
1933
 
1929
1934
        /* validate hostApiSpecificStreamInfo */
1930
 
        inputStreamInfo = (PaAsioStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
1931
 
        result = ValidateAsioSpecificStreamInfo( inputParameters, inputStreamInfo,
1932
 
            asioDeviceInfo->commonDeviceInfo.maxInputChannels,
1933
 
            &inputChannelSelectors
1934
 
        );
1935
 
        if( result != paNoError ) return result;
1936
 
    }
1937
 
    else
1938
 
    {
 
1935
        inputStreamInfo = (PaAsioStreamInfo*) inputParameters->hostApiSpecificStreamInfo;
 
1936
        result = ValidateAsioSpecificStreamInfo (inputParameters, inputStreamInfo,
 
1937
                 asioDeviceInfo->commonDeviceInfo.maxInputChannels,
 
1938
                 &inputChannelSelectors
 
1939
                                                );
 
1940
 
 
1941
        if (result != paNoError) return result;
 
1942
    } else {
1939
1943
        inputChannelCount = 0;
1940
1944
        inputSampleFormat = 0;
1941
1945
        suggestedInputLatencyFrames = 0;
1942
1946
    }
1943
1947
 
1944
 
    if( outputParameters )
1945
 
    {
 
1948
    if (outputParameters) {
1946
1949
        outputChannelCount = outputParameters->channelCount;
1947
1950
        outputSampleFormat = outputParameters->sampleFormat;
1948
 
        suggestedOutputLatencyFrames = (unsigned long)((outputParameters->suggestedLatency * sampleRate)+0.5f);
 
1951
        suggestedOutputLatencyFrames = (unsigned long) ( (outputParameters->suggestedLatency * sampleRate) +0.5f);
1949
1952
 
1950
1953
        /* unless alternate device specification is supported, reject the use of
1951
1954
            paUseHostApiSpecificDeviceSpecification */
1952
 
        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
 
1955
        if (outputParameters->device == paUseHostApiSpecificDeviceSpecification)
1953
1956
            return paInvalidDevice;
1954
1957
 
1955
1958
        asioDeviceIndex = outputParameters->device;
1956
1959
 
1957
 
        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex];
 
1960
        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*) hostApi->deviceInfos[asioDeviceIndex];
1958
1961
 
1959
1962
        /* validate hostApiSpecificStreamInfo */
1960
 
        outputStreamInfo = (PaAsioStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
1961
 
        result = ValidateAsioSpecificStreamInfo( outputParameters, outputStreamInfo,
1962
 
            asioDeviceInfo->commonDeviceInfo.maxOutputChannels,
1963
 
            &outputChannelSelectors
1964
 
        );
1965
 
        if( result != paNoError ) return result;
1966
 
    }
1967
 
    else
1968
 
    {
 
1963
        outputStreamInfo = (PaAsioStreamInfo*) outputParameters->hostApiSpecificStreamInfo;
 
1964
        result = ValidateAsioSpecificStreamInfo (outputParameters, outputStreamInfo,
 
1965
                 asioDeviceInfo->commonDeviceInfo.maxOutputChannels,
 
1966
                 &outputChannelSelectors
 
1967
                                                );
 
1968
 
 
1969
        if (result != paNoError) return result;
 
1970
    } else {
1969
1971
        outputChannelCount = 0;
1970
1972
        outputSampleFormat = 0;
1971
1973
        suggestedOutputLatencyFrames = 0;
1976
1978
    /* NOTE: we load the driver and use its current settings
1977
1979
        rather than the ones in our device info structure which may be stale */
1978
1980
 
1979
 
    result = LoadAsioDriver( asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
1980
 
            driverInfo, asioHostApi->systemSpecific );
1981
 
    if( result == paNoError )
 
1981
    result = LoadAsioDriver (asioHostApi, asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
 
1982
                             driverInfo, asioHostApi->systemSpecific);
 
1983
 
 
1984
    if (result == paNoError)
1982
1985
        asioIsInitialized = 1;
1983
 
    else{
1984
 
        PA_DEBUG(("OpenStream ERROR1 - LoadAsioDriver returned %d\n", result));
 
1986
    else {
 
1987
        PA_DEBUG ( ("OpenStream ERROR1 - LoadAsioDriver returned %d\n", result));
1985
1988
        goto error;
1986
1989
    }
1987
1990
 
1988
1991
    /* check that input device can support inputChannelCount */
1989
 
    if( inputChannelCount > 0 )
1990
 
    {
1991
 
        if( inputChannelCount > driverInfo->inputChannelCount )
1992
 
        {
 
1992
    if (inputChannelCount > 0) {
 
1993
        if (inputChannelCount > driverInfo->inputChannelCount) {
1993
1994
            result = paInvalidChannelCount;
1994
 
            PA_DEBUG(("OpenStream ERROR2\n"));
 
1995
            PA_DEBUG ( ("OpenStream ERROR2\n"));
1995
1996
            goto error;
1996
1997
        }
1997
1998
    }
1998
1999
 
1999
2000
    /* check that output device can support outputChannelCount */
2000
 
    if( outputChannelCount )
2001
 
    {
2002
 
        if( outputChannelCount > driverInfo->outputChannelCount )
2003
 
        {
 
2001
    if (outputChannelCount) {
 
2002
        if (outputChannelCount > driverInfo->outputChannelCount) {
2004
2003
            result = paInvalidChannelCount;
2005
 
            PA_DEBUG(("OpenStream ERROR3\n"));
 
2004
            PA_DEBUG ( ("OpenStream ERROR3\n"));
2006
2005
            goto error;
2007
2006
        }
2008
2007
    }
2009
2008
 
2010
 
    result = ValidateAndSetSampleRate( sampleRate );
2011
 
    if( result != paNoError )
 
2009
    result = ValidateAndSetSampleRate (sampleRate);
 
2010
 
 
2011
    if (result != paNoError)
2012
2012
        goto error;
2013
2013
 
2014
2014
    /*
2018
2018
    */
2019
2019
 
2020
2020
    /* validate platform specific flags */
2021
 
    if( (streamFlags & paPlatformSpecificFlags) != 0 ){
2022
 
        PA_DEBUG(("OpenStream invalid flags!!\n"));
 
2021
    if ( (streamFlags & paPlatformSpecificFlags) != 0) {
 
2022
        PA_DEBUG ( ("OpenStream invalid flags!!\n"));
2023
2023
        return paInvalidFlag; /* unexpected platform specific flag */
2024
2024
    }
2025
2025
 
2026
2026
 
2027
 
    stream = (PaAsioStream*)PaUtil_AllocateMemory( sizeof(PaAsioStream) );
2028
 
    if( !stream )
2029
 
    {
 
2027
    stream = (PaAsioStream*) PaUtil_AllocateMemory (sizeof (PaAsioStream));
 
2028
 
 
2029
    if (!stream) {
2030
2030
        result = paInsufficientMemory;
2031
 
        PA_DEBUG(("OpenStream ERROR5\n"));
 
2031
        PA_DEBUG ( ("OpenStream ERROR5\n"));
2032
2032
        goto error;
2033
2033
    }
 
2034
 
2034
2035
    stream->blockingState = NULL; /* Blocking i/o not initialized, yet. */
2035
2036
 
2036
2037
 
2037
 
    stream->completedBuffersPlayedEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
2038
 
    if( stream->completedBuffersPlayedEvent == NULL )
2039
 
    {
 
2038
    stream->completedBuffersPlayedEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
 
2039
 
 
2040
    if (stream->completedBuffersPlayedEvent == NULL) {
2040
2041
        result = paUnanticipatedHostError;
2041
 
        PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
2042
 
        PA_DEBUG(("OpenStream ERROR6\n"));
 
2042
        PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
 
2043
        PA_DEBUG ( ("OpenStream ERROR6\n"));
2043
2044
        goto error;
2044
2045
    }
 
2046
 
2045
2047
    completedBuffersPlayedEventInited = 1;
2046
2048
 
2047
2049
 
2050
2052
    stream->bufferPtrs = 0; /* for deallocation in error */
2051
2053
 
2052
2054
    /* Using blocking i/o interface... */
2053
 
    if( usingBlockingIo )
2054
 
    {
 
2055
    if (usingBlockingIo) {
2055
2056
        /* Blocking i/o is implemented by running callback mode, using a special blocking i/o callback. */
2056
2057
        streamCallback = BlockingIoPaCallback; /* Setup PA to use the ASIO blocking i/o callback. */
2057
2058
        userData       = &theAsioStream;       /* The callback user data will be the PA ASIO stream. */
2058
 
        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
2059
 
                                               &asioHostApi->blockingStreamInterface, streamCallback, userData );
2060
 
    }
2061
 
    else /* Using callback interface... */
2062
 
    {
2063
 
        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
2064
 
                                               &asioHostApi->callbackStreamInterface, streamCallback, userData );
2065
 
    }
2066
 
 
2067
 
 
2068
 
    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
2069
 
 
2070
 
 
2071
 
    stream->asioBufferInfos = (ASIOBufferInfo*)PaUtil_AllocateMemory(
2072
 
            sizeof(ASIOBufferInfo) * (inputChannelCount + outputChannelCount) );
2073
 
    if( !stream->asioBufferInfos )
2074
 
    {
 
2059
        PaUtil_InitializeStreamRepresentation (&stream->streamRepresentation,
 
2060
                                               &asioHostApi->blockingStreamInterface, streamCallback, userData);
 
2061
    } else { /* Using callback interface... */
 
2062
        PaUtil_InitializeStreamRepresentation (&stream->streamRepresentation,
 
2063
                                               &asioHostApi->callbackStreamInterface, streamCallback, userData);
 
2064
    }
 
2065
 
 
2066
 
 
2067
    PaUtil_InitializeCpuLoadMeasurer (&stream->cpuLoadMeasurer, sampleRate);
 
2068
 
 
2069
 
 
2070
    stream->asioBufferInfos = (ASIOBufferInfo*) PaUtil_AllocateMemory (
 
2071
                                  sizeof (ASIOBufferInfo) * (inputChannelCount + outputChannelCount));
 
2072
 
 
2073
    if (!stream->asioBufferInfos) {
2075
2074
        result = paInsufficientMemory;
2076
 
        PA_DEBUG(("OpenStream ERROR7\n"));
 
2075
        PA_DEBUG ( ("OpenStream ERROR7\n"));
2077
2076
        goto error;
2078
2077
    }
2079
2078
 
2080
2079
 
2081
 
    for( i=0; i < inputChannelCount; ++i )
2082
 
    {
 
2080
    for (i=0; i < inputChannelCount; ++i) {
2083
2081
        ASIOBufferInfo *info = &stream->asioBufferInfos[i];
2084
2082
 
2085
2083
        info->isInput = ASIOTrue;
2086
2084
 
2087
 
        if( inputChannelSelectors ){
 
2085
        if (inputChannelSelectors) {
2088
2086
            // inputChannelSelectors values have already been validated in
2089
2087
            // ValidateAsioSpecificStreamInfo() above
2090
2088
            info->channelNum = inputChannelSelectors[i];
2091
 
        }else{
 
2089
        } else {
2092
2090
            info->channelNum = i;
2093
2091
        }
2094
2092
 
2095
2093
        info->buffers[0] = info->buffers[1] = 0;
2096
2094
    }
2097
2095
 
2098
 
    for( i=0; i < outputChannelCount; ++i ){
 
2096
    for (i=0; i < outputChannelCount; ++i) {
2099
2097
        ASIOBufferInfo *info = &stream->asioBufferInfos[inputChannelCount+i];
2100
2098
 
2101
2099
        info->isInput = ASIOFalse;
2102
2100
 
2103
 
        if( outputChannelSelectors ){
 
2101
        if (outputChannelSelectors) {
2104
2102
            // outputChannelSelectors values have already been validated in
2105
2103
            // ValidateAsioSpecificStreamInfo() above
2106
2104
            info->channelNum = outputChannelSelectors[i];
2107
 
        }else{
 
2105
        } else {
2108
2106
            info->channelNum = i;
2109
2107
        }
2110
 
        
 
2108
 
2111
2109
        info->buffers[0] = info->buffers[1] = 0;
2112
2110
    }
2113
2111
 
2114
2112
 
2115
2113
    /* Using blocking i/o interface... */
2116
 
    if( usingBlockingIo )
2117
 
    {
2118
 
/** @todo REVIEW selection of host buffer size for blocking i/o */
 
2114
    if (usingBlockingIo) {
 
2115
        /** @todo REVIEW selection of host buffer size for blocking i/o */
2119
2116
        /* Use default host latency for blocking i/o. */
2120
 
        framesPerHostBuffer = SelectHostBufferSize( 0, driverInfo );
2121
 
 
2122
 
    }
2123
 
    else /* Using callback interface... */
2124
 
    {
2125
 
        framesPerHostBuffer = SelectHostBufferSize(
2126
 
                (( suggestedInputLatencyFrames > suggestedOutputLatencyFrames )
2127
 
                        ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames),
2128
 
                driverInfo );
2129
 
    }
2130
 
 
2131
 
 
2132
 
    PA_DEBUG(("PaAsioOpenStream: framesPerHostBuffer :%d\n",  framesPerHostBuffer));
2133
 
 
2134
 
    asioError = ASIOCreateBuffers( stream->asioBufferInfos,
2135
 
            inputChannelCount+outputChannelCount,
2136
 
            framesPerHostBuffer, &asioCallbacks_ );
2137
 
 
2138
 
    if( asioError != ASE_OK
2139
 
            && framesPerHostBuffer != (unsigned long)driverInfo->bufferPreferredSize )
2140
 
    {
2141
 
        PA_DEBUG(("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
2117
        framesPerHostBuffer = SelectHostBufferSize (0, driverInfo);
 
2118
 
 
2119
    } else { /* Using callback interface... */
 
2120
        framesPerHostBuffer = SelectHostBufferSize (
 
2121
                                  ( (suggestedInputLatencyFrames > suggestedOutputLatencyFrames)
 
2122
                                    ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames),
 
2123
                                  driverInfo);
 
2124
    }
 
2125
 
 
2126
 
 
2127
    PA_DEBUG ( ("PaAsioOpenStream: framesPerHostBuffer :%d\n",  framesPerHostBuffer));
 
2128
 
 
2129
    asioError = ASIOCreateBuffers (stream->asioBufferInfos,
 
2130
                                   inputChannelCount+outputChannelCount,
 
2131
                                   framesPerHostBuffer, &asioCallbacks_);
 
2132
 
 
2133
    if (asioError != ASE_OK
 
2134
            && framesPerHostBuffer != (unsigned long) driverInfo->bufferPreferredSize) {
 
2135
        PA_DEBUG ( ("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText (asioError)));
2142
2136
        /*
2143
2137
            Some buggy drivers (like the Hoontech DSP24) give incorrect
2144
2138
            [min, preferred, max] values They should work with the preferred size
2148
2142
 
2149
2143
        framesPerHostBuffer = driverInfo->bufferPreferredSize;
2150
2144
 
2151
 
        PA_DEBUG(("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n",  framesPerHostBuffer));
2152
 
 
2153
 
        ASIOError asioError2 = ASIOCreateBuffers( stream->asioBufferInfos,
2154
 
                inputChannelCount+outputChannelCount,
2155
 
                 framesPerHostBuffer, &asioCallbacks_ );
2156
 
        if( asioError2 == ASE_OK )
 
2145
        PA_DEBUG ( ("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n",  framesPerHostBuffer));
 
2146
 
 
2147
        ASIOError asioError2 = ASIOCreateBuffers (stream->asioBufferInfos,
 
2148
                               inputChannelCount+outputChannelCount,
 
2149
                               framesPerHostBuffer, &asioCallbacks_);
 
2150
 
 
2151
        if (asioError2 == ASE_OK)
2157
2152
            asioError = ASE_OK;
2158
2153
    }
2159
2154
 
2160
 
    if( asioError != ASE_OK )
2161
 
    {
 
2155
    if (asioError != ASE_OK) {
2162
2156
        result = paUnanticipatedHostError;
2163
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
2164
 
        PA_DEBUG(("OpenStream ERROR9\n"));
 
2157
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
 
2158
        PA_DEBUG ( ("OpenStream ERROR9\n"));
2165
2159
        goto error;
2166
2160
    }
2167
2161
 
2168
2162
    asioBuffersCreated = 1;
2169
2163
 
2170
 
    stream->asioChannelInfos = (ASIOChannelInfo*)PaUtil_AllocateMemory(
2171
 
            sizeof(ASIOChannelInfo) * (inputChannelCount + outputChannelCount) );
2172
 
    if( !stream->asioChannelInfos )
2173
 
    {
 
2164
    stream->asioChannelInfos = (ASIOChannelInfo*) PaUtil_AllocateMemory (
 
2165
                                   sizeof (ASIOChannelInfo) * (inputChannelCount + outputChannelCount));
 
2166
 
 
2167
    if (!stream->asioChannelInfos) {
2174
2168
        result = paInsufficientMemory;
2175
 
        PA_DEBUG(("OpenStream ERROR10\n"));
 
2169
        PA_DEBUG ( ("OpenStream ERROR10\n"));
2176
2170
        goto error;
2177
2171
    }
2178
2172
 
2179
 
    for( i=0; i < inputChannelCount + outputChannelCount; ++i )
2180
 
    {
 
2173
    for (i=0; i < inputChannelCount + outputChannelCount; ++i) {
2181
2174
        stream->asioChannelInfos[i].channel = stream->asioBufferInfos[i].channelNum;
2182
2175
        stream->asioChannelInfos[i].isInput = stream->asioBufferInfos[i].isInput;
2183
 
        asioError = ASIOGetChannelInfo( &stream->asioChannelInfos[i] );
2184
 
        if( asioError != ASE_OK )
2185
 
        {
 
2176
        asioError = ASIOGetChannelInfo (&stream->asioChannelInfos[i]);
 
2177
 
 
2178
        if (asioError != ASE_OK) {
2186
2179
            result = paUnanticipatedHostError;
2187
 
            PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
2188
 
            PA_DEBUG(("OpenStream ERROR11\n"));
 
2180
            PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
 
2181
            PA_DEBUG ( ("OpenStream ERROR11\n"));
2189
2182
            goto error;
2190
2183
        }
2191
2184
    }
2192
2185
 
2193
 
    stream->bufferPtrs = (void**)PaUtil_AllocateMemory(
2194
 
            2 * sizeof(void*) * (inputChannelCount + outputChannelCount) );
2195
 
    if( !stream->bufferPtrs )
2196
 
    {
 
2186
    stream->bufferPtrs = (void**) PaUtil_AllocateMemory (
 
2187
                             2 * sizeof (void*) * (inputChannelCount + outputChannelCount));
 
2188
 
 
2189
    if (!stream->bufferPtrs) {
2197
2190
        result = paInsufficientMemory;
2198
 
        PA_DEBUG(("OpenStream ERROR12\n"));
 
2191
        PA_DEBUG ( ("OpenStream ERROR12\n"));
2199
2192
        goto error;
2200
2193
    }
2201
2194
 
2202
 
    if( inputChannelCount > 0 )
2203
 
    {
 
2195
    if (inputChannelCount > 0) {
2204
2196
        stream->inputBufferPtrs[0] = stream-> bufferPtrs;
2205
2197
        stream->inputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount];
2206
2198
 
2207
 
        for( i=0; i<inputChannelCount; ++i )
2208
 
        {
 
2199
        for (i=0; i<inputChannelCount; ++i) {
2209
2200
            stream->inputBufferPtrs[0][i] = stream->asioBufferInfos[i].buffers[0];
2210
2201
            stream->inputBufferPtrs[1][i] = stream->asioBufferInfos[i].buffers[1];
2211
2202
        }
2212
 
    }
2213
 
    else
2214
 
    {
 
2203
    } else {
2215
2204
        stream->inputBufferPtrs[0] = 0;
2216
2205
        stream->inputBufferPtrs[1] = 0;
2217
2206
    }
2218
2207
 
2219
 
    if( outputChannelCount > 0 )
2220
 
    {
 
2208
    if (outputChannelCount > 0) {
2221
2209
        stream->outputBufferPtrs[0] = &stream->bufferPtrs[inputChannelCount*2];
2222
2210
        stream->outputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount*2 + outputChannelCount];
2223
2211
 
2224
 
        for( i=0; i<outputChannelCount; ++i )
2225
 
        {
 
2212
        for (i=0; i<outputChannelCount; ++i) {
2226
2213
            stream->outputBufferPtrs[0][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[0];
2227
2214
            stream->outputBufferPtrs[1][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[1];
2228
2215
        }
2229
 
    }
2230
 
    else
2231
 
    {
 
2216
    } else {
2232
2217
        stream->outputBufferPtrs[0] = 0;
2233
2218
        stream->outputBufferPtrs[1] = 0;
2234
2219
    }
2235
2220
 
2236
 
    if( inputChannelCount > 0 )
2237
 
    {
 
2221
    if (inputChannelCount > 0) {
2238
2222
        /* FIXME: assume all channels use the same type for now */
2239
2223
        ASIOSampleType inputType = stream->asioChannelInfos[0].type;
2240
2224
 
2241
 
        PA_DEBUG(("ASIO Input  type:%d",inputType));
2242
 
        AsioSampleTypeLOG(inputType);
2243
 
        hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType );
 
2225
        PA_DEBUG ( ("ASIO Input  type:%d",inputType));
 
2226
        AsioSampleTypeLOG (inputType);
 
2227
        hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat (inputType);
2244
2228
 
2245
 
        SelectAsioToPaConverter( inputType, &stream->inputBufferConverter, &stream->inputShift );
2246
 
    }
2247
 
    else
2248
 
    {
 
2229
        SelectAsioToPaConverter (inputType, &stream->inputBufferConverter, &stream->inputShift);
 
2230
    } else {
2249
2231
        hostInputSampleFormat = 0;
2250
2232
        stream->inputBufferConverter = 0;
2251
2233
    }
2252
2234
 
2253
 
    if( outputChannelCount > 0 )
2254
 
    {
 
2235
    if (outputChannelCount > 0) {
2255
2236
        /* FIXME: assume all channels use the same type for now */
2256
2237
        ASIOSampleType outputType = stream->asioChannelInfos[inputChannelCount].type;
2257
2238
 
2258
 
        PA_DEBUG(("ASIO Output type:%d",outputType));
2259
 
        AsioSampleTypeLOG(outputType);
2260
 
        hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType );
 
2239
        PA_DEBUG ( ("ASIO Output type:%d",outputType));
 
2240
        AsioSampleTypeLOG (outputType);
 
2241
        hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat (outputType);
2261
2242
 
2262
 
        SelectPaToAsioConverter( outputType, &stream->outputBufferConverter, &stream->outputShift );
2263
 
    }
2264
 
    else
2265
 
    {
 
2243
        SelectPaToAsioConverter (outputType, &stream->outputBufferConverter, &stream->outputShift);
 
2244
    } else {
2266
2245
        hostOutputSampleFormat = 0;
2267
2246
        stream->outputBufferConverter = 0;
2268
2247
    }
2269
2248
 
2270
2249
 
2271
 
    ASIOGetLatencies( &stream->inputLatency, &stream->outputLatency );
 
2250
    ASIOGetLatencies (&stream->inputLatency, &stream->outputLatency);
2272
2251
 
2273
2252
 
2274
2253
    /* Using blocking i/o interface... */
2275
 
    if( usingBlockingIo )
2276
 
    {
 
2254
    if (usingBlockingIo) {
2277
2255
        /* Allocate the blocking i/o input ring buffer memory. */
2278
 
        stream->blockingState = (PaAsioStreamBlockingState*)PaUtil_AllocateMemory( sizeof(PaAsioStreamBlockingState) );
2279
 
        if( !stream->blockingState )
2280
 
        {
 
2256
        stream->blockingState = (PaAsioStreamBlockingState*) PaUtil_AllocateMemory (sizeof (PaAsioStreamBlockingState));
 
2257
 
 
2258
        if (!stream->blockingState) {
2281
2259
            result = paInsufficientMemory;
2282
 
            PA_DEBUG(("ERROR! Blocking i/o interface struct allocation failed in OpenStream()\n"));
 
2260
            PA_DEBUG ( ("ERROR! Blocking i/o interface struct allocation failed in OpenStream()\n"));
2283
2261
            goto error;
2284
2262
        }
2285
2263
 
2294
2272
 
2295
2273
 
2296
2274
        /* If the user buffer is unspecified */
2297
 
        if( framesPerBuffer == paFramesPerBufferUnspecified )
2298
 
        {
 
2275
        if (framesPerBuffer == paFramesPerBufferUnspecified) {
2299
2276
            /* Make the user buffer the same size as the host buffer. */
2300
2277
            framesPerBuffer = framesPerHostBuffer;
2301
2278
        }
2302
2279
 
2303
2280
 
2304
2281
        /* Initialize callback buffer processor. */
2305
 
        result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor               ,
2306
 
                                                    inputChannelCount                     ,
2307
 
                                                    inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */
2308
 
                                                    hostInputSampleFormat                 , /* Host format. */
2309
 
                                                    outputChannelCount                    ,
2310
 
                                                    outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */
2311
 
                                                    hostOutputSampleFormat                , /* Host format. */
2312
 
                                                    sampleRate                            ,
2313
 
                                                    streamFlags                           ,
2314
 
                                                    framesPerBuffer                       , /* Frames per ring buffer block. */
2315
 
                                                    framesPerHostBuffer                   , /* Frames per asio buffer. */
2316
 
                                                    paUtilFixedHostBufferSize             ,
2317
 
                                                    streamCallback                        ,
2318
 
                                                    userData                               );
2319
 
        if( result != paNoError ){
2320
 
            PA_DEBUG(("OpenStream ERROR13\n"));
 
2282
        result = PaUtil_InitializeBufferProcessor (&stream->bufferProcessor               ,
 
2283
                 inputChannelCount                     ,
 
2284
                 inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */
 
2285
                 hostInputSampleFormat                 , /* Host format. */
 
2286
                 outputChannelCount                    ,
 
2287
                 outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */
 
2288
                 hostOutputSampleFormat                , /* Host format. */
 
2289
                 sampleRate                            ,
 
2290
                 streamFlags                           ,
 
2291
                 framesPerBuffer                       , /* Frames per ring buffer block. */
 
2292
                 framesPerHostBuffer                   , /* Frames per asio buffer. */
 
2293
                 paUtilFixedHostBufferSize             ,
 
2294
                 streamCallback                        ,
 
2295
                 userData);
 
2296
 
 
2297
        if (result != paNoError) {
 
2298
            PA_DEBUG ( ("OpenStream ERROR13\n"));
2321
2299
            goto error;
2322
2300
        }
 
2301
 
2323
2302
        callbackBufferProcessorInited = TRUE;
2324
2303
 
2325
2304
        /* Initialize the blocking i/o buffer processor. */
2326
 
        result = PaUtil_InitializeBufferProcessor(&stream->blockingState->bufferProcessor,
2327
 
                                                   inputChannelCount                     ,
2328
 
                                                   inputSampleFormat                     , /* User format. */
2329
 
                                                   inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */
2330
 
                                                   outputChannelCount                    ,
2331
 
                                                   outputSampleFormat                    , /* User format. */
2332
 
                                                   outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */
2333
 
                                                   sampleRate                            ,
2334
 
                                                   paClipOff | paDitherOff               , /* Don't use dither nor clipping. */
2335
 
                                                   framesPerBuffer                       , /* Frames per user buffer. */
2336
 
                                                   framesPerBuffer                       , /* Frames per ring buffer block. */
2337
 
                                                   paUtilBoundedHostBufferSize           ,
2338
 
                                                   NULL, NULL                            );/* No callback! */
2339
 
        if( result != paNoError ){
2340
 
            PA_DEBUG(("ERROR! Blocking i/o buffer processor initialization failed in OpenStream()\n"));
 
2305
        result = PaUtil_InitializeBufferProcessor (&stream->blockingState->bufferProcessor,
 
2306
                 inputChannelCount                     ,
 
2307
                 inputSampleFormat                     , /* User format. */
 
2308
                 inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */
 
2309
                 outputChannelCount                    ,
 
2310
                 outputSampleFormat                    , /* User format. */
 
2311
                 outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */
 
2312
                 sampleRate                            ,
 
2313
                 paClipOff | paDitherOff               , /* Don't use dither nor clipping. */
 
2314
                 framesPerBuffer                       , /* Frames per user buffer. */
 
2315
                 framesPerBuffer                       , /* Frames per ring buffer block. */
 
2316
                 paUtilBoundedHostBufferSize           ,
 
2317
                 NULL, NULL);                            /* No callback! */
 
2318
 
 
2319
        if (result != paNoError) {
 
2320
            PA_DEBUG ( ("ERROR! Blocking i/o buffer processor initialization failed in OpenStream()\n"));
2341
2321
            goto error;
2342
2322
        }
 
2323
 
2343
2324
        blockingBufferProcessorInited = TRUE;
2344
2325
 
2345
2326
        /* If input is requested. */
2346
 
        if( inputChannelCount )
2347
 
        {
 
2327
        if (inputChannelCount) {
2348
2328
            /* Create the callback sync-event. */
2349
 
            stream->blockingState->readFramesReadyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
2350
 
            if( stream->blockingState->readFramesReadyEvent == NULL )
2351
 
            {
 
2329
            stream->blockingState->readFramesReadyEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
 
2330
 
 
2331
            if (stream->blockingState->readFramesReadyEvent == NULL) {
2352
2332
                result = paUnanticipatedHostError;
2353
 
                PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
2354
 
                PA_DEBUG(("ERROR! Blocking i/o \"read frames ready\" event creation failed in OpenStream()\n"));
 
2333
                PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
 
2334
                PA_DEBUG ( ("ERROR! Blocking i/o \"read frames ready\" event creation failed in OpenStream()\n"));
2355
2335
                goto error;
2356
2336
            }
 
2337
 
2357
2338
            blockingReadFramesReadyEventInitialized = 1;
2358
2339
 
2359
2340
 
2360
2341
            /* Create pointer buffer to access non-interleaved data in ReadStream() */
2361
 
            stream->blockingState->readStreamBuffer = (void**)PaUtil_AllocateMemory( sizeof(void*) * inputChannelCount );
2362
 
            if( !stream->blockingState->readStreamBuffer )
2363
 
            {
 
2342
            stream->blockingState->readStreamBuffer = (void**) PaUtil_AllocateMemory (sizeof (void*) * inputChannelCount);
 
2343
 
 
2344
            if (!stream->blockingState->readStreamBuffer) {
2364
2345
                result = paInsufficientMemory;
2365
 
                PA_DEBUG(("ERROR! Blocking i/o read stream buffer allocation failed in OpenStream()\n"));
 
2346
                PA_DEBUG ( ("ERROR! Blocking i/o read stream buffer allocation failed in OpenStream()\n"));
2366
2347
                goto error;
2367
2348
            }
2368
2349
 
2387
2368
 
2388
2369
            /* Get the next larger or equal power-of-two buffersize. */
2389
2370
            lBlockingBufferSizePow2 = 1;
2390
 
            while( lBlockingBufferSize > (lBlockingBufferSizePow2<<=1) );
 
2371
 
 
2372
            while (lBlockingBufferSize > (lBlockingBufferSizePow2<<=1));
 
2373
 
2391
2374
            lBlockingBufferSize = lBlockingBufferSizePow2;
2392
2375
 
2393
2376
            /* Compute total intput latency in seconds */
2394
2377
            stream->streamRepresentation.streamInfo.inputLatency =
2395
 
                (double)( PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor               )
2396
 
                        + PaUtil_GetBufferProcessorInputLatency(&stream->blockingState->bufferProcessor)
2397
 
                        + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer
2398
 
                        + stream->inputLatency )
 
2378
                (double) (PaUtil_GetBufferProcessorInputLatency (&stream->bufferProcessor)
 
2379
                          + PaUtil_GetBufferProcessorInputLatency (&stream->blockingState->bufferProcessor)
 
2380
                          + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer
 
2381
                          + stream->inputLatency)
2399
2382
                / sampleRate;
2400
2383
 
2401
2384
            /* The code below prints the ASIO latency which doesn't include
2402
2385
               the buffer processor latency nor the blocking i/o latency. It
2403
2386
               reports the added latency separately.
2404
2387
            */
2405
 
            PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms),\n         added buffProc:%ld (%ld ms),\n         added blocking:%ld (%ld ms)\n",
2406
 
                stream->inputLatency,
2407
 
                (long)( stream->inputLatency * (1000.0 / sampleRate) ),
2408
 
                PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor),
2409
 
                (long)( PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor) * (1000.0 / sampleRate) ),
2410
 
                PaUtil_GetBufferProcessorInputLatency(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer,
2411
 
                (long)( (PaUtil_GetBufferProcessorInputLatency(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate) )
2412
 
                ));
 
2388
            PA_DEBUG ( ("PaAsio : ASIO InputLatency = %ld (%ld ms),\n         added buffProc:%ld (%ld ms),\n         added blocking:%ld (%ld ms)\n",
 
2389
                        stream->inputLatency,
 
2390
                        (long) (stream->inputLatency * (1000.0 / sampleRate)),
 
2391
                        PaUtil_GetBufferProcessorInputLatency (&stream->bufferProcessor),
 
2392
                        (long) (PaUtil_GetBufferProcessorInputLatency (&stream->bufferProcessor) * (1000.0 / sampleRate)),
 
2393
                        PaUtil_GetBufferProcessorInputLatency (&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer,
 
2394
                        (long) ( (PaUtil_GetBufferProcessorInputLatency (&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate))
 
2395
                       ));
2413
2396
 
2414
2397
            /* Determine the size of ring buffer in bytes. */
2415
 
            lBytesPerFrame = inputChannelCount * Pa_GetSampleSize(inputSampleFormat );
 
2398
            lBytesPerFrame = inputChannelCount * Pa_GetSampleSize (inputSampleFormat);
2416
2399
 
2417
2400
            /* Allocate the blocking i/o input ring buffer memory. */
2418
 
            stream->blockingState->readRingBufferData = (void*)PaUtil_AllocateMemory( lBlockingBufferSize * lBytesPerFrame );
2419
 
            if( !stream->blockingState->readRingBufferData )
2420
 
            {
 
2401
            stream->blockingState->readRingBufferData = (void*) PaUtil_AllocateMemory (lBlockingBufferSize * lBytesPerFrame);
 
2402
 
 
2403
            if (!stream->blockingState->readRingBufferData) {
2421
2404
                result = paInsufficientMemory;
2422
 
                PA_DEBUG(("ERROR! Blocking i/o input ring buffer allocation failed in OpenStream()\n"));
 
2405
                PA_DEBUG ( ("ERROR! Blocking i/o input ring buffer allocation failed in OpenStream()\n"));
2423
2406
                goto error;
2424
2407
            }
2425
2408
 
2426
2409
            /* Initialize the input ring buffer struct. */
2427
 
            PaUtil_InitializeRingBuffer( &stream->blockingState->readRingBuffer    ,
2428
 
                                          lBytesPerFrame                           ,
2429
 
                                          lBlockingBufferSize                      ,
2430
 
                                          stream->blockingState->readRingBufferData );
 
2410
            PaUtil_InitializeRingBuffer (&stream->blockingState->readRingBuffer    ,
 
2411
                                         lBytesPerFrame                           ,
 
2412
                                         lBlockingBufferSize                      ,
 
2413
                                         stream->blockingState->readRingBufferData);
2431
2414
        }
2432
2415
 
2433
2416
        /* If output is requested. */
2434
 
        if( outputChannelCount )
2435
 
        {
2436
 
            stream->blockingState->writeBuffersReadyEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
2437
 
            if( stream->blockingState->writeBuffersReadyEvent == NULL )
2438
 
            {
 
2417
        if (outputChannelCount) {
 
2418
            stream->blockingState->writeBuffersReadyEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
 
2419
 
 
2420
            if (stream->blockingState->writeBuffersReadyEvent == NULL) {
2439
2421
                result = paUnanticipatedHostError;
2440
 
                PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
2441
 
                PA_DEBUG(("ERROR! Blocking i/o \"write buffers ready\" event creation failed in OpenStream()\n"));
 
2422
                PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
 
2423
                PA_DEBUG ( ("ERROR! Blocking i/o \"write buffers ready\" event creation failed in OpenStream()\n"));
2442
2424
                goto error;
2443
2425
            }
 
2426
 
2444
2427
            blockingWriteBuffersReadyEventInitialized = 1;
2445
2428
 
2446
2429
            /* Create pointer buffer to access non-interleaved data in WriteStream() */
2447
 
            stream->blockingState->writeStreamBuffer = (const void**)PaUtil_AllocateMemory( sizeof(const void*) * outputChannelCount );
2448
 
            if( !stream->blockingState->writeStreamBuffer )
2449
 
            {
 
2430
            stream->blockingState->writeStreamBuffer = (const void**) PaUtil_AllocateMemory (sizeof (const void*) * outputChannelCount);
 
2431
 
 
2432
            if (!stream->blockingState->writeStreamBuffer) {
2450
2433
                result = paInsufficientMemory;
2451
 
                PA_DEBUG(("ERROR! Blocking i/o write stream buffer allocation failed in OpenStream()\n"));
 
2434
                PA_DEBUG ( ("ERROR! Blocking i/o write stream buffer allocation failed in OpenStream()\n"));
2452
2435
                goto error;
2453
2436
            }
2454
2437
 
2478
2461
 
2479
2462
            /* Get the next larger or equal power-of-two buffersize. */
2480
2463
            lBlockingBufferSizePow2 = 1;
2481
 
            while( lBlockingBufferSize > (lBlockingBufferSizePow2<<=1) );
 
2464
 
 
2465
            while (lBlockingBufferSize > (lBlockingBufferSizePow2<<=1));
 
2466
 
2482
2467
            lBlockingBufferSize = lBlockingBufferSizePow2;
2483
2468
 
2484
2469
            /* Compute total output latency in seconds */
2485
2470
            stream->streamRepresentation.streamInfo.outputLatency =
2486
 
                (double)( PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor               )
2487
 
                        + PaUtil_GetBufferProcessorOutputLatency(&stream->blockingState->bufferProcessor)
2488
 
                        + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer
2489
 
                        + stream->outputLatency )
 
2471
                (double) (PaUtil_GetBufferProcessorOutputLatency (&stream->bufferProcessor)
 
2472
                          + PaUtil_GetBufferProcessorOutputLatency (&stream->blockingState->bufferProcessor)
 
2473
                          + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer
 
2474
                          + stream->outputLatency)
2490
2475
                / sampleRate;
2491
2476
 
2492
2477
            /* The code below prints the ASIO latency which doesn't include
2493
2478
               the buffer processor latency nor the blocking i/o latency. It
2494
2479
               reports the added latency separately.
2495
2480
            */
2496
 
            PA_DEBUG(("PaAsio : ASIO OutputLatency = %ld (%ld ms),\n         added buffProc:%ld (%ld ms),\n         added blocking:%ld (%ld ms)\n",
2497
 
                stream->outputLatency,
2498
 
                (long)( stream->inputLatency * (1000.0 / sampleRate) ),
2499
 
                PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor),
2500
 
                (long)( PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor) * (1000.0 / sampleRate) ),
2501
 
                PaUtil_GetBufferProcessorOutputLatency(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer,
2502
 
                (long)( (PaUtil_GetBufferProcessorOutputLatency(&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate) )
2503
 
                ));
 
2481
            PA_DEBUG ( ("PaAsio : ASIO OutputLatency = %ld (%ld ms),\n         added buffProc:%ld (%ld ms),\n         added blocking:%ld (%ld ms)\n",
 
2482
                        stream->outputLatency,
 
2483
                        (long) (stream->inputLatency * (1000.0 / sampleRate)),
 
2484
                        PaUtil_GetBufferProcessorOutputLatency (&stream->bufferProcessor),
 
2485
                        (long) (PaUtil_GetBufferProcessorOutputLatency (&stream->bufferProcessor) * (1000.0 / sampleRate)),
 
2486
                        PaUtil_GetBufferProcessorOutputLatency (&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer,
 
2487
                        (long) ( (PaUtil_GetBufferProcessorOutputLatency (&stream->blockingState->bufferProcessor) + (lBlockingBufferSize / framesPerBuffer - 1) * framesPerBuffer) * (1000.0 / sampleRate))
 
2488
                       ));
2504
2489
 
2505
2490
            /* Determine the size of ring buffer in bytes. */
2506
 
            lBytesPerFrame = outputChannelCount * Pa_GetSampleSize(outputSampleFormat);
 
2491
            lBytesPerFrame = outputChannelCount * Pa_GetSampleSize (outputSampleFormat);
2507
2492
 
2508
2493
            /* Allocate the blocking i/o output ring buffer memory. */
2509
 
            stream->blockingState->writeRingBufferData = (void*)PaUtil_AllocateMemory( lBlockingBufferSize * lBytesPerFrame );
2510
 
            if( !stream->blockingState->writeRingBufferData )
2511
 
            {
 
2494
            stream->blockingState->writeRingBufferData = (void*) PaUtil_AllocateMemory (lBlockingBufferSize * lBytesPerFrame);
 
2495
 
 
2496
            if (!stream->blockingState->writeRingBufferData) {
2512
2497
                result = paInsufficientMemory;
2513
 
                PA_DEBUG(("ERROR! Blocking i/o output ring buffer allocation failed in OpenStream()\n"));
 
2498
                PA_DEBUG ( ("ERROR! Blocking i/o output ring buffer allocation failed in OpenStream()\n"));
2514
2499
                goto error;
2515
2500
            }
2516
2501
 
2517
2502
            /* Initialize the output ring buffer struct. */
2518
 
            PaUtil_InitializeRingBuffer( &stream->blockingState->writeRingBuffer    ,
2519
 
                                          lBytesPerFrame                            ,
2520
 
                                          lBlockingBufferSize                       ,
2521
 
                                          stream->blockingState->writeRingBufferData );
 
2503
            PaUtil_InitializeRingBuffer (&stream->blockingState->writeRingBuffer    ,
 
2504
                                         lBytesPerFrame                            ,
 
2505
                                         lBlockingBufferSize                       ,
 
2506
                                         stream->blockingState->writeRingBufferData);
2522
2507
        }
2523
2508
 
2524
2509
        stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
2525
2510
 
2526
2511
 
2527
 
    }
2528
 
    else /* Using callback interface... */
2529
 
    {
2530
 
        result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
2531
 
                        inputChannelCount, inputSampleFormat, hostInputSampleFormat,
2532
 
                        outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
2533
 
                        sampleRate, streamFlags, framesPerBuffer,
2534
 
                        framesPerHostBuffer, paUtilFixedHostBufferSize,
2535
 
                        streamCallback, userData );
2536
 
        if( result != paNoError ){
2537
 
            PA_DEBUG(("OpenStream ERROR13\n"));
 
2512
    } else { /* Using callback interface... */
 
2513
        result =  PaUtil_InitializeBufferProcessor (&stream->bufferProcessor,
 
2514
                  inputChannelCount, inputSampleFormat, hostInputSampleFormat,
 
2515
                  outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
 
2516
                  sampleRate, streamFlags, framesPerBuffer,
 
2517
                  framesPerHostBuffer, paUtilFixedHostBufferSize,
 
2518
                  streamCallback, userData);
 
2519
 
 
2520
        if (result != paNoError) {
 
2521
            PA_DEBUG ( ("OpenStream ERROR13\n"));
2538
2522
            goto error;
2539
2523
        }
 
2524
 
2540
2525
        callbackBufferProcessorInited = TRUE;
2541
2526
 
2542
2527
        stream->streamRepresentation.streamInfo.inputLatency =
2543
 
                (double)( PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)
2544
 
                    + stream->inputLatency) / sampleRate;   // seconds
 
2528
            (double) (PaUtil_GetBufferProcessorInputLatency (&stream->bufferProcessor)
 
2529
                      + stream->inputLatency) / sampleRate;   // seconds
2545
2530
        stream->streamRepresentation.streamInfo.outputLatency =
2546
 
                (double)( PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)
2547
 
                    + stream->outputLatency) / sampleRate; // seconds
 
2531
            (double) (PaUtil_GetBufferProcessorOutputLatency (&stream->bufferProcessor)
 
2532
                      + stream->outputLatency) / sampleRate; // seconds
2548
2533
        stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
2549
2534
 
2550
2535
        // the code below prints the ASIO latency which doesn't include the
2551
2536
        // buffer processor latency. it reports the added latency separately
2552
 
        PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
2553
 
                stream->inputLatency,
2554
 
                (long)((stream->inputLatency*1000)/ sampleRate),  
2555
 
                PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor),
2556
 
                (long)((PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
2557
 
                ));
 
2537
        PA_DEBUG ( ("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
 
2538
                    stream->inputLatency,
 
2539
                    (long) ( (stream->inputLatency*1000) / sampleRate),
 
2540
                    PaUtil_GetBufferProcessorInputLatency (&stream->bufferProcessor),
 
2541
                    (long) ( (PaUtil_GetBufferProcessorInputLatency (&stream->bufferProcessor) *1000) / sampleRate)
 
2542
                   ));
2558
2543
 
2559
 
        PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
2560
 
                stream->outputLatency,
2561
 
                (long)((stream->outputLatency*1000)/ sampleRate), 
2562
 
                PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor),
2563
 
                (long)((PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
2564
 
                ));
 
2544
        PA_DEBUG ( ("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
 
2545
                    stream->outputLatency,
 
2546
                    (long) ( (stream->outputLatency*1000) / sampleRate),
 
2547
                    PaUtil_GetBufferProcessorOutputLatency (&stream->bufferProcessor),
 
2548
                    (long) ( (PaUtil_GetBufferProcessorOutputLatency (&stream->bufferProcessor) *1000) / sampleRate)
 
2549
                   ));
2565
2550
    }
2566
2551
 
2567
2552
    stream->asioHostApi = asioHostApi;
2572
2557
    stream->postOutput = driverInfo->postOutput;
2573
2558
    stream->isStopped = 1;
2574
2559
    stream->isActive = 0;
2575
 
    
 
2560
 
2576
2561
    asioHostApi->openAsioDeviceIndex = asioDeviceIndex;
2577
2562
 
2578
2563
    theAsioStream = stream;
2579
 
    *s = (PaStream*)stream;
 
2564
    *s = (PaStream*) stream;
2580
2565
 
2581
2566
    return result;
2582
2567
 
2583
2568
error:
2584
 
    PA_DEBUG(("goto errored\n"));
2585
 
    if( stream )
2586
 
    {
2587
 
        if( stream->blockingState )
2588
 
        {
2589
 
            if( blockingBufferProcessorInited )
2590
 
                PaUtil_TerminateBufferProcessor( &stream->blockingState->bufferProcessor );
2591
 
 
2592
 
            if( stream->blockingState->writeRingBufferData )
2593
 
                PaUtil_FreeMemory( stream->blockingState->writeRingBufferData );
2594
 
            if( stream->blockingState->writeStreamBuffer )
2595
 
                PaUtil_FreeMemory( stream->blockingState->writeStreamBuffer );
2596
 
            if( blockingWriteBuffersReadyEventInitialized )
2597
 
                CloseHandle( stream->blockingState->writeBuffersReadyEvent );
2598
 
 
2599
 
            if( stream->blockingState->readRingBufferData )
2600
 
                PaUtil_FreeMemory( stream->blockingState->readRingBufferData );
2601
 
            if( stream->blockingState->readStreamBuffer )
2602
 
                PaUtil_FreeMemory( stream->blockingState->readStreamBuffer );
2603
 
            if( blockingReadFramesReadyEventInitialized )
2604
 
                CloseHandle( stream->blockingState->readFramesReadyEvent );
2605
 
 
2606
 
            PaUtil_FreeMemory( stream->blockingState );
 
2569
    PA_DEBUG ( ("goto errored\n"));
 
2570
 
 
2571
    if (stream) {
 
2572
        if (stream->blockingState) {
 
2573
            if (blockingBufferProcessorInited)
 
2574
                PaUtil_TerminateBufferProcessor (&stream->blockingState->bufferProcessor);
 
2575
 
 
2576
            if (stream->blockingState->writeRingBufferData)
 
2577
                PaUtil_FreeMemory (stream->blockingState->writeRingBufferData);
 
2578
 
 
2579
            if (stream->blockingState->writeStreamBuffer)
 
2580
                PaUtil_FreeMemory (stream->blockingState->writeStreamBuffer);
 
2581
 
 
2582
            if (blockingWriteBuffersReadyEventInitialized)
 
2583
                CloseHandle (stream->blockingState->writeBuffersReadyEvent);
 
2584
 
 
2585
            if (stream->blockingState->readRingBufferData)
 
2586
                PaUtil_FreeMemory (stream->blockingState->readRingBufferData);
 
2587
 
 
2588
            if (stream->blockingState->readStreamBuffer)
 
2589
                PaUtil_FreeMemory (stream->blockingState->readStreamBuffer);
 
2590
 
 
2591
            if (blockingReadFramesReadyEventInitialized)
 
2592
                CloseHandle (stream->blockingState->readFramesReadyEvent);
 
2593
 
 
2594
            PaUtil_FreeMemory (stream->blockingState);
2607
2595
        }
2608
2596
 
2609
 
        if( callbackBufferProcessorInited )
2610
 
            PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
2611
 
 
2612
 
        if( completedBuffersPlayedEventInited )
2613
 
            CloseHandle( stream->completedBuffersPlayedEvent );
2614
 
 
2615
 
        if( stream->asioBufferInfos )
2616
 
            PaUtil_FreeMemory( stream->asioBufferInfos );
2617
 
 
2618
 
        if( stream->asioChannelInfos )
2619
 
            PaUtil_FreeMemory( stream->asioChannelInfos );
2620
 
 
2621
 
        if( stream->bufferPtrs )
2622
 
            PaUtil_FreeMemory( stream->bufferPtrs );
2623
 
 
2624
 
        PaUtil_FreeMemory( stream );
 
2597
        if (callbackBufferProcessorInited)
 
2598
            PaUtil_TerminateBufferProcessor (&stream->bufferProcessor);
 
2599
 
 
2600
        if (completedBuffersPlayedEventInited)
 
2601
            CloseHandle (stream->completedBuffersPlayedEvent);
 
2602
 
 
2603
        if (stream->asioBufferInfos)
 
2604
            PaUtil_FreeMemory (stream->asioBufferInfos);
 
2605
 
 
2606
        if (stream->asioChannelInfos)
 
2607
            PaUtil_FreeMemory (stream->asioChannelInfos);
 
2608
 
 
2609
        if (stream->bufferPtrs)
 
2610
            PaUtil_FreeMemory (stream->bufferPtrs);
 
2611
 
 
2612
        PaUtil_FreeMemory (stream);
2625
2613
    }
2626
2614
 
2627
 
    if( asioBuffersCreated )
 
2615
    if (asioBuffersCreated)
2628
2616
        ASIODisposeBuffers();
2629
2617
 
2630
 
    if( asioIsInitialized )
2631
 
        {
2632
 
                UnloadAsioDriver();
2633
 
        }
 
2618
    if (asioIsInitialized) {
 
2619
        UnloadAsioDriver();
 
2620
    }
 
2621
 
2634
2622
    return result;
2635
2623
}
2636
2624
 
2639
2627
    When CloseStream() is called, the multi-api layer ensures that
2640
2628
    the stream has already been stopped or aborted.
2641
2629
*/
2642
 
static PaError CloseStream( PaStream* s )
 
2630
static PaError CloseStream (PaStream* s)
2643
2631
{
2644
2632
    PaError result = paNoError;
2645
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
2633
    PaAsioStream *stream = (PaAsioStream*) s;
2646
2634
 
2647
2635
    /*
2648
2636
        IMPLEMENT ME:
2649
2637
            - additional stream closing + cleanup
2650
2638
    */
2651
2639
 
2652
 
    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
2653
 
    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
 
2640
    PaUtil_TerminateBufferProcessor (&stream->bufferProcessor);
 
2641
    PaUtil_TerminateStreamRepresentation (&stream->streamRepresentation);
2654
2642
 
2655
2643
    stream->asioHostApi->openAsioDeviceIndex = paNoDevice;
2656
2644
 
2657
 
    CloseHandle( stream->completedBuffersPlayedEvent );
 
2645
    CloseHandle (stream->completedBuffersPlayedEvent);
2658
2646
 
2659
2647
    /* Using blocking i/o interface... */
2660
 
    if( stream->blockingState )
2661
 
    {
2662
 
        PaUtil_TerminateBufferProcessor( &stream->blockingState->bufferProcessor );
2663
 
 
2664
 
        if( stream->inputChannelCount ) {
2665
 
            PaUtil_FreeMemory( stream->blockingState->readRingBufferData );
2666
 
            PaUtil_FreeMemory( stream->blockingState->readStreamBuffer  );
2667
 
            CloseHandle( stream->blockingState->readFramesReadyEvent );
2668
 
        }
2669
 
        if( stream->outputChannelCount ) {
2670
 
            PaUtil_FreeMemory( stream->blockingState->writeRingBufferData );
2671
 
            PaUtil_FreeMemory( stream->blockingState->writeStreamBuffer );
2672
 
            CloseHandle( stream->blockingState->writeBuffersReadyEvent );
2673
 
        }
2674
 
 
2675
 
        PaUtil_FreeMemory( stream->blockingState );
 
2648
    if (stream->blockingState) {
 
2649
        PaUtil_TerminateBufferProcessor (&stream->blockingState->bufferProcessor);
 
2650
 
 
2651
        if (stream->inputChannelCount) {
 
2652
            PaUtil_FreeMemory (stream->blockingState->readRingBufferData);
 
2653
            PaUtil_FreeMemory (stream->blockingState->readStreamBuffer);
 
2654
            CloseHandle (stream->blockingState->readFramesReadyEvent);
 
2655
        }
 
2656
 
 
2657
        if (stream->outputChannelCount) {
 
2658
            PaUtil_FreeMemory (stream->blockingState->writeRingBufferData);
 
2659
            PaUtil_FreeMemory (stream->blockingState->writeStreamBuffer);
 
2660
            CloseHandle (stream->blockingState->writeBuffersReadyEvent);
 
2661
        }
 
2662
 
 
2663
        PaUtil_FreeMemory (stream->blockingState);
2676
2664
    }
2677
2665
 
2678
 
    PaUtil_FreeMemory( stream->asioBufferInfos );
2679
 
    PaUtil_FreeMemory( stream->asioChannelInfos );
2680
 
    PaUtil_FreeMemory( stream->bufferPtrs );
2681
 
    PaUtil_FreeMemory( stream );
 
2666
    PaUtil_FreeMemory (stream->asioBufferInfos);
 
2667
    PaUtil_FreeMemory (stream->asioChannelInfos);
 
2668
    PaUtil_FreeMemory (stream->bufferPtrs);
 
2669
    PaUtil_FreeMemory (stream);
2682
2670
 
2683
2671
    ASIODisposeBuffers();
2684
2672
    UnloadAsioDriver();
2689
2677
}
2690
2678
 
2691
2679
 
2692
 
static void bufferSwitch(long index, ASIOBool directProcess)
 
2680
static void bufferSwitch (long index, ASIOBool directProcess)
2693
2681
{
2694
2682
//TAKEN FROM THE ASIO SDK
2695
2683
 
2703
2691
    // timeInfo.systemTime fields and the according flags
2704
2692
 
2705
2693
    ASIOTime  timeInfo;
2706
 
    memset( &timeInfo, 0, sizeof (timeInfo) );
 
2694
    memset (&timeInfo, 0, sizeof (timeInfo));
2707
2695
 
2708
2696
    // get the time stamp of the buffer, not necessary if no
2709
2697
    // synchronization to other media is required
2710
 
    if( ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK)
2711
 
            timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
 
2698
    if (ASIOGetSamplePosition (&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK)
 
2699
        timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
2712
2700
 
2713
2701
    // Call the real callback
2714
 
    bufferSwitchTimeInfo( &timeInfo, index, directProcess );
 
2702
    bufferSwitchTimeInfo (&timeInfo, index, directProcess);
2715
2703
}
2716
2704
 
2717
2705
 
2718
2706
// conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
2719
2707
#if NATIVE_INT64
2720
 
    #define ASIO64toDouble(a)  (a)
 
2708
#define ASIO64toDouble(a)  (a)
2721
2709
#else
2722
 
    const double twoRaisedTo32 = 4294967296.;
2723
 
    #define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)
 
2710
const double twoRaisedTo32 = 4294967296.;
 
2711
#define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)
2724
2712
#endif
2725
2713
 
2726
 
static ASIOTime *bufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool directProcess )
 
2714
static ASIOTime *bufferSwitchTimeInfo (ASIOTime *timeInfo, long index, ASIOBool directProcess)
2727
2715
{
2728
2716
    // the actual processing callback.
2729
2717
    // Beware that this is normally in a seperate thread, hence be sure that
2752
2740
    // synchronization to other media is required
2753
2741
 
2754
2742
    if (timeInfo->timeInfo.flags & kSystemTimeValid)
2755
 
            asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
 
2743
        asioDriverInfo.nanoSeconds = ASIO64toDouble (timeInfo->timeInfo.systemTime);
2756
2744
    else
2757
 
            asioDriverInfo.nanoSeconds = 0;
 
2745
        asioDriverInfo.nanoSeconds = 0;
2758
2746
 
2759
2747
    if (timeInfo->timeInfo.flags & kSamplePositionValid)
2760
 
            asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
 
2748
        asioDriverInfo.samples = ASIO64toDouble (timeInfo->timeInfo.samplePosition);
2761
2749
    else
2762
 
            asioDriverInfo.samples = 0;
 
2750
        asioDriverInfo.samples = 0;
2763
2751
 
2764
2752
    if (timeInfo->timeCode.flags & kTcValid)
2765
 
            asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
 
2753
        asioDriverInfo.tcSamples = ASIO64toDouble (timeInfo->timeCode.timeCodeSamples);
2766
2754
    else
2767
 
            asioDriverInfo.tcSamples = 0;
 
2755
        asioDriverInfo.tcSamples = 0;
2768
2756
 
2769
2757
    // get the system reference time
2770
2758
    asioDriverInfo.sysRefTime = get_sys_reference_time();
2776
2764
    // the event notification.
2777
2765
    static double last_samples = 0;
2778
2766
    char tmp[128];
2779
 
    sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples                 \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples));
 
2767
    sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples                 \n", asioDriverInfo.sysRefTime - (long) (asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long) (asioDriverInfo.nanoSeconds / 1000000.0), (long) (asioDriverInfo.samples - last_samples));
2780
2768
    OutputDebugString (tmp);
2781
2769
    last_samples = asioDriverInfo.samples;
2782
2770
#endif
2783
2771
 
2784
2772
 
2785
 
    if( !theAsioStream )
 
2773
    if (!theAsioStream)
2786
2774
        return 0L;
2787
2775
 
2788
2776
    // Keep sample position
2790
2778
 
2791
2779
 
2792
2780
    // protect against reentrancy
2793
 
    if( PaAsio_AtomicIncrement(&theAsioStream->reenterCount) )
2794
 
    {
 
2781
    if (PaAsio_AtomicIncrement (&theAsioStream->reenterCount)) {
2795
2782
        theAsioStream->reenterError++;
2796
2783
        //DBUG(("bufferSwitchTimeInfo : reentrancy detection = %d\n", asioDriverInfo.reenterError));
2797
2784
        return 0L;
2798
2785
    }
2799
2786
 
2800
2787
    int buffersDone = 0;
2801
 
    
2802
 
    do
2803
 
    {
2804
 
        if( buffersDone > 0 )
2805
 
        {
 
2788
 
 
2789
    do {
 
2790
        if (buffersDone > 0) {
2806
2791
            // this is a reentered buffer, we missed processing it on time
2807
2792
            // set the input overflow and output underflow flags as appropriate
2808
 
            
2809
 
            if( theAsioStream->inputChannelCount > 0 )
 
2793
 
 
2794
            if (theAsioStream->inputChannelCount > 0)
2810
2795
                theAsioStream->callbackFlags |= paInputOverflow;
2811
 
                
2812
 
            if( theAsioStream->outputChannelCount > 0 )
 
2796
 
 
2797
            if (theAsioStream->outputChannelCount > 0)
2813
2798
                theAsioStream->callbackFlags |= paOutputUnderflow;
2814
 
        }
2815
 
        else
2816
 
        {
2817
 
            if( theAsioStream->zeroOutput )
2818
 
            {
2819
 
                ZeroOutputBuffers( theAsioStream, index );
 
2799
        } else {
 
2800
            if (theAsioStream->zeroOutput) {
 
2801
                ZeroOutputBuffers (theAsioStream, index);
2820
2802
 
2821
2803
                // Finally if the driver supports the ASIOOutputReady() optimization,
2822
2804
                // do it here, all data are in place
2823
 
                if( theAsioStream->postOutput )
 
2805
                if (theAsioStream->postOutput)
2824
2806
                    ASIOOutputReady();
2825
2807
 
2826
 
                if( theAsioStream->stopProcessing )
2827
 
                {
2828
 
                    if( theAsioStream->stopPlayoutCount < 2 )
2829
 
                    {
 
2808
                if (theAsioStream->stopProcessing) {
 
2809
                    if (theAsioStream->stopPlayoutCount < 2) {
2830
2810
                        ++theAsioStream->stopPlayoutCount;
2831
 
                        if( theAsioStream->stopPlayoutCount == 2 )
2832
 
                        {
 
2811
 
 
2812
                        if (theAsioStream->stopPlayoutCount == 2) {
2833
2813
                            theAsioStream->isActive = 0;
2834
 
                            if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 )
2835
 
                                theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData );
 
2814
 
 
2815
                            if (theAsioStream->streamRepresentation.streamFinishedCallback != 0)
 
2816
                                theAsioStream->streamRepresentation.streamFinishedCallback (theAsioStream->streamRepresentation.userData);
 
2817
 
2836
2818
                            theAsioStream->streamFinishedCallbackCalled = true;
2837
 
                            SetEvent( theAsioStream->completedBuffersPlayedEvent );
 
2819
                            SetEvent (theAsioStream->completedBuffersPlayedEvent);
2838
2820
                        }
2839
2821
                    }
2840
2822
                }
2841
 
            }
2842
 
            else
2843
 
            {
 
2823
            } else {
2844
2824
 
2845
2825
#if 0
2846
2826
// test code to try to detect slip conditions... these may work on some systems
2848
2828
 
2849
2829
// check that sample delta matches buffer size (otherwise we must have skipped
2850
2830
// a buffer.
2851
 
static double last_samples = -512;
2852
 
double samples;
 
2831
                static double last_samples = -512;
 
2832
                double samples;
2853
2833
//if( timeInfo->timeCode.flags & kTcValid )
2854
2834
//    samples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
2855
2835
//else
2856
 
    samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
2857
 
int delta = samples - last_samples;
 
2836
                samples = ASIO64toDouble (timeInfo->timeInfo.samplePosition);
 
2837
                int delta = samples - last_samples;
2858
2838
//printf( "%d\n", delta);
2859
 
last_samples = samples;
2860
 
 
2861
 
if( delta > theAsioStream->framesPerHostCallback )
2862
 
{
2863
 
    if( theAsioStream->inputChannelCount > 0 )
2864
 
        theAsioStream->callbackFlags |= paInputOverflow;
2865
 
 
2866
 
    if( theAsioStream->outputChannelCount > 0 )
2867
 
        theAsioStream->callbackFlags |= paOutputUnderflow;
2868
 
}
 
2839
                last_samples = samples;
 
2840
 
 
2841
                if (delta > theAsioStream->framesPerHostCallback) {
 
2842
                    if (theAsioStream->inputChannelCount > 0)
 
2843
                        theAsioStream->callbackFlags |= paInputOverflow;
 
2844
 
 
2845
                    if (theAsioStream->outputChannelCount > 0)
 
2846
                        theAsioStream->callbackFlags |= paOutputUnderflow;
 
2847
                }
2869
2848
 
2870
2849
// check that the buffer index is not the previous index (which would indicate
2871
2850
// that a buffer was skipped.
2872
 
static int previousIndex = 1;
2873
 
if( index == previousIndex )
2874
 
{
2875
 
    if( theAsioStream->inputChannelCount > 0 )
2876
 
        theAsioStream->callbackFlags |= paInputOverflow;
2877
 
 
2878
 
    if( theAsioStream->outputChannelCount > 0 )
2879
 
        theAsioStream->callbackFlags |= paOutputUnderflow;
2880
 
}
2881
 
previousIndex = index;
 
2851
                static int previousIndex = 1;
 
2852
 
 
2853
                if (index == previousIndex) {
 
2854
                    if (theAsioStream->inputChannelCount > 0)
 
2855
                        theAsioStream->callbackFlags |= paInputOverflow;
 
2856
 
 
2857
                    if (theAsioStream->outputChannelCount > 0)
 
2858
                        theAsioStream->callbackFlags |= paOutputUnderflow;
 
2859
                }
 
2860
 
 
2861
                previousIndex = index;
2882
2862
#endif
2883
2863
 
2884
2864
                int i;
2885
2865
 
2886
 
                PaUtil_BeginCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer );
 
2866
                PaUtil_BeginCpuLoadMeasurement (&theAsioStream->cpuLoadMeasurer);
2887
2867
 
2888
2868
                PaStreamCallbackTimeInfo paTimeInfo;
2889
2869
 
2890
2870
                // asio systemTime is supposed to be measured according to the same
2891
2871
                // clock as timeGetTime
2892
 
                paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001);
 
2872
                paTimeInfo.currentTime = (ASIO64toDouble (timeInfo->timeInfo.systemTime) * .000000001);
2893
2873
 
2894
2874
                /* patch from Paul Boege */
2895
2875
                paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime -
2896
 
                    ((double)theAsioStream->inputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
 
2876
                                                ( (double) theAsioStream->inputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
2897
2877
 
2898
2878
                paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime +
2899
 
                    ((double)theAsioStream->outputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
 
2879
                                                 ( (double) theAsioStream->outputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
2900
2880
 
2901
2881
                /* old version is buggy because the buffer processor also adds in its latency to the time parameters
2902
2882
                paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency;
2903
2883
                paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency;
2904
2884
                */
2905
2885
 
2906
 
/* Disabled! Stopping and re-starting the stream causes an input overflow / output undeflow. S.Fischer */
 
2886
                /* Disabled! Stopping and re-starting the stream causes an input overflow / output undeflow. S.Fischer */
2907
2887
#if 0
2908
2888
// detect underflows by checking inter-callback time > 2 buffer period
2909
 
static double previousTime = -1;
2910
 
if( previousTime > 0 ){
2911
 
 
2912
 
    double delta = paTimeInfo.currentTime - previousTime;
2913
 
 
2914
 
    if( delta >= 2. * (theAsioStream->framesPerHostCallback / theAsioStream->streamRepresentation.streamInfo.sampleRate) ){
2915
 
        if( theAsioStream->inputChannelCount > 0 )
2916
 
            theAsioStream->callbackFlags |= paInputOverflow;
2917
 
 
2918
 
        if( theAsioStream->outputChannelCount > 0 )
2919
 
            theAsioStream->callbackFlags |= paOutputUnderflow;
2920
 
    }
2921
 
}
2922
 
previousTime = paTimeInfo.currentTime;
 
2889
                static double previousTime = -1;
 
2890
 
 
2891
                if (previousTime > 0) {
 
2892
 
 
2893
                    double delta = paTimeInfo.currentTime - previousTime;
 
2894
 
 
2895
                    if (delta >= 2. * (theAsioStream->framesPerHostCallback / theAsioStream->streamRepresentation.streamInfo.sampleRate)) {
 
2896
                        if (theAsioStream->inputChannelCount > 0)
 
2897
                            theAsioStream->callbackFlags |= paInputOverflow;
 
2898
 
 
2899
                        if (theAsioStream->outputChannelCount > 0)
 
2900
                            theAsioStream->callbackFlags |= paOutputUnderflow;
 
2901
                    }
 
2902
                }
 
2903
 
 
2904
                previousTime = paTimeInfo.currentTime;
2923
2905
#endif
2924
2906
 
2925
2907
                // note that the above input and output times do not need to be
2926
2908
                // adjusted for the latency of the buffer processor -- the buffer
2927
2909
                // processor handles that.
2928
2910
 
2929
 
                if( theAsioStream->inputBufferConverter )
2930
 
                {
2931
 
                    for( i=0; i<theAsioStream->inputChannelCount; i++ )
2932
 
                    {
2933
 
                        theAsioStream->inputBufferConverter( theAsioStream->inputBufferPtrs[index][i],
2934
 
                                theAsioStream->inputShift, theAsioStream->framesPerHostCallback );
 
2911
                if (theAsioStream->inputBufferConverter) {
 
2912
                    for (i=0; i<theAsioStream->inputChannelCount; i++) {
 
2913
                        theAsioStream->inputBufferConverter (theAsioStream->inputBufferPtrs[index][i],
 
2914
                                                             theAsioStream->inputShift, theAsioStream->framesPerHostCallback);
2935
2915
                    }
2936
2916
                }
2937
2917
 
2938
 
                PaUtil_BeginBufferProcessing( &theAsioStream->bufferProcessor, &paTimeInfo, theAsioStream->callbackFlags );
 
2918
                PaUtil_BeginBufferProcessing (&theAsioStream->bufferProcessor, &paTimeInfo, theAsioStream->callbackFlags);
2939
2919
 
2940
2920
                /* reset status flags once they've been passed to the callback */
2941
2921
                theAsioStream->callbackFlags = 0;
2942
2922
 
2943
 
                PaUtil_SetInputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ );
2944
 
                for( i=0; i<theAsioStream->inputChannelCount; ++i )
2945
 
                    PaUtil_SetNonInterleavedInputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->inputBufferPtrs[index][i] );
2946
 
 
2947
 
                PaUtil_SetOutputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ );
2948
 
                for( i=0; i<theAsioStream->outputChannelCount; ++i )
2949
 
                    PaUtil_SetNonInterleavedOutputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i] );
 
2923
                PaUtil_SetInputFrameCount (&theAsioStream->bufferProcessor, 0 /* default to host buffer size */);
 
2924
 
 
2925
                for (i=0; i<theAsioStream->inputChannelCount; ++i)
 
2926
                    PaUtil_SetNonInterleavedInputChannel (&theAsioStream->bufferProcessor, i, theAsioStream->inputBufferPtrs[index][i]);
 
2927
 
 
2928
                PaUtil_SetOutputFrameCount (&theAsioStream->bufferProcessor, 0 /* default to host buffer size */);
 
2929
 
 
2930
                for (i=0; i<theAsioStream->outputChannelCount; ++i)
 
2931
                    PaUtil_SetNonInterleavedOutputChannel (&theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i]);
2950
2932
 
2951
2933
                int callbackResult;
2952
 
                if( theAsioStream->stopProcessing )
 
2934
 
 
2935
                if (theAsioStream->stopProcessing)
2953
2936
                    callbackResult = paComplete;
2954
2937
                else
2955
2938
                    callbackResult = paContinue;
2956
 
                unsigned long framesProcessed = PaUtil_EndBufferProcessing( &theAsioStream->bufferProcessor, &callbackResult );
2957
 
 
2958
 
                if( theAsioStream->outputBufferConverter )
2959
 
                {
2960
 
                    for( i=0; i<theAsioStream->outputChannelCount; i++ )
2961
 
                    {
2962
 
                        theAsioStream->outputBufferConverter( theAsioStream->outputBufferPtrs[index][i],
2963
 
                                theAsioStream->outputShift, theAsioStream->framesPerHostCallback );
 
2939
 
 
2940
                unsigned long framesProcessed = PaUtil_EndBufferProcessing (&theAsioStream->bufferProcessor, &callbackResult);
 
2941
 
 
2942
                if (theAsioStream->outputBufferConverter) {
 
2943
                    for (i=0; i<theAsioStream->outputChannelCount; i++) {
 
2944
                        theAsioStream->outputBufferConverter (theAsioStream->outputBufferPtrs[index][i],
 
2945
                                                              theAsioStream->outputShift, theAsioStream->framesPerHostCallback);
2964
2946
                    }
2965
2947
                }
2966
2948
 
2967
 
                PaUtil_EndCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer, framesProcessed );
 
2949
                PaUtil_EndCpuLoadMeasurement (&theAsioStream->cpuLoadMeasurer, framesProcessed);
2968
2950
 
2969
2951
                // Finally if the driver supports the ASIOOutputReady() optimization,
2970
2952
                // do it here, all data are in place
2971
 
                if( theAsioStream->postOutput )
 
2953
                if (theAsioStream->postOutput)
2972
2954
                    ASIOOutputReady();
2973
2955
 
2974
 
                if( callbackResult == paContinue )
2975
 
                {
 
2956
                if (callbackResult == paContinue) {
2976
2957
                    /* nothing special to do */
2977
 
                }
2978
 
                else if( callbackResult == paAbort )
2979
 
                {
 
2958
                } else if (callbackResult == paAbort) {
2980
2959
                    /* finish playback immediately  */
2981
2960
                    theAsioStream->isActive = 0;
2982
 
                    if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 )
2983
 
                        theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData );
 
2961
 
 
2962
                    if (theAsioStream->streamRepresentation.streamFinishedCallback != 0)
 
2963
                        theAsioStream->streamRepresentation.streamFinishedCallback (theAsioStream->streamRepresentation.userData);
 
2964
 
2984
2965
                    theAsioStream->streamFinishedCallbackCalled = true;
2985
 
                    SetEvent( theAsioStream->completedBuffersPlayedEvent );
 
2966
                    SetEvent (theAsioStream->completedBuffersPlayedEvent);
2986
2967
                    theAsioStream->zeroOutput = true;
2987
 
                }
2988
 
                else /* paComplete or other non-zero value indicating complete */
2989
 
                {
 
2968
                } else { /* paComplete or other non-zero value indicating complete */
2990
2969
                    /* Finish playback once currently queued audio has completed. */
2991
2970
                    theAsioStream->stopProcessing = true;
2992
2971
 
2993
 
                    if( PaUtil_IsBufferProcessorOutputEmpty( &theAsioStream->bufferProcessor ) )
2994
 
                    {
 
2972
                    if (PaUtil_IsBufferProcessorOutputEmpty (&theAsioStream->bufferProcessor)) {
2995
2973
                        theAsioStream->zeroOutput = true;
2996
2974
                        theAsioStream->stopPlayoutCount = 0;
2997
2975
                    }
2998
2976
                }
2999
2977
            }
3000
2978
        }
3001
 
        
 
2979
 
3002
2980
        ++buffersDone;
3003
 
    }while( PaAsio_AtomicDecrement(&theAsioStream->reenterCount) >= 0 );
 
2981
    } while (PaAsio_AtomicDecrement (&theAsioStream->reenterCount) >= 0);
3004
2982
 
3005
2983
    return 0L;
3006
2984
}
3007
2985
 
3008
2986
 
3009
 
static void sampleRateChanged(ASIOSampleRate sRate)
 
2987
static void sampleRateChanged (ASIOSampleRate sRate)
3010
2988
{
3011
2989
    // TAKEN FROM THE ASIO SDK
3012
2990
    // do whatever you need to do if the sample rate changed
3017
2995
    // You might have to update time/sample related conversion routines, etc.
3018
2996
 
3019
2997
    (void) sRate; /* unused parameter */
3020
 
    PA_DEBUG( ("sampleRateChanged : %d \n", sRate));
 
2998
    PA_DEBUG ( ("sampleRateChanged : %d \n", sRate));
3021
2999
}
3022
3000
 
3023
 
static long asioMessages(long selector, long value, void* message, double* opt)
 
3001
static long asioMessages (long selector, long value, void* message, double* opt)
3024
3002
{
3025
3003
// TAKEN FROM THE ASIO SDK
3026
3004
    // currently the parameters "value", "message" and "opt" are not used.
3029
3007
    (void) message; /* unused parameters */
3030
3008
    (void) opt;
3031
3009
 
3032
 
    PA_DEBUG( ("asioMessages : %d , %d \n", selector, value));
 
3010
    PA_DEBUG ( ("asioMessages : %d , %d \n", selector, value));
3033
3011
 
3034
 
    switch(selector)
3035
 
    {
 
3012
    switch (selector) {
3036
3013
        case kAsioSelectorSupported:
3037
 
            if(value == kAsioResetRequest
3038
 
            || value == kAsioEngineVersion
3039
 
            || value == kAsioResyncRequest
3040
 
            || value == kAsioLatenciesChanged
3041
 
            // the following three were added for ASIO 2.0, you don't necessarily have to support them
3042
 
            || value == kAsioSupportsTimeInfo
3043
 
            || value == kAsioSupportsTimeCode
3044
 
            || value == kAsioSupportsInputMonitor)
3045
 
                    ret = 1L;
 
3014
 
 
3015
            if (value == kAsioResetRequest
 
3016
                    || value == kAsioEngineVersion
 
3017
                    || value == kAsioResyncRequest
 
3018
                    || value == kAsioLatenciesChanged
 
3019
                    // the following three were added for ASIO 2.0, you don't necessarily have to support them
 
3020
                    || value == kAsioSupportsTimeInfo
 
3021
                    || value == kAsioSupportsTimeCode
 
3022
                    || value == kAsioSupportsInputMonitor)
 
3023
                ret = 1L;
 
3024
 
3046
3025
            break;
3047
3026
 
3048
3027
        case kAsioBufferSizeChange:
3100
3079
            ret = 0;
3101
3080
            break;
3102
3081
    }
 
3082
 
3103
3083
    return ret;
3104
3084
}
3105
3085
 
3106
3086
 
3107
 
static PaError StartStream( PaStream *s )
 
3087
static PaError StartStream (PaStream *s)
3108
3088
{
3109
3089
    PaError result = paNoError;
3110
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3090
    PaAsioStream *stream = (PaAsioStream*) s;
3111
3091
    PaAsioStreamBlockingState *blockingState = stream->blockingState;
3112
3092
    ASIOError asioError;
3113
3093
 
3114
 
    if( stream->outputChannelCount > 0 )
3115
 
    {
3116
 
        ZeroOutputBuffers( stream, 0 );
3117
 
        ZeroOutputBuffers( stream, 1 );
 
3094
    if (stream->outputChannelCount > 0) {
 
3095
        ZeroOutputBuffers (stream, 0);
 
3096
        ZeroOutputBuffers (stream, 1);
3118
3097
    }
3119
3098
 
3120
 
    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
 
3099
    PaUtil_ResetBufferProcessor (&stream->bufferProcessor);
3121
3100
    stream->stopProcessing = false;
3122
3101
    stream->zeroOutput = false;
3123
3102
 
3127
3106
 
3128
3107
    stream->callbackFlags = 0;
3129
3108
 
3130
 
    if( ResetEvent( stream->completedBuffersPlayedEvent ) == 0 )
3131
 
    {
 
3109
    if (ResetEvent (stream->completedBuffersPlayedEvent) == 0) {
3132
3110
        result = paUnanticipatedHostError;
3133
 
        PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
 
3111
        PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
3134
3112
    }
3135
3113
 
3136
3114
 
3137
3115
    /* Using blocking i/o interface... */
3138
 
    if( blockingState )
3139
 
    {
 
3116
    if (blockingState) {
3140
3117
        /* Reset blocking i/o buffer processor. */
3141
 
        PaUtil_ResetBufferProcessor( &blockingState->bufferProcessor );
 
3118
        PaUtil_ResetBufferProcessor (&blockingState->bufferProcessor);
3142
3119
 
3143
3120
        /* If we're about to process some input data. */
3144
 
        if( stream->inputChannelCount )
3145
 
        {
 
3121
        if (stream->inputChannelCount) {
3146
3122
            /* Reset callback-ReadStream sync event. */
3147
 
            if( ResetEvent( blockingState->readFramesReadyEvent ) == 0 )
3148
 
            {
 
3123
            if (ResetEvent (blockingState->readFramesReadyEvent) == 0) {
3149
3124
                result = paUnanticipatedHostError;
3150
 
                PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
 
3125
                PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
3151
3126
            }
3152
3127
 
3153
3128
            /* Flush blocking i/o ring buffer. */
3154
 
            PaUtil_FlushRingBuffer( &blockingState->readRingBuffer );
3155
 
            (*blockingState->bufferProcessor.inputZeroer)( blockingState->readRingBuffer.buffer, 1, blockingState->bufferProcessor.inputChannelCount * blockingState->readRingBuffer.bufferSize );
 
3129
            PaUtil_FlushRingBuffer (&blockingState->readRingBuffer);
 
3130
            (*blockingState->bufferProcessor.inputZeroer) (blockingState->readRingBuffer.buffer, 1, blockingState->bufferProcessor.inputChannelCount * blockingState->readRingBuffer.bufferSize);
3156
3131
        }
3157
3132
 
3158
3133
        /* If we're about to process some output data. */
3159
 
        if( stream->outputChannelCount )
3160
 
        {
 
3134
        if (stream->outputChannelCount) {
3161
3135
            /* Reset callback-WriteStream sync event. */
3162
 
            if( ResetEvent( blockingState->writeBuffersReadyEvent ) == 0 )
3163
 
            {
 
3136
            if (ResetEvent (blockingState->writeBuffersReadyEvent) == 0) {
3164
3137
                result = paUnanticipatedHostError;
3165
 
                PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
 
3138
                PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
3166
3139
            }
3167
3140
 
3168
3141
            /* Flush blocking i/o ring buffer. */
3169
 
            PaUtil_FlushRingBuffer( &blockingState->writeRingBuffer );
3170
 
            (*blockingState->bufferProcessor.outputZeroer)( blockingState->writeRingBuffer.buffer, 1, blockingState->bufferProcessor.outputChannelCount * blockingState->writeRingBuffer.bufferSize );
 
3142
            PaUtil_FlushRingBuffer (&blockingState->writeRingBuffer);
 
3143
            (*blockingState->bufferProcessor.outputZeroer) (blockingState->writeRingBuffer.buffer, 1, blockingState->bufferProcessor.outputChannelCount * blockingState->writeRingBuffer.bufferSize);
3171
3144
 
3172
3145
            /* Initialize the output ring buffer to "silence". */
3173
 
            PaUtil_AdvanceRingBufferWriteIndex( &blockingState->writeRingBuffer, blockingState->writeRingBufferInitialFrames );
 
3146
            PaUtil_AdvanceRingBufferWriteIndex (&blockingState->writeRingBuffer, blockingState->writeRingBufferInitialFrames);
3174
3147
        }
3175
3148
 
3176
3149
        /* Clear requested frames / buffers count. */
3184
3157
    }
3185
3158
 
3186
3159
 
3187
 
    if( result == paNoError )
3188
 
    {
3189
 
        assert( theAsioStream == stream ); /* theAsioStream should be set correctly in OpenStream */
 
3160
    if (result == paNoError) {
 
3161
        assert (theAsioStream == stream);  /* theAsioStream should be set correctly in OpenStream */
3190
3162
 
3191
3163
        /* initialize these variables before the callback has a chance to be invoked */
3192
3164
        stream->isStopped = 0;
3194
3166
        stream->streamFinishedCallbackCalled = false;
3195
3167
 
3196
3168
        asioError = ASIOStart();
3197
 
        if( asioError != ASE_OK )
3198
 
        {
 
3169
 
 
3170
        if (asioError != ASE_OK) {
3199
3171
            stream->isStopped = 1;
3200
3172
            stream->isActive = 0;
3201
3173
 
3202
3174
            result = paUnanticipatedHostError;
3203
 
            PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
3175
            PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
3204
3176
        }
3205
3177
    }
3206
3178
 
3207
3179
    return result;
3208
3180
}
3209
3181
 
3210
 
static void EnsureCallbackHasCompleted( PaAsioStream *stream )
 
3182
static void EnsureCallbackHasCompleted (PaAsioStream *stream)
3211
3183
{
3212
3184
    // make sure that the callback is not still in-flight after ASIOStop()
3213
3185
    // returns. This has been observed to happen on the Hoontech DSP24 for
3214
3186
    // example.
3215
3187
    int count = 2000;  // only wait for 2 seconds, rather than hanging.
3216
 
    while( stream->reenterCount != -1 && count > 0 )
3217
 
    {
3218
 
        Sleep(1);
 
3188
 
 
3189
    while (stream->reenterCount != -1 && count > 0) {
 
3190
        Sleep (1);
3219
3191
        --count;
3220
3192
    }
3221
3193
}
3222
3194
 
3223
 
static PaError StopStream( PaStream *s )
 
3195
static PaError StopStream (PaStream *s)
3224
3196
{
3225
3197
    PaError result = paNoError;
3226
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3198
    PaAsioStream *stream = (PaAsioStream*) s;
3227
3199
    PaAsioStreamBlockingState *blockingState = stream->blockingState;
3228
3200
    ASIOError asioError;
3229
3201
 
3230
 
    if( stream->isActive )
3231
 
    {
 
3202
    if (stream->isActive) {
3232
3203
        /* If blocking i/o output is in use */
3233
 
        if( blockingState && stream->outputChannelCount )
3234
 
        {
 
3204
        if (blockingState && stream->outputChannelCount) {
3235
3205
            /* Request the whole output buffer to be available. */
3236
3206
            blockingState->writeBuffersRequested = blockingState->writeRingBuffer.bufferSize;
3237
3207
            /* Signalize that additional buffers are need. */
3242
3212
            /* Wait until requested number of buffers has been freed. Time
3243
3213
               out after twice the blocking i/o ouput buffer could have
3244
3214
               been consumed. */
3245
 
            DWORD timeout = (DWORD)( 2 * blockingState->writeRingBuffer.bufferSize * 1000
3246
 
                                       / stream->streamRepresentation.streamInfo.sampleRate );
3247
 
            DWORD waitResult = WaitForSingleObject( blockingState->writeBuffersReadyEvent, timeout );
 
3215
            DWORD timeout = (DWORD) (2 * blockingState->writeRingBuffer.bufferSize * 1000
 
3216
                                     / stream->streamRepresentation.streamInfo.sampleRate);
 
3217
            DWORD waitResult = WaitForSingleObject (blockingState->writeBuffersReadyEvent, timeout);
3248
3218
 
3249
3219
            /* If something seriously went wrong... */
3250
 
            if( waitResult == WAIT_FAILED )
3251
 
            {
3252
 
                PA_DEBUG(("WaitForSingleObject() failed in StopStream()\n"));
 
3220
            if (waitResult == WAIT_FAILED) {
 
3221
                PA_DEBUG ( ("WaitForSingleObject() failed in StopStream()\n"));
3253
3222
                result = paUnanticipatedHostError;
3254
 
                PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
3255
 
            }
3256
 
            else if( waitResult == WAIT_TIMEOUT )
3257
 
            {
3258
 
                PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n"));
 
3223
                PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
 
3224
            } else if (waitResult == WAIT_TIMEOUT) {
 
3225
                PA_DEBUG ( ("WaitForSingleObject() timed out in StopStream()\n"));
3259
3226
                result = paTimedOut;
3260
3227
            }
3261
3228
        }
3269
3236
            length is longer than the asio buffer size then that should
3270
3237
            be taken into account.
3271
3238
        */
3272
 
        if( WaitForSingleObject( stream->completedBuffersPlayedEvent,
3273
 
                (DWORD)(stream->streamRepresentation.streamInfo.outputLatency * 1000. * 4.) )
3274
 
                    == WAIT_TIMEOUT )
3275
 
        {
3276
 
            PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n" ));
 
3239
        if (WaitForSingleObject (stream->completedBuffersPlayedEvent,
 
3240
                                 (DWORD) (stream->streamRepresentation.streamInfo.outputLatency * 1000. * 4.))
 
3241
                == WAIT_TIMEOUT) {
 
3242
            PA_DEBUG ( ("WaitForSingleObject() timed out in StopStream()\n"));
3277
3243
        }
3278
3244
    }
3279
3245
 
3280
3246
    asioError = ASIOStop();
3281
 
    if( asioError == ASE_OK )
3282
 
    {
3283
 
        EnsureCallbackHasCompleted( stream );
3284
 
    }
3285
 
    else
3286
 
    {
 
3247
 
 
3248
    if (asioError == ASE_OK) {
 
3249
        EnsureCallbackHasCompleted (stream);
 
3250
    } else {
3287
3251
        result = paUnanticipatedHostError;
3288
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
3252
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
3289
3253
    }
3290
3254
 
3291
3255
    stream->isStopped = 1;
3292
3256
    stream->isActive = 0;
3293
3257
 
3294
 
    if( !stream->streamFinishedCallbackCalled )
3295
 
    {
3296
 
        if( stream->streamRepresentation.streamFinishedCallback != 0 )
3297
 
            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
 
3258
    if (!stream->streamFinishedCallbackCalled) {
 
3259
        if (stream->streamRepresentation.streamFinishedCallback != 0)
 
3260
            stream->streamRepresentation.streamFinishedCallback (stream->streamRepresentation.userData);
3298
3261
    }
3299
3262
 
3300
3263
    return result;
3301
3264
}
3302
3265
 
3303
 
static PaError AbortStream( PaStream *s )
 
3266
static PaError AbortStream (PaStream *s)
3304
3267
{
3305
3268
    PaError result = paNoError;
3306
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3269
    PaAsioStream *stream = (PaAsioStream*) s;
3307
3270
    ASIOError asioError;
3308
3271
 
3309
3272
    stream->zeroOutput = true;
3310
3273
 
3311
3274
    asioError = ASIOStop();
3312
 
    if( asioError == ASE_OK )
3313
 
    {
3314
 
        EnsureCallbackHasCompleted( stream );
3315
 
    }
3316
 
    else
3317
 
    {
 
3275
 
 
3276
    if (asioError == ASE_OK) {
 
3277
        EnsureCallbackHasCompleted (stream);
 
3278
    } else {
3318
3279
        result = paUnanticipatedHostError;
3319
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
3280
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
3320
3281
    }
3321
3282
 
3322
3283
    stream->isStopped = 1;
3323
3284
    stream->isActive = 0;
3324
3285
 
3325
 
    if( !stream->streamFinishedCallbackCalled )
3326
 
    {
3327
 
        if( stream->streamRepresentation.streamFinishedCallback != 0 )
3328
 
            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
 
3286
    if (!stream->streamFinishedCallbackCalled) {
 
3287
        if (stream->streamRepresentation.streamFinishedCallback != 0)
 
3288
            stream->streamRepresentation.streamFinishedCallback (stream->streamRepresentation.userData);
3329
3289
    }
3330
3290
 
3331
3291
    return result;
3332
3292
}
3333
3293
 
3334
3294
 
3335
 
static PaError IsStreamStopped( PaStream *s )
 
3295
static PaError IsStreamStopped (PaStream *s)
3336
3296
{
3337
 
    PaAsioStream *stream = (PaAsioStream*)s;
3338
 
    
 
3297
    PaAsioStream *stream = (PaAsioStream*) s;
 
3298
 
3339
3299
    return stream->isStopped;
3340
3300
}
3341
3301
 
3342
3302
 
3343
 
static PaError IsStreamActive( PaStream *s )
 
3303
static PaError IsStreamActive (PaStream *s)
3344
3304
{
3345
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3305
    PaAsioStream *stream = (PaAsioStream*) s;
3346
3306
 
3347
3307
    return stream->isActive;
3348
3308
}
3349
3309
 
3350
3310
 
3351
 
static PaTime GetStreamTime( PaStream *s )
 
3311
static PaTime GetStreamTime (PaStream *s)
3352
3312
{
3353
3313
    (void) s; /* unused parameter */
3354
 
    return (double)timeGetTime() * .001;
 
3314
    return (double) timeGetTime() * .001;
3355
3315
}
3356
3316
 
3357
3317
 
3358
 
static double GetStreamCpuLoad( PaStream* s )
 
3318
static double GetStreamCpuLoad (PaStream* s)
3359
3319
{
3360
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3320
    PaAsioStream *stream = (PaAsioStream*) s;
3361
3321
 
3362
 
    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
 
3322
    return PaUtil_GetCpuLoad (&stream->cpuLoadMeasurer);
3363
3323
}
3364
3324
 
3365
3325
 
3369
3329
    for blocking streams.
3370
3330
*/
3371
3331
 
3372
 
static PaError ReadStream( PaStream      *s     ,
 
3332
static PaError ReadStream (PaStream      *s     ,
3373
3333
                           void          *buffer,
3374
 
                           unsigned long  frames )
 
3334
                           unsigned long  frames)
3375
3335
{
3376
3336
    PaError result = paNoError; /* Initial return value. */
3377
 
    PaAsioStream *stream = (PaAsioStream*)s; /* The PA ASIO stream. */
 
3337
    PaAsioStream *stream = (PaAsioStream*) s; /* The PA ASIO stream. */
3378
3338
 
3379
3339
    /* Pointer to the blocking i/o data struct. */
3380
3340
    PaAsioStreamBlockingState *blockingState = stream->blockingState;
3403
3363
    unsigned int i; /* Just a counter. */
3404
3364
 
3405
3365
    /* About the time, needed to process 8 data blocks. */
3406
 
    DWORD timeout = (DWORD)( 8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate );
 
3366
    DWORD timeout = (DWORD) (8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate);
3407
3367
    DWORD waitResult = 0;
3408
3368
 
3409
3369
 
3410
3370
    /* Check if the stream is still available ready to gather new data. */
3411
 
    if( blockingState->stopFlag || !stream->isActive )
3412
 
    {
3413
 
        PA_DEBUG(("Warning! Stream no longer available for reading in ReadStream()\n"));
 
3371
    if (blockingState->stopFlag || !stream->isActive) {
 
3372
        PA_DEBUG ( ("Warning! Stream no longer available for reading in ReadStream()\n"));
3414
3373
        result = paStreamIsStopped;
3415
3374
        return result;
3416
3375
    }
3417
3376
 
3418
3377
    /* If the stream is a input stream. */
3419
 
    if( stream->inputChannelCount )
3420
 
    {
 
3378
    if (stream->inputChannelCount) {
3421
3379
        /* Prepare buffer access. */
3422
 
        if( !pBp->userOutputIsInterleaved )
3423
 
        {
 
3380
        if (!pBp->userOutputIsInterleaved) {
3424
3381
            userBuffer = blockingState->readStreamBuffer;
3425
 
            for( i = 0; i<pBp->inputChannelCount; ++i )
3426
 
            {
3427
 
                ((void**)userBuffer)[i] = ((void**)buffer)[i];
 
3382
 
 
3383
            for (i = 0; i<pBp->inputChannelCount; ++i) {
 
3384
                ( (void**) userBuffer) [i] = ( (void**) buffer) [i];
3428
3385
            }
3429
3386
        } /* Use the unchanged buffer. */
3430
 
        else { userBuffer = buffer; }
 
3387
        else {
 
3388
            userBuffer = buffer;
 
3389
        }
3431
3390
 
3432
 
        do /* Internal block processing for too large user data buffers. */
3433
 
        {
 
3391
        do { /* Internal block processing for too large user data buffers. */
3434
3392
            /* Get the size of the current data block to be processed. */
3435
 
            lFramesPerBlock =(lFramesPerBlock < lFramesRemaining)
3436
 
                            ? lFramesPerBlock : lFramesRemaining;
 
3393
            lFramesPerBlock = (lFramesPerBlock < lFramesRemaining)
 
3394
                              ? lFramesPerBlock : lFramesRemaining;
3437
3395
            /* Use predefined block size for as long there are enough
3438
3396
               buffers available, thereafter reduce the processing block
3439
3397
               size to match the number of remaining buffers. So the final
3440
3398
               data block is processed although it may be incomplete. */
3441
3399
 
3442
3400
            /* If the available amount of data frames is insufficient. */
3443
 
            if( PaUtil_GetRingBufferReadAvailable(pRb) < (long) lFramesPerBlock )
3444
 
            {
 
3401
            if (PaUtil_GetRingBufferReadAvailable (pRb) < (long) lFramesPerBlock) {
3445
3402
                /* Make sure, the event isn't already set! */
3446
3403
                /* ResetEvent( blockingState->readFramesReadyEvent ); */
3447
3404
 
3452
3409
                blockingState->readFramesRequestedFlag = TRUE;
3453
3410
 
3454
3411
                /* Wait until requested number of buffers has been freed. */
3455
 
                waitResult = WaitForSingleObject( blockingState->readFramesReadyEvent, timeout );
 
3412
                waitResult = WaitForSingleObject (blockingState->readFramesReadyEvent, timeout);
3456
3413
 
3457
3414
                /* If something seriously went wrong... */
3458
 
                if( waitResult == WAIT_FAILED )
3459
 
                {
3460
 
                    PA_DEBUG(("WaitForSingleObject() failed in ReadStream()\n"));
 
3415
                if (waitResult == WAIT_FAILED) {
 
3416
                    PA_DEBUG ( ("WaitForSingleObject() failed in ReadStream()\n"));
3461
3417
                    result = paUnanticipatedHostError;
3462
 
                    PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
 
3418
                    PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
3463
3419
                    return result;
3464
 
                }
3465
 
                else if( waitResult == WAIT_TIMEOUT )
3466
 
                {
3467
 
                    PA_DEBUG(("WaitForSingleObject() timed out in ReadStream()\n"));
 
3420
                } else if (waitResult == WAIT_TIMEOUT) {
 
3421
                    PA_DEBUG ( ("WaitForSingleObject() timed out in ReadStream()\n"));
3468
3422
 
3469
3423
                    /* If block processing has stopped, abort! */
3470
 
                    if( blockingState->stopFlag ) { return result = paStreamIsStopped; }
 
3424
                    if (blockingState->stopFlag) {
 
3425
                        return result = paStreamIsStopped;
 
3426
                    }
3471
3427
 
3472
3428
                    /* If a timeout is encountered, give up eventually. */
3473
3429
                    return result = paTimedOut;
3474
3430
                }
3475
3431
            }
 
3432
 
3476
3433
            /* Now, the ring buffer contains the required amount of data
3477
3434
               frames.
3478
3435
               (Therefor we don't need to check the return argument of
3485
3442
               segment is returned. Otherwise, i.e. if the first segment
3486
3443
               is large enough, the second segment's pointer will be NULL.
3487
3444
            */
3488
 
            PaUtil_GetRingBufferReadRegions(pRb                ,
3489
 
                                            lFramesPerBlock    ,
3490
 
                                            &pRingBufferData1st,
3491
 
                                            &lRingBufferSize1st,
3492
 
                                            &pRingBufferData2nd,
3493
 
                                            &lRingBufferSize2nd);
 
3445
            PaUtil_GetRingBufferReadRegions (pRb                ,
 
3446
                                             lFramesPerBlock    ,
 
3447
                                             &pRingBufferData1st,
 
3448
                                             &lRingBufferSize1st,
 
3449
                                             &pRingBufferData2nd,
 
3450
                                             &lRingBufferSize2nd);
3494
3451
 
3495
3452
            /* Set number of frames to be copied from the ring buffer. */
3496
 
            PaUtil_SetInputFrameCount( pBp, lRingBufferSize1st ); 
 
3453
            PaUtil_SetInputFrameCount (pBp, lRingBufferSize1st);
3497
3454
            /* Setup ring buffer access. */
3498
 
            PaUtil_SetInterleavedInputChannels(pBp               ,  /* Buffer processor. */
3499
 
                                               0                 ,  /* The first channel's index. */
3500
 
                                               pRingBufferData1st,  /* First ring buffer segment. */
3501
 
                                               0                 ); /* Use all available channels. */
 
3455
            PaUtil_SetInterleavedInputChannels (pBp               , /* Buffer processor. */
 
3456
                                                0                 ,  /* The first channel's index. */
 
3457
                                                pRingBufferData1st,  /* First ring buffer segment. */
 
3458
                                                0);                  /* Use all available channels. */
3502
3459
 
3503
3460
            /* If a second ring buffer segment is required. */
3504
 
            if( lRingBufferSize2nd ) {
 
3461
            if (lRingBufferSize2nd) {
3505
3462
                /* Set number of frames to be copied from the ring buffer. */
3506
 
                PaUtil_Set2ndInputFrameCount( pBp, lRingBufferSize2nd );
 
3463
                PaUtil_Set2ndInputFrameCount (pBp, lRingBufferSize2nd);
3507
3464
                /* Setup ring buffer access. */
3508
 
                PaUtil_Set2ndInterleavedInputChannels(pBp               ,  /* Buffer processor. */
3509
 
                                                      0                 ,  /* The first channel's index. */
3510
 
                                                      pRingBufferData2nd,  /* Second ring buffer segment. */
3511
 
                                                      0                 ); /* Use all available channels. */
 
3465
                PaUtil_Set2ndInterleavedInputChannels (pBp               , /* Buffer processor. */
 
3466
                                                       0                 ,  /* The first channel's index. */
 
3467
                                                       pRingBufferData2nd,  /* Second ring buffer segment. */
 
3468
                                                       0);                  /* Use all available channels. */
3512
3469
            }
3513
3470
 
3514
3471
            /* Let the buffer processor handle "copy and conversion" and
3515
3472
               update the ring buffer indices manually. */
3516
 
            lFramesCopied = PaUtil_CopyInput( pBp, &buffer, lFramesPerBlock );
3517
 
            PaUtil_AdvanceRingBufferReadIndex( pRb, lFramesCopied );
 
3473
            lFramesCopied = PaUtil_CopyInput (pBp, &buffer, lFramesPerBlock);
 
3474
            PaUtil_AdvanceRingBufferReadIndex (pRb, lFramesCopied);
3518
3475
 
3519
3476
            /* Decrease number of unprocessed frames. */
3520
3477
            lFramesRemaining -= lFramesCopied;
3521
3478
 
3522
3479
        } /* Continue with the next data chunk. */
3523
 
        while( lFramesRemaining );
 
3480
 
 
3481
        while (lFramesRemaining);
3524
3482
 
3525
3483
 
3526
3484
        /* If there has been an input overflow within the callback */
3527
 
        if( blockingState->inputOverflowFlag )
3528
 
        {
 
3485
        if (blockingState->inputOverflowFlag) {
3529
3486
            blockingState->inputOverflowFlag = FALSE;
3530
3487
 
3531
3488
            /* Return the corresponding error code. */
3540
3497
    return result;
3541
3498
}
3542
3499
 
3543
 
static PaError WriteStream( PaStream      *s     ,
 
3500
static PaError WriteStream (PaStream      *s     ,
3544
3501
                            const void    *buffer,
3545
 
                            unsigned long  frames )
 
3502
                            unsigned long  frames)
3546
3503
{
3547
3504
    PaError result = paNoError; /* Initial return value. */
3548
 
    PaAsioStream *stream = (PaAsioStream*)s; /* The PA ASIO stream. */
 
3505
    PaAsioStream *stream = (PaAsioStream*) s; /* The PA ASIO stream. */
3549
3506
 
3550
3507
    /* Pointer to the blocking i/o data struct. */
3551
3508
    PaAsioStreamBlockingState *blockingState = stream->blockingState;
3570
3527
    unsigned long lFramesRemaining = frames;
3571
3528
 
3572
3529
    /* About the time, needed to process 8 data blocks. */
3573
 
    DWORD timeout = (DWORD)( 8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate );
 
3530
    DWORD timeout = (DWORD) (8 * lFramesPerBlock * 1000 / stream->streamRepresentation.streamInfo.sampleRate);
3574
3531
    DWORD waitResult = 0;
3575
3532
 
3576
3533
    /* Copy the input argument to avoid pointer increment! */
3579
3536
 
3580
3537
 
3581
3538
    /* Check if the stream ist still available ready to recieve new data. */
3582
 
    if( blockingState->stopFlag || !stream->isActive )
3583
 
    {
3584
 
        PA_DEBUG(("Warning! Stream no longer available for writing in WriteStream()\n"));
 
3539
    if (blockingState->stopFlag || !stream->isActive) {
 
3540
        PA_DEBUG ( ("Warning! Stream no longer available for writing in WriteStream()\n"));
3585
3541
        result = paStreamIsStopped;
3586
3542
        return result;
3587
3543
    }
3588
3544
 
3589
3545
    /* If the stream is a output stream. */
3590
 
    if( stream->outputChannelCount )
3591
 
    {
 
3546
    if (stream->outputChannelCount) {
3592
3547
        /* Prepare buffer access. */
3593
 
        if( !pBp->userOutputIsInterleaved )
3594
 
        {
 
3548
        if (!pBp->userOutputIsInterleaved) {
3595
3549
            userBuffer = blockingState->writeStreamBuffer;
3596
 
            for( i = 0; i<pBp->outputChannelCount; ++i )
3597
 
            {
3598
 
                ((const void**)userBuffer)[i] = ((const void**)buffer)[i];
 
3550
 
 
3551
            for (i = 0; i<pBp->outputChannelCount; ++i) {
 
3552
                ( (const void**) userBuffer) [i] = ( (const void**) buffer) [i];
3599
3553
            }
3600
3554
        } /* Use the unchanged buffer. */
3601
 
        else { userBuffer = buffer; }
3602
 
 
3603
 
 
3604
 
        do /* Internal block processing for too large user data buffers. */
3605
 
        {
 
3555
        else {
 
3556
            userBuffer = buffer;
 
3557
        }
 
3558
 
 
3559
 
 
3560
        do { /* Internal block processing for too large user data buffers. */
3606
3561
            /* Get the size of the current data block to be processed. */
3607
 
            lFramesPerBlock =(lFramesPerBlock < lFramesRemaining)
3608
 
                            ? lFramesPerBlock : lFramesRemaining;
 
3562
            lFramesPerBlock = (lFramesPerBlock < lFramesRemaining)
 
3563
                              ? lFramesPerBlock : lFramesRemaining;
3609
3564
            /* Use predefined block size for as long there are enough
3610
3565
               frames available, thereafter reduce the processing block
3611
3566
               size to match the number of remaining frames. So the final
3612
3567
               data block is processed although it may be incomplete. */
3613
3568
 
3614
3569
            /* If the available amount of buffers is insufficient. */
3615
 
            if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) lFramesPerBlock )
3616
 
            {
 
3570
            if (PaUtil_GetRingBufferWriteAvailable (pRb) < (long) lFramesPerBlock) {
3617
3571
                /* Make sure, the event isn't already set! */
3618
3572
                /* ResetEvent( blockingState->writeBuffersReadyEvent ); */
3619
3573
 
3624
3578
                blockingState->writeBuffersRequestedFlag = TRUE;
3625
3579
 
3626
3580
                /* Wait until requested number of buffers has been freed. */
3627
 
                waitResult = WaitForSingleObject( blockingState->writeBuffersReadyEvent, timeout );
 
3581
                waitResult = WaitForSingleObject (blockingState->writeBuffersReadyEvent, timeout);
3628
3582
 
3629
3583
                /* If something seriously went wrong... */
3630
 
                if( waitResult == WAIT_FAILED )
3631
 
                {
3632
 
                    PA_DEBUG(("WaitForSingleObject() failed in WriteStream()\n"));
 
3584
                if (waitResult == WAIT_FAILED) {
 
3585
                    PA_DEBUG ( ("WaitForSingleObject() failed in WriteStream()\n"));
3633
3586
                    result = paUnanticipatedHostError;
3634
 
                    PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
 
3587
                    PA_ASIO_SET_LAST_SYSTEM_ERROR (GetLastError());
3635
3588
                    return result;
3636
 
                }
3637
 
                else if( waitResult == WAIT_TIMEOUT )
3638
 
                {
3639
 
                    PA_DEBUG(("WaitForSingleObject() timed out in WriteStream()\n"));
 
3589
                } else if (waitResult == WAIT_TIMEOUT) {
 
3590
                    PA_DEBUG ( ("WaitForSingleObject() timed out in WriteStream()\n"));
3640
3591
 
3641
3592
                    /* If block processing has stopped, abort! */
3642
 
                    if( blockingState->stopFlag ) { return result = paStreamIsStopped; }
3643
 
                    
 
3593
                    if (blockingState->stopFlag) {
 
3594
                        return result = paStreamIsStopped;
 
3595
                    }
 
3596
 
3644
3597
                    /* If a timeout is encountered, give up eventually. */
3645
3598
                    return result = paTimedOut;
3646
3599
                }
3647
3600
            }
 
3601
 
3648
3602
            /* Now, the ring buffer contains the required amount of free
3649
3603
               space to store the provided number of data frames.
3650
3604
               (Therefor we don't need to check the return argument of
3657
3611
               segment is returned. Otherwise, i.e. if the first segment
3658
3612
               is large enough, the second segment's pointer will be NULL.
3659
3613
            */
3660
 
            PaUtil_GetRingBufferWriteRegions(pRb                ,
3661
 
                                             lFramesPerBlock    ,
3662
 
                                             &pRingBufferData1st,
3663
 
                                             &lRingBufferSize1st,
3664
 
                                             &pRingBufferData2nd,
3665
 
                                             &lRingBufferSize2nd);
 
3614
            PaUtil_GetRingBufferWriteRegions (pRb                ,
 
3615
                                              lFramesPerBlock    ,
 
3616
                                              &pRingBufferData1st,
 
3617
                                              &lRingBufferSize1st,
 
3618
                                              &pRingBufferData2nd,
 
3619
                                              &lRingBufferSize2nd);
3666
3620
 
3667
3621
            /* Set number of frames to be copied to the ring buffer. */
3668
 
            PaUtil_SetOutputFrameCount( pBp, lRingBufferSize1st ); 
 
3622
            PaUtil_SetOutputFrameCount (pBp, lRingBufferSize1st);
3669
3623
            /* Setup ring buffer access. */
3670
 
            PaUtil_SetInterleavedOutputChannels(pBp               ,  /* Buffer processor. */
3671
 
                                                0                 ,  /* The first channel's index. */
3672
 
                                                pRingBufferData1st,  /* First ring buffer segment. */
3673
 
                                                0                 ); /* Use all available channels. */
 
3624
            PaUtil_SetInterleavedOutputChannels (pBp               , /* Buffer processor. */
 
3625
                                                 0                 ,  /* The first channel's index. */
 
3626
                                                 pRingBufferData1st,  /* First ring buffer segment. */
 
3627
                                                 0);                  /* Use all available channels. */
3674
3628
 
3675
3629
            /* If a second ring buffer segment is required. */
3676
 
            if( lRingBufferSize2nd ) {
 
3630
            if (lRingBufferSize2nd) {
3677
3631
                /* Set number of frames to be copied to the ring buffer. */
3678
 
                PaUtil_Set2ndOutputFrameCount( pBp, lRingBufferSize2nd );
 
3632
                PaUtil_Set2ndOutputFrameCount (pBp, lRingBufferSize2nd);
3679
3633
                /* Setup ring buffer access. */
3680
 
                PaUtil_Set2ndInterleavedOutputChannels(pBp               ,  /* Buffer processor. */
3681
 
                                                       0                 ,  /* The first channel's index. */
3682
 
                                                       pRingBufferData2nd,  /* Second ring buffer segment. */
3683
 
                                                       0                 ); /* Use all available channels. */
 
3634
                PaUtil_Set2ndInterleavedOutputChannels (pBp               , /* Buffer processor. */
 
3635
                                                        0                 ,  /* The first channel's index. */
 
3636
                                                        pRingBufferData2nd,  /* Second ring buffer segment. */
 
3637
                                                        0);                  /* Use all available channels. */
3684
3638
            }
3685
3639
 
3686
3640
            /* Let the buffer processor handle "copy and conversion" and
3687
3641
               update the ring buffer indices manually. */
3688
 
            lFramesCopied = PaUtil_CopyOutput( pBp, &userBuffer, lFramesPerBlock );
3689
 
            PaUtil_AdvanceRingBufferWriteIndex( pRb, lFramesCopied );
 
3642
            lFramesCopied = PaUtil_CopyOutput (pBp, &userBuffer, lFramesPerBlock);
 
3643
            PaUtil_AdvanceRingBufferWriteIndex (pRb, lFramesCopied);
3690
3644
 
3691
3645
            /* Decrease number of unprocessed frames. */
3692
3646
            lFramesRemaining -= lFramesCopied;
3693
3647
 
3694
3648
        } /* Continue with the next data chunk. */
3695
 
        while( lFramesRemaining );
 
3649
 
 
3650
        while (lFramesRemaining);
3696
3651
 
3697
3652
 
3698
3653
        /* If there has been an output underflow within the callback */
3699
 
        if( blockingState->outputUnderflowFlag )
3700
 
        {
 
3654
        if (blockingState->outputUnderflowFlag) {
3701
3655
            blockingState->outputUnderflowFlag = FALSE;
3702
3656
 
3703
3657
            /* Return the corresponding error code. */
3705
3659
        }
3706
3660
 
3707
3661
    } /* If this is not an output stream. */
3708
 
    else
3709
 
    {
 
3662
    else {
3710
3663
        result = paCanNotWriteToAnInputOnlyStream;
3711
3664
    }
3712
3665
 
3714
3667
}
3715
3668
 
3716
3669
 
3717
 
static signed long GetStreamReadAvailable( PaStream* s )
 
3670
static signed long GetStreamReadAvailable (PaStream* s)
3718
3671
{
3719
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3672
    PaAsioStream *stream = (PaAsioStream*) s;
3720
3673
 
3721
3674
    /* Call buffer utility routine to get the number of available frames. */
3722
 
    return PaUtil_GetRingBufferReadAvailable( &stream->blockingState->readRingBuffer );
 
3675
    return PaUtil_GetRingBufferReadAvailable (&stream->blockingState->readRingBuffer);
3723
3676
}
3724
3677
 
3725
3678
 
3726
 
static signed long GetStreamWriteAvailable( PaStream* s )
 
3679
static signed long GetStreamWriteAvailable (PaStream* s)
3727
3680
{
3728
 
    PaAsioStream *stream = (PaAsioStream*)s;
 
3681
    PaAsioStream *stream = (PaAsioStream*) s;
3729
3682
 
3730
3683
    /* Call buffer utility routine to get the number of empty buffers. */
3731
 
    return PaUtil_GetRingBufferWriteAvailable( &stream->blockingState->writeRingBuffer );
 
3684
    return PaUtil_GetRingBufferWriteAvailable (&stream->blockingState->writeRingBuffer);
3732
3685
}
3733
3686
 
3734
3687
 
3736
3689
** It may called at interrupt level on some machines so don't do anything
3737
3690
** that could mess up the system like calling malloc() or free().
3738
3691
*/
3739
 
static int BlockingIoPaCallback(const void                     *inputBuffer    ,
3740
 
                                      void                     *outputBuffer   ,
3741
 
                                      unsigned long             framesPerBuffer,
3742
 
                                const PaStreamCallbackTimeInfo *timeInfo       ,
3743
 
                                      PaStreamCallbackFlags     statusFlags    ,
3744
 
                                      void                     *userData       )
 
3692
static int BlockingIoPaCallback (const void                     *inputBuffer    ,
 
3693
                                 void                     *outputBuffer   ,
 
3694
                                 unsigned long             framesPerBuffer,
 
3695
                                 const PaStreamCallbackTimeInfo *timeInfo       ,
 
3696
                                 PaStreamCallbackFlags     statusFlags    ,
 
3697
                                 void                     *userData)
3745
3698
{
3746
3699
    PaError result = paNoError; /* Initial return value. */
3747
 
    PaAsioStream *stream = *(PaAsioStream**)userData; /* The PA ASIO stream. */
 
3700
    PaAsioStream *stream = * (PaAsioStream**) userData; /* The PA ASIO stream. */
3748
3701
    PaAsioStreamBlockingState *blockingState = stream->blockingState; /* Persume blockingState is valid, otherwise the callback wouldn't be running. */
3749
3702
 
3750
3703
    /* Get a pointer to the stream's blocking i/o buffer processor. */
3752
3705
    PaUtilRingBuffer      *pRb = NULL;
3753
3706
 
3754
3707
    /* If output data has been requested. */
3755
 
    if( stream->outputChannelCount )
3756
 
    {
 
3708
    if (stream->outputChannelCount) {
3757
3709
        /* If the callback input argument signalizes a output underflow,
3758
3710
           make sure the WriteStream() function knows about it, too! */
3759
 
        if( statusFlags & paOutputUnderflowed ) {
 
3711
        if (statusFlags & paOutputUnderflowed) {
3760
3712
            blockingState->outputUnderflowFlag = TRUE;
3761
3713
        }
3762
3714
 
3764
3716
        pRb = &blockingState->writeRingBuffer;
3765
3717
 
3766
3718
        /* If the blocking i/o buffer contains enough output data, */
3767
 
        if( PaUtil_GetRingBufferReadAvailable(pRb) >= (long) framesPerBuffer )
3768
 
        {
 
3719
        if (PaUtil_GetRingBufferReadAvailable (pRb) >= (long) framesPerBuffer) {
3769
3720
            /* Extract the requested data from the ring buffer. */
3770
 
            PaUtil_ReadRingBuffer( pRb, outputBuffer, framesPerBuffer );
3771
 
        }
3772
 
        else /* If no output data is available :-( */
3773
 
        {
 
3721
            PaUtil_ReadRingBuffer (pRb, outputBuffer, framesPerBuffer);
 
3722
        } else { /* If no output data is available :-( */
3774
3723
            /* Signalize a write-buffer underflow. */
3775
3724
            blockingState->outputUnderflowFlag = TRUE;
3776
3725
 
3777
3726
            /* Fill the output buffer with silence. */
3778
 
            (*pBp->outputZeroer)( outputBuffer, 1, pBp->outputChannelCount * framesPerBuffer );
 
3727
            (*pBp->outputZeroer) (outputBuffer, 1, pBp->outputChannelCount * framesPerBuffer);
3779
3728
 
3780
3729
            /* If playback is to be stopped */
3781
 
            if( blockingState->stopFlag && PaUtil_GetRingBufferReadAvailable(pRb) < (long) framesPerBuffer )
3782
 
            {
 
3730
            if (blockingState->stopFlag && PaUtil_GetRingBufferReadAvailable (pRb) < (long) framesPerBuffer) {
3783
3731
                /* Extract all the remaining data from the ring buffer,
3784
3732
                   whether it is a complete data block or not. */
3785
 
                PaUtil_ReadRingBuffer( pRb, outputBuffer, PaUtil_GetRingBufferReadAvailable(pRb) );
 
3733
                PaUtil_ReadRingBuffer (pRb, outputBuffer, PaUtil_GetRingBufferReadAvailable (pRb));
3786
3734
            }
3787
3735
        }
3788
3736
 
3789
3737
        /* Set blocking i/o event? */
3790
 
        if( blockingState->writeBuffersRequestedFlag && PaUtil_GetRingBufferWriteAvailable(pRb) >= (long) blockingState->writeBuffersRequested )
3791
 
        {
 
3738
        if (blockingState->writeBuffersRequestedFlag && PaUtil_GetRingBufferWriteAvailable (pRb) >= (long) blockingState->writeBuffersRequested) {
3792
3739
            /* Reset buffer request. */
3793
3740
            blockingState->writeBuffersRequestedFlag = FALSE;
3794
3741
            blockingState->writeBuffersRequested     = 0;
3795
3742
            /* Signalize that requested buffers are ready. */
3796
 
            SetEvent( blockingState->writeBuffersReadyEvent );
 
3743
            SetEvent (blockingState->writeBuffersReadyEvent);
3797
3744
            /* What do we do if SetEvent() returns zero, i.e. the event
3798
3745
               could not be set? How to return errors from within the
3799
3746
               callback? - S.Fischer */
3801
3748
    }
3802
3749
 
3803
3750
    /* If input data has been supplied. */
3804
 
    if( stream->inputChannelCount )
3805
 
    {
 
3751
    if (stream->inputChannelCount) {
3806
3752
        /* If the callback input argument signalizes a input overflow,
3807
3753
           make sure the ReadStream() function knows about it, too! */
3808
 
        if( statusFlags & paInputOverflowed ) {
 
3754
        if (statusFlags & paInputOverflowed) {
3809
3755
            blockingState->inputOverflowFlag = TRUE;
3810
3756
        }
3811
3757
 
3813
3759
        pRb = &blockingState->readRingBuffer;
3814
3760
 
3815
3761
        /* If the blocking i/o buffer contains not enough input buffers */
3816
 
        if( PaUtil_GetRingBufferWriteAvailable(pRb) < (long) framesPerBuffer )
3817
 
        {
 
3762
        if (PaUtil_GetRingBufferWriteAvailable (pRb) < (long) framesPerBuffer) {
3818
3763
            /* Signalize a read-buffer overflow. */
3819
3764
            blockingState->inputOverflowFlag = TRUE;
3820
3765
 
3821
3766
            /* Remove some old data frames from the buffer. */
3822
 
            PaUtil_AdvanceRingBufferReadIndex( pRb, framesPerBuffer );
 
3767
            PaUtil_AdvanceRingBufferReadIndex (pRb, framesPerBuffer);
3823
3768
        }
3824
3769
 
3825
3770
        /* Insert the current input data into the ring buffer. */
3826
 
        PaUtil_WriteRingBuffer( pRb, inputBuffer, framesPerBuffer );
 
3771
        PaUtil_WriteRingBuffer (pRb, inputBuffer, framesPerBuffer);
3827
3772
 
3828
3773
        /* Set blocking i/o event? */
3829
 
        if( blockingState->readFramesRequestedFlag && PaUtil_GetRingBufferReadAvailable(pRb) >= (long) blockingState->readFramesRequested )
3830
 
        {
 
3774
        if (blockingState->readFramesRequestedFlag && PaUtil_GetRingBufferReadAvailable (pRb) >= (long) blockingState->readFramesRequested) {
3831
3775
            /* Reset buffer request. */
3832
3776
            blockingState->readFramesRequestedFlag = FALSE;
3833
3777
            blockingState->readFramesRequested     = 0;
3834
3778
            /* Signalize that requested buffers are ready. */
3835
 
            SetEvent( blockingState->readFramesReadyEvent );
 
3779
            SetEvent (blockingState->readFramesReadyEvent);
3836
3780
            /* What do we do if SetEvent() returns zero, i.e. the event
3837
3781
               could not be set? How to return errors from within the
3838
3782
               callback? - S.Fischer */
3844
3788
}
3845
3789
 
3846
3790
 
3847
 
PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific )
 
3791
PaError PaAsio_ShowControlPanel (PaDeviceIndex device, void* systemSpecific)
3848
3792
{
3849
3793
    PaError result = paNoError;
3850
3794
    PaUtilHostApiRepresentation *hostApi;
3856
3800
    PaAsioDeviceInfo *asioDeviceInfo;
3857
3801
 
3858
3802
 
3859
 
    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
3860
 
    if( result != paNoError )
 
3803
    result = PaUtil_GetHostApiRepresentation (&hostApi, paASIO);
 
3804
 
 
3805
    if (result != paNoError)
3861
3806
        goto error;
3862
3807
 
3863
 
    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
3864
 
    if( result != paNoError )
 
3808
    result = PaUtil_DeviceIndexToHostApiDeviceIndex (&hostApiDevice, device, hostApi);
 
3809
 
 
3810
    if (result != paNoError)
3865
3811
        goto error;
3866
3812
 
3867
3813
    /*
3872
3818
        done safely while a stream is open.
3873
3819
    */
3874
3820
 
3875
 
    asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
3876
 
    if( asioHostApi->openAsioDeviceIndex != paNoDevice )
3877
 
    {
 
3821
    asioHostApi = (PaAsioHostApiRepresentation*) hostApi;
 
3822
 
 
3823
    if (asioHostApi->openAsioDeviceIndex != paNoDevice) {
3878
3824
        result = paDeviceUnavailable;
3879
3825
        goto error;
3880
3826
    }
3881
3827
 
3882
 
    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
 
3828
    asioDeviceInfo = (PaAsioDeviceInfo*) hostApi->deviceInfos[hostApiDevice];
3883
3829
 
3884
3830
    /* See notes about CoInitialize(0) in LoadAsioDriver(). */
3885
 
        CoInitialize(0);
 
3831
    CoInitialize (0);
3886
3832
 
3887
 
    if( !asioHostApi->asioDrivers->loadDriver( const_cast<char*>(asioDeviceInfo->commonDeviceInfo.name) ) )
3888
 
    {
 
3833
    if (!asioHostApi->asioDrivers->loadDriver (const_cast<char*> (asioDeviceInfo->commonDeviceInfo.name))) {
3889
3834
        result = paUnanticipatedHostError;
3890
3835
        goto error;
3891
3836
    }
3892
3837
 
3893
3838
    /* CRUCIAL!!! */
3894
 
    memset( &asioDriverInfo, 0, sizeof(ASIODriverInfo) );
 
3839
    memset (&asioDriverInfo, 0, sizeof (ASIODriverInfo));
3895
3840
    asioDriverInfo.asioVersion = 2;
3896
3841
    asioDriverInfo.sysRef = systemSpecific;
3897
 
    asioError = ASIOInit( &asioDriverInfo );
3898
 
    if( asioError != ASE_OK )
3899
 
    {
 
3842
    asioError = ASIOInit (&asioDriverInfo);
 
3843
 
 
3844
    if (asioError != ASE_OK) {
3900
3845
        result = paUnanticipatedHostError;
3901
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
3846
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
3902
3847
        goto error;
3903
 
    }
3904
 
    else
3905
 
    {
 
3848
    } else {
3906
3849
        asioIsInitialized = 1;
3907
3850
    }
3908
3851
 
3909
 
PA_DEBUG(("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
3910
 
PA_DEBUG(("asioVersion: ASIOInit(): %ld\n",   asioDriverInfo.asioVersion )); 
3911
 
PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion )); 
3912
 
PA_DEBUG(("Name: ASIOInit(): %s\n",           asioDriverInfo.name )); 
3913
 
PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n",   asioDriverInfo.errorMessage )); 
 
3852
    PA_DEBUG ( ("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText (asioError)));
 
3853
    PA_DEBUG ( ("asioVersion: ASIOInit(): %ld\n",   asioDriverInfo.asioVersion));
 
3854
    PA_DEBUG ( ("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion));
 
3855
    PA_DEBUG ( ("Name: ASIOInit(): %s\n",           asioDriverInfo.name));
 
3856
    PA_DEBUG ( ("ErrorMessage: ASIOInit(): %s\n",   asioDriverInfo.errorMessage));
3914
3857
 
3915
3858
    asioError = ASIOControlPanel();
3916
 
    if( asioError != ASE_OK )
3917
 
    {
3918
 
        PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
3859
 
 
3860
    if (asioError != ASE_OK) {
 
3861
        PA_DEBUG ( ("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText (asioError)));
3919
3862
        result = paUnanticipatedHostError;
3920
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
3863
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
3921
3864
        goto error;
3922
3865
    }
3923
3866
 
3924
 
PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
3867
    PA_DEBUG ( ("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText (asioError)));
3925
3868
 
3926
3869
    asioError = ASIOExit();
3927
 
    if( asioError != ASE_OK )
3928
 
    {
 
3870
 
 
3871
    if (asioError != ASE_OK) {
3929
3872
        result = paUnanticipatedHostError;
3930
 
        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
 
3873
        PA_ASIO_SET_LAST_ASIO_ERROR (asioError);
3931
3874
        asioIsInitialized = 0;
3932
3875
        goto error;
3933
3876
    }
3934
3877
 
3935
 
        CoUninitialize();
3936
 
PA_DEBUG(("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
 
3878
    CoUninitialize();
 
3879
    PA_DEBUG ( ("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText (asioError)));
3937
3880
 
3938
3881
    return result;
3939
3882
 
3940
3883
error:
3941
 
    if( asioIsInitialized )
3942
 
        {
3943
 
                ASIOExit();
3944
 
        }
3945
 
        CoUninitialize();
 
3884
 
 
3885
    if (asioIsInitialized) {
 
3886
        ASIOExit();
 
3887
    }
 
3888
 
 
3889
    CoUninitialize();
3946
3890
 
3947
3891
    return result;
3948
3892
}
3949
3893
 
3950
3894
 
3951
 
PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
3952
 
        const char** channelName )
 
3895
PaError PaAsio_GetInputChannelName (PaDeviceIndex device, int channelIndex,
 
3896
                                    const char** channelName)
3953
3897
{
3954
3898
    PaError result = paNoError;
3955
3899
    PaUtilHostApiRepresentation *hostApi;
3957
3901
    PaAsioDeviceInfo *asioDeviceInfo;
3958
3902
 
3959
3903
 
3960
 
    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
3961
 
    if( result != paNoError )
3962
 
        goto error;
3963
 
 
3964
 
    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
3965
 
    if( result != paNoError )
3966
 
        goto error;
3967
 
 
3968
 
    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
3969
 
 
3970
 
    if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels ){
 
3904
    result = PaUtil_GetHostApiRepresentation (&hostApi, paASIO);
 
3905
 
 
3906
    if (result != paNoError)
 
3907
        goto error;
 
3908
 
 
3909
    result = PaUtil_DeviceIndexToHostApiDeviceIndex (&hostApiDevice, device, hostApi);
 
3910
 
 
3911
    if (result != paNoError)
 
3912
        goto error;
 
3913
 
 
3914
    asioDeviceInfo = (PaAsioDeviceInfo*) hostApi->deviceInfos[hostApiDevice];
 
3915
 
 
3916
    if (channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels) {
3971
3917
        result = paInvalidChannelCount;
3972
3918
        goto error;
3973
3919
    }
3975
3921
    *channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name;
3976
3922
 
3977
3923
    return paNoError;
3978
 
    
 
3924
 
3979
3925
error:
3980
3926
    return result;
3981
3927
}
3982
3928
 
3983
3929
 
3984
 
PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
3985
 
        const char** channelName )
 
3930
PaError PaAsio_GetOutputChannelName (PaDeviceIndex device, int channelIndex,
 
3931
                                     const char** channelName)
3986
3932
{
3987
3933
    PaError result = paNoError;
3988
3934
    PaUtilHostApiRepresentation *hostApi;
3990
3936
    PaAsioDeviceInfo *asioDeviceInfo;
3991
3937
 
3992
3938
 
3993
 
    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
3994
 
    if( result != paNoError )
3995
 
        goto error;
3996
 
 
3997
 
    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
3998
 
    if( result != paNoError )
3999
 
        goto error;
4000
 
 
4001
 
    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
4002
 
 
4003
 
    if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels ){
 
3939
    result = PaUtil_GetHostApiRepresentation (&hostApi, paASIO);
 
3940
 
 
3941
    if (result != paNoError)
 
3942
        goto error;
 
3943
 
 
3944
    result = PaUtil_DeviceIndexToHostApiDeviceIndex (&hostApiDevice, device, hostApi);
 
3945
 
 
3946
    if (result != paNoError)
 
3947
        goto error;
 
3948
 
 
3949
    asioDeviceInfo = (PaAsioDeviceInfo*) hostApi->deviceInfos[hostApiDevice];
 
3950
 
 
3951
    if (channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels) {
4004
3952
        result = paInvalidChannelCount;
4005
3953
        goto error;
4006
3954
    }
4007
3955
 
4008
3956
    *channelName = asioDeviceInfo->asioChannelInfos[
4009
 
            asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name;
 
3957
                       asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name;
4010
3958
 
4011
3959
    return paNoError;
4012
 
    
 
3960
 
4013
3961
error:
4014
3962
    return result;
4015
3963
}
4020
3968
    we don't have the benefit of pa_front.c's parameter checking.
4021
3969
*/
4022
3970
 
4023
 
static PaError GetAsioStreamPointer( PaAsioStream **stream, PaStream *s )
 
3971
static PaError GetAsioStreamPointer (PaAsioStream **stream, PaStream *s)
4024
3972
{
4025
3973
    PaError result;
4026
3974
    PaUtilHostApiRepresentation *hostApi;
4027
3975
    PaAsioHostApiRepresentation *asioHostApi;
4028
 
    
4029
 
    result = PaUtil_ValidateStreamPointer( s );
4030
 
    if( result != paNoError )
4031
 
        return result;
4032
 
 
4033
 
    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
4034
 
    if( result != paNoError )
4035
 
        return result;
4036
 
 
4037
 
    asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
4038
 
    
4039
 
    if( PA_STREAM_REP( s )->streamInterface == &asioHostApi->callbackStreamInterface
4040
 
            || PA_STREAM_REP( s )->streamInterface == &asioHostApi->blockingStreamInterface )
4041
 
    {
 
3976
 
 
3977
    result = PaUtil_ValidateStreamPointer (s);
 
3978
 
 
3979
    if (result != paNoError)
 
3980
        return result;
 
3981
 
 
3982
    result = PaUtil_GetHostApiRepresentation (&hostApi, paASIO);
 
3983
 
 
3984
    if (result != paNoError)
 
3985
        return result;
 
3986
 
 
3987
    asioHostApi = (PaAsioHostApiRepresentation*) hostApi;
 
3988
 
 
3989
    if (PA_STREAM_REP (s)->streamInterface == &asioHostApi->callbackStreamInterface
 
3990
            || PA_STREAM_REP (s)->streamInterface == &asioHostApi->blockingStreamInterface) {
4042
3991
        /* s is an ASIO  stream */
4043
 
        *stream = (PaAsioStream *)s;
 
3992
        *stream = (PaAsioStream *) s;
4044
3993
        return paNoError;
4045
 
    }
4046
 
    else
4047
 
    {
 
3994
    } else {
4048
3995
        return paIncompatibleStreamHostApi;
4049
3996
    }
4050
3997
}
4051
3998
 
4052
3999
 
4053
 
PaError PaAsio_SetStreamSampleRate( PaStream* s, double sampleRate )
 
4000
PaError PaAsio_SetStreamSampleRate (PaStream* s, double sampleRate)
4054
4001
{
4055
4002
    PaAsioStream *stream;
4056
 
    PaError result = GetAsioStreamPointer( &stream, s );
4057
 
    if( result != paNoError )
 
4003
    PaError result = GetAsioStreamPointer (&stream, s);
 
4004
 
 
4005
    if (result != paNoError)
4058
4006
        return result;
4059
4007
 
4060
 
    if( stream != theAsioStream )
 
4008
    if (stream != theAsioStream)
4061
4009
        return paBadStreamPtr;
4062
4010
 
4063
 
    return ValidateAndSetSampleRate( sampleRate );
 
4011
    return ValidateAndSetSampleRate (sampleRate);
4064
4012
}
4065
4013