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

📄 pa_win_ds.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 5 页
字号:
    {
        namesAndGUIDs->items[namesAndGUIDs->count].lpGUID =
                &namesAndGUIDs->items[namesAndGUIDs->count].guid;
      
        memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) );
    }

    namesAndGUIDs->items[namesAndGUIDs->count].name =
            DuplicateDeviceNameString( namesAndGUIDs->allocations, 
	    PJ_NATIVE_TO_STRING(lpszDesc,atemp,sizeof(atemp)));
    if( namesAndGUIDs->items[namesAndGUIDs->count].name == NULL )
    {
        namesAndGUIDs->enumerationError = paInsufficientMemory;
        return FALSE;
    }

    ++namesAndGUIDs->count;
    --namesAndGUIDs->free;
    
    return TRUE;
}


#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 };


/************************************************************************************
** Extract capabilities from an output 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 AddOutputDeviceInfoFromDirectSound(
        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;
    LPDIRECTSOUND                 lpDirectSound;
    DSCAPS                        caps;
    int                           deviceOK = TRUE;
    PaError                       result = paNoError;
    int                           i;
    
    /* Copy GUID to the device info structure. Set pointer. */
    if( lpGUID == NULL )
    {
        winDsDeviceInfo->lpGUID = NULL;
    }
    else
    {
        memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
        winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
    }

    
    /* Create a DirectSound object for the specified GUID
        Note that using CoCreateInstance doesn't work on windows CE.
    */
    hr = dswDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, 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_DirectSound, NULL, CLSCTX_INPROC_SERVER,
            &IID_IDirectSound, (void**)&lpDirectSound );

    if( hr == S_OK )
    {
        hr = IDirectSound_Initialize( lpDirectSound, lpGUID );
    }
    */
    
    if( hr != DS_OK )
    {
        DBUG(("Cannot create DirectSound for %s. Result = 0x%x\n", name, hr ));
        deviceOK = FALSE;
    }
    else
    {
        /* Query device characteristics. */
        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 */
                
                /* initialize defaultSampleRate */
                
                if( caps.dwFlags & DSCAPS_CONTINUOUSRATE )
                {
                    /* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */
                    deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;

                    for( i = 0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i )
                    {
                        if( defaultSampleRateSearchOrder_[i] >= caps.dwMinSecondarySampleRate
                                && defaultSampleRateSearchOrder_[i] <= caps.dwMaxSecondarySampleRate ){

                            deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[i];
                            break;
                        }
                    }
                }
                else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate )
                {
                    if( caps.dwMinSecondarySampleRate == 0 )
                    {
                        /*
                        ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !!
                        ** But it supports continuous sampling.
                        ** So fake range of rates, and hope it really supports it.
                        */
                        deviceInfo->defaultSampleRate = 44100.0f;

                        DBUG(("PA - Reported rates both zero. Setting to fake values for device #%d\n", sDeviceIndex ));
                    }
                    else
                    {
	                    deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
                    }
                }
                else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )
                {
                    /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000.
                    ** But we know that they really support a range of rates!
                    ** So when we see a ridiculous set of rates, assume it is a range.
                    */
                  deviceInfo->defaultSampleRate = 44100.0f;
                  DBUG(("PA - Sample rate range used instead of two odd values for device #%d\n", sDeviceIndex ));
                }
                else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;


                //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 */

/*  constants from a WINE patch by Francois Gouget, see:
    http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html

    ---
    Date: Fri, 14 May 2004 10:38:12 +0200 (CEST)
    From: Francois Gouget <fgouget@ ... .fr>
    To: Ross Bencina <rbencina@ ... .au>
    Subject: Re: Permission to use wine 48/96 wave patch in BSD licensed library

    [snip]

    I give you permission to use the patch below under the BSD license.
    http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html

    [snip]
*/
#ifndef WAVE_FORMAT_48M08
#define WAVE_FORMAT_48M08      0x00001000    /* 48     kHz, Mono,   8-bit  */
#define WAVE_FORMAT_48S08      0x00002000    /* 48     kHz, Stereo, 8-bit  */
#define WAVE_FORMAT_48M16      0x00004000    /* 48     kHz, Mono,   16-bit */
#define WAVE_FORMAT_48S16      0x00008000    /* 48     kHz, Stereo, 16-bit */
#define WAVE_FORMAT_96M08      0x00010000    /* 96     kHz, Mono,   8-bit  */
#define WAVE_FORMAT_96S08      0x00020000    /* 96     kHz, Stereo, 8-bit  */
#define WAVE_FORMAT_96M16      0x00040000    /* 96     kHz, Mono,   16-bit */
#define WAVE_FORMAT_96S16      0x00080000    /* 96     kHz, Stereo, 16-bit */
#endif

                /* defaultSampleRate */
                if( caps.dwChannels == 2 )
                {
                    if( caps.dwFormats & WAVE_FORMAT_4S16 )
                        deviceInfo->defaultSampleRate = 44100.0;
                    else if( caps.dwFormats & WAVE_FORMAT_48S16 )
                        deviceInfo->defaultSampleRate = 48000.0;
                    else if( caps.dwFormats & WAVE_FORMAT_2S16 )
                        deviceInfo->defaultSampleRate = 22050.0;
                    else if( caps.dwFormats & WAVE_FORMAT_1S16 )
                        deviceInfo->defaultSampleRate = 11025.0;
                    else if( caps.dwFormats & WAVE_FORMAT_96S16 )
                        deviceInfo->defaultSampleRate = 96000.0;
                    else
                        deviceInfo->defaultSampleRate = 0.;
                }
                else if( caps.dwChannels == 1 )
                {
                    if( caps.dwFormats & WAVE_FORMAT_4M16 )
                        deviceInfo->defaultSampleRate = 44100.0;
                    else if( caps.dwFormats & WAVE_FORMAT_48M16 )
                        deviceInfo->defaultSampleRate = 48000.0;
                    else if( caps.dwFormats & WAVE_FORMAT_2M16 )
                        deviceInfo->defaultSampleRate = 22050.0;
                    else if( caps.dwFormats & WAVE_FORMAT_1M16 )
                        deviceInfo->defaultSampleRate = 11025.0;
                    else if( caps.dwFormats & WAVE_FORMAT_96M16 )
                        deviceInfo->defaultSampleRate = 96000.0;
                    else
                        deviceInfo->defaultSampleRate = 0.;
                }
                else deviceInfo->defaultSampleRate = 0.;
            }
        }
        
        IDirectSoundCapture_Release( lpDirectSoundCapture );
    }

    if( deviceOK )
    {
        deviceInfo->name = name;

        if( lpGUID == NULL )
            hostApi->info.defaultInputDevice = hostApi->info.deviceCount;

        hostApi->info.deviceCount++;
    }

    return result;
}


/***********************************************************************************/

⌨️ 快捷键说明

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