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

📄 pa_lib.c

📁 一个任天堂掌上游戏机NDS的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: pa_lib.c,v 1.3 2002/04/17 06:29:07 rossb Exp $ * Portable Audio I/O Library * Host Independant Layer * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2000 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. * * 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. * * 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. * *//* Modification History: PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC PLB20010820 - fix dither and shift for recording PaUInt8 format */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */#ifdef _WIN32#ifndef __MWERKS__#include <memory.h>#endif  /* __MWERKS__ */#else   /* !_WIN32 */#include <memory.h>#endif  /* _WIN32 */#include "portaudio.h"#include "pa_host.h"//#include "pa_trace.h"/* The reason we might NOT want to validate the rate before opening the stream * is because many DirectSound drivers lie about the rates they actually support. */#define PA_VALIDATE_RATE    (0)   /* If true validate sample rate against driver info. *//*O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion*/#ifndef FALSE #define FALSE  (0) #define TRUE   (!FALSE)#endif#define PRINT(x) { printf x; fflush(stdout); }#define ERR_RPT(x) PRINT(x)#define DBUG(x)  /* PRINT(x) */#define DBUGX(x) /* PRINT(x) */static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */static PaError Pa_KillStream(  PortAudioStream *stream, int abort );/***********************************************************************/int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable, int numRates, double frameRate ){    double err, minErr = allowableError;    int i, bestFit = -1;    for( i=0; i<numRates; i++ )    {        err = fabs( frameRate - rateTable[i] );        if( err < minErr )        {            minErr = err;            bestFit = i;        }    }    return bestFit;}/**************************************************************************** Make sure sample rate is legal and also convert to enumeration for driver.*/PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,                                   double *closestFrameRatePtr ){    long bestRateIndex;    const PaDeviceInfo *pdi;    pdi = Pa_GetDeviceInfo( id );    if( pdi == NULL )    {        return paInvalidDeviceId;    }    if( pdi->numSampleRates == -1 )    {        /* Is it out of range? */        if( (requestedFrameRate < pdi->sampleRates[0]) ||                (requestedFrameRate > pdi->sampleRates[1]) )        {            return paInvalidSampleRate;        }        *closestFrameRatePtr = requestedFrameRate;    }    else    {        bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );        if( bestRateIndex < 0 ) return paInvalidSampleRate;        *closestFrameRatePtr = pdi->sampleRates[bestRateIndex];    }    return paNoError;}/*************************************************************************/PaError Pa_OpenStream(    PortAudioStream** streamPtrPtr,    PaDeviceID inputDeviceID,    int numInputChannels,    PaSampleFormat inputSampleFormat,    void *inputDriverInfo,    PaDeviceID outputDeviceID,    int numOutputChannels,    PaSampleFormat outputSampleFormat,    void *outputDriverInfo,    double sampleRate,    unsigned long framesPerBuffer,    unsigned long numberOfBuffers,    unsigned long streamFlags,    PortAudioCallback *callback,    void *userData ){    internalPortAudioStream   *past = NULL;    PaError                    result = paNoError;    int                        bitsPerInputSample;    int                        bitsPerOutputSample;    /* Print passed parameters. */    DBUG(("Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \n",          streamPtrPtr, inputDeviceID, numInputChannels,          inputSampleFormat, inputDriverInfo ));    DBUG(("               %d, %d, %d, %p, /* output */\n",          outputDeviceID, numOutputChannels,          outputSampleFormat, outputDriverInfo ));    DBUG(("               %g, %d, %d, 0x%x, , %p )\n",          sampleRate, framesPerBuffer, numberOfBuffers,          streamFlags, userData ));    /* Check for parameter errors. */    if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;    if( streamPtrPtr == NULL ) return paBadStreamPtr;    if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */    if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */    if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;    if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) )    {        return paInvalidDeviceId;    }    if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;#if SUPPORT_AUDIO_CAPTURE    if( inputDeviceID >= 0 )    {        PaError size = Pa_GetSampleSize( inputSampleFormat );        if( size < 0 ) return size;        bitsPerInputSample = 8 * size;        if( (numInputChannels <= 0) ) return paInvalidChannelCount;    }#else    if( inputDeviceID >= 0 )    {        return paInvalidChannelCount;    }#endif /* SUPPORT_AUDIO_CAPTURE */    else    {        if( numInputChannels > 0 ) return paInvalidChannelCount;        bitsPerInputSample = 0;    }    if( outputDeviceID >= 0 )    {        PaError size = Pa_GetSampleSize( outputSampleFormat );        if( size < 0 ) return size;        bitsPerOutputSample = 8 * size;        if( (numOutputChannels <= 0) ) return paInvalidChannelCount;    }    else    {        if( numOutputChannels > 0 ) return paInvalidChannelCount;        bitsPerOutputSample = 0;    }    if( callback == NULL ) return paNullCallback;    /* Allocate and clear stream structure. */    past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );    if( past == NULL ) return paInsufficientMemory;    memset( past, 0, sizeof(internalPortAudioStream) );    //AddTraceMessage("Pa_OpenStream: past", (long) past );    past->past_Magic = PA_MAGIC;  /* Set ID to catch bugs. */    past->past_FramesPerUserBuffer = framesPerBuffer;    past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() MUST CHECK FOR ZERO! */    past->past_Callback = callback;    past->past_UserData = userData;    past->past_OutputSampleFormat = outputSampleFormat;    past->past_InputSampleFormat = inputSampleFormat;    past->past_OutputDeviceID = outputDeviceID;    past->past_InputDeviceID = inputDeviceID;    past->past_NumInputChannels = numInputChannels;    past->past_NumOutputChannels = numOutputChannels;    past->past_Flags = streamFlags;    /* Check for absurd sample rates. */    if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )    {        result = paInvalidSampleRate;        goto cleanup;    }    /* Allocate buffers that may be used for format conversion from user to native buffers. */    if( numInputChannels > 0 )    {#if PA_VALIDATE_RATE        result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );        if( result < 0 )        {            goto cleanup;        }#else        past->past_SampleRate = sampleRate;#endif        /* Allocate single Input buffer for passing formatted samples to user callback. */        past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);        past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);        if( past->past_InputBuffer == NULL )        {            result = paInsufficientMemory;            goto cleanup;        }    }    else    {        past->past_InputBuffer = NULL;    }    /* Allocate single Output buffer. */    if( numOutputChannels > 0 )    {#if PA_VALIDATE_RATE        result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );        if( result < 0 )        {            goto cleanup;        }#else        past->past_SampleRate = sampleRate;#endif        past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);        past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);        if( past->past_OutputBuffer == NULL )        {            result = paInsufficientMemory;            goto cleanup;        }    }    else    {        past->past_OutputBuffer = NULL;    }    result = PaHost_OpenStream( past );    if( result < 0 ) goto cleanup;    *streamPtrPtr = (void *) past;    return result;cleanup:    if( past != NULL ) Pa_CloseStream( past );    *streamPtrPtr = NULL;    return result;}/*************************************************************************/PaError Pa_OpenDefaultStream( PortAudioStream** stream,                              int numInputChannels,                              int numOutputChannels,                              PaSampleFormat sampleFormat,                              double sampleRate,                              unsigned long framesPerBuffer,                              unsigned long numberOfBuffers,                              PortAudioCallback *callback,                              void *userData ){    return Pa_OpenStream(               stream,               ((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),               numInputChannels, sampleFormat, NULL,               ((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),               numOutputChannels, sampleFormat, NULL,               sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );}/*************************************************************************/PaError Pa_CloseStream( PortAudioStream* stream){    PaError   result;    internalPortAudioStream   *past;    DBUG(("Pa_CloseStream()\n"));    if( stream == NULL ) return paBadStreamPtr;    past = (internalPortAudioStream *) stream;    Pa_AbortStream( past );    result = PaHost_CloseStream( past );    if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );    if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );    PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );    return result;}/*************************************************************************/PaError Pa_StartStream( PortAudioStream *stream ){    PaError result = paHostError;    internalPortAudioStream   *past;    if( stream == NULL ) return paBadStreamPtr;    past = (internalPortAudioStream *) stream;    past->past_FrameCount = 0.0;    if( past->past_NumInputChannels > 0 )    {        result = PaHost_StartInput( past );        DBUG(("Pa_StartStream: PaHost_StartInput returned = 0x%X.\n", result));        if( result < 0 ) goto error;    }    if( past->past_NumOutputChannels > 0 )    {        result = PaHost_StartOutput( past );        DBUG(("Pa_StartStream: PaHost_StartOutput returned = 0x%X.\n", result));        if( result < 0 ) goto error;    }    result = PaHost_StartEngine( past );    DBUG(("Pa_StartStream: PaHost_StartEngine returned = 0x%X.\n", result));    if( result < 0 ) goto error;    return paNoError;error:    return result;}/*************************************************************************/PaError Pa_StopStream(  PortAudioStream *stream ){    return Pa_KillStream( stream, 0 );}/*************************************************************************/PaError Pa_AbortStream(  PortAudioStream *stream ){    return Pa_KillStream( stream, 1 );}/*************************************************************************/static PaError Pa_KillStream(  PortAudioStream *stream, int abort ){    PaError result = paNoError;    internalPortAudioStream   *past;    DBUG(("Pa_StopStream().\n"));    if( stream == NULL ) return paBadStreamPtr;    past = (internalPortAudioStream *) stream;    if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )    {        result = PaHost_StopEngine( past, abort );        DBUG(("Pa_StopStream: PaHost_StopEngine returned = 0x%X.\n", result));

⌨️ 快捷键说明

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