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

📄 pa_win_wmme.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
    return sPaHostError;}/*************************************************************************/int Pa_CountDevices(){    if( PaHost_IsInitialized() )        return sNumDevices;    else        return 0;}/************************************************************************* * If a PaDeviceInfo structure has not already been created, * then allocate one and fill it in for the selected device. * * We create one extra input and one extra output device for the WAVE_MAPPER. * [Does anyone know how to query the default device and get its name?] */const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ){#define NUM_STANDARDSAMPLINGRATES   3   /* 11025, 22050, 44100 */    static DWORD customSamplingRates[] = { 8000, 32000, 48000, 64000, 88200, 96000 };#define NUM_CUSTOMSAMPLINGRATES     (sizeof(customSamplingRates)/sizeof(DWORD))#define MAX_NUMSAMPLINGRATES        (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES)    PaDeviceInfo *deviceInfo;    double *sampleRates; /* non-const ptr */    int i;    char *s;    if( id < 0 || id >= sNumDevices )        return NULL;    if( sDevicePtrs[ id ] != NULL )    {        return sDevicePtrs[ id ];    }    deviceInfo = (PaDeviceInfo *)PaHost_AllocateTrackedMemory( sizeof(PaDeviceInfo) ); /* MEM */    if( deviceInfo == NULL ) return NULL;    deviceInfo->structVersion = 1;    deviceInfo->maxInputChannels = 0;    deviceInfo->maxOutputChannels = 0;    deviceInfo->numSampleRates = 0;    sampleRates = (double*)PaHost_AllocateTrackedMemory( MAX_NUMSAMPLINGRATES * sizeof(double) ); /* MEM */    deviceInfo->sampleRates = sampleRates;    deviceInfo->nativeSampleFormats = paInt16;       /* should query for higher bit depths below */    if( id < sNumInputDevices )    {        /* input device */        int inputMmID = PaDeviceIdToWinId(id);        WAVEINCAPS wic;        if( waveInGetDevCaps( inputMmID, &wic, sizeof( WAVEINCAPS ) ) != MMSYSERR_NOERROR )            goto error;        /* Append I/O suffix to WAVE_MAPPER device. */        if( inputMmID == WAVE_MAPPER )        {            s = (char *) PaHost_AllocateTrackedMemory( strlen( wic.szPname ) + 1 + sizeof(sMapperSuffixInput) ); /* MEM */            strcpy( s, wic.szPname );            strcat( s, sMapperSuffixInput );        }        else        {            s = (char *) PaHost_AllocateTrackedMemory( strlen( wic.szPname ) + 1 ); /* MEM */            strcpy( s, wic.szPname );        }        deviceInfo->name = s;        deviceInfo->maxInputChannels = wic.wChannels;        /* Sometimes a device can return a rediculously large number of channels.         * This happened with an SBLive card on a Windows ME box.         * If that happens, then force it to 2 channels.  PLB20010413         */        if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )        {            ERR_RPT(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", deviceInfo->maxOutputChannels ));            deviceInfo->maxInputChannels = 2;        }        /* Add a sample rate to the list if we can do stereo 16 bit at that rate         * based on the format flags. */        if( wic.dwFormats & WAVE_FORMAT_1M16 ||wic.dwFormats & WAVE_FORMAT_1S16 )            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;        if( wic.dwFormats & WAVE_FORMAT_2M16 ||wic.dwFormats & WAVE_FORMAT_2S16 )            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;        if( wic.dwFormats & WAVE_FORMAT_4M16 ||wic.dwFormats & WAVE_FORMAT_4S16 )            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;        /* Add a sample rate to the list if we can do stereo 16 bit at that rate         * based on opening the device successfully. */        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )        {            WAVEFORMATEX wfx;            wfx.wFormatTag = WAVE_FORMAT_PCM;            wfx.nSamplesPerSec = customSamplingRates[i];            wfx.wBitsPerSample = 16;            wfx.cbSize = 0; /* ignored */            wfx.nChannels = (WORD)deviceInfo->maxInputChannels;            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));            if( waveInOpen( NULL, inputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )            {                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];            }        }    }    else if( id - sNumInputDevices < sNumOutputDevices )    {        /* output device */        int outputMmID = PaDeviceIdToWinId(id);        WAVEOUTCAPS woc;        if( waveOutGetDevCaps( outputMmID, &woc, sizeof( WAVEOUTCAPS ) ) != MMSYSERR_NOERROR )            goto error;        /* Append I/O suffix to WAVE_MAPPER device. */        if( outputMmID == WAVE_MAPPER )        {            s = (char *) PaHost_AllocateTrackedMemory( strlen( woc.szPname ) + 1 + sizeof(sMapperSuffixOutput) );  /* MEM */            strcpy( s, woc.szPname );            strcat( s, sMapperSuffixOutput );        }        else        {            s = (char *) PaHost_AllocateTrackedMemory( strlen( woc.szPname ) + 1 );  /* MEM */            strcpy( s, woc.szPname );        }        deviceInfo->name = s;        deviceInfo->maxOutputChannels = woc.wChannels;        /* Sometimes a device can return a rediculously large number of channels.         * This happened with an SBLive card on a Windows ME box.         * It also happens on Win XP!         */        if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )        {#if 1            deviceInfo->maxOutputChannels = 2;#else        /* If channel max is goofy, then query for max channels. PLB20020228         * This doesn't seem to help. Disable code for now. Remove it later.         */            ERR_RPT(("Pa_GetDeviceInfo: Num output channels reported as %d!", deviceInfo->maxOutputChannels ));            deviceInfo->maxOutputChannels = 0;			/* Attempt to find the correct maximum by querying the device. */			for( i=2; i<16; i += 2 )			{				WAVEFORMATEX wfx;				wfx.wFormatTag = WAVE_FORMAT_PCM;				wfx.nSamplesPerSec = 44100;				wfx.wBitsPerSample = 16;				wfx.cbSize = 0; /* ignored */				wfx.nChannels = (WORD) i;				wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);				wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));				if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )				{					deviceInfo->maxOutputChannels = i;				}				else				{					break;				}			}#endif            ERR_RPT((" Changed to %d.\n", deviceInfo->maxOutputChannels ));        }        /* Add a sample rate to the list if we can do stereo 16 bit at that rate         * based on the format flags. */        if( woc.dwFormats & WAVE_FORMAT_1M16 ||woc.dwFormats & WAVE_FORMAT_1S16 )            sampleRates[ deviceInfo->numSampleRates++ ] = 11025.;        if( woc.dwFormats & WAVE_FORMAT_2M16 ||woc.dwFormats & WAVE_FORMAT_2S16 )            sampleRates[ deviceInfo->numSampleRates++ ] = 22050.;        if( woc.dwFormats & WAVE_FORMAT_4M16 ||woc.dwFormats & WAVE_FORMAT_4S16 )            sampleRates[ deviceInfo->numSampleRates++ ] = 44100.;        /* Add a sample rate to the list if we can do stereo 16 bit at that rate         * based on opening the device successfully. */        for( i=0; i < NUM_CUSTOMSAMPLINGRATES; i++ )        {            WAVEFORMATEX wfx;            wfx.wFormatTag = WAVE_FORMAT_PCM;            wfx.nSamplesPerSec = customSamplingRates[i];            wfx.wBitsPerSample = 16;            wfx.cbSize = 0; /* ignored */            wfx.nChannels = (WORD)deviceInfo->maxOutputChannels;            wfx.nAvgBytesPerSec = wfx.nChannels * wfx.nSamplesPerSec * sizeof(short);            wfx.nBlockAlign = (WORD)(wfx.nChannels * sizeof(short));            if( waveOutOpen( NULL, outputMmID, &wfx, 0, 0, WAVE_FORMAT_QUERY ) == MMSYSERR_NOERROR )            {                sampleRates[ deviceInfo->numSampleRates++ ] = customSamplingRates[i];            }        }    }    sDevicePtrs[ id ] = deviceInfo;    return deviceInfo;error:    PaHost_FreeTrackedMemory( sampleRates ); /* MEM */    PaHost_FreeTrackedMemory( deviceInfo ); /* MEM */    return NULL;}/************************************************************************* * Returns recommended device ID. * On the PC, the recommended device can be specified by the user by * setting an environment variable. For example, to use device #1. * *    set PA_RECOMMENDED_OUTPUT_DEVICE=1 * * The user should first determine the available device ID by using * the supplied application "pa_devs". */#define PA_ENV_BUF_SIZE  (32)#define PA_REC_IN_DEV_ENV_NAME  ("PA_RECOMMENDED_INPUT_DEVICE")#define PA_REC_OUT_DEV_ENV_NAME  ("PA_RECOMMENDED_OUTPUT_DEVICE")static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName ){    DWORD   hresult;    char    envbuf[PA_ENV_BUF_SIZE];    PaDeviceID recommendedID = paNoDevice;    /* Let user determine default device by setting environment variable. */    hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )    {        recommendedID = atoi( envbuf );    }    return recommendedID;}/********************************************************************** * Check for environment variable, else query devices and use result. */PaDeviceID Pa_GetDefaultInputDeviceID( void ){    PaDeviceID result;    result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );    if( result == paNoDevice || result < 0 || result >= sNumInputDevices )    {        result = sDefaultInputDeviceID;    }    return result;}PaDeviceID Pa_GetDefaultOutputDeviceID( void ){    PaDeviceID result;    result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );    if( result == paNoDevice || result < sNumInputDevices || result >= sNumDevices )    {        result = sDefaultOutputDeviceID;    }    return result;}/********************************************************************** * Initialize Host dependant part of API. */PaError PaHost_Init( void ){#if PA_TRACK_MEMORY    PRINT(("PaHost_Init: sNumAllocations = %d\n", sNumAllocations ));#endif#if PA_SIMULATE_UNDERFLOW    PRINT(("WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\n"));#endif       Pa_InitializeNumDevices();    return Pa_AllocateDevicePtrs();}/********************************************************************** * Check WAVE buffers to see if they are done. * Fill any available output buffers and use any available * input buffers by calling user callback. * * This routine will loop until: *    user callback returns !=0 OR *    all output buffers are filled OR *    past->past_StopSoon is set OR *    an error occurs when calling WMME. * * Returns >0 when user requests a stop, <0 on error. * */static PaError Pa_TimeSlice( internalPortAudioStream *stream ){    PaError           result = paNoError;    MMRESULT          mmresult;    char             *inBufPtr;    char             *outBufPtr;    int               gotInput = 0;    int               gotOutput = 0;    int               i;    int               buffersProcessed = 0;    int               done = 0;    PaWMMEStreamData *wmmeStreamData = (PaWMMEStreamData *) stream->past_DeviceData;    if( wmmeStreamData == NULL ) return paInternalError;    stream->past_NumCallbacks += 1;#if PA_TRACE_RUN    AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ", stream->past_NumCallbacks );#endif    /* JM20020118 - prevent hung thread when buffers underflow. */    /* while( !done ) /* BAD */    while( !done && !stream->past_StopSoon ) /* GOOD */    {#if PA_SIMULATE_UNDERFLOW        if(gUnderCallbackCounter++ == UNDER_SLEEP_AT)        {            Sleep(UNDER_SLEEP_FOR);        }#endif        /* If we are using output, then we need an empty output buffer. */        gotOutput = 0;        outBufPtr = NULL;        if( stream->past_NumOutputChannels > 0 )        {            if((wmmeStreamData->outputBuffers[ wmmeStreamData->currentOutputBuffer ].dwFlags & WHDR_DONE) == 0)            {                break;  /* If none empty then bail and try again later. */            }            else            {                outBufPtr = wmmeStreamData->outputBuffers[ wmmeStreamData->currentOutputBuffer ].lpData;                gotOutput = 1;            }        }        /* Use an input buffer if one is available. */        gotInput = 0;        inBufPtr = NULL;        if( ( stream->past_NumInputChannels > 0 ) &&                (wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ].dwFlags & WHDR_DONE) )        {            inBufPtr = wmmeStreamData->inputBuffers[ wmmeStreamData->currentInputBuffer ].lpData;            gotInput = 1;#if PA_TRACE_RUN            AddTraceMessage("Pa_TimeSlice: got input buffer at ", (int)inBufPtr );

⌨️ 快捷键说明

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