diff options
Diffstat (limited to 'portaudio/src/common/pa_front.c')
-rw-r--r-- | portaudio/src/common/pa_front.c | 1810 |
1 files changed, 0 insertions, 1810 deletions
diff --git a/portaudio/src/common/pa_front.c b/portaudio/src/common/pa_front.c deleted file mode 100644 index 65a656f..0000000 --- a/portaudio/src/common/pa_front.c +++ /dev/null @@ -1,1810 +0,0 @@ -/* - * $Id$ - * Portable Audio I/O Library Multi-Host API front end - * Validate function parameters and manage multiple host APIs. - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2008 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup common_src - - @brief Implements PortAudio API functions defined in portaudio.h, checks - some errors, delegates platform-specific behavior to host API implementations. - - Implements the functions defined in the PortAudio API (portaudio.h), - validates some parameters and checks for state inconsistencies before - forwarding API requests to specific Host API implementations (via the - interface declared in pa_hostapi.h), and Streams (via the interface - declared in pa_stream.h). - - This file manages initialization and termination of Host API - implementations via initializer functions stored in the paHostApiInitializers - global array (usually defined in an os-specific pa_[os]_hostapis.c file). - - This file maintains a list of all open streams and closes them at Pa_Terminate(). - - Some utility functions declared in pa_util.h are implemented in this file. - - All PortAudio API functions can be conditionally compiled with logging code. - To compile with logging, define the PA_LOG_API_CALLS precompiler symbol. -*/ - - -#include <stdio.h> -#include <memory.h> -#include <string.h> -#include <stdlib.h> /* needed for strtol() */ -#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */ - -#include "portaudio.h" -#include "pa_util.h" -#include "pa_endianness.h" -#include "pa_types.h" -#include "pa_hostapi.h" -#include "pa_stream.h" -#include "pa_trace.h" /* still useful?*/ -#include "pa_debugprint.h" - -#ifndef PA_GIT_REVISION -#include "pa_gitrevision.h" -#endif - -/** - * This is incremented if we make incompatible API changes. - * This version scheme is based loosely on http://semver.org/ - */ -#define paVersionMajor 19 - -/** - * This is incremented when we add functionality in a backwards-compatible manner. - * Or it is set to zero when paVersionMajor is incremented. - */ -#define paVersionMinor 7 - -/** - * This is incremented when we make backwards-compatible bug fixes. - * Or it is set to zero when paVersionMinor changes. - */ -#define paVersionSubMinor 0 - -/** - * This is a combination of paVersionMajor, paVersionMinor and paVersionSubMinor. - * It will always increase so that version numbers can be compared as integers to - * see which is later. - */ -#define paVersion paMakeVersionNumber(paVersionMajor, paVersionMinor, paVersionSubMinor) - -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) - -#define PA_VERSION_STRING_ TOSTRING(paVersionMajor) "." TOSTRING(paVersionMinor) "." TOSTRING(paVersionSubMinor) -#define PA_VERSION_TEXT_ "PortAudio V" PA_VERSION_STRING_ "-devel, revision " TOSTRING(PA_GIT_REVISION) - -int Pa_GetVersion( void ) -{ - return paVersion; -} - -const char* Pa_GetVersionText( void ) -{ - return PA_VERSION_TEXT_; -} - -static PaVersionInfo versionInfo_ = { - /*.versionMajor =*/ paVersionMajor, - /*.versionMinor =*/ paVersionMinor, - /*.versionSubMinor =*/ paVersionSubMinor, - /*.versionControlRevision =*/ TOSTRING(PA_GIT_REVISION), - /*.versionText =*/ PA_VERSION_TEXT_ -}; - -const PaVersionInfo* Pa_GetVersionInfo( void ) -{ - return &versionInfo_; -} - -#define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024 - -static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0}; - -static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ }; - - -void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode, - const char *errorText ) -{ - lastHostErrorInfo_.hostApiType = hostApiType; - lastHostErrorInfo_.errorCode = errorCode; - - strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ ); -} - - - -static PaUtilHostApiRepresentation **hostApis_ = 0; -static int hostApisCount_ = 0; -static int defaultHostApiIndex_ = 0; -static int initializationCount_ = 0; -static int deviceCount_ = 0; - -PaUtilStreamRepresentation *firstOpenStream_ = NULL; - - -#define PA_IS_INITIALISED_ (initializationCount_ != 0) - - -static int CountHostApiInitializers( void ) -{ - int result = 0; - - while( paHostApiInitializers[ result ] != 0 ) - ++result; - return result; -} - - -static void TerminateHostApis( void ) -{ - /* terminate in reverse order from initialization */ - PA_DEBUG(("TerminateHostApis in \n")); - - while( hostApisCount_ > 0 ) - { - --hostApisCount_; - hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] ); - } - hostApisCount_ = 0; - defaultHostApiIndex_ = 0; - deviceCount_ = 0; - - if( hostApis_ != 0 ) - PaUtil_FreeMemory( hostApis_ ); - hostApis_ = 0; - - PA_DEBUG(("TerminateHostApis out\n")); -} - - -static PaError InitializeHostApis( void ) -{ - PaError result = paNoError; - int i, initializerCount, baseDeviceIndex; - - initializerCount = CountHostApiInitializers(); - - hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory( - sizeof(PaUtilHostApiRepresentation*) * initializerCount ); - if( !hostApis_ ) - { - result = paInsufficientMemory; - goto error; - } - - hostApisCount_ = 0; - defaultHostApiIndex_ = -1; /* indicates that we haven't determined the default host API yet */ - deviceCount_ = 0; - baseDeviceIndex = 0; - - for( i=0; i< initializerCount; ++i ) - { - hostApis_[hostApisCount_] = NULL; - - PA_DEBUG(( "before paHostApiInitializers[%d].\n",i)); - - result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ ); - if( result != paNoError ) - goto error; - - PA_DEBUG(( "after paHostApiInitializers[%d].\n",i)); - - if( hostApis_[hostApisCount_] ) - { - PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_]; - assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount ); - assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount ); - - /* the first successfully initialized host API with a default input *or* - output device is used as the default host API. - */ - if( (defaultHostApiIndex_ == -1) && - ( hostApi->info.defaultInputDevice != paNoDevice - || hostApi->info.defaultOutputDevice != paNoDevice ) ) - { - defaultHostApiIndex_ = hostApisCount_; - } - - hostApi->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex; - - if( hostApi->info.defaultInputDevice != paNoDevice ) - hostApi->info.defaultInputDevice += baseDeviceIndex; - - if( hostApi->info.defaultOutputDevice != paNoDevice ) - hostApi->info.defaultOutputDevice += baseDeviceIndex; - - baseDeviceIndex += hostApi->info.deviceCount; - deviceCount_ += hostApi->info.deviceCount; - - ++hostApisCount_; - } - } - - /* if no host APIs have devices, the default host API is the first initialized host API */ - if( defaultHostApiIndex_ == -1 ) - defaultHostApiIndex_ = 0; - - return result; - -error: - TerminateHostApis(); - return result; -} - - -/* - FindHostApi() finds the index of the host api to which - <device> belongs and returns it. if <hostSpecificDeviceIndex> is - non-null, the host specific device index is returned in it. - returns -1 if <device> is out of range. - -*/ -static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex ) -{ - int i=0; - - if( !PA_IS_INITIALISED_ ) - return -1; - - if( device < 0 ) - return -1; - - while( i < hostApisCount_ - && device >= hostApis_[i]->info.deviceCount ) - { - - device -= hostApis_[i]->info.deviceCount; - ++i; - } - - if( i >= hostApisCount_ ) - return -1; - - if( hostSpecificDeviceIndex ) - *hostSpecificDeviceIndex = device; - - return i; -} - - -static void AddOpenStream( PaStream* stream ) -{ - ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_; - firstOpenStream_ = (PaUtilStreamRepresentation*)stream; -} - - -static void RemoveOpenStream( PaStream* stream ) -{ - PaUtilStreamRepresentation *previous = NULL; - PaUtilStreamRepresentation *current = firstOpenStream_; - - while( current != NULL ) - { - if( ((PaStream*)current) == stream ) - { - if( previous == NULL ) - { - firstOpenStream_ = current->nextOpenStream; - } - else - { - previous->nextOpenStream = current->nextOpenStream; - } - return; - } - else - { - previous = current; - current = current->nextOpenStream; - } - } -} - - -static void CloseOpenStreams( void ) -{ - /* we call Pa_CloseStream() here to ensure that the same destruction - logic is used for automatically closed streams */ - - while( firstOpenStream_ != NULL ) - Pa_CloseStream( firstOpenStream_ ); -} - - -PaError Pa_Initialize( void ) -{ - PaError result; - - PA_LOGAPI_ENTER( "Pa_Initialize" ); - - if( PA_IS_INITIALISED_ ) - { - ++initializationCount_; - result = paNoError; - } - else - { - PA_VALIDATE_TYPE_SIZES; - PA_VALIDATE_ENDIANNESS; - - PaUtil_InitializeClock(); - PaUtil_ResetTraceMessages(); - - result = InitializeHostApis(); - if( result == paNoError ) - ++initializationCount_; - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_Initialize", result ); - - return result; -} - - -PaError Pa_Terminate( void ) -{ - PaError result; - - PA_LOGAPI_ENTER( "Pa_Terminate" ); - - if( PA_IS_INITIALISED_ ) - { - // leave initializationCount_>0 so that Pa_CloseStream() can execute - if( initializationCount_ == 1 ) - { - CloseOpenStreams(); - - TerminateHostApis(); - - PaUtil_DumpTraceMessages(); - } - --initializationCount_; - result = paNoError; - } - else - { - result= paNotInitialized; - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_Terminate", result ); - - return result; -} - - -const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void ) -{ - return &lastHostErrorInfo_; -} - - -const char *Pa_GetErrorText( PaError errorCode ) -{ - const char *result; - - switch( errorCode ) - { - case paNoError: result = "Success"; break; - case paNotInitialized: result = "PortAudio not initialized"; break; - /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError. see: http://www.portaudio.com/trac/ticket/114 */ - case paUnanticipatedHostError: result = "Unanticipated host error"; break; - case paInvalidChannelCount: result = "Invalid number of channels"; break; - case paInvalidSampleRate: result = "Invalid sample rate"; break; - case paInvalidDevice: result = "Invalid device"; break; - case paInvalidFlag: result = "Invalid flag"; break; - case paSampleFormatNotSupported: result = "Sample format not supported"; break; - case paBadIODeviceCombination: result = "Illegal combination of I/O devices"; break; - case paInsufficientMemory: result = "Insufficient memory"; break; - case paBufferTooBig: result = "Buffer too big"; break; - case paBufferTooSmall: result = "Buffer too small"; break; - case paNullCallback: result = "No callback routine specified"; break; - case paBadStreamPtr: result = "Invalid stream pointer"; break; - case paTimedOut: result = "Wait timed out"; break; - case paInternalError: result = "Internal PortAudio error"; break; - case paDeviceUnavailable: result = "Device unavailable"; break; - case paIncompatibleHostApiSpecificStreamInfo: result = "Incompatible host API specific stream info"; break; - case paStreamIsStopped: result = "Stream is stopped"; break; - case paStreamIsNotStopped: result = "Stream is not stopped"; break; - case paInputOverflowed: result = "Input overflowed"; break; - case paOutputUnderflowed: result = "Output underflowed"; break; - case paHostApiNotFound: result = "Host API not found"; break; - case paInvalidHostApi: result = "Invalid host API"; break; - case paCanNotReadFromACallbackStream: result = "Can't read from a callback stream"; break; - case paCanNotWriteToACallbackStream: result = "Can't write to a callback stream"; break; - case paCanNotReadFromAnOutputOnlyStream: result = "Can't read from an output only stream"; break; - case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break; - case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break; - case paBadBufferPtr: result = "Bad buffer pointer"; break; - default: - if( errorCode > 0 ) - result = "Invalid error code (value greater than zero)"; - else - result = "Invalid error code"; - break; - } - return result; -} - - -PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ) -{ - PaHostApiIndex result; - int i; - - PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" ); - PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type )); - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - } - else - { - result = paHostApiNotFound; - - for( i=0; i < hostApisCount_; ++i ) - { - if( hostApis_[i]->info.type == type ) - { - result = i; - break; - } - } - } - - PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiTypeIdToHostApiIndex", "PaHostApiIndex: %d", result ); - - return result; -} - - -PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi, - PaHostApiTypeId type ) -{ - PaError result; - int i; - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - } - else - { - result = paHostApiNotFound; - - for( i=0; i < hostApisCount_; ++i ) - { - if( hostApis_[i]->info.type == type ) - { - *hostApi = hostApis_[i]; - result = paNoError; - break; - } - } - } - - return result; -} - - -PaError PaUtil_DeviceIndexToHostApiDeviceIndex( - PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi ) -{ - PaError result; - PaDeviceIndex x; - - x = device - hostApi->privatePaFrontInfo.baseDeviceIndex; - - if( x < 0 || x >= hostApi->info.deviceCount ) - { - result = paInvalidDevice; - } - else - { - *hostApiDevice = x; - result = paNoError; - } - - return result; -} - - -PaHostApiIndex Pa_GetHostApiCount( void ) -{ - int result; - - PA_LOGAPI_ENTER( "Pa_GetHostApiCount" ); - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - } - else - { - result = hostApisCount_; - } - - PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetHostApiCount", "PaHostApiIndex: %d", result ); - - return result; -} - - -PaHostApiIndex Pa_GetDefaultHostApi( void ) -{ - int result; - - PA_LOGAPI_ENTER( "Pa_GetDefaultHostApi" ); - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - } - else - { - result = defaultHostApiIndex_; - - /* internal consistency check: make sure that the default host api - index is within range */ - - if( result < 0 || result >= hostApisCount_ ) - { - result = paInternalError; - } - } - - PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDefaultHostApi", "PaHostApiIndex: %d", result ); - - return result; -} - - -const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi ) -{ - PaHostApiInfo *info; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetHostApiInfo" ); - PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); - - if( !PA_IS_INITIALISED_ ) - { - info = NULL; - - PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); - PA_LOGAPI(("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n" )); - - } - else if( hostApi < 0 || hostApi >= hostApisCount_ ) - { - info = NULL; - - PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); - PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" )); - - } - else - { - info = &hostApis_[hostApi]->info; - - PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" )); - PA_LOGAPI(("\tPaHostApiInfo*: 0x%p\n", info )); - PA_LOGAPI(("\t{\n" )); - PA_LOGAPI(("\t\tint structVersion: %d\n", info->structVersion )); - PA_LOGAPI(("\t\tPaHostApiTypeId type: %d\n", info->type )); - PA_LOGAPI(("\t\tconst char *name: %s\n", info->name )); - PA_LOGAPI(("\t}\n" )); - - } - - return info; -} - - -PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex ) -{ - PaDeviceIndex result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiDeviceIndexToPaDeviceIndex" ); - PA_LOGAPI(("\tPaHostApiIndex hostApi: %d\n", hostApi )); - PA_LOGAPI(("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex )); - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - } - else - { - if( hostApi < 0 || hostApi >= hostApisCount_ ) - { - result = paInvalidHostApi; - } - else - { - if( hostApiDeviceIndex < 0 || - hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount ) - { - result = paInvalidDevice; - } - else - { - result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex; - } - } - } - - PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_HostApiDeviceIndexToPaDeviceIndex", "PaDeviceIndex: %d", result ); - - return result; -} - - -PaDeviceIndex Pa_GetDeviceCount( void ) -{ - PaDeviceIndex result; - - PA_LOGAPI_ENTER( "Pa_GetDeviceCount" ); - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - } - else - { - result = deviceCount_; - } - - PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetDeviceCount", "PaDeviceIndex: %d", result ); - - return result; -} - - -PaDeviceIndex Pa_GetDefaultInputDevice( void ) -{ - PaHostApiIndex hostApi; - PaDeviceIndex result; - - PA_LOGAPI_ENTER( "Pa_GetDefaultInputDevice" ); - - hostApi = Pa_GetDefaultHostApi(); - if( hostApi < 0 ) - { - result = paNoDevice; - } - else - { - result = hostApis_[hostApi]->info.defaultInputDevice; - } - - PA_LOGAPI_EXIT_T( "Pa_GetDefaultInputDevice", "PaDeviceIndex: %d", result ); - - return result; -} - - -PaDeviceIndex Pa_GetDefaultOutputDevice( void ) -{ - PaHostApiIndex hostApi; - PaDeviceIndex result; - - PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" ); - - hostApi = Pa_GetDefaultHostApi(); - if( hostApi < 0 ) - { - result = paNoDevice; - } - else - { - result = hostApis_[hostApi]->info.defaultOutputDevice; - } - - PA_LOGAPI_EXIT_T( "Pa_GetDefaultOutputDevice", "PaDeviceIndex: %d", result ); - - return result; -} - - -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device ) -{ - int hostSpecificDeviceIndex; - int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex ); - PaDeviceInfo *result; - - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetDeviceInfo" ); - PA_LOGAPI(("\tPaDeviceIndex device: %d\n", device )); - - if( hostApiIndex < 0 ) - { - result = NULL; - - PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); - PA_LOGAPI(("\tPaDeviceInfo* NULL [ invalid device index ]\n" )); - - } - else - { - result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ]; - - PA_LOGAPI(("Pa_GetDeviceInfo returned:\n" )); - PA_LOGAPI(("\tPaDeviceInfo*: 0x%p:\n", result )); - PA_LOGAPI(("\t{\n" )); - - PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); - PA_LOGAPI(("\t\tconst char *name: %s\n", result->name )); - PA_LOGAPI(("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi )); - PA_LOGAPI(("\t\tint maxInputChannels: %d\n", result->maxInputChannels )); - PA_LOGAPI(("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels )); - PA_LOGAPI(("\t}\n" )); - - } - - return result; -} - - -/* - SampleFormatIsValid() returns 1 if sampleFormat is a sample format - defined in portaudio.h, or 0 otherwise. -*/ -static int SampleFormatIsValid( PaSampleFormat format ) -{ - switch( format & ~paNonInterleaved ) - { - case paFloat32: return 1; - case paInt16: return 1; - case paInt32: return 1; - case paInt24: return 1; - case paInt8: return 1; - case paUInt8: return 1; - case paCustomFormat: return 1; - default: return 0; - } -} - -/* - NOTE: make sure this validation list is kept synchronised with the one in - pa_hostapi.h - - ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream() - conform to the expected values as described below. This function is - also designed to be used with the proposed Pa_IsFormatSupported() function. - - There are basically two types of validation that could be performed: - Generic conformance validation, and device capability mismatch - validation. This function performs only generic conformance validation. - Validation that would require knowledge of device capabilities is - not performed because of potentially complex relationships between - combinations of parameters - for example, even if the sampleRate - seems ok, it might not be for a duplex stream - we have no way of - checking this in an API-neutral way, so we don't try. - - On success the function returns PaNoError and fills in hostApi, - hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure - the function returns an error code indicating the first encountered - parameter error. - - - If ValidateOpenStreamParameters() returns paNoError, the following - assertions are guaranteed to be true. - - - at least one of inputParameters & outputParmeters is valid (not NULL) - - - if inputParameters & outputParameters are both valid, that - inputParameters->device & outputParameters->device both use the same host api - - PaDeviceIndex inputParameters->device - - is within range (0 to Pa_GetDeviceCount-1) Or: - - is paUseHostApiSpecificDeviceSpecification and - inputParameters->hostApiSpecificStreamInfo is non-NULL and refers - to a valid host api - - int inputParameters->channelCount - - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0 - - upper bound is NOT validated against device capabilities - - PaSampleFormat inputParameters->sampleFormat - - is one of the sample formats defined in portaudio.h - - void *inputParameters->hostApiSpecificStreamInfo - - if supplied its hostApi field matches the input device's host Api - - PaDeviceIndex outputParmeters->device - - is within range (0 to Pa_GetDeviceCount-1) - - int outputParmeters->channelCount - - if inputDevice is valid, channelCount is > 0 - - upper bound is NOT validated against device capabilities - - PaSampleFormat outputParmeters->sampleFormat - - is one of the sample formats defined in portaudio.h - - void *outputParmeters->hostApiSpecificStreamInfo - - if supplied its hostApi field matches the output device's host Api - - double sampleRate - - is not an 'absurd' rate (less than 1000. or greater than 384000.) - - sampleRate is NOT validated against device capabilities - - PaStreamFlags streamFlags - - unused platform neutral flags are zero - - paNeverDropInput is only used for full-duplex callback streams with - variable buffer size (paFramesPerBufferUnspecified) -*/ -static PaError ValidateOpenStreamParameters( - const PaStreamParameters *inputParameters, - const PaStreamParameters *outputParameters, - double sampleRate, - unsigned long framesPerBuffer, - PaStreamFlags streamFlags, - PaStreamCallback *streamCallback, - PaUtilHostApiRepresentation **hostApi, - PaDeviceIndex *hostApiInputDevice, - PaDeviceIndex *hostApiOutputDevice ) -{ - int inputHostApiIndex = -1; /* Suppress uninitialised var warnings: compiler does */ - int outputHostApiIndex = -1; /* not see that if inputParameters and outputParameters */ - /* are both nonzero, these indices are set. */ - - if( (inputParameters == NULL) && (outputParameters == NULL) ) - { - return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */ - } - else - { - if( inputParameters == NULL ) - { - *hostApiInputDevice = paNoDevice; - } - else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification ) - { - if( inputParameters->hostApiSpecificStreamInfo ) - { - inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( - ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType ); - - if( inputHostApiIndex != -1 ) - { - *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification; - *hostApi = hostApis_[inputHostApiIndex]; - } - else - { - return paInvalidDevice; - } - } - else - { - return paInvalidDevice; - } - } - else - { - if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ ) - return paInvalidDevice; - - inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice ); - if( inputHostApiIndex < 0 ) - return paInternalError; - - *hostApi = hostApis_[inputHostApiIndex]; - - if( inputParameters->channelCount <= 0 ) - return paInvalidChannelCount; - - if( !SampleFormatIsValid( inputParameters->sampleFormat ) ) - return paSampleFormatNotSupported; - - if( inputParameters->hostApiSpecificStreamInfo != NULL ) - { - if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType - != (*hostApi)->info.type ) - return paIncompatibleHostApiSpecificStreamInfo; - } - } - - if( outputParameters == NULL ) - { - *hostApiOutputDevice = paNoDevice; - } - else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification ) - { - if( outputParameters->hostApiSpecificStreamInfo ) - { - outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex( - ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType ); - - if( outputHostApiIndex != -1 ) - { - *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification; - *hostApi = hostApis_[outputHostApiIndex]; - } - else - { - return paInvalidDevice; - } - } - else - { - return paInvalidDevice; - } - } - else - { - if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ ) - return paInvalidDevice; - - outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice ); - if( outputHostApiIndex < 0 ) - return paInternalError; - - *hostApi = hostApis_[outputHostApiIndex]; - - if( outputParameters->channelCount <= 0 ) - return paInvalidChannelCount; - - if( !SampleFormatIsValid( outputParameters->sampleFormat ) ) - return paSampleFormatNotSupported; - - if( outputParameters->hostApiSpecificStreamInfo != NULL ) - { - if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType - != (*hostApi)->info.type ) - return paIncompatibleHostApiSpecificStreamInfo; - } - } - - if( (inputParameters != NULL) && (outputParameters != NULL) ) - { - /* ensure that both devices use the same API */ - if( inputHostApiIndex != outputHostApiIndex ) - return paBadIODeviceCombination; - } - } - - - /* Check for absurd sample rates. */ - if( (sampleRate < 1000.0) || (sampleRate > 384000.0) ) - return paInvalidSampleRate; - - if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 ) - return paInvalidFlag; - - if( streamFlags & paNeverDropInput ) - { - /* must be a callback stream */ - if( !streamCallback ) - return paInvalidFlag; - - /* must be a full duplex stream */ - if( (inputParameters == NULL) || (outputParameters == NULL) ) - return paInvalidFlag; - - /* must use paFramesPerBufferUnspecified */ - if( framesPerBuffer != paFramesPerBufferUnspecified ) - return paInvalidFlag; - } - - return paNoError; -} - - -PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters, - const PaStreamParameters *outputParameters, - double sampleRate ) -{ - PaError result; - PaUtilHostApiRepresentation *hostApi = 0; - PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; - PaStreamParameters hostApiInputParameters, hostApiOutputParameters; - PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; - - -#ifdef PA_LOG_API_CALLS - PA_LOGAPI_ENTER_PARAMS( "Pa_IsFormatSupported" ); - - if( inputParameters == NULL ){ - PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); - }else{ - PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); - PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); - PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); - PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); - PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); - PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); - } - - if( outputParameters == NULL ){ - PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); - }else{ - PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); - PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); - PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); - PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); - PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); - PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); - } - - PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); -#endif - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - - PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); - return result; - } - - result = ValidateOpenStreamParameters( inputParameters, - outputParameters, - sampleRate, 0, paNoFlag, 0, - &hostApi, - &hostApiInputDevice, - &hostApiOutputDevice ); - if( result != paNoError ) - { - PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result ); - return result; - } - - - if( inputParameters ) - { - hostApiInputParameters.device = hostApiInputDevice; - hostApiInputParameters.channelCount = inputParameters->channelCount; - hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; - hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; - hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; - hostApiInputParametersPtr = &hostApiInputParameters; - } - else - { - hostApiInputParametersPtr = NULL; - } - - if( outputParameters ) - { - hostApiOutputParameters.device = hostApiOutputDevice; - hostApiOutputParameters.channelCount = outputParameters->channelCount; - hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; - hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; - hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; - hostApiOutputParametersPtr = &hostApiOutputParameters; - } - else - { - hostApiOutputParametersPtr = NULL; - } - - result = hostApi->IsFormatSupported( hostApi, - hostApiInputParametersPtr, hostApiOutputParametersPtr, - sampleRate ); - -#ifdef PA_LOG_API_CALLS - PA_LOGAPI(("Pa_OpenStream returned:\n" )); - if( result == paFormatIsSupported ) - PA_LOGAPI(("\tPaError: 0 [ paFormatIsSupported ]\n" )); - else - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); -#endif - - return result; -} - - -PaError Pa_OpenStream( PaStream** stream, - const PaStreamParameters *inputParameters, - const PaStreamParameters *outputParameters, - double sampleRate, - unsigned long framesPerBuffer, - PaStreamFlags streamFlags, - PaStreamCallback *streamCallback, - void *userData ) -{ - PaError result; - PaUtilHostApiRepresentation *hostApi = 0; - PaDeviceIndex hostApiInputDevice = paNoDevice, hostApiOutputDevice = paNoDevice; - PaStreamParameters hostApiInputParameters, hostApiOutputParameters; - PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; - - -#ifdef PA_LOG_API_CALLS - PA_LOGAPI_ENTER_PARAMS( "Pa_OpenStream" ); - PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); - - if( inputParameters == NULL ){ - PA_LOGAPI(("\tPaStreamParameters *inputParameters: NULL\n" )); - }else{ - PA_LOGAPI(("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters )); - PA_LOGAPI(("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device )); - PA_LOGAPI(("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount )); - PA_LOGAPI(("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat )); - PA_LOGAPI(("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency )); - PA_LOGAPI(("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo )); - } - - if( outputParameters == NULL ){ - PA_LOGAPI(("\tPaStreamParameters *outputParameters: NULL\n" )); - }else{ - PA_LOGAPI(("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters )); - PA_LOGAPI(("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device )); - PA_LOGAPI(("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount )); - PA_LOGAPI(("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat )); - PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency )); - PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo )); - } - - PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); - PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); - PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags )); - PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); - PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); -#endif - - if( !PA_IS_INITIALISED_ ) - { - result = paNotInitialized; - - PA_LOGAPI(("Pa_OpenStream returned:\n" )); - PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - return result; - } - - /* Check for parameter errors. - NOTE: make sure this validation list is kept synchronised with the one - in pa_hostapi.h - */ - - if( stream == NULL ) - { - result = paBadStreamPtr; - - PA_LOGAPI(("Pa_OpenStream returned:\n" )); - PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - return result; - } - - result = ValidateOpenStreamParameters( inputParameters, - outputParameters, - sampleRate, framesPerBuffer, - streamFlags, streamCallback, - &hostApi, - &hostApiInputDevice, - &hostApiOutputDevice ); - if( result != paNoError ) - { - PA_LOGAPI(("Pa_OpenStream returned:\n" )); - PA_LOGAPI(("\t*(PaStream** stream): undefined\n" )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - return result; - } - - - if( inputParameters ) - { - hostApiInputParameters.device = hostApiInputDevice; - hostApiInputParameters.channelCount = inputParameters->channelCount; - hostApiInputParameters.sampleFormat = inputParameters->sampleFormat; - hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency; - hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo; - hostApiInputParametersPtr = &hostApiInputParameters; - } - else - { - hostApiInputParametersPtr = NULL; - } - - if( outputParameters ) - { - hostApiOutputParameters.device = hostApiOutputDevice; - hostApiOutputParameters.channelCount = outputParameters->channelCount; - hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat; - hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency; - hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo; - hostApiOutputParametersPtr = &hostApiOutputParameters; - } - else - { - hostApiOutputParametersPtr = NULL; - } - - result = hostApi->OpenStream( hostApi, stream, - hostApiInputParametersPtr, hostApiOutputParametersPtr, - sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); - - if( result == paNoError ) - AddOpenStream( *stream ); - - - PA_LOGAPI(("Pa_OpenStream returned:\n" )); - PA_LOGAPI(("\t*(PaStream** stream): 0x%p\n", *stream )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - - return result; -} - - -PaError Pa_OpenDefaultStream( PaStream** stream, - int inputChannelCount, - int outputChannelCount, - PaSampleFormat sampleFormat, - double sampleRate, - unsigned long framesPerBuffer, - PaStreamCallback *streamCallback, - void *userData ) -{ - PaError result; - PaStreamParameters hostApiInputParameters, hostApiOutputParameters; - PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr; - - PA_LOGAPI_ENTER_PARAMS( "Pa_OpenDefaultStream" ); - PA_LOGAPI(("\tPaStream** stream: 0x%p\n", stream )); - PA_LOGAPI(("\tint inputChannelCount: %d\n", inputChannelCount )); - PA_LOGAPI(("\tint outputChannelCount: %d\n", outputChannelCount )); - PA_LOGAPI(("\tPaSampleFormat sampleFormat: %d\n", sampleFormat )); - PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate )); - PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer )); - PA_LOGAPI(("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback )); - PA_LOGAPI(("\tvoid *userData: 0x%p\n", userData )); - - - if( inputChannelCount > 0 ) - { - hostApiInputParameters.device = Pa_GetDefaultInputDevice(); - if( hostApiInputParameters.device == paNoDevice ) - return paDeviceUnavailable; - - hostApiInputParameters.channelCount = inputChannelCount; - hostApiInputParameters.sampleFormat = sampleFormat; - /* defaultHighInputLatency is used below instead of - defaultLowInputLatency because it is more important for the default - stream to work reliably than it is for it to work with the lowest - latency. - */ - hostApiInputParameters.suggestedLatency = - Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency; - hostApiInputParameters.hostApiSpecificStreamInfo = NULL; - hostApiInputParametersPtr = &hostApiInputParameters; - } - else - { - hostApiInputParametersPtr = NULL; - } - - if( outputChannelCount > 0 ) - { - hostApiOutputParameters.device = Pa_GetDefaultOutputDevice(); - if( hostApiOutputParameters.device == paNoDevice ) - return paDeviceUnavailable; - - hostApiOutputParameters.channelCount = outputChannelCount; - hostApiOutputParameters.sampleFormat = sampleFormat; - /* defaultHighOutputLatency is used below instead of - defaultLowOutputLatency because it is more important for the default - stream to work reliably than it is for it to work with the lowest - latency. - */ - hostApiOutputParameters.suggestedLatency = - Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency; - hostApiOutputParameters.hostApiSpecificStreamInfo = NULL; - hostApiOutputParametersPtr = &hostApiOutputParameters; - } - else - { - hostApiOutputParametersPtr = NULL; - } - - - result = Pa_OpenStream( - stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, - sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData ); - - PA_LOGAPI(("Pa_OpenDefaultStream returned:\n" )); - PA_LOGAPI(("\t*(PaStream** stream): 0x%p", *stream )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - - return result; -} - - -PaError PaUtil_ValidateStreamPointer( PaStream* stream ) -{ - if( !PA_IS_INITIALISED_ ) return paNotInitialized; - - if( stream == NULL ) return paBadStreamPtr; - - if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC ) - return paBadStreamPtr; - - return paNoError; -} - - -PaError Pa_CloseStream( PaStream* stream ) -{ - PaUtilStreamInterface *interface; - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_CloseStream" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - /* always remove the open stream from our list, even if this function - eventually returns an error. Otherwise CloseOpenStreams() will - get stuck in an infinite loop */ - RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */ - - if( result == paNoError ) - { - interface = PA_STREAM_INTERFACE(stream); - - /* abort the stream if it isn't stopped */ - result = interface->IsStopped( stream ); - if( result == 1 ) - result = paNoError; - else if( result == 0 ) - result = interface->Abort( stream ); - - if( result == paNoError ) /** @todo REVIEW: shouldn't we close anyway? see: http://www.portaudio.com/trac/ticket/115 */ - result = interface->Close( stream ); - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_CloseStream", result ); - - return result; -} - - -PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_SetStreamFinishedCallback" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - PA_LOGAPI(("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback )); - - if( result == paNoError ) - { - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - if( result == 0 ) - { - result = paStreamIsNotStopped ; - } - if( result == 1 ) - { - PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback; - result = paNoError; - } - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_SetStreamFinishedCallback", result ); - - return result; - -} - - -PaError Pa_StartStream( PaStream *stream ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_StartStream" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - { - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - if( result == 0 ) - { - result = paStreamIsNotStopped ; - } - else if( result == 1 ) - { - result = PA_STREAM_INTERFACE(stream)->Start( stream ); - } - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_StartStream", result ); - - return result; -} - - -PaError Pa_StopStream( PaStream *stream ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_StopStream" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - { - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - if( result == 0 ) - { - result = PA_STREAM_INTERFACE(stream)->Stop( stream ); - } - else if( result == 1 ) - { - result = paStreamIsStopped; - } - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_StopStream", result ); - - return result; -} - - -PaError Pa_AbortStream( PaStream *stream ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_AbortStream" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - { - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - if( result == 0 ) - { - result = PA_STREAM_INTERFACE(stream)->Abort( stream ); - } - else if( result == 1 ) - { - result = paStreamIsStopped; - } - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_AbortStream", result ); - - return result; -} - - -PaError Pa_IsStreamStopped( PaStream *stream ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamStopped" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - - PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamStopped", result ); - - return result; -} - - -PaError Pa_IsStreamActive( PaStream *stream ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_IsStreamActive" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - result = PA_STREAM_INTERFACE(stream)->IsActive( stream ); - - - PA_LOGAPI_EXIT_PAERROR( "Pa_IsStreamActive", result ); - - return result; -} - - -const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream ) -{ - PaError error = PaUtil_ValidateStreamPointer( stream ); - const PaStreamInfo *result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamInfo" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( error != paNoError ) - { - result = 0; - - PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); - PA_LOGAPI(("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n", error, Pa_GetErrorText( error ) )); - - } - else - { - result = &PA_STREAM_REP( stream )->streamInfo; - - PA_LOGAPI(("Pa_GetStreamInfo returned:\n" )); - PA_LOGAPI(("\tconst PaStreamInfo*: 0x%p:\n", result )); - PA_LOGAPI(("\t{" )); - - PA_LOGAPI(("\t\tint structVersion: %d\n", result->structVersion )); - PA_LOGAPI(("\t\tPaTime inputLatency: %f\n", result->inputLatency )); - PA_LOGAPI(("\t\tPaTime outputLatency: %f\n", result->outputLatency )); - PA_LOGAPI(("\t\tdouble sampleRate: %f\n", result->sampleRate )); - PA_LOGAPI(("\t}\n" )); - - } - - return result; -} - - -PaTime Pa_GetStreamTime( PaStream *stream ) -{ - PaError error = PaUtil_ValidateStreamPointer( stream ); - PaTime result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamTime" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( error != paNoError ) - { - result = 0; - - PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); - PA_LOGAPI(("\tPaTime: 0 [PaError error:%d ( %s )]\n", result, error, Pa_GetErrorText( error ) )); - - } - else - { - result = PA_STREAM_INTERFACE(stream)->GetTime( stream ); - - PA_LOGAPI(("Pa_GetStreamTime returned:\n" )); - PA_LOGAPI(("\tPaTime: %g\n", result )); - - } - - return result; -} - - -double Pa_GetStreamCpuLoad( PaStream* stream ) -{ - PaError error = PaUtil_ValidateStreamPointer( stream ); - double result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamCpuLoad" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( error != paNoError ) - { - - result = 0.0; - - PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); - PA_LOGAPI(("\tdouble: 0.0 [PaError error: %d ( %s )]\n", error, Pa_GetErrorText( error ) )); - - } - else - { - result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream ); - - PA_LOGAPI(("Pa_GetStreamCpuLoad returned:\n" )); - PA_LOGAPI(("\tdouble: %g\n", result )); - - } - - return result; -} - - -PaError Pa_ReadStream( PaStream* stream, - void *buffer, - unsigned long frames ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_ReadStream" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - { - if( frames == 0 ) - { - /* @todo Should we not allow the implementation to signal any overflow condition? see: http://www.portaudio.com/trac/ticket/116*/ - result = paNoError; - } - else if( buffer == 0 ) - { - result = paBadBufferPtr; - } - else - { - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - if( result == 0 ) - { - result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames ); - } - else if( result == 1 ) - { - result = paStreamIsStopped; - } - } - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_ReadStream", result ); - - return result; -} - - -PaError Pa_WriteStream( PaStream* stream, - const void *buffer, - unsigned long frames ) -{ - PaError result = PaUtil_ValidateStreamPointer( stream ); - - PA_LOGAPI_ENTER_PARAMS( "Pa_WriteStream" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( result == paNoError ) - { - if( frames == 0 ) - { - /* @todo Should we not allow the implementation to signal any underflow condition? see: http://www.portaudio.com/trac/ticket/116*/ - result = paNoError; - } - else if( buffer == 0 ) - { - result = paBadBufferPtr; - } - else - { - result = PA_STREAM_INTERFACE(stream)->IsStopped( stream ); - if( result == 0 ) - { - result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames ); - } - else if( result == 1 ) - { - result = paStreamIsStopped; - } - } - } - - PA_LOGAPI_EXIT_PAERROR( "Pa_WriteStream", result ); - - return result; -} - -signed long Pa_GetStreamReadAvailable( PaStream* stream ) -{ - PaError error = PaUtil_ValidateStreamPointer( stream ); - signed long result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamReadAvailable" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( error != paNoError ) - { - result = 0; - - PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); - PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); - - } - else - { - result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream ); - - PA_LOGAPI(("Pa_GetStreamReadAvailable returned:\n" )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - - } - - return result; -} - - -signed long Pa_GetStreamWriteAvailable( PaStream* stream ) -{ - PaError error = PaUtil_ValidateStreamPointer( stream ); - signed long result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetStreamWriteAvailable" ); - PA_LOGAPI(("\tPaStream* stream: 0x%p\n", stream )); - - if( error != paNoError ) - { - result = 0; - - PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); - PA_LOGAPI(("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n", error, Pa_GetErrorText( error ) )); - - } - else - { - result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream ); - - PA_LOGAPI(("Pa_GetStreamWriteAvailable returned:\n" )); - PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )); - - } - - return result; -} - - -PaError Pa_GetSampleSize( PaSampleFormat format ) -{ - int result; - - PA_LOGAPI_ENTER_PARAMS( "Pa_GetSampleSize" ); - PA_LOGAPI(("\tPaSampleFormat format: %d\n", format )); - - switch( format & ~paNonInterleaved ) - { - - case paUInt8: - case paInt8: - result = 1; - break; - - case paInt16: - result = 2; - break; - - case paInt24: - result = 3; - break; - - case paFloat32: - case paInt32: - result = 4; - break; - - default: - result = paSampleFormatNotSupported; - break; - } - - PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( "Pa_GetSampleSize", "int: %d", result ); - - return (PaError) result; -} |