~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/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: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* 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
 
}