📄 pa_win_ds.c
字号:
{
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 + -