~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/third_party/portaudio/src/common/pa_front.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: pa_front.c 1396 2008-11-03 19:31:30Z philburk $
 
3
 * Portable Audio I/O Library Multi-Host API front end
 
4
 * Validate function parameters and manage multiple host APIs.
 
5
 *
 
6
 * Based on the Open Source API proposed by Ross Bencina
 
7
 * Copyright (c) 1999-2008 Ross Bencina, Phil Burk
 
8
 *
 
9
 * Permission is hereby granted, free of charge, to any person obtaining
 
10
 * a copy of this software and associated documentation files
 
11
 * (the "Software"), to deal in the Software without restriction,
 
12
 * including without limitation the rights to use, copy, modify, merge,
 
13
 * publish, distribute, sublicense, and/or sell copies of the Software,
 
14
 * and to permit persons to whom the Software is furnished to do so,
 
15
 * subject to the following conditions:
 
16
 *
 
17
 * The above copyright notice and this permission notice shall be
 
18
 * included in all copies or substantial portions of the Software.
 
19
 *
 
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
23
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 
24
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 
25
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
 */
 
28
 
 
29
/*
 
30
 * The text above constitutes the entire PortAudio license; however, 
 
31
 * the PortAudio community also makes the following non-binding requests:
 
32
 *
 
33
 * Any person wishing to distribute modifications to the Software is
 
34
 * requested to send the modifications to the original developer so that
 
35
 * they can be incorporated into the canonical version. It is also 
 
36
 * requested that these non-binding requests be included along with the 
 
37
 * license above.
 
38
 */
 
39
 
 
40
/** @file
 
41
 @ingroup common_src
 
42
 
 
43
 @brief Implements PortAudio API functions defined in portaudio.h, checks 
 
44
 some errors, delegates platform-specific behavior to host API implementations.
 
45
 
 
46
 Implements the functions defined in the PortAudio API (portaudio.h), 
 
47
 validates some parameters and checks for state inconsistencies before 
 
48
 forwarding API requests to specific Host API implementations (via the 
 
49
 interface declared in pa_hostapi.h), and Streams (via the interface 
 
50
 declared in pa_stream.h).
 
51
 
 
52
 This file manages initialization and termination of Host API
 
53
 implementations via initializer functions stored in the paHostApiInitializers
 
54
 global array (usually defined in an os-specific pa_[os]_hostapis.c file).
 
55
 
 
56
 This file maintains a list of all open streams and closes them at Pa_Terminate().
 
57
 
 
58
 Some utility functions declared in pa_util.h are implemented in this file.
 
59
 
 
60
 All PortAudio API functions can be conditionally compiled with logging code.
 
61
 To compile with logging, define the PA_LOG_API_CALLS precompiler symbol.
 
62
 
 
63
    @todo Consider adding host API specific error text in Pa_GetErrorText() for
 
64
    paUnanticipatedHostError
 
65
 
 
66
    @todo Consider adding a new error code for when (inputParameters == NULL)
 
67
    && (outputParameters == NULL)
 
68
 
 
69
    @todo review whether Pa_CloseStream() should call the interface's
 
70
    CloseStream function if aborting the stream returns an error code.
 
71
 
 
72
    @todo Create new error codes if a NULL buffer pointer, or a
 
73
    zero frame count is passed to Pa_ReadStream or Pa_WriteStream.
 
74
*/
 
75
 
 
76
 
 
77
#include <stdio.h>
 
78
#include <memory.h>
 
79
#include <string.h>
 
80
#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
 
81
 
 
82
#include "portaudio.h"
 
83
#include "pa_util.h"
 
84
#include "pa_endianness.h"
 
85
#include "pa_types.h"
 
86
#include "pa_hostapi.h"
 
87
#include "pa_stream.h"
 
88
#include "pa_trace.h" /* still usefull?*/
 
89
#include "pa_debugprint.h"
 
90
 
 
91
 
 
92
#define PA_VERSION_  1899
 
93
#define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__  " " __TIME__ ")"
 
94
 
 
95
 
 
96
 
 
97
 
 
98
int Pa_GetVersion( void )
 
99
{
 
100
    return PA_VERSION_;
 
101
}
 
102
 
 
103
 
 
104
const char* Pa_GetVersionText( void )
 
105
{
 
106
    return PA_VERSION_TEXT_;
 
107
}
 
108
 
 
109
 
 
110
 
 
111
#define PA_LAST_HOST_ERROR_TEXT_LENGTH_  1024
 
112
 
 
113
static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0};
 
114
 
 
115
static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ };
 
116
 
 
117
 
 
118
void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
 
119
        const char *errorText )
 
120
{
 
121
    lastHostErrorInfo_.hostApiType = hostApiType;
 
122
    lastHostErrorInfo_.errorCode = errorCode;
 
123
 
 
124
    strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ );
 
125
}
 
126
 
 
127
 
 
128
 
 
129
static PaUtilHostApiRepresentation **hostApis_ = 0;
 
130
static int hostApisCount_ = 0;
 
131
static int initializationCount_ = 0;
 
132
static int deviceCount_ = 0;
 
133
 
 
134
PaUtilStreamRepresentation *firstOpenStream_ = NULL;
 
135
 
 
136
 
 
137
#define PA_IS_INITIALISED_ (initializationCount_ != 0)
 
138
 
 
139
 
 
140
static int CountHostApiInitializers( void )
 
141
{
 
142
    int result = 0;
 
143
 
 
144
    while( paHostApiInitializers[ result ] != 0 )
 
145
        ++result;
 
146
    return result;
 
147
}
 
148
 
 
149
 
 
150
static void TerminateHostApis( void )
 
151
{
 
152
    /* terminate in reverse order from initialization */
 
153
    PA_DEBUG(("TerminateHostApis in \n"));
 
154
 
 
155
    while( hostApisCount_ > 0 )
 
156
    {
 
157
        --hostApisCount_;
 
158
        hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] );
 
159
    }
 
160
    hostApisCount_ = 0;
 
161
    deviceCount_ = 0;
 
162
 
 
163
    if( hostApis_ != 0 )
 
164
        PaUtil_FreeMemory( hostApis_ );
 
165
    hostApis_ = 0;
 
166
 
 
167
    PA_DEBUG(("TerminateHostApis out\n"));
 
168
}
 
169
 
 
170
 
 
171
static PaError InitializeHostApis( void )
 
172
{
 
173
    PaError result = paNoError;
 
174
    int i, initializerCount, baseDeviceIndex;
 
175
 
 
176
    initializerCount = CountHostApiInitializers();
 
177
 
 
178
    hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory(
 
179
            sizeof(PaUtilHostApiRepresentation*) * initializerCount );
 
180
    if( !hostApis_ )
 
181
    {
 
182
        result = paInsufficientMemory;
 
183
        goto error; 
 
184
    }
 
185
 
 
186
    hostApisCount_ = 0;
 
187
    deviceCount_ = 0;
 
188
    baseDeviceIndex = 0;
 
189
 
 
190
    for( i=0; i< initializerCount; ++i )
 
191
    {
 
192
        hostApis_[hostApisCount_] = NULL;
 
193
 
 
194
        PA_DEBUG(( "before paHostApiInitializers[%d].\n",i));
 
195
 
 
196
        result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );
 
197
        if( result != paNoError )
 
198
            goto error;
 
199
 
 
200
        PA_DEBUG(( "after paHostApiInitializers[%d].\n",i));
 
201
 
 
202
        if( hostApis_[hostApisCount_] )
 
203
        {
 
204
            PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_];
 
205
            assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
 
206
            assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
 
207
 
 
208
            hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex;
 
209
 
 
210
            if( hostApi->info.defaultInputDevice != paNoDevice )
 
211
                hostApi->info.defaultInputDevice += baseDeviceIndex;
 
212
 
 
213
            if( hostApi->info.defaultOutputDevice != paNoDevice )
 
214
                hostApi->info.defaultOutputDevice += baseDeviceIndex;
 
215
 
 
216
            baseDeviceIndex += hostApi->info.deviceCount;
 
217
            deviceCount_ += hostApi->info.deviceCount;
 
218
 
 
219
            ++hostApisCount_;
 
220
        }
 
221
    }
 
222
 
 
223
    return result;
 
224
 
 
225
error:
 
226
    TerminateHostApis();
 
227
    return result;
 
228
}
 
229
 
 
230
 
 
231
/*
 
232
    FindHostApi() finds the index of the host api to which
 
233
    <device> belongs and returns it. if <hostSpecificDeviceIndex> is
 
234
    non-null, the host specific device index is returned in it.
 
235
    returns -1 if <device> is out of range.
 
236
 
 
237
*/
 
238
static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
 
239
{
 
240
    int i=0;
 
241
 
 
242
    if( !PA_IS_INITIALISED_ )
 
243
        return -1;
 
244
 
 
245
    if( device < 0 )
 
246
        return -1;
 
247
 
 
248
    while( i < hostApisCount_
 
249
            && device >= hostApis_[i]->info.deviceCount )
 
250
    {
 
251
 
 
252
        device -= hostApis_[i]->info.deviceCount;
 
253
        ++i;
 
254
    }
 
255
 
 
256
    if( i >= hostApisCount_ )
 
257
        return -1;
 
258
 
 
259
    if( hostSpecificDeviceIndex )
 
260
        *hostSpecificDeviceIndex = device;
 
261
 
 
262
    return i;
 
263
}
 
264
 
 
265
 
 
266
static void AddOpenStream( PaStream* stream )
 
267
{
 
268
    ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_;
 
269
    firstOpenStream_ = (PaUtilStreamRepresentation*)stream;
 
270
}
 
271
 
 
272
 
 
273
static void RemoveOpenStream( PaStream* stream )
 
274
{
 
275
    PaUtilStreamRepresentation *previous = NULL;
 
276
    PaUtilStreamRepresentation *current = firstOpenStream_;
 
277
 
 
278
    while( current != NULL )
 
279
    {
 
280
        if( ((PaStream*)current) == stream )
 
281
        {
 
282
            if( previous == NULL )
 
283
            {
 
284
                firstOpenStream_ = current->nextOpenStream;
 
285
            }
 
286
            else
 
287
            {
 
288
                previous->nextOpenStream = current->nextOpenStream;
 
289
            }
 
290
            return;
 
291
        }
 
292
        else
 
293
        {
 
294
            previous = current;
 
295
            current = current->nextOpenStream;
 
296
        }
 
297
    }
 
298
}
 
299
 
 
300
 
 
301
static void CloseOpenStreams( void )
 
302
{
 
303
    /* we call Pa_CloseStream() here to ensure that the same destruction
 
304
        logic is used for automatically closed streams */
 
305
 
 
306
    while( firstOpenStream_ != NULL )
 
307
        Pa_CloseStream( firstOpenStream_ );
 
308
}
 
309
 
 
310
 
 
311
PaError Pa_Initialize( void )
 
312
{
 
313
    PaError result;
 
314
 
 
315
    PA_LOGAPI_ENTER( "Pa_Initialize" );
 
316
 
 
317
    if( PA_IS_INITIALISED_ )
 
318
    {
 
319
        ++initializationCount_;
 
320
        result = paNoError;
 
321
    }
 
322
    else
 
323
    {
 
324
        PA_VALIDATE_TYPE_SIZES;
 
325
        PA_VALIDATE_ENDIANNESS;
 
326
        
 
327
        PaUtil_InitializeClock();
 
328
        PaUtil_ResetTraceMessages();
 
329
 
 
330
        result = InitializeHostApis();
 
331
        if( result == paNoError )
 
332
            ++initializationCount_;
 
333
    }
 
334
 
 
335
    PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result );
 
336
 
 
337
    return result;
 
338
}
 
339
 
 
340
 
 
341
PaError Pa_Terminate( void )
 
342
{
 
343
    PaError result;
 
344
 
 
345
    PA_LOGAPI_ENTER( "Pa_Terminate" );
 
346
 
 
347
    if( PA_IS_INITIALISED_ )
 
348
    {
 
349
        if( --initializationCount_ == 0 )
 
350
        {
 
351
            CloseOpenStreams();
 
352
 
 
353
            TerminateHostApis();
 
354
 
 
355
            PaUtil_DumpTraceMessages();
 
356
        }
 
357
        result = paNoError;
 
358
    }
 
359
    else
 
360
    {
 
361
        result=  paNotInitialized;
 
362
    }
 
363
 
 
364
    PA_LOGAPI_EXIT_PAERROR( "Pa_Terminate", result );
 
365
 
 
366
    return result;
 
367
}
 
368
 
 
369
 
 
370
const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void )
 
371
{
 
372
    return &lastHostErrorInfo_;
 
373
}
 
374
 
 
375
 
 
376
const char *Pa_GetErrorText( PaError errorCode )
 
377
{
 
378
    const char *result;
 
379
 
 
380
    switch( errorCode )
 
381
    {
 
382
    case paNoError:                  result = "Success"; break;
 
383
    case paNotInitialized:           result = "PortAudio not initialized"; break;
 
384
    /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError */
 
385
    case paUnanticipatedHostError:   result = "Unanticipated host error"; break;
 
386
    case paInvalidChannelCount:      result = "Invalid number of channels"; break;
 
387
    case paInvalidSampleRate:        result = "Invalid sample rate"; break;
 
388
    case paInvalidDevice:            result = "Invalid device"; break;
 
389
    case paInvalidFlag:              result = "Invalid flag"; break;
 
390
    case paSampleFormatNotSupported: result = "Sample format not supported"; break;
 
391
    case paBadIODeviceCombination:   result = "Illegal combination of I/O devices"; break;
 
392
    case paInsufficientMemory:       result = "Insufficient memory"; break;
 
393
    case paBufferTooBig:             result = "Buffer too big"; break;
 
394
    case paBufferTooSmall:           result = "Buffer too small"; break;
 
395
    case paNullCallback:             result = "No callback routine specified"; break;
 
396
    case paBadStreamPtr:             result = "Invalid stream pointer"; break;
 
397
    case paTimedOut:                 result = "Wait timed out"; break;
 
398
    case paInternalError:            result = "Internal PortAudio error"; break;
 
399
    case paDeviceUnavailable:        result = "Device unavailable"; break;
 
400
    case paIncompatibleHostApiSpecificStreamInfo:   result = "Incompatible host API specific stream info"; break;
 
401
    case paStreamIsStopped:          result = "Stream is stopped"; break;
 
402
    case paStreamIsNotStopped:       result = "Stream is not stopped"; break;
 
403
    case paInputOverflowed:          result = "Input overflowed"; break;
 
404
    case paOutputUnderflowed:        result = "Output underflowed"; break;
 
405
    case paHostApiNotFound:          result = "Host API not found"; break;
 
406
    case paInvalidHostApi:           result = "Invalid host API"; break;
 
407
    case paCanNotReadFromACallbackStream:       result = "Can't read from a callback stream"; break;
 
408
    case paCanNotWriteToACallbackStream:        result = "Can't write to a callback stream"; break;
 
409
    case paCanNotReadFromAnOutputOnlyStream:    result = "Can't read from an output only stream"; break;
 
410
    case paCanNotWriteToAnInputOnlyStream:      result = "Can't write to an input only stream"; break;
 
411
    case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break;
 
412
    case paBadBufferPtr:             result = "Bad buffer pointer"; break;
 
413
    default:                         
 
414
                if( errorCode > 0 )
 
415
                        result = "Invalid error code (value greater than zero)"; 
 
416
        else
 
417
                        result = "Invalid error code"; 
 
418
        break;
 
419
    }
 
420
    return result;
 
421
}
 
422
 
 
423
 
 
424
PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
 
425
{
 
426
    PaHostApiIndex result;
 
427
    int i;
 
428
    
 
429
    PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" );
 
430
    PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type ));
 
431
 
 
432
    if( !PA_IS_INITIALISED_ )
 
433
    {
 
434
        result = paNotInitialized;
 
435
    }
 
436
    else
 
437
    {
 
438
        result = paHostApiNotFound;
 
439
        
 
440
        for( i=0; i < hostApisCount_; ++i )
 
441
        {
 
442
            if( hostApis_[i]->info.type == type )
 
443
            {
 
444
                result = i;
 
445
                break;
 
446
            }         
 
447
        }
 
448
    }
 
449
 
 
450
    PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiTypeIdToHostApiIndex", "PaHostApiIndex: %d", result );
 
451
 
 
452
    return result;
 
453
}
 
454
 
 
455
 
 
456
PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
 
457
        PaHostApiTypeId type )
 
458
{
 
459
    PaError result;
 
460
    int i;
 
461
    
 
462
    if( !PA_IS_INITIALISED_ )
 
463
    {
 
464
        result = paNotInitialized;
 
465
    }
 
466
    else
 
467
    {
 
468
        result = paHostApiNotFound;
 
469
                
 
470
        for( i=0; i < hostApisCount_; ++i )
 
471
        {
 
472
            if( hostApis_[i]->info.type == type )
 
473
            {
 
474
                *hostApi = hostApis_[i];
 
475
                result = paNoError;
 
476
                break;
 
477
            }
 
478
        }
 
479
    }
 
480
 
 
481
    return result;
 
482
}
 
483
 
 
484
 
 
485
PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
 
486
        PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi )
 
487
{
 
488
    PaError result;
 
489
    PaDeviceIndex x;
 
490
    
 
491
    x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
 
492
 
 
493
    if( x < 0 || x >= hostApi->info.deviceCount )
 
494
    {
 
495
        result = paInvalidDevice;
 
496
    }
 
497
    else
 
498
    {
 
499
        *hostApiDevice = x;
 
500
        result = paNoError;
 
501
    }
 
502
 
 
503
    return result;
 
504
}
 
505
 
 
506
 
 
507
PaHostApiIndex Pa_GetHostApiCount( void )
 
508
{
 
509
    int result;
 
510
 
 
511
    PA_LOGAPI_ENTER( "Pa_GetHostApiCount" );
 
512
 
 
513
    if( !PA_IS_INITIALISED_ )
 
514
    {
 
515
        result = paNotInitialized;
 
516
    }
 
517
    else
 
518
    {
 
519
        result = hostApisCount_;
 
520
    }
 
521
 
 
522
    PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result );
 
523
 
 
524
    return result;
 
525
}
 
526
 
 
527
 
 
528
PaHostApiIndex Pa_GetDefaultHostApi( void )
 
529
{
 
530
    int result;
 
531
 
 
532
    PA_LOGAPI_ENTER( "Pa_GetDefaultHostApi" );
 
533
 
 
534
    if( !PA_IS_INITIALISED_ )
 
535
    {
 
536
        result = paNotInitialized;
 
537
    }
 
538
    else
 
539
    {
 
540
        result = paDefaultHostApiIndex;
 
541
 
 
542
        /* internal consistency check: make sure that the default host api
 
543
         index is within range */
 
544
 
 
545
        if( result < 0 || result >= hostApisCount_ )
 
546
        {
 
547
            result = paInternalError;
 
548
        }
 
549
    }
 
550
 
 
551
    PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDefaultHostApi", "PaHostApiIndex: %d", result );
 
552
 
 
553
    return result;
 
554
}
 
555
 
 
556
 
 
557
const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
 
558
{
 
559
    PaHostApiInfo *info;
 
560
 
 
561
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetHostApiInfo" );
 
562
    PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi ));
 
563
 
 
564
    if( !PA_IS_INITIALISED_ )
 
565
    {
 
566
        info = NULL;
 
567
 
 
568
        PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
 
569
        PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" ));
 
570
 
 
571
    }
 
572
    else if( hostApi < 0 || hostApi >= hostApisCount_ )
 
573
    {
 
574
        info = NULL;
 
575
        
 
576
        PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
 
577
        PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" ));
 
578
 
 
579
    }
 
580
    else
 
581
    {
 
582
        info = &hostApis_[hostApi]->info;
 
583
 
 
584
        PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
 
585
        PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info ));
 
586
        PA_LOGAPI(("\t{\n" ));
 
587
        PA_LOGAPI(("\t\tint structVersion: %d\n", info->structVersion ));
 
588
        PA_LOGAPI(("\t\tPaHostApiTypeId type: %d\n", info->type ));
 
589
        PA_LOGAPI(("\t\tconst char *name: %s\n", info->name ));
 
590
        PA_LOGAPI(("\t}\n" ));
 
591
 
 
592
    }
 
593
 
 
594
     return info;
 
595
}
 
596
 
 
597
 
 
598
PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex )
 
599
{
 
600
    PaDeviceIndex result;
 
601
 
 
602
    PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiDeviceIndexToPaDeviceIndex" );
 
603
    PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi ));
 
604
    PA_LOGAPI(("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex ));
 
605
 
 
606
    if( !PA_IS_INITIALISED_ )
 
607
    {
 
608
        result = paNotInitialized;
 
609
    }
 
610
    else
 
611
    {
 
612
        if( hostApi < 0 || hostApi >= hostApisCount_ )
 
613
        {
 
614
            result = paInvalidHostApi;
 
615
        }
 
616
        else
 
617
        {
 
618
            if( hostApiDeviceIndex < 0 ||
 
619
                    hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount )
 
620
            {
 
621
                result = paInvalidDevice;
 
622
            }
 
623
            else
 
624
            {
 
625
                result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex;
 
626
            }
 
627
        }
 
628
    }
 
629
 
 
630
    PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiDeviceIndexToPaDeviceIndex", "PaDeviceIndex: %d", result );
 
631
 
 
632
    return result;
 
633
}
 
634
 
 
635
 
 
636
PaDeviceIndex Pa_GetDeviceCount( void )
 
637
{
 
638
    PaDeviceIndex result;
 
639
 
 
640
    PA_LOGAPI_ENTER( "Pa_GetDeviceCount" );
 
641
 
 
642
    if( !PA_IS_INITIALISED_ )
 
643
    {
 
644
        result = paNotInitialized;
 
645
    }
 
646
    else
 
647
    {
 
648
        result = deviceCount_;
 
649
    }
 
650
 
 
651
    PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result );
 
652
 
 
653
    return result;
 
654
}
 
655
 
 
656
 
 
657
PaDeviceIndex Pa_GetDefaultInputDevice( void )
 
658
{
 
659
    PaHostApiIndex hostApi;
 
660
    PaDeviceIndex result;
 
661
 
 
662
    PA_LOGAPI_ENTER( "Pa_GetDefaultInputDevice" );
 
663
 
 
664
    hostApi = Pa_GetDefaultHostApi();
 
665
    if( hostApi < 0 )
 
666
    {
 
667
        result = paNoDevice;
 
668
    }
 
669
    else
 
670
    {
 
671
        result = hostApis_[hostApi]->info.defaultInputDevice;
 
672
    }
 
673
 
 
674
    PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result );
 
675
 
 
676
    return result;
 
677
}
 
678
 
 
679
 
 
680
PaDeviceIndex Pa_GetDefaultOutputDevice( void )
 
681
{
 
682
    PaHostApiIndex hostApi;
 
683
    PaDeviceIndex result;
 
684
    
 
685
    PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" );
 
686
 
 
687
    hostApi = Pa_GetDefaultHostApi();
 
688
    if( hostApi < 0 )
 
689
    {
 
690
        result = paNoDevice;
 
691
    }
 
692
    else
 
693
    {
 
694
        result = hostApis_[hostApi]->info.defaultOutputDevice;
 
695
    }
 
696
 
 
697
    PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result );
 
698
 
 
699
    return result;
 
700
}
 
701
 
 
702
 
 
703
const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
 
704
{
 
705
    int hostSpecificDeviceIndex;
 
706
    int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex );
 
707
    PaDeviceInfo *result;
 
708
 
 
709
 
 
710
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetDeviceInfo" );
 
711
    PA_LOGAPI(("\tPaDeviceIndex device: %d\n", device ));
 
712
 
 
713
    if( hostApiIndex < 0 )
 
714
    {
 
715
        result = NULL;
 
716
 
 
717
        PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" ));
 
718
        PA_LOGAPI(("\tPaDeviceInfo* NULL [ invalid device index ]\n" ));
 
719
 
 
720
    }
 
721
    else
 
722
    {
 
723
        result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ];
 
724
 
 
725
        PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" ));
 
726
        PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result ));
 
727
        PA_LOGAPI(("\t{\n" ));
 
728
 
 
729
        PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion ));
 
730
        PA_LOGAPI(("\t\tconst char *name: %s\n", result->name ));
 
731
        PA_LOGAPI(("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi ));
 
732
        PA_LOGAPI(("\t\tint maxInputChannels: %d\n", result->maxInputChannels ));
 
733
        PA_LOGAPI(("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels ));
 
734
        PA_LOGAPI(("\t}\n" ));
 
735
 
 
736
    }
 
737
 
 
738
    return result;
 
739
}
 
740
 
 
741
 
 
742
/*
 
743
    SampleFormatIsValid() returns 1 if sampleFormat is a sample format
 
744
    defined in portaudio.h, or 0 otherwise.
 
745
*/
 
746
static int SampleFormatIsValid( PaSampleFormat format )
 
747
{
 
748
    switch( format & ~paNonInterleaved )
 
749
    {
 
750
    case paFloat32: return 1;
 
751
    case paInt16: return 1;
 
752
    case paInt32: return 1;
 
753
    case paInt24: return 1;
 
754
    case paInt8: return 1;
 
755
    case paUInt8: return 1;
 
756
    case paCustomFormat: return 1;
 
757
    default: return 0;
 
758
    }
 
759
}
 
760
 
 
761
/*
 
762
    NOTE: make sure this validation list is kept syncronised with the one in
 
763
            pa_hostapi.h
 
764
 
 
765
    ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream()
 
766
    conform to the expected values as described below. This function is
 
767
    also designed to be used with the proposed Pa_IsFormatSupported() function.
 
768
    
 
769
    There are basically two types of validation that could be performed:
 
770
    Generic conformance validation, and device capability mismatch
 
771
    validation. This function performs only generic conformance validation.
 
772
    Validation that would require knowledge of device capabilities is
 
773
    not performed because of potentially complex relationships between
 
774
    combinations of parameters - for example, even if the sampleRate
 
775
    seems ok, it might not be for a duplex stream - we have no way of
 
776
    checking this in an API-neutral way, so we don't try.
 
777
 
 
778
    On success the function returns PaNoError and fills in hostApi,
 
779
    hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure
 
780
    the function returns an error code indicating the first encountered
 
781
    parameter error.
 
782
 
 
783
 
 
784
    If ValidateOpenStreamParameters() returns paNoError, the following
 
785
    assertions are guaranteed to be true.
 
786
 
 
787
    - at least one of inputParameters & outputParmeters is valid (not NULL)
 
788
 
 
789
    - if inputParameters & outputParameters are both valid, that
 
790
        inputParameters->device & outputParameters->device  both use the same host api
 
791
 
 
792
    PaDeviceIndex inputParameters->device
 
793
        - is within range (0 to Pa_GetDeviceCount-1) Or:
 
794
        - is paUseHostApiSpecificDeviceSpecification and
 
795
            inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
 
796
            to a valid host api
 
797
 
 
798
    int inputParameters->channelCount
 
799
        - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
 
800
        - upper bound is NOT validated against device capabilities
 
801
 
 
802
    PaSampleFormat inputParameters->sampleFormat
 
803
        - is one of the sample formats defined in portaudio.h
 
804
 
 
805
    void *inputParameters->hostApiSpecificStreamInfo
 
806
        - if supplied its hostApi field matches the input device's host Api
 
807
 
 
808
    PaDeviceIndex outputParmeters->device
 
809
        - is within range (0 to Pa_GetDeviceCount-1)
 
810
 
 
811
    int outputParmeters->channelCount
 
812
        - if inputDevice is valid, channelCount is > 0
 
813
        - upper bound is NOT validated against device capabilities
 
814
 
 
815
    PaSampleFormat outputParmeters->sampleFormat
 
816
        - is one of the sample formats defined in portaudio.h
 
817
        
 
818
    void *outputParmeters->hostApiSpecificStreamInfo
 
819
        - if supplied its hostApi field matches the output device's host Api
 
820
 
 
821
    double sampleRate
 
822
        - is not an 'absurd' rate (less than 1000. or greater than 200000.)
 
823
        - sampleRate is NOT validated against device capabilities
 
824
 
 
825
    PaStreamFlags streamFlags
 
826
        - unused platform neutral flags are zero
 
827
        - paNeverDropInput is only used for full-duplex callback streams with
 
828
            variable buffer size (paFramesPerBufferUnspecified)
 
829
*/
 
830
static PaError ValidateOpenStreamParameters(
 
831
    const PaStreamParameters *inputParameters,
 
832
    const PaStreamParameters *outputParameters,
 
833
    double sampleRate,
 
834
    unsigned long framesPerBuffer,
 
835
    PaStreamFlags streamFlags,
 
836
    PaStreamCallback *streamCallback,
 
837
    PaUtilHostApiRepresentation **hostApi,
 
838
    PaDeviceIndex *hostApiInputDevice,
 
839
    PaDeviceIndex *hostApiOutputDevice )
 
840
{
 
841
    int inputHostApiIndex  = -1, /* Surpress uninitialised var warnings: compiler does */
 
842
        outputHostApiIndex = -1; /* not see that if inputParameters and outputParame-  */
 
843
                                 /* ters are both nonzero, these indices are set.      */
 
844
 
 
845
    if( (inputParameters == NULL) && (outputParameters == NULL) )
 
846
    {
 
847
        return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */
 
848
    }
 
849
    else
 
850
    {
 
851
        if( inputParameters == NULL )
 
852
        {
 
853
            *hostApiInputDevice = paNoDevice;
 
854
        }
 
855
        else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
 
856
        {
 
857
            if( inputParameters->hostApiSpecificStreamInfo )
 
858
            {
 
859
                inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
 
860
                        ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType );
 
861
 
 
862
                if( inputHostApiIndex != -1 )
 
863
                {
 
864
                    *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification;
 
865
                    *hostApi = hostApis_[inputHostApiIndex];
 
866
                }
 
867
                else
 
868
                {
 
869
                    return paInvalidDevice;
 
870
                }
 
871
            }
 
872
            else
 
873
            {
 
874
                return paInvalidDevice;
 
875
            }
 
876
        }
 
877
        else
 
878
        {
 
879
            if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ )
 
880
                return paInvalidDevice;
 
881
 
 
882
            inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice );
 
883
            if( inputHostApiIndex < 0 )
 
884
                return paInternalError;
 
885
 
 
886
            *hostApi = hostApis_[inputHostApiIndex];
 
887
 
 
888
            if( inputParameters->channelCount <= 0 )
 
889
                return paInvalidChannelCount;
 
890
 
 
891
            if( !SampleFormatIsValid( inputParameters->sampleFormat ) )
 
892
                return paSampleFormatNotSupported;
 
893
 
 
894
            if( inputParameters->hostApiSpecificStreamInfo != NULL )
 
895
            {
 
896
                if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType
 
897
                        != (*hostApi)->info.type )
 
898
                    return paIncompatibleHostApiSpecificStreamInfo;
 
899
            }
 
900
        }
 
901
 
 
902
        if( outputParameters == NULL )
 
903
        {
 
904
            *hostApiOutputDevice = paNoDevice;
 
905
        }
 
906
        else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification  )
 
907
        {
 
908
            if( outputParameters->hostApiSpecificStreamInfo )
 
909
            {
 
910
                outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
 
911
                        ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType );
 
912
 
 
913
                if( outputHostApiIndex != -1 )
 
914
                {
 
915
                    *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification;
 
916
                    *hostApi = hostApis_[outputHostApiIndex];
 
917
                }
 
918
                else
 
919
                {
 
920
                    return paInvalidDevice;
 
921
                }
 
922
            }
 
923
            else
 
924
            {
 
925
                return paInvalidDevice;
 
926
            }
 
927
        }
 
928
        else
 
929
        {
 
930
            if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ )
 
931
                return paInvalidDevice;
 
932
 
 
933
            outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice );
 
934
            if( outputHostApiIndex < 0 )
 
935
                return paInternalError;
 
936
 
 
937
            *hostApi = hostApis_[outputHostApiIndex];
 
938
 
 
939
            if( outputParameters->channelCount <= 0 )
 
940
                return paInvalidChannelCount;
 
941
 
 
942
            if( !SampleFormatIsValid( outputParameters->sampleFormat ) )
 
943
                return paSampleFormatNotSupported;
 
944
 
 
945
            if( outputParameters->hostApiSpecificStreamInfo != NULL )
 
946
            {
 
947
                if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType
 
948
                        != (*hostApi)->info.type )
 
949
                    return paIncompatibleHostApiSpecificStreamInfo;
 
950
            }
 
951
        }   
 
952
 
 
953
        if( (inputParameters != NULL) && (outputParameters != NULL) )
 
954
        {
 
955
            /* ensure that both devices use the same API */
 
956
            if( inputHostApiIndex != outputHostApiIndex )
 
957
                return paBadIODeviceCombination;
 
958
        }
 
959
    }
 
960
    
 
961
    
 
962
    /* Check for absurd sample rates. */
 
963
    if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
 
964
        return paInvalidSampleRate;
 
965
 
 
966
    if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
 
967
        return paInvalidFlag;
 
968
 
 
969
    if( streamFlags & paNeverDropInput )
 
970
    {
 
971
        /* must be a callback stream */
 
972
        if( !streamCallback )
 
973
             return paInvalidFlag;
 
974
 
 
975
        /* must be a full duplex stream */
 
976
        if( (inputParameters == NULL) || (outputParameters == NULL) )
 
977
            return paInvalidFlag;
 
978
 
 
979
        /* must use paFramesPerBufferUnspecified */
 
980
        if( framesPerBuffer != paFramesPerBufferUnspecified )
 
981
            return paInvalidFlag;
 
982
    }
 
983
    
 
984
    return paNoError;
 
985
}
 
986
 
 
987
 
 
988
PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
 
989
                              const PaStreamParameters *outputParameters,
 
990
                              double sampleRate )
 
991
{
 
992
    PaError result;
 
993
    PaUtilHostApiRepresentation *hostApi = 0;
 
994
    PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice;
 
995
    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
 
996
    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
 
997
 
 
998
 
 
999
#ifdef PA_LOG_API_CALLS
 
1000
    PA_LOGAPI_ENTER_PARAMS( "Pa_IsFormatSupported" );
 
1001
 
 
1002
    if( inputParameters == NULL ){
 
1003
        PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" ));
 
1004
    }else{
 
1005
        PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters ));
 
1006
        PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device ));
 
1007
        PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount ));
 
1008
        PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat ));
 
1009
        PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency ));
 
1010
        PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo ));
 
1011
    }
 
1012
 
 
1013
    if( outputParameters == NULL ){
 
1014
        PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" ));
 
1015
    }else{
 
1016
        PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters ));
 
1017
        PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device ));
 
1018
        PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount ));
 
1019
        PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat ));
 
1020
        PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
 
1021
        PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
 
1022
    }
 
1023
    
 
1024
    PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
 
1025
#endif
 
1026
 
 
1027
    if( !PA_IS_INITIALISED_ )
 
1028
    {
 
1029
        result = paNotInitialized;
 
1030
 
 
1031
        PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result );
 
1032
        return result;
 
1033
    }
 
1034
 
 
1035
    result = ValidateOpenStreamParameters( inputParameters,
 
1036
                                           outputParameters,
 
1037
                                           sampleRate, 0, paNoFlag, 0,
 
1038
                                           &hostApi,
 
1039
                                           &hostApiInputDevice,
 
1040
                                           &hostApiOutputDevice );
 
1041
    if( result != paNoError )
 
1042
    {
 
1043
        PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result );
 
1044
        return result;
 
1045
    }
 
1046
    
 
1047
 
 
1048
    if( inputParameters )
 
1049
    {
 
1050
        hostApiInputParameters.device = hostApiInputDevice;
 
1051
        hostApiInputParameters.channelCount = inputParameters->channelCount;
 
1052
        hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
 
1053
        hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
 
1054
        hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
 
1055
        hostApiInputParametersPtr = &hostApiInputParameters;
 
1056
    }
 
1057
    else
 
1058
    {
 
1059
        hostApiInputParametersPtr = NULL;
 
1060
    }
 
1061
 
 
1062
    if( outputParameters )
 
1063
    {
 
1064
        hostApiOutputParameters.device = hostApiOutputDevice;
 
1065
        hostApiOutputParameters.channelCount = outputParameters->channelCount;
 
1066
        hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
 
1067
        hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
 
1068
        hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
 
1069
        hostApiOutputParametersPtr = &hostApiOutputParameters;
 
1070
    }
 
1071
    else
 
1072
    {
 
1073
        hostApiOutputParametersPtr = NULL;
 
1074
    }
 
1075
 
 
1076
    result = hostApi->IsFormatSupported( hostApi,
 
1077
                                  hostApiInputParametersPtr, hostApiOutputParametersPtr,
 
1078
                                  sampleRate );
 
1079
 
 
1080
#ifdef PA_LOG_API_CALLS
 
1081
    PA_LOGAPI(("Pa_OpenStream returned:\n" ));
 
1082
    if( result == paFormatIsSupported )
 
1083
        PA_LOGAPI(("\tPaError: 0 [ paFormatIsSupported ]\n" ));
 
1084
    else
 
1085
        PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1086
#endif
 
1087
 
 
1088
    return result;
 
1089
}
 
1090
 
 
1091
 
 
1092
PaError Pa_OpenStream( PaStream** stream,
 
1093
                       const PaStreamParameters *inputParameters,
 
1094
                       const PaStreamParameters *outputParameters,
 
1095
                       double sampleRate,
 
1096
                       unsigned long framesPerBuffer,
 
1097
                       PaStreamFlags streamFlags,
 
1098
                       PaStreamCallback *streamCallback,
 
1099
                       void *userData )
 
1100
{
 
1101
    PaError result;
 
1102
    PaUtilHostApiRepresentation *hostApi = 0;
 
1103
    PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice;
 
1104
    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
 
1105
    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
 
1106
 
 
1107
 
 
1108
#ifdef PA_LOG_API_CALLS
 
1109
    PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" );
 
1110
    PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));
 
1111
 
 
1112
    if( inputParameters == NULL ){
 
1113
        PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" ));
 
1114
    }else{
 
1115
        PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters ));
 
1116
        PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device ));
 
1117
        PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount ));
 
1118
        PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat ));
 
1119
        PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency ));
 
1120
        PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo ));
 
1121
    }
 
1122
 
 
1123
    if( outputParameters == NULL ){
 
1124
        PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" ));
 
1125
    }else{
 
1126
        PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters ));
 
1127
        PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device ));
 
1128
        PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount ));
 
1129
        PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat ));
 
1130
        PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
 
1131
        PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
 
1132
    }
 
1133
    
 
1134
    PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
 
1135
    PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer ));
 
1136
    PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags ));
 
1137
    PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback ));
 
1138
    PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData ));
 
1139
#endif
 
1140
 
 
1141
    if( !PA_IS_INITIALISED_ )
 
1142
    {
 
1143
        result = paNotInitialized;
 
1144
 
 
1145
        PA_LOGAPI(("Pa_OpenStream returned:\n" ));
 
1146
        PA_LOGAPI(("\t*(PaStream** stream): undefined\n" ));
 
1147
        PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1148
        return result;
 
1149
    }
 
1150
 
 
1151
    /* Check for parameter errors.
 
1152
        NOTE: make sure this validation list is kept syncronised with the one
 
1153
        in pa_hostapi.h
 
1154
    */
 
1155
 
 
1156
    if( stream == NULL )
 
1157
    {
 
1158
        result = paBadStreamPtr;
 
1159
 
 
1160
        PA_LOGAPI(("Pa_OpenStream returned:\n" ));
 
1161
        PA_LOGAPI(("\t*(PaStream** stream): undefined\n" ));
 
1162
        PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1163
        return result;
 
1164
    }
 
1165
 
 
1166
    result = ValidateOpenStreamParameters( inputParameters,
 
1167
                                           outputParameters,
 
1168
                                           sampleRate, framesPerBuffer,
 
1169
                                           streamFlags, streamCallback,
 
1170
                                           &hostApi,
 
1171
                                           &hostApiInputDevice,
 
1172
                                           &hostApiOutputDevice );
 
1173
    if( result != paNoError )
 
1174
    {
 
1175
        PA_LOGAPI(("Pa_OpenStream returned:\n" ));
 
1176
        PA_LOGAPI(("\t*(PaStream** stream): undefined\n" ));
 
1177
        PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1178
        return result;
 
1179
    }
 
1180
    
 
1181
 
 
1182
    if( inputParameters )
 
1183
    {
 
1184
        hostApiInputParameters.device = hostApiInputDevice;
 
1185
        hostApiInputParameters.channelCount = inputParameters->channelCount;
 
1186
        hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
 
1187
        hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
 
1188
        hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
 
1189
        hostApiInputParametersPtr = &hostApiInputParameters;
 
1190
    }
 
1191
    else
 
1192
    {
 
1193
        hostApiInputParametersPtr = NULL;
 
1194
    }
 
1195
 
 
1196
    if( outputParameters )
 
1197
    {
 
1198
        hostApiOutputParameters.device = hostApiOutputDevice;
 
1199
        hostApiOutputParameters.channelCount = outputParameters->channelCount;
 
1200
        hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
 
1201
        hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
 
1202
        hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
 
1203
        hostApiOutputParametersPtr = &hostApiOutputParameters;
 
1204
    }
 
1205
    else
 
1206
    {
 
1207
        hostApiOutputParametersPtr = NULL;
 
1208
    }
 
1209
 
 
1210
    result = hostApi->OpenStream( hostApi, stream,
 
1211
                                  hostApiInputParametersPtr, hostApiOutputParametersPtr,
 
1212
                                  sampleRate, framesPerBuffer, streamFlags, streamCallback, userData );
 
1213
 
 
1214
    if( result == paNoError )
 
1215
        AddOpenStream( *stream );
 
1216
 
 
1217
 
 
1218
    PA_LOGAPI(("Pa_OpenStream returned:\n" ));
 
1219
    PA_LOGAPI(("\t*(PaStream** stream): 0x%p\n", *stream ));
 
1220
    PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1221
 
 
1222
    return result;
 
1223
}
 
1224
 
 
1225
 
 
1226
PaError Pa_OpenDefaultStream( PaStream** stream,
 
1227
                              int inputChannelCount,
 
1228
                              int outputChannelCount,
 
1229
                              PaSampleFormat sampleFormat,
 
1230
                              double sampleRate,
 
1231
                              unsigned long framesPerBuffer,
 
1232
                              PaStreamCallback *streamCallback,
 
1233
                              void *userData )
 
1234
{
 
1235
    PaError result;
 
1236
    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
 
1237
    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
 
1238
 
 
1239
    PA_LOGAPI_ENTER_PARAMS( "Pa_OpenDefaultStream" );
 
1240
    PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream ));
 
1241
    PA_LOGAPI(("\tint inputChannelCount: %d\n", inputChannelCount ));
 
1242
    PA_LOGAPI(("\tint outputChannelCount: %d\n", outputChannelCount ));
 
1243
    PA_LOGAPI(("\tPaSampleFormat sampleFormat: %d\n", sampleFormat ));
 
1244
    PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
 
1245
    PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer ));
 
1246
    PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback ));
 
1247
    PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData ));
 
1248
 
 
1249
 
 
1250
    if( inputChannelCount > 0 )
 
1251
    {
 
1252
        hostApiInputParameters.device = Pa_GetDefaultInputDevice();
 
1253
                if( hostApiInputParameters.device == paNoDevice )
 
1254
                        return paDeviceUnavailable; 
 
1255
        
 
1256
        hostApiInputParameters.channelCount = inputChannelCount;
 
1257
        hostApiInputParameters.sampleFormat = sampleFormat;
 
1258
        /* defaultHighInputLatency is used below instead of
 
1259
           defaultLowInputLatency because it is more important for the default
 
1260
           stream to work reliably than it is for it to work with the lowest
 
1261
           latency.
 
1262
         */
 
1263
        hostApiInputParameters.suggestedLatency = 
 
1264
             Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
 
1265
        hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
 
1266
        hostApiInputParametersPtr = &hostApiInputParameters;
 
1267
    }
 
1268
    else
 
1269
    {
 
1270
        hostApiInputParametersPtr = NULL;
 
1271
    }
 
1272
 
 
1273
    if( outputChannelCount > 0 )
 
1274
    {
 
1275
        hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
 
1276
                if( hostApiOutputParameters.device == paNoDevice )
 
1277
                        return paDeviceUnavailable; 
 
1278
 
 
1279
        hostApiOutputParameters.channelCount = outputChannelCount;
 
1280
        hostApiOutputParameters.sampleFormat = sampleFormat;
 
1281
        /* defaultHighOutputLatency is used below instead of
 
1282
           defaultLowOutputLatency because it is more important for the default
 
1283
           stream to work reliably than it is for it to work with the lowest
 
1284
           latency.
 
1285
         */
 
1286
        hostApiOutputParameters.suggestedLatency =
 
1287
             Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
 
1288
        hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
 
1289
        hostApiOutputParametersPtr = &hostApiOutputParameters;
 
1290
    }
 
1291
    else
 
1292
    {
 
1293
        hostApiOutputParametersPtr = NULL;
 
1294
    }
 
1295
 
 
1296
 
 
1297
    result = Pa_OpenStream(
 
1298
                 stream, hostApiInputParametersPtr, hostApiOutputParametersPtr,
 
1299
                 sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
 
1300
 
 
1301
    PA_LOGAPI(("Pa_OpenDefaultStream returned:\n" ));
 
1302
    PA_LOGAPI(("\t*(PaStream** stream): 0x%p", *stream ));
 
1303
    PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1304
 
 
1305
    return result;
 
1306
}
 
1307
 
 
1308
 
 
1309
PaError PaUtil_ValidateStreamPointer( PaStream* stream )
 
1310
{
 
1311
    if( !PA_IS_INITIALISED_ ) return paNotInitialized;
 
1312
 
 
1313
    if( stream == NULL ) return paBadStreamPtr;
 
1314
 
 
1315
    if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC )
 
1316
        return paBadStreamPtr;
 
1317
 
 
1318
    return paNoError;
 
1319
}
 
1320
 
 
1321
 
 
1322
PaError Pa_CloseStream( PaStream* stream )
 
1323
{
 
1324
    PaUtilStreamInterface *interface;
 
1325
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1326
 
 
1327
    PA_LOGAPI_ENTER_PARAMS( "Pa_CloseStream" );
 
1328
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1329
 
 
1330
    /* always remove the open stream from our list, even if this function
 
1331
        eventually returns an error. Otherwise CloseOpenStreams() will
 
1332
        get stuck in an infinite loop */
 
1333
    RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */
 
1334
 
 
1335
    if( result == paNoError )
 
1336
    {
 
1337
        interface = PA_STREAM_INTERFACE(stream);
 
1338
 
 
1339
        /* abort the stream if it isn't stopped */
 
1340
        result = interface->IsStopped( stream );
 
1341
        if( result == 1 )
 
1342
            result = paNoError;
 
1343
        else if( result == 0 )
 
1344
            result = interface->Abort( stream );
 
1345
 
 
1346
        if( result == paNoError )                 /** @todo REVIEW: shouldn't we close anyway? */
 
1347
            result = interface->Close( stream );
 
1348
    }
 
1349
 
 
1350
    PA_LOGAPI_EXIT_PAERROR( "Pa_CloseStream", result );
 
1351
 
 
1352
    return result;
 
1353
}
 
1354
 
 
1355
 
 
1356
PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback )
 
1357
{
 
1358
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1359
 
 
1360
    PA_LOGAPI_ENTER_PARAMS( "Pa_SetStreamFinishedCallback" );
 
1361
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1362
    PA_LOGAPI(("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback ));
 
1363
 
 
1364
    if( result == paNoError )
 
1365
    {
 
1366
        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1367
        if( result == 0 )
 
1368
        {
 
1369
            result = paStreamIsNotStopped ;
 
1370
        }
 
1371
        if( result == 1 )
 
1372
        {
 
1373
            PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback;
 
1374
            result = paNoError;
 
1375
        }
 
1376
    }
 
1377
 
 
1378
    PA_LOGAPI_EXIT_PAERROR( "Pa_SetStreamFinishedCallback", result );
 
1379
 
 
1380
    return result;
 
1381
 
 
1382
}
 
1383
 
 
1384
 
 
1385
PaError Pa_StartStream( PaStream *stream )
 
1386
{
 
1387
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1388
 
 
1389
    PA_LOGAPI_ENTER_PARAMS( "Pa_StartStream" );
 
1390
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1391
 
 
1392
    if( result == paNoError )
 
1393
    {
 
1394
        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1395
        if( result == 0 )
 
1396
        {
 
1397
            result = paStreamIsNotStopped ;
 
1398
        }
 
1399
        else if( result == 1 )
 
1400
        {
 
1401
            result = PA_STREAM_INTERFACE(stream)->Start( stream );
 
1402
        }
 
1403
    }
 
1404
 
 
1405
    PA_LOGAPI_EXIT_PAERROR( "Pa_StartStream", result );
 
1406
 
 
1407
    return result;
 
1408
}
 
1409
 
 
1410
 
 
1411
PaError Pa_StopStream( PaStream *stream )
 
1412
{
 
1413
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1414
 
 
1415
    PA_LOGAPI_ENTER_PARAMS( "Pa_StopStream" );
 
1416
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1417
 
 
1418
    if( result == paNoError )
 
1419
    {
 
1420
        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1421
        if( result == 0 )
 
1422
        {
 
1423
            result = PA_STREAM_INTERFACE(stream)->Stop( stream );
 
1424
        }
 
1425
        else if( result == 1 )
 
1426
        {
 
1427
            result = paStreamIsStopped;
 
1428
        }
 
1429
    }
 
1430
 
 
1431
    PA_LOGAPI_EXIT_PAERROR( "Pa_StopStream", result );
 
1432
 
 
1433
    return result;
 
1434
}
 
1435
 
 
1436
 
 
1437
PaError Pa_AbortStream( PaStream *stream )
 
1438
{
 
1439
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1440
 
 
1441
    PA_LOGAPI_ENTER_PARAMS( "Pa_AbortStream" );
 
1442
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1443
 
 
1444
    if( result == paNoError )
 
1445
    {
 
1446
        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1447
        if( result == 0 )
 
1448
        {
 
1449
            result = PA_STREAM_INTERFACE(stream)->Abort( stream );
 
1450
        }
 
1451
        else if( result == 1 )
 
1452
        {
 
1453
            result = paStreamIsStopped;
 
1454
        }
 
1455
    }
 
1456
 
 
1457
    PA_LOGAPI_EXIT_PAERROR( "Pa_AbortStream", result );
 
1458
 
 
1459
    return result;
 
1460
}
 
1461
 
 
1462
 
 
1463
PaError Pa_IsStreamStopped( PaStream *stream )
 
1464
{
 
1465
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1466
 
 
1467
    PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamStopped" );
 
1468
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1469
 
 
1470
    if( result == paNoError )
 
1471
        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1472
 
 
1473
    PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamStopped", result );
 
1474
 
 
1475
    return result;
 
1476
}
 
1477
 
 
1478
 
 
1479
PaError Pa_IsStreamActive( PaStream *stream )
 
1480
{
 
1481
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1482
 
 
1483
    PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamActive" );
 
1484
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1485
 
 
1486
    if( result == paNoError )
 
1487
        result = PA_STREAM_INTERFACE(stream)->IsActive( stream );
 
1488
 
 
1489
 
 
1490
    PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamActive", result );
 
1491
 
 
1492
    return result;
 
1493
}
 
1494
 
 
1495
 
 
1496
const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream )
 
1497
{
 
1498
    PaError error = PaUtil_ValidateStreamPointer( stream );
 
1499
    const PaStreamInfo *result;
 
1500
 
 
1501
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamInfo" );
 
1502
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1503
 
 
1504
    if( error != paNoError )
 
1505
    {
 
1506
        result = 0;
 
1507
 
 
1508
        PA_LOGAPI(("Pa_GetStreamInfo returned:\n" ));
 
1509
        PA_LOGAPI(("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n", error, Pa_GetErrorText( error ) ));
 
1510
 
 
1511
    }
 
1512
    else
 
1513
    {
 
1514
        result = &PA_STREAM_REP( stream )->streamInfo;
 
1515
 
 
1516
        PA_LOGAPI(("Pa_GetStreamInfo returned:\n" ));
 
1517
        PA_LOGAPI(("\tconst PaStreamInfo*: 0x%p:\n", result ));
 
1518
        PA_LOGAPI(("\t{" ));
 
1519
 
 
1520
        PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion ));
 
1521
        PA_LOGAPI(("\t\tPaTime inputLatency: %f\n", result->inputLatency ));
 
1522
        PA_LOGAPI(("\t\tPaTime outputLatency: %f\n", result->outputLatency ));
 
1523
        PA_LOGAPI(("\t\tdouble sampleRate: %f\n", result->sampleRate ));
 
1524
        PA_LOGAPI(("\t}\n" ));
 
1525
 
 
1526
    }
 
1527
 
 
1528
    return result;
 
1529
}
 
1530
 
 
1531
 
 
1532
PaTime Pa_GetStreamTime( PaStream *stream )
 
1533
{
 
1534
    PaError error = PaUtil_ValidateStreamPointer( stream );
 
1535
    PaTime result;
 
1536
 
 
1537
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamTime" );
 
1538
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1539
 
 
1540
    if( error != paNoError )
 
1541
    {
 
1542
        result = 0;
 
1543
 
 
1544
        PA_LOGAPI(("Pa_GetStreamTime returned:\n" ));
 
1545
        PA_LOGAPI(("\tPaTime: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) ));
 
1546
 
 
1547
    }
 
1548
    else
 
1549
    {
 
1550
        result = PA_STREAM_INTERFACE(stream)->GetTime( stream );
 
1551
 
 
1552
        PA_LOGAPI(("Pa_GetStreamTime returned:\n" ));
 
1553
        PA_LOGAPI(("\tPaTime: %g\n", result ));
 
1554
 
 
1555
    }
 
1556
 
 
1557
    return result;
 
1558
}
 
1559
 
 
1560
 
 
1561
double Pa_GetStreamCpuLoad( PaStream* stream )
 
1562
{
 
1563
    PaError error = PaUtil_ValidateStreamPointer( stream );
 
1564
    double result;
 
1565
 
 
1566
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamCpuLoad" );
 
1567
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1568
 
 
1569
    if( error != paNoError )
 
1570
    {
 
1571
 
 
1572
        result = 0.0;
 
1573
 
 
1574
        PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" ));
 
1575
        PA_LOGAPI(("\tdouble: 0.0 [PaError error: %d ( %s )]\n", error, Pa_GetErrorText( error ) ));
 
1576
 
 
1577
    }
 
1578
    else
 
1579
    {
 
1580
        result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream );
 
1581
 
 
1582
        PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" ));
 
1583
        PA_LOGAPI(("\tdouble: %g\n", result ));
 
1584
 
 
1585
    }
 
1586
 
 
1587
    return result;
 
1588
}
 
1589
 
 
1590
 
 
1591
PaError Pa_ReadStream( PaStream* stream,
 
1592
                       void *buffer,
 
1593
                       unsigned long frames )
 
1594
{
 
1595
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1596
 
 
1597
    PA_LOGAPI_ENTER_PARAMS( "Pa_ReadStream" );
 
1598
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1599
 
 
1600
    if( result == paNoError )
 
1601
    {
 
1602
        if( frames == 0 )
 
1603
        {
 
1604
            /* XXX: Should we not allow the implementation to signal any overflow condition? */
 
1605
            result = paNoError;
 
1606
        }
 
1607
        else if( buffer == 0 )
 
1608
        {
 
1609
            result = paBadBufferPtr;
 
1610
        }
 
1611
        else
 
1612
        {
 
1613
            result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1614
            if( result == 0 )
 
1615
            {
 
1616
                result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames );
 
1617
            }
 
1618
            else if( result == 1 )
 
1619
            {
 
1620
                result = paStreamIsStopped;
 
1621
            }
 
1622
        }
 
1623
    }
 
1624
 
 
1625
    PA_LOGAPI_EXIT_PAERROR( "Pa_ReadStream", result );
 
1626
 
 
1627
    return result;
 
1628
}
 
1629
 
 
1630
 
 
1631
PaError Pa_WriteStream( PaStream* stream,
 
1632
                        const void *buffer,
 
1633
                        unsigned long frames )
 
1634
{
 
1635
    PaError result = PaUtil_ValidateStreamPointer( stream );
 
1636
 
 
1637
    PA_LOGAPI_ENTER_PARAMS( "Pa_WriteStream" );
 
1638
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1639
 
 
1640
    if( result == paNoError )
 
1641
    {
 
1642
        if( frames == 0 )
 
1643
        {
 
1644
            /* XXX: Should we not allow the implementation to signal any underflow condition? */
 
1645
            result = paNoError;
 
1646
        }
 
1647
        else if( buffer == 0 )
 
1648
        {
 
1649
            result = paBadBufferPtr;
 
1650
        }
 
1651
        else
 
1652
        {
 
1653
            result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
 
1654
            if( result == 0 )
 
1655
            {
 
1656
                result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames );
 
1657
            }
 
1658
            else if( result == 1 )
 
1659
            {
 
1660
                result = paStreamIsStopped;
 
1661
            }  
 
1662
        }
 
1663
    }
 
1664
 
 
1665
    PA_LOGAPI_EXIT_PAERROR( "Pa_WriteStream", result );
 
1666
 
 
1667
    return result;
 
1668
}
 
1669
 
 
1670
signed long Pa_GetStreamReadAvailable( PaStream* stream )
 
1671
{
 
1672
    PaError error = PaUtil_ValidateStreamPointer( stream );
 
1673
    signed long result;
 
1674
 
 
1675
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamReadAvailable" );
 
1676
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1677
 
 
1678
    if( error != paNoError )
 
1679
    {
 
1680
        result = 0;
 
1681
 
 
1682
        PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" ));
 
1683
        PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) ));
 
1684
 
 
1685
    }
 
1686
    else
 
1687
    {
 
1688
        result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream );
 
1689
 
 
1690
        PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" ));
 
1691
        PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1692
 
 
1693
    }
 
1694
 
 
1695
    return result;
 
1696
}
 
1697
 
 
1698
 
 
1699
signed long Pa_GetStreamWriteAvailable( PaStream* stream )
 
1700
{
 
1701
    PaError error = PaUtil_ValidateStreamPointer( stream );
 
1702
    signed long result;
 
1703
 
 
1704
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamWriteAvailable" );
 
1705
    PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream ));
 
1706
 
 
1707
    if( error != paNoError )
 
1708
    {
 
1709
        result = 0;
 
1710
 
 
1711
        PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" ));
 
1712
        PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) ));
 
1713
 
 
1714
    }
 
1715
    else
 
1716
    {
 
1717
        result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream );
 
1718
 
 
1719
        PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" ));
 
1720
        PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
 
1721
 
 
1722
    }
 
1723
 
 
1724
    return result;
 
1725
}
 
1726
 
 
1727
 
 
1728
PaError Pa_GetSampleSize( PaSampleFormat format )
 
1729
{
 
1730
    int result;
 
1731
 
 
1732
    PA_LOGAPI_ENTER_PARAMS( "Pa_GetSampleSize" );
 
1733
    PA_LOGAPI(("\tPaSampleFormat format: %d\n", format ));
 
1734
 
 
1735
    switch( format & ~paNonInterleaved )
 
1736
    {
 
1737
 
 
1738
    case paUInt8:
 
1739
    case paInt8:
 
1740
        result = 1;
 
1741
        break;
 
1742
 
 
1743
    case paInt16:
 
1744
        result = 2;
 
1745
        break;
 
1746
 
 
1747
    case paInt24:
 
1748
        result = 3;
 
1749
        break;
 
1750
 
 
1751
    case paFloat32:
 
1752
    case paInt32:
 
1753
        result = 4;
 
1754
        break;
 
1755
 
 
1756
    default:
 
1757
        result = paSampleFormatNotSupported;
 
1758
        break;
 
1759
    }
 
1760
 
 
1761
    PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetSampleSize", "int: %d", result );
 
1762
 
 
1763
    return (PaError) result;
 
1764
}
 
1765