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

📄 pa_win_wmme.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
    PaUtilAllocationGroup *allocations;        int inputDeviceCount, outputDeviceCount;    /** winMmeDeviceIds is an array of WinMme device ids.        fields in the range [0, inputDeviceCount) are input device ids,        and [inputDeviceCount, inputDeviceCount + outputDeviceCount) are output        device ids.     */     UINT *winMmeDeviceIds;}PaWinMmeHostApiRepresentation;typedef struct{    PaDeviceInfo inheritedDeviceInfo;    DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */}PaWinMmeDeviceInfo;/************************************************************************* * 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 PaDeviceIndex GetEnvDefaultDeviceID( char *envName ){    PaDeviceIndex recommendedIndex = paNoDevice;    DWORD   hresult;    char    envbuf[PA_ENV_BUF_SIZE_];#ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */    /* 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_) )    {        recommendedIndex = atoi( envbuf );    }#endif    return recommendedIndex;}static void InitializeDefaultDeviceIdsFromEnv( PaWinMmeHostApiRepresentation *hostApi ){    PaDeviceIndex device;    /* input */    device = GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME_ );    if( device != paNoDevice &&            ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) &&            hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxInputChannels > 0 )    {        hostApi->inheritedHostApiRep.info.defaultInputDevice = device;    }    /* output */    device = GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME_ );    if( device != paNoDevice &&            ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) &&            hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxOutputChannels > 0 )    {        hostApi->inheritedHostApiRep.info.defaultOutputDevice = device;    }}/** Convert external PA ID to a windows multimedia device ID*/static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device ){    assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount );	return hostApi->winMmeDeviceIds[ device ];}static PaError QueryInputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ){    MMRESULT mmresult;        switch( mmresult = waveInOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) )    {        case MMSYSERR_NOERROR:            return paNoError;        case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */            return paDeviceUnavailable;        case MMSYSERR_NODRIVER:	    /* No device driver is present. */            return paDeviceUnavailable;        case MMSYSERR_NOMEM:	    /* Unable to allocate or lock memory. */            return paInsufficientMemory;        case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */            return paSampleFormatNotSupported;                            case MMSYSERR_BADDEVICEID:	/* Specified device identifier is out of range. */            /* falls through */        default:            PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );            return paUnanticipatedHostError;    }}static PaError QueryOutputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx ){    MMRESULT mmresult;        switch( mmresult = waveOutOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) )    {        case MMSYSERR_NOERROR:            return paNoError;        case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */            return paDeviceUnavailable;        case MMSYSERR_NODRIVER:	    /* No device driver is present. */            return paDeviceUnavailable;        case MMSYSERR_NOMEM:	    /* Unable to allocate or lock memory. */            return paInsufficientMemory;        case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */            return paSampleFormatNotSupported;                            case MMSYSERR_BADDEVICEID:	/* Specified device identifier is out of range. */            /* falls through */        default:            PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );            return paUnanticipatedHostError;    }}static PaError QueryFormatSupported( PaDeviceInfo *deviceInfo,        PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*),        int winMmeDeviceId, int channels, double sampleRate ){    PaWinMmeDeviceInfo *winMmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfo;    WAVEFORMATEX waveFormatEx;        if( sampleRate == 11025.0        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1M16))            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1S16)) ) ){        return paNoError;    }    if( sampleRate == 22050.0        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2M16))            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2S16)) ) ){        return paNoError;    }    if( sampleRate == 44100.0        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4M16))            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4S16)) ) ){        return paNoError;    }    waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;    waveFormatEx.nChannels = (WORD)channels;    waveFormatEx.nSamplesPerSec = (DWORD)sampleRate;    waveFormatEx.nAvgBytesPerSec = waveFormatEx.nSamplesPerSec * channels * sizeof(short);    waveFormatEx.nBlockAlign = (WORD)(channels * sizeof(short));    waveFormatEx.wBitsPerSample = 16;    waveFormatEx.cbSize = 0;    return waveFormatExQueryFunction( winMmeDeviceId, &waveFormatEx );}#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_  (13) /* must match array length below */static double defaultSampleRateSearchOrder_[] =    { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0,        16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int winMmeDeviceId,        PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int maxChannels ){    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;    int i;        deviceInfo->defaultSampleRate = 0.;    for( i=0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i )    {        double sampleRate = defaultSampleRateSearchOrder_[ i ];         PaError paerror = QueryFormatSupported( deviceInfo, waveFormatExQueryFunction, winMmeDeviceId, maxChannels, sampleRate );        if( paerror == paNoError )        {            deviceInfo->defaultSampleRate = sampleRate;            break;        }    }}static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,        PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success ){    PaError result = paNoError;    char *deviceName; /* non-const ptr */    MMRESULT mmresult;    WAVEINCAPS wic;    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;        *success = 0;    mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) );    if( mmresult == MMSYSERR_NOMEM )    {        result = paInsufficientMemory;        goto error;    }    else if( mmresult != MMSYSERR_NOERROR )    {        /* instead of returning paUnanticipatedHostError we return            paNoError, but leave success set as 0. This allows            Pa_Initialize to just ignore this device, without failing            the entire initialisation process.        */        return paNoError;    }               if( winMmeInputDeviceId == WAVE_MAPPER )    {        /* Append I/O suffix to WAVE_MAPPER device. */        deviceName = (char *)PaUtil_GroupAllocateMemory(                    winMmeHostApi->allocations, strlen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_) );        if( !deviceName )        {            result = paInsufficientMemory;            goto error;        }        strcpy( deviceName, wic.szPname );        strcat( deviceName, constInputMapperSuffix_ );    }    else    {        deviceName = (char*)PaUtil_GroupAllocateMemory(                    winMmeHostApi->allocations, strlen( wic.szPname ) + 1 );        if( !deviceName )        {            result = paInsufficientMemory;            goto error;        }        strcpy( deviceName, wic.szPname  );    }    deviceInfo->name = deviceName;    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) )    {        PA_DEBUG(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", deviceInfo->maxInputChannels ));        deviceInfo->maxInputChannels = 2;    }    winMmeDeviceInfo->dwFormats = wic.dwFormats;    DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId,            QueryInputWaveFormatEx, deviceInfo->maxInputChannels );    *success = 1;    error:    return result;}static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,        PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success ){    PaError result = paNoError;    char *deviceName; /* non-const ptr */    MMRESULT mmresult;    WAVEOUTCAPS woc;    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;        *success = 0;    mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) );    if( mmresult == MMSYSERR_NOMEM )    {        result = paInsufficientMemory;        goto error;    }    else if( mmresult != MMSYSERR_NOERROR )    {        /* instead of returning paUnanticipatedHostError we return            paNoError, but leave success set as 0. This allows            Pa_Initialize to just ignore this device, without failing            the entire initialisation process.        */        return paNoError;    }    if( winMmeOutputDeviceId == WAVE_MAPPER )    {        /* Append I/O suffix to WAVE_MAPPER device. */        deviceName = (char *)PaUtil_GroupAllocateMemory(                    winMmeHostApi->allocations, strlen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_) );        if( !deviceName )        {            result = paInsufficientMemory;            goto error;        }        strcpy( deviceName, woc.szPname );        strcat( deviceName, constOutputMapperSuffix_ );    }    else    {        deviceName = (char*)PaUtil_GroupAllocateMemory(                    winMmeHostApi->allocations, strlen( woc.szPname ) + 1 );        if( !deviceName )        {            result = paInsufficientMemory;            goto error;        }        strcpy( deviceName, woc.szPname  );    }    deviceInfo->name = deviceName;    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.

⌨️ 快捷键说明

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