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

📄 pa_win_ds.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 4 页
字号:
        memset( &caps, 0, sizeof(caps) );         caps.dwSize = sizeof(caps);        hr = IDirectSound_GetCaps( lpDirectSound, &caps );        if( hr != DS_OK )        {            DBUG(("Cannot GetCaps() for DirectSound device %s. Result = 0x%x\n", name, hr ));            deviceOK = FALSE;        }        else        {#ifndef PA_NO_WMME            if( caps.dwFlags & DSCAPS_EMULDRIVER )            {                /* If WMME supported, then reject Emulated drivers because they are lousy. */                deviceOK = FALSE;            }#endif            if( deviceOK )            {                deviceInfo->maxInputChannels = 0;                /* Mono or stereo device? */                deviceInfo->maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;                deviceInfo->defaultLowInputLatency = 0.;    /** @todo IMPLEMENT ME */                deviceInfo->defaultLowOutputLatency = 0.;   /** @todo IMPLEMENT ME */                deviceInfo->defaultHighInputLatency = 0.;   /** @todo IMPLEMENT ME */                deviceInfo->defaultHighOutputLatency = 0.;  /** @todo IMPLEMENT ME */                deviceInfo->defaultSampleRate = 0;          /** @todo IMPLEMENT ME */                //printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate );                // dwFlags | DSCAPS_CONTINUOUSRATE             }        }        IDirectSound_Release( lpDirectSound );    }    if( deviceOK )    {        deviceInfo->name = name;        if( lpGUID == NULL )            hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;                    hostApi->info.deviceCount++;    }    return result;}/************************************************************************************** Extract capabilities from an input device, and add it to the device info list** if successful. This function assumes that there is enough room in the** device info list to accomodate all entries.**** The device will not be added to the device list if any errors are encountered.*/static PaError AddInputDeviceInfoFromDirectSoundCapture(        PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID ){    PaUtilHostApiRepresentation  *hostApi = &winDsHostApi->inheritedHostApiRep;    PaDeviceInfo                 *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount];    PaWinDsDeviceInfo            *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount];    HRESULT                       hr;    LPDIRECTSOUNDCAPTURE          lpDirectSoundCapture;    DSCCAPS                       caps;    int                           deviceOK = TRUE;    PaError                       result = paNoError;        /* Copy GUID to the device info structure. Set pointer. */    if( lpGUID == NULL )    {        winDsDeviceInfo->lpGUID = NULL;    }    else    {        winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;        memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );    }    hr = dswDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL );    /** try using CoCreateInstance because DirectSoundCreate was hanging under        some circumstances - note this was probably related to the        #define BOOL short bug which has now been fixed        @todo delete this comment and the following code once we've ensured        there is no bug.    */    /*    hr = CoCreateInstance( &CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,            &IID_IDirectSoundCapture, (void**)&lpDirectSoundCapture );    */    if( hr != DS_OK )    {        DBUG(("Cannot create Capture for %s. Result = 0x%x\n", name, hr ));        deviceOK = FALSE;    }    else    {        /* Query device characteristics. */        memset( &caps, 0, sizeof(caps) );        caps.dwSize = sizeof(caps);        hr = IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps );        if( hr != DS_OK )        {            DBUG(("Cannot GetCaps() for Capture device %s. Result = 0x%x\n", name, hr ));            deviceOK = FALSE;        }        else        {#ifndef PA_NO_WMME            if( caps.dwFlags & DSCAPS_EMULDRIVER )            {                /* If WMME supported, then reject Emulated drivers because they are lousy. */                deviceOK = FALSE;            }#endif            if( deviceOK )            {                deviceInfo->maxInputChannels = caps.dwChannels;                deviceInfo->maxOutputChannels = 0;                deviceInfo->defaultLowInputLatency = 0.;    /** @todo IMPLEMENT ME */                deviceInfo->defaultLowOutputLatency = 0.;   /** @todo IMPLEMENT ME */                deviceInfo->defaultHighInputLatency = 0.;   /** @todo IMPLEMENT ME */                deviceInfo->defaultHighOutputLatency = 0.;  /** @todo IMPLEMENT ME */                deviceInfo->defaultSampleRate = 0;          /** @todo IMPLEMENT ME */            }        }                IDirectSoundCapture_Release( lpDirectSoundCapture );    }    if( deviceOK )    {        deviceInfo->name = name;        if( lpGUID == NULL )            hostApi->info.defaultInputDevice = hostApi->info.deviceCount;        hostApi->info.deviceCount++;    }    return result;}/***********************************************************************************/PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ){    PaError result = paNoError;    int i, deviceCount;    PaWinDsHostApiRepresentation *winDsHostApi;    DSDeviceNameAndGUIDVector inputNamesAndGUIDs, outputNamesAndGUIDs;    PaDeviceInfo *deviceInfoArray;    HRESULT hr = CoInitialize(NULL);        /** @todo: should uninitialize too */    if( FAILED(hr) ){        return paUnanticipatedHostError;    }                /* initialise guid vectors so they can be safely deleted on error */    inputNamesAndGUIDs.items = NULL;    outputNamesAndGUIDs.items = NULL;    DSW_InitializeDSoundEntryPoints();    winDsHostApi = (PaWinDsHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinDsHostApiRepresentation) );    if( !winDsHostApi )    {        result = paInsufficientMemory;        goto error;    }    winDsHostApi->allocations = PaUtil_CreateAllocationGroup();    if( !winDsHostApi->allocations )    {        result = paInsufficientMemory;        goto error;    }    *hostApi = &winDsHostApi->inheritedHostApiRep;    (*hostApi)->info.structVersion = 1;    (*hostApi)->info.type = paDirectSound;    (*hostApi)->info.name = "Windows DirectSound";        (*hostApi)->info.deviceCount = 0;    (*hostApi)->info.defaultInputDevice = paNoDevice;    (*hostApi)->info.defaultOutputDevice = paNoDevice;    /* DSound - enumerate devices to count them and to gather their GUIDs */    result = InitializeDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs, winDsHostApi->allocations );    if( result != paNoError )        goto error;    result = InitializeDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs, winDsHostApi->allocations );    if( result != paNoError )        goto error;    dswDSoundEntryPoints.DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&inputNamesAndGUIDs );    dswDSoundEntryPoints.DirectSoundEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&outputNamesAndGUIDs );    if( inputNamesAndGUIDs.enumerationError != paNoError )    {        result = inputNamesAndGUIDs.enumerationError;        goto error;    }    if( outputNamesAndGUIDs.enumerationError != paNoError )    {        result = outputNamesAndGUIDs.enumerationError;        goto error;    }    deviceCount = inputNamesAndGUIDs.count + outputNamesAndGUIDs.count;    if( deviceCount > 0 )    {        /* allocate array for pointers to PaDeviceInfo structs */        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(                winDsHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );        if( !(*hostApi)->deviceInfos )        {            result = paInsufficientMemory;            goto error;        }        /* allocate all PaDeviceInfo structs in a contiguous block */        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(                winDsHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );        if( !deviceInfoArray )        {            result = paInsufficientMemory;            goto error;        }        /* allocate all DSound specific info structs in a contiguous block */        winDsHostApi->winDsDeviceInfos = (PaWinDsDeviceInfo*)PaUtil_GroupAllocateMemory(                winDsHostApi->allocations, sizeof(PaWinDsDeviceInfo) * deviceCount );        if( !winDsHostApi->winDsDeviceInfos )        {            result = paInsufficientMemory;            goto error;        }        for( i=0; i < deviceCount; ++i )        {            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];            deviceInfo->structVersion = 2;            deviceInfo->hostApi = hostApiIndex;            deviceInfo->name = 0;            (*hostApi)->deviceInfos[i] = deviceInfo;        }        for( i=0; i< inputNamesAndGUIDs.count; ++i )        {            result = AddInputDeviceInfoFromDirectSoundCapture( winDsHostApi,                    inputNamesAndGUIDs.items[i].name,                    inputNamesAndGUIDs.items[i].lpGUID );            if( result != paNoError )                goto error;        }        for( i=0; i< outputNamesAndGUIDs.count; ++i )        {            result = AddOutputDeviceInfoFromDirectSound( winDsHostApi,                    outputNamesAndGUIDs.items[i].name,                    outputNamesAndGUIDs.items[i].lpGUID );            if( result != paNoError )                goto error;        }    }        result = TerminateDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs );    if( result != paNoError )        goto error;    result = TerminateDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs );    if( result != paNoError )        goto error;        (*hostApi)->Terminate = Terminate;    (*hostApi)->OpenStream = OpenStream;    (*hostApi)->IsFormatSupported = IsFormatSupported;    PaUtil_InitializeStreamInterface( &winDsHostApi->callbackStreamInterface, CloseStream, StartStream,                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,                                      GetStreamTime, GetStreamCpuLoad,                                      PaUtil_DummyRead, PaUtil_DummyWrite,                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );    PaUtil_InitializeStreamInterface( &winDsHostApi->blockingStreamInterface, CloseStream, StartStream,                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,                                      GetStreamTime, PaUtil_DummyGetCpuLoad,                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );    return result;error:    if( winDsHostApi )    {        if( winDsHostApi->allocations )        {            PaUtil_FreeAllAllocations( winDsHostApi->allocations );            PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );        }                        PaUtil_FreeMemory( winDsHostApi );    }    TerminateDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs );    TerminateDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs );    return result;}/***********************************************************************************/static void Terminate( struct PaUtilHostApiRepresentation *hostApi ){    PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi;    /*        IMPLEMENT ME:            - clean up any resources not handled by the allocation group    */    if( winDsHostApi->allocations )    {        PaUtil_FreeAllAllocations( winDsHostApi->allocations );        PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );    }    PaUtil_FreeMemory( winDsHostApi );    DSW_TerminateDSoundEntryPoints();    CoUninitialize();}/* Set minimal latency based on whether NT or Win95. * NT has higher latency. */static int PaWinDS_GetMinSystemLatency( void ){    int minLatencyMsec;    /* Set minimal latency based on whether NT or other OS.     * NT has higher latency.     */    OSVERSIONINFO osvi;	osvi.dwOSVersionInfoSize = sizeof( osvi );	GetVersionEx( &osvi );    DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));    DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));    DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));    /* Check for NT */	if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )	{		minLatencyMsec = PA_WIN_NT_LATENCY;	}	else if(osvi.dwMajorVersion >= 5)	{		minLatencyMsec = PA_WIN_WDM_LATENCY;	}	else	{		minLatencyMsec = PA_WIN_9X_LATENCY;	}    return minLatencyMsec;}/***********************************************************************************/static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,                                  const PaStreamParameters *inputParameters,                                  const PaStreamParameters *outputParameters,                                  double sampleRate ){    int inputChannelCount, outputChannelCount;    PaSampleFormat inputSampleFormat, outputSampleFormat;        if( inputParameters )    {        inputChannelCount = inputParameters->channelCount;        inputSampleFormat = inputParameters->sampleFormat;        /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that input device can support inputChannelCount */        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )            return paInvalidChannelCount;        /* validate inputStreamInfo */        if( inputParameters->hostApiSpecificStreamInfo )            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */    }    else    {        inputChannelCount = 0;    }    if( outputParameters )    {        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;                /* unless alternate device specification is supported, reject the use of            paUseHostApiSpecificDeviceSpecification */        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )            return paInvalidDevice;        /* check that output device can support inputChannelCount */        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )

⌨️ 快捷键说明

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