⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pa_front.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * $Id: pa_front.c 1139 2006-11-22 06:51:06Z rossb $ * 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-2002 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 public PortAudio API, checks some errors, forwards to host API implementations.  Implements the functions defined in the PortAudio API, checks for some parameter and state inconsistencies and forwards 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 handles initialization and termination of Host API implementations via initializers stored in the paHostApiInitializers global variable. 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.    @todo Consider adding host API specific error text in Pa_GetErrorText() for    paUnanticipatedHostError    @todo Consider adding a new error code for when (inputParameters == NULL)    && (outputParameters == NULL)    @todo review whether Pa_CloseStream() should call the interface's    CloseStream function if aborting the stream returns an error code.    @todo Create new error codes if a NULL buffer pointer, or a    zero frame count is passed to Pa_ReadStream or Pa_WriteStream.*/#include <stdio.h>#include <memory.h>#include <string.h>#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"#define PA_VERSION_  1899#define PA_VERSION_TEXT_ "PortAudio V19-devel"/* #define PA_LOG_API_CALLS *//*    The basic format for log messages is described below. If you need to    add any log messages, please follow this format.     Function entry (void function):         "FunctionName called.\n"     Function entry (non void function):         "FunctionName called:\n"        "\tParam1Type param1: param1Value\n"        "\tParam2Type param2: param2Value\n"      (etc...)      Function exit (no return value):         "FunctionName returned.\n"     Function exit (simple return value):         "FunctionName returned:\n"        "\tReturnType: returnValue\n\n"     If the return type is an error code, the error text is displayed in ()     If the return type is not an error code, but has taken a special value    because an error occurred, then the reason for the error is shown in []     If the return type is a struct ptr, the struct is dumped.     See the code below for examples*/int Pa_GetVersion( void ){    return PA_VERSION_;}const char* Pa_GetVersionText( void ){    return PA_VERSION_TEXT_;}#define PA_LAST_HOST_ERROR_TEXT_LENGTH_  1024static 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 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 */    while( hostApisCount_ > 0 )    {        --hostApisCount_;        hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] );    }    hostApisCount_ = 0;    deviceCount_ = 0;    if( hostApis_ != 0 )        PaUtil_FreeMemory( hostApis_ );    hostApis_ = 0;}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;    deviceCount_ = 0;    baseDeviceIndex = 0;    for( i=0; i< initializerCount; ++i )    {        hostApis_[hostApisCount_] = NULL;        result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );        if( result != paNoError )            goto error;        if( hostApis_[hostApisCount_] )        {            PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_];            assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );            assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );            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_;        }    }    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;#ifdef PA_LOG_API_CALLS    PaUtil_DebugPrint( "Pa_Initialize called.\n" );#endif    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_;    }#ifdef PA_LOG_API_CALLS    PaUtil_DebugPrint( "Pa_Initialize returned:\n" );    PaUtil_DebugPrint( "\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );#endif    return result;}PaError Pa_Terminate( void ){    PaError result;#ifdef PA_LOG_API_CALLS    PaUtil_DebugPrint("Pa_Terminate called.\n" );#endif    if( PA_IS_INITIALISED_ )    {        if( --initializationCount_ == 0 )        {            CloseOpenStreams();            TerminateHostApis();            PaUtil_DumpTraceMessages();        }        result = paNoError;    }    else    {        result=  paNotInitialized;    }#ifdef PA_LOG_API_CALLS    PaUtil_DebugPrint("Pa_Terminate returned:\n" );    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );#endif    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 */    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;    default:                         result = "Illegal error number"; break;    }    return result;}PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type ){    PaHostApiIndex result;    int i;    #ifdef PA_LOG_API_CALLS    PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex called:\n" );    PaUtil_DebugPrint("\tPaHostApiTypeId type: %d\n", type );#endif    if( !PA_IS_INITIALISED_ )    {        result = paNotInitialized;    }    else    {        result = paHostApiNotFound;                for( i=0; i < hostApisCount_; ++i )        {            if( hostApis_[i]->info.type == type )            {                result = i;                break;            }                 }    }#ifdef PA_LOG_API_CALLS    PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex returned:\n" );    if( result < 0 )        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );    else        PaUtil_DebugPrint("\tPaHostApiIndex: %d\n\n", result );#endif    return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -