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