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.
6 * Based on the Open Source API proposed by Ross Bencina
7 * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
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:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
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.
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.
33 /* doxygen index page */
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.
41 See the PortAudio website for further information http://www.portaudio.com/
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
48 This documentation is under construction. Things you might be interested in
51 - The PortAudio API 2.0, as documented in portaudio.h
53 - The <a href="todo.html">TODO List</a>
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.
61 @brief Implements public PortAudio API, checks some errors, forwards to
62 host API implementations.
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).
69 This file handles initialization and termination of Host API
70 implementations via initializers stored in the paHostApiInitializers
73 Some utility functions declared in pa_util.h are implemented in this file.
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.
78 @todo Consider adding host API specific error text in Pa_GetErrorText() for
79 paUnanticipatedHostError
81 @todo Consider adding a new error code for when (inputParameters == NULL)
82 && (outputParameters == NULL)
84 @todo review whether Pa_CloseStream() should call the interface's
85 CloseStream function if aborting the stream returns an error code.
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.
96 #include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
98 #include "portaudio.h"
100 #include "pa_endianness.h"
101 #include "pa_types.h"
102 #include "pa_hostapi.h"
103 #include "pa_stream.h"
105 #include "pa_trace.h"
108 #define PA_VERSION_ 1899
109 #define PA_VERSION_TEXT_ "PortAudio V19-devel"
113 /* #define PA_LOG_API_CALLS */
116 The basic format for log messages is described below. If you need to
117 add any log messages, please follow this format.
119 Function entry (void function):
121 "FunctionName called.\n"
123 Function entry (non void function):
125 "FunctionName called:\n"
126 "\tParam1Type param1: param1Value\n"
127 "\tParam2Type param2: param2Value\n" (etc...)
130 Function exit (no return value):
132 "FunctionName returned.\n"
134 Function exit (simple return value):
136 "FunctionName returned:\n"
137 "\tReturnType: returnValue\n\n"
139 If the return type is an error code, the error text is displayed in ()
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 []
144 If the return type is a struct ptr, the struct is dumped.
146 See the code below for examples
150 int Pa_GetVersion( void )
156 const char* Pa_GetVersionText( void )
158 return PA_VERSION_TEXT_;
163 #define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024
165 static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0};
167 static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ };
170 void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
171 const char *errorText )
173 lastHostErrorInfo_.hostApiType = hostApiType;
174 lastHostErrorInfo_.errorCode = errorCode;
176 strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ );
180 void PaUtil_DebugPrint( const char *format, ... )
184 va_start( ap, format );
185 vfprintf( stderr, format, ap );
192 static PaUtilHostApiRepresentation **hostApis_ = 0;
193 static int hostApisCount_ = 0;
194 static int initializationCount_ = 0;
195 static int deviceCount_ = 0;
197 PaUtilStreamRepresentation *firstOpenStream_ = NULL;
200 #define PA_IS_INITIALISED_ (initializationCount_ != 0)
203 static int CountHostApiInitializers( void )
207 while( paHostApiInitializers[ result ] != 0 )
213 static void TerminateHostApis( void )
215 /* terminate in reverse order from initialization */
217 while( hostApisCount_ > 0 )
220 hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] );
226 PaUtil_FreeMemory( hostApis_ );
231 static PaError InitializeHostApis( void )
233 PaError result = paNoError;
234 int i, initializerCount, baseDeviceIndex;
236 initializerCount = CountHostApiInitializers();
238 hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory(
239 sizeof(PaUtilHostApiRepresentation*) * initializerCount );
242 result = paInsufficientMemory;
250 for( i=0; i< initializerCount; ++i )
252 hostApis_[hostApisCount_] = NULL;
253 result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );
254 if( result != paNoError )
257 if( hostApis_[hostApisCount_] )
259 PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_];
260 assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
261 assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
263 hostApis_[hostApisCount_]->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex;
265 if( hostApis_[hostApisCount_]->info.defaultInputDevice != paNoDevice )
266 hostApis_[hostApisCount_]->info.defaultInputDevice += baseDeviceIndex;
268 if( hostApis_[hostApisCount_]->info.defaultOutputDevice != paNoDevice )
269 hostApis_[hostApisCount_]->info.defaultOutputDevice += baseDeviceIndex;
271 baseDeviceIndex += hostApis_[hostApisCount_]->info.deviceCount;
272 deviceCount_ += hostApis_[hostApisCount_]->info.deviceCount;
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.
293 static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
297 if( !PA_IS_INITIALISED_ )
303 while( i < hostApisCount_
304 && device >= hostApis_[i]->info.deviceCount )
307 device -= hostApis_[i]->info.deviceCount;
311 if( i >= hostApisCount_ )
314 if( hostSpecificDeviceIndex )
315 *hostSpecificDeviceIndex = device;
321 static void AddOpenStream( PaStream* stream )
323 ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_;
324 firstOpenStream_ = (PaUtilStreamRepresentation*)stream;
328 static void RemoveOpenStream( PaStream* stream )
330 PaUtilStreamRepresentation *previous = NULL;
331 PaUtilStreamRepresentation *current = firstOpenStream_;
333 while( current != NULL )
335 if( ((PaStream*)current) == stream )
337 if( previous == NULL )
339 firstOpenStream_ = current->nextOpenStream;
343 previous->nextOpenStream = current->nextOpenStream;
350 current = current->nextOpenStream;
356 static void CloseOpenStreams( void )
358 /* we call Pa_CloseStream() here to ensure that the same destruction
359 logic is used for automatically closed streams */
361 while( firstOpenStream_ != NULL )
362 Pa_CloseStream( firstOpenStream_ );
366 PaError Pa_Initialize( void )
370 #ifdef PA_LOG_API_CALLS
371 PaUtil_DebugPrint( "Pa_Initialize called.\n" );
374 if( PA_IS_INITIALISED_ )
376 ++initializationCount_;
381 PA_VALIDATE_TYPE_SIZES;
382 PA_VALIDATE_ENDIANNESS;
384 PaUtil_InitializeClock();
385 PaUtil_ResetTraceMessages();
387 result = InitializeHostApis();
388 if( result == paNoError )
389 ++initializationCount_;
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 ) );
401 PaError Pa_Terminate( void )
405 #ifdef PA_LOG_API_CALLS
406 PaUtil_DebugPrint("Pa_Terminate called.\n" );
409 if( PA_IS_INITIALISED_ )
411 if( --initializationCount_ == 0 )
417 PaUtil_DumpTraceMessages();
423 result= paNotInitialized;
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 ) );
435 const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void )
437 return &lastHostErrorInfo_;
441 const char *Pa_GetErrorText( PaError errorCode )
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;
482 PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
484 PaHostApiIndex result;
487 #ifdef PA_LOG_API_CALLS
488 PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex called:\n" );
489 PaUtil_DebugPrint("\tPaHostApiTypeId type: %d\n", type );
492 if( !PA_IS_INITIALISED_ )
494 result = paNotInitialized;
498 result = paHostApiNotFound;
500 for( i=0; i < hostApisCount_; ++i )
502 if( hostApis_[i]->info.type == type )
510 #ifdef PA_LOG_API_CALLS
511 PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex returned:\n" );
513 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
515 PaUtil_DebugPrint("\tPaHostApiIndex: %d\n\n", result );
522 PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
523 PaHostApiTypeId type )
528 if( !PA_IS_INITIALISED_ )
530 result = paNotInitialized;
534 result = paHostApiNotFound;
536 for( i=0; i < hostApisCount_; ++i )
538 if( hostApis_[i]->info.type == type )
540 *hostApi = hostApis_[i];
551 PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
552 PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi )
557 x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
559 if( x < 0 || x >= hostApi->info.deviceCount )
561 result = paInvalidDevice;
573 PaHostApiIndex Pa_GetHostApiCount( void )
577 #ifdef PA_LOG_API_CALLS
578 PaUtil_DebugPrint("Pa_GetHostApiCount called.\n" );
581 if( !PA_IS_INITIALISED_ )
583 result = paNotInitialized;
587 result = hostApisCount_;
590 #ifdef PA_LOG_API_CALLS
591 PaUtil_DebugPrint("Pa_GetHostApiCount returned:\n" );
593 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
595 PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", result );
602 PaHostApiIndex Pa_GetDefaultHostApi( void )
606 #ifdef PA_LOG_API_CALLS
607 PaUtil_DebugPrint("Pa_GetDefaultHostApi called.\n" );
610 if( !PA_IS_INITIALISED_ )
612 result = paNotInitialized;
616 result = paDefaultHostApiIndex;
618 /* internal consistency check: make sure that the default host api
619 index is within range */
621 if( result < 0 || result >= hostApisCount_ )
623 result = paInternalError;
627 #ifdef PA_LOG_API_CALLS
628 PaUtil_DebugPrint("Pa_GetDefaultHostApi returned:\n" );
630 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
632 PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", result );
639 const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
643 #ifdef PA_LOG_API_CALLS
644 PaUtil_DebugPrint("Pa_GetHostApiInfo called:\n" );
645 PaUtil_DebugPrint("\tPaHostApiIndex hostApi: %d\n", hostApi );
648 if( !PA_IS_INITIALISED_ )
652 #ifdef PA_LOG_API_CALLS
653 PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
654 PaUtil_DebugPrint("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n\n" );
658 else if( hostApi < 0 || hostApi >= hostApisCount_ )
662 #ifdef PA_LOG_API_CALLS
663 PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
664 PaUtil_DebugPrint("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n\n" );
670 info = &hostApis_[hostApi]->info;
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" );
688 PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex )
690 PaDeviceIndex result;
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 );
698 if( !PA_IS_INITIALISED_ )
700 result = paNotInitialized;
704 if( hostApi < 0 || hostApi >= hostApisCount_ )
706 result = paInvalidHostApi;
710 if( hostApiDeviceIndex < 0 ||
711 hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount )
713 result = paInvalidDevice;
717 result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex;
722 #ifdef PA_LOG_API_CALLS
723 PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" );
725 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
727 PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
734 PaDeviceIndex Pa_GetDeviceCount( void )
736 PaDeviceIndex result;
738 #ifdef PA_LOG_API_CALLS
739 PaUtil_DebugPrint("Pa_GetDeviceCount called.\n" );
742 if( !PA_IS_INITIALISED_ )
744 result = paNotInitialized;
748 result = deviceCount_;
751 #ifdef PA_LOG_API_CALLS
752 PaUtil_DebugPrint("Pa_GetDeviceCount returned:\n" );
754 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
756 PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
763 PaDeviceIndex Pa_GetDefaultInputDevice( void )
765 PaHostApiIndex hostApi;
766 PaDeviceIndex result;
768 #ifdef PA_LOG_API_CALLS
769 PaUtil_DebugPrint("Pa_GetDefaultInputDevice called.\n" );
772 hostApi = Pa_GetDefaultHostApi();
779 result = hostApis_[hostApi]->info.defaultInputDevice;
782 #ifdef PA_LOG_API_CALLS
783 PaUtil_DebugPrint("Pa_GetDefaultInputDevice returned:\n" );
784 PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
791 PaDeviceIndex Pa_GetDefaultOutputDevice( void )
793 PaHostApiIndex hostApi;
794 PaDeviceIndex result;
796 #ifdef PA_LOG_API_CALLS
797 PaUtil_DebugPrint("Pa_GetDefaultOutputDevice called.\n" );
800 hostApi = Pa_GetDefaultHostApi();
807 result = hostApis_[hostApi]->info.defaultOutputDevice;
810 #ifdef PA_LOG_API_CALLS
811 PaUtil_DebugPrint("Pa_GetDefaultOutputDevice returned:\n" );
812 PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
819 const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
821 int hostSpecificDeviceIndex;
822 int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex );
823 PaDeviceInfo *result;
826 #ifdef PA_LOG_API_CALLS
827 PaUtil_DebugPrint("Pa_GetDeviceInfo called:\n" );
828 PaUtil_DebugPrint("\tPaDeviceIndex device: %d\n", device );
831 if( hostApiIndex < 0 )
835 #ifdef PA_LOG_API_CALLS
836 PaUtil_DebugPrint("Pa_GetDeviceInfo returned:\n" );
837 PaUtil_DebugPrint("\tPaDeviceInfo* NULL [ invalid device index ]\n\n" );
843 result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ];
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" );
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" );
865 SampleFormatIsValid() returns 1 if sampleFormat is a sample format
866 defined in portaudio.h, or 0 otherwise.
868 static int SampleFormatIsValid( PaSampleFormat format )
870 switch( format & ~paNonInterleaved )
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;
884 NOTE: make sure this validation list is kept syncronised with the one in
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.
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.
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
906 If ValidateOpenStreamParameters() returns paNoError, the following
907 assertions are guaranteed to be true.
909 - at least one of inputParameters & outputParmeters is valid (not NULL)
911 - if inputParameters & outputParameters are both valid, that
912 inputParameters->device & outputParameters->device both use the same host api
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
920 int inputParameters->channelCount
921 - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
922 - upper bound is NOT validated against device capabilities
924 PaSampleFormat inputParameters->sampleFormat
925 - is one of the sample formats defined in portaudio.h
927 void *inputParameters->hostApiSpecificStreamInfo
928 - if supplied its hostApi field matches the input device's host Api
930 PaDeviceIndex outputParmeters->device
931 - is within range (0 to Pa_GetDeviceCount-1)
933 int outputParmeters->channelCount
934 - if inputDevice is valid, channelCount is > 0
935 - upper bound is NOT validated against device capabilities
937 PaSampleFormat outputParmeters->sampleFormat
938 - is one of the sample formats defined in portaudio.h
940 void *outputParmeters->hostApiSpecificStreamInfo
941 - if supplied its hostApi field matches the output device's host Api
944 - is not an 'absurd' rate (less than 1000. or greater than 200000.)
945 - sampleRate is NOT validated against device capabilities
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)
952 static PaError ValidateOpenStreamParameters(
953 const PaStreamParameters *inputParameters,
954 const PaStreamParameters *outputParameters,
956 unsigned long framesPerBuffer,
957 PaStreamFlags streamFlags,
958 PaStreamCallback *streamCallback,
959 PaUtilHostApiRepresentation **hostApi,
960 PaDeviceIndex *hostApiInputDevice,
961 PaDeviceIndex *hostApiOutputDevice )
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. */
967 if( (inputParameters == NULL) && (outputParameters == NULL) )
969 return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */
973 if( inputParameters == NULL )
975 *hostApiInputDevice = paNoDevice;
977 else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
979 if( inputParameters->hostApiSpecificStreamInfo )
981 inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
982 ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType );
984 if( inputHostApiIndex != -1 )
986 *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification;
987 *hostApi = hostApis_[inputHostApiIndex];
991 return paInvalidDevice;
996 return paInvalidDevice;
1001 if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ )
1002 return paInvalidDevice;
1004 inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice );
1005 if( inputHostApiIndex < 0 )
1006 return paInternalError;
1008 *hostApi = hostApis_[inputHostApiIndex];
1010 if( inputParameters->channelCount <= 0 )
1011 return paInvalidChannelCount;
1013 if( !SampleFormatIsValid( inputParameters->sampleFormat ) )
1014 return paSampleFormatNotSupported;
1016 if( inputParameters->hostApiSpecificStreamInfo != NULL )
1018 if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType
1019 != (*hostApi)->info.type )
1020 return paIncompatibleHostApiSpecificStreamInfo;
1024 if( outputParameters == NULL )
1026 *hostApiOutputDevice = paNoDevice;
1028 else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
1030 if( outputParameters->hostApiSpecificStreamInfo )
1032 outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
1033 ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType );
1035 if( outputHostApiIndex != -1 )
1037 *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification;
1038 *hostApi = hostApis_[outputHostApiIndex];
1042 return paInvalidDevice;
1047 return paInvalidDevice;
1052 if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ )
1053 return paInvalidDevice;
1055 outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice );
1056 if( outputHostApiIndex < 0 )
1057 return paInternalError;
1059 *hostApi = hostApis_[outputHostApiIndex];
1061 if( outputParameters->channelCount <= 0 )
1062 return paInvalidChannelCount;
1064 if( !SampleFormatIsValid( outputParameters->sampleFormat ) )
1065 return paSampleFormatNotSupported;
1067 if( outputParameters->hostApiSpecificStreamInfo != NULL )
1069 if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType
1070 != (*hostApi)->info.type )
1071 return paIncompatibleHostApiSpecificStreamInfo;
1075 if( (inputParameters != NULL) && (outputParameters != NULL) )
1077 /* ensure that both devices use the same API */
1078 if( inputHostApiIndex != outputHostApiIndex )
1079 return paBadIODeviceCombination;
1084 /* Check for absurd sample rates. */
1085 if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
1086 return paInvalidSampleRate;
1088 if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
1089 return paInvalidFlag;
1091 if( streamFlags & paNeverDropInput )
1093 /* must be a callback stream */
1094 if( !streamCallback )
1095 return paInvalidFlag;
1097 /* must be a full duplex stream */
1098 if( (inputParameters == NULL) || (outputParameters == NULL) )
1099 return paInvalidFlag;
1101 /* must use paFramesPerBufferUnspecified */
1102 if( framesPerBuffer != paFramesPerBufferUnspecified )
1103 return paInvalidFlag;
1110 PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
1111 const PaStreamParameters *outputParameters,
1115 PaUtilHostApiRepresentation *hostApi;
1116 PaDeviceIndex hostApiInputDevice, hostApiOutputDevice;
1117 PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
1118 PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
1121 #ifdef PA_LOG_API_CALLS
1122 PaUtil_DebugPrint("Pa_IsFormatSupported called:\n" );
1124 if( inputParameters == NULL ){
1125 PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: NULL\n" );
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 );
1135 if( outputParameters == NULL ){
1136 PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: NULL\n" );
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 );
1146 PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
1149 if( !PA_IS_INITIALISED_ )
1151 result = paNotInitialized;
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 ) );
1160 result = ValidateOpenStreamParameters( inputParameters,
1162 sampleRate, 0, paNoFlag, 0,
1164 &hostApiInputDevice,
1165 &hostApiOutputDevice );
1166 if( result != paNoError )
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 ) );
1176 if( inputParameters )
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;
1187 hostApiInputParametersPtr = NULL;
1190 if( outputParameters )
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;
1201 hostApiOutputParametersPtr = NULL;
1204 result = hostApi->IsFormatSupported( hostApi,
1205 hostApiInputParametersPtr, hostApiOutputParametersPtr,
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" );
1213 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
1220 PaError Pa_OpenStream( PaStream** stream,
1221 const PaStreamParameters *inputParameters,
1222 const PaStreamParameters *outputParameters,
1224 unsigned long framesPerBuffer,
1225 PaStreamFlags streamFlags,
1226 PaStreamCallback *streamCallback,
1230 PaUtilHostApiRepresentation *hostApi;
1231 PaDeviceIndex hostApiInputDevice, hostApiOutputDevice;
1232 PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
1233 PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
1236 #ifdef PA_LOG_API_CALLS
1237 PaUtil_DebugPrint("Pa_OpenStream called:\n" );
1238 PaUtil_DebugPrint("\tPaStream** stream: 0x%p\n", stream );
1240 if( inputParameters == NULL ){
1241 PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: NULL\n" );
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 );
1251 if( outputParameters == NULL ){
1252 PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: NULL\n" );
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 );
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 );
1269 if( !PA_IS_INITIALISED_ )
1271 result = paNotInitialized;
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 ) );
1281 /* Check for parameter errors.
1282 NOTE: make sure this validation list is kept syncronised with the one
1286 if( stream == NULL )
1288 result = paBadStreamPtr;
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 ) );
1298 result = ValidateOpenStreamParameters( inputParameters,
1300 sampleRate, framesPerBuffer,
1301 streamFlags, streamCallback,
1303 &hostApiInputDevice,
1304 &hostApiOutputDevice );
1305 if( result != paNoError )
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 ) );
1316 if( inputParameters )
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;
1327 hostApiInputParametersPtr = NULL;
1330 if( outputParameters )
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;
1341 hostApiOutputParametersPtr = NULL;
1344 result = hostApi->OpenStream( hostApi, stream,
1345 hostApiInputParametersPtr, hostApiOutputParametersPtr,
1346 sampleRate, framesPerBuffer, streamFlags, streamCallback, userData );
1348 if( result == paNoError )
1349 AddOpenStream( *stream );
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 ) );
1362 PaError Pa_OpenDefaultStream( PaStream** stream,
1363 int inputChannelCount,
1364 int outputChannelCount,
1365 PaSampleFormat sampleFormat,
1367 unsigned long framesPerBuffer,
1368 PaStreamCallback *streamCallback,
1372 PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
1373 PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
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 );
1388 if( inputChannelCount > 0 )
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
1398 hostApiInputParameters.suggestedLatency =
1399 Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
1400 hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
1401 hostApiInputParametersPtr = &hostApiInputParameters;
1405 hostApiInputParametersPtr = NULL;
1408 if( outputChannelCount > 0 )
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
1418 hostApiOutputParameters.suggestedLatency =
1419 Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
1420 hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
1421 hostApiOutputParametersPtr = &hostApiOutputParameters;
1425 hostApiOutputParametersPtr = NULL;
1429 result = Pa_OpenStream(
1430 stream, hostApiInputParametersPtr, hostApiOutputParametersPtr,
1431 sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
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 ) );
1443 PaError PaUtil_ValidateStreamPointer( PaStream* stream )
1445 if( !PA_IS_INITIALISED_ ) return paNotInitialized;
1447 if( stream == NULL ) return paBadStreamPtr;
1449 if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC )
1450 return paBadStreamPtr;
1456 PaError Pa_CloseStream( PaStream* stream )
1458 PaUtilStreamInterface *interface;
1459 PaError result = PaUtil_ValidateStreamPointer( stream );
1461 #ifdef PA_LOG_API_CALLS
1462 PaUtil_DebugPrint("Pa_CloseStream called:\n" );
1463 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
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 */
1471 if( result == paNoError )
1473 interface = PA_STREAM_INTERFACE(stream);
1475 /* abort the stream if it isn't stopped */
1476 result = interface->IsStopped( stream );
1479 else if( result == 0 )
1480 result = interface->Abort( stream );
1482 if( result == paNoError ) /** @todo REVIEW: shouldn't we close anyway? */
1483 result = interface->Close( stream );
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 ) );
1495 PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback )
1497 PaError result = PaUtil_ValidateStreamPointer( stream );
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 );
1505 if( result == paNoError )
1507 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1510 result = paStreamIsNotStopped ;
1514 PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback;
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 ) );
1529 PaError Pa_StartStream( PaStream *stream )
1531 PaError result = PaUtil_ValidateStreamPointer( stream );
1533 #ifdef PA_LOG_API_CALLS
1534 PaUtil_DebugPrint("Pa_StartStream called:\n" );
1535 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1538 if( result == paNoError )
1540 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1543 result = paStreamIsNotStopped ;
1545 else if( result == 1 )
1547 result = PA_STREAM_INTERFACE(stream)->Start( stream );
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 ) );
1560 PaError Pa_StopStream( PaStream *stream )
1562 PaError result = PaUtil_ValidateStreamPointer( stream );
1564 #ifdef PA_LOG_API_CALLS
1565 PaUtil_DebugPrint("Pa_StopStream called\n" );
1566 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1569 if( result == paNoError )
1571 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1574 result = PA_STREAM_INTERFACE(stream)->Stop( stream );
1576 else if( result == 1 )
1578 result = paStreamIsStopped;
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 ) );
1591 PaError Pa_AbortStream( PaStream *stream )
1593 PaError result = PaUtil_ValidateStreamPointer( stream );
1595 #ifdef PA_LOG_API_CALLS
1596 PaUtil_DebugPrint("Pa_AbortStream called:\n" );
1597 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1600 if( result == paNoError )
1602 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1605 result = PA_STREAM_INTERFACE(stream)->Abort( stream );
1607 else if( result == 1 )
1609 result = paStreamIsStopped;
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 ) );
1622 PaError Pa_IsStreamStopped( PaStream *stream )
1624 PaError result = PaUtil_ValidateStreamPointer( stream );
1626 #ifdef PA_LOG_API_CALLS
1627 PaUtil_DebugPrint("Pa_IsStreamStopped called:\n" );
1628 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1631 if( result == paNoError )
1632 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
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 ) );
1643 PaError Pa_IsStreamActive( PaStream *stream )
1645 PaError result = PaUtil_ValidateStreamPointer( stream );
1647 #ifdef PA_LOG_API_CALLS
1648 PaUtil_DebugPrint("Pa_IsStreamActive called:\n" );
1649 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1652 if( result == paNoError )
1653 result = PA_STREAM_INTERFACE(stream)->IsActive( stream );
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 ) );
1664 const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream )
1666 PaError error = PaUtil_ValidateStreamPointer( stream );
1667 const PaStreamInfo *result;
1669 #ifdef PA_LOG_API_CALLS
1670 PaUtil_DebugPrint("Pa_GetStreamInfo called:\n" );
1671 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1674 if( error != paNoError )
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 ) );
1686 result = &PA_STREAM_REP( stream )->streamInfo;
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{" );
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" );
1706 PaTime Pa_GetStreamTime( PaStream *stream )
1708 PaError error = PaUtil_ValidateStreamPointer( stream );
1711 #ifdef PA_LOG_API_CALLS
1712 PaUtil_DebugPrint("Pa_GetStreamTime called:\n" );
1713 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1716 if( error != paNoError )
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 ) );
1728 result = PA_STREAM_INTERFACE(stream)->GetTime( stream );
1730 #ifdef PA_LOG_API_CALLS
1731 PaUtil_DebugPrint("Pa_GetStreamTime returned:\n" );
1732 PaUtil_DebugPrint("\tPaTime: %g\n\n", result );
1741 double Pa_GetStreamCpuLoad( PaStream* stream )
1743 PaError error = PaUtil_ValidateStreamPointer( stream );
1746 #ifdef PA_LOG_API_CALLS
1747 PaUtil_DebugPrint("Pa_GetStreamCpuLoad called:\n" );
1748 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1751 if( error != paNoError )
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 ) );
1764 result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream );
1766 #ifdef PA_LOG_API_CALLS
1767 PaUtil_DebugPrint("Pa_GetStreamCpuLoad returned:\n" );
1768 PaUtil_DebugPrint("\tdouble: %g\n\n", result );
1777 PaError Pa_ReadStream( PaStream* stream,
1779 unsigned long frames )
1781 PaError result = PaUtil_ValidateStreamPointer( stream );
1783 #ifdef PA_LOG_API_CALLS
1784 PaUtil_DebugPrint("Pa_ReadStream called:\n" );
1785 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1788 if( result == paNoError )
1792 /* XXX: Should we not allow the implementation to signal any overflow condition? */
1795 else if( buffer == 0 )
1797 result = paBadBufferPtr;
1801 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1804 result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames );
1806 else if( result == 1 )
1808 result = paStreamIsStopped;
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 ) );
1822 PaError Pa_WriteStream( PaStream* stream,
1824 unsigned long frames )
1826 PaError result = PaUtil_ValidateStreamPointer( stream );
1828 #ifdef PA_LOG_API_CALLS
1829 PaUtil_DebugPrint("Pa_WriteStream called:\n" );
1830 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1833 if( result == paNoError )
1837 /* XXX: Should we not allow the implementation to signal any underflow condition? */
1840 else if( buffer == 0 )
1842 result = paBadBufferPtr;
1846 result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
1849 result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames );
1851 else if( result == 1 )
1853 result = paStreamIsStopped;
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 ) );
1866 signed long Pa_GetStreamReadAvailable( PaStream* stream )
1868 PaError error = PaUtil_ValidateStreamPointer( stream );
1871 #ifdef PA_LOG_API_CALLS
1872 PaUtil_DebugPrint("Pa_GetStreamReadAvailable called:\n" );
1873 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1876 if( error != paNoError )
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 ) );
1888 result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream );
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 ) );
1901 signed long Pa_GetStreamWriteAvailable( PaStream* stream )
1903 PaError error = PaUtil_ValidateStreamPointer( stream );
1906 #ifdef PA_LOG_API_CALLS
1907 PaUtil_DebugPrint("Pa_GetStreamWriteAvailable called:\n" );
1908 PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
1911 if( error != paNoError )
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 ) );
1923 result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream );
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 ) );
1936 PaError Pa_GetSampleSize( PaSampleFormat format )
1940 #ifdef PA_LOG_API_CALLS
1941 PaUtil_DebugPrint("Pa_GetSampleSize called:\n" );
1942 PaUtil_DebugPrint("\tPaSampleFormat format: %d\n", format );
1945 switch( format & ~paNonInterleaved )
1967 result = paSampleFormatNotSupported;
1971 #ifdef PA_LOG_API_CALLS
1972 PaUtil_DebugPrint("Pa_GetSampleSize returned:\n" );
1974 PaUtil_DebugPrint("\tint: %d\n\n", result );
1976 PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
1979 return (PaError) result;