Clean up whitespace in src\hostapi\dsound in preparation for .editorconfig. Convert tabs to 4 spaces. Indent by 4 spaces. Strip trailing whitespace. Ensure EOL at EOF. (#412)
This commit is contained in:
parent
238d8db31a
commit
fd4cebf2cb
3 changed files with 137 additions and 137 deletions
|
|
@ -27,13 +27,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
* The text above constitutes the entire PortAudio license; however,
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
* the PortAudio community also makes the following non-binding requests:
|
||||||
*
|
*
|
||||||
* Any person wishing to distribute modifications to the Software is
|
* Any person wishing to distribute modifications to the Software is
|
||||||
* requested to send the modifications to the original developer so that
|
* requested to send the modifications to the original developer so that
|
||||||
* they can be incorporated into the canonical version. It is also
|
* they can be incorporated into the canonical version. It is also
|
||||||
* requested that these non-binding requests be included along with the
|
* requested that these non-binding requests be included along with the
|
||||||
* license above.
|
* license above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -278,7 +278,7 @@ typedef struct PaWinDsStream
|
||||||
UINT readOffset; /* last read position */
|
UINT readOffset; /* last read position */
|
||||||
UINT inputBufferSizeBytes;
|
UINT inputBufferSizeBytes;
|
||||||
|
|
||||||
|
|
||||||
int hostBufferSizeFrames; /* input and output host ringbuffers have the same number of frames */
|
int hostBufferSizeFrames; /* input and output host ringbuffers have the same number of frames */
|
||||||
double framesWritten;
|
double framesWritten;
|
||||||
double secondsPerHostByte; /* Used to optimize latency calculation for outTime */
|
double secondsPerHostByte; /* Used to optimize latency calculation for outTime */
|
||||||
|
|
@ -289,14 +289,14 @@ typedef struct PaWinDsStream
|
||||||
PaStreamFlags streamFlags;
|
PaStreamFlags streamFlags;
|
||||||
int callbackResult;
|
int callbackResult;
|
||||||
HANDLE processingCompleted;
|
HANDLE processingCompleted;
|
||||||
|
|
||||||
/* FIXME - move all below to PaUtilStreamRepresentation */
|
/* FIXME - move all below to PaUtilStreamRepresentation */
|
||||||
volatile int isStarted;
|
volatile int isStarted;
|
||||||
volatile int isActive;
|
volatile int isActive;
|
||||||
volatile int stopProcessing; /* stop thread once existing buffers have been returned */
|
volatile int stopProcessing; /* stop thread once existing buffers have been returned */
|
||||||
volatile int abortProcessing; /* stop thread immediately */
|
volatile int abortProcessing; /* stop thread immediately */
|
||||||
|
|
||||||
UINT systemTimerResolutionPeriodMs; /* set to 0 if we were unable to set the timer period */
|
UINT systemTimerResolutionPeriodMs; /* set to 0 if we were unable to set the timer period */
|
||||||
|
|
||||||
#ifdef PA_WIN_DS_USE_WMME_TIMER
|
#ifdef PA_WIN_DS_USE_WMME_TIMER
|
||||||
MMRESULT timerID;
|
MMRESULT timerID;
|
||||||
|
|
@ -361,7 +361,7 @@ See: http://www.codeproject.com/Articles/678606/Part-Overcoming-Windows-s-deprec
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
** Return minimum workable latency required for this host. This is returned
|
** Return minimum workable latency required for this host. This is returned
|
||||||
** As the default stream latency in PaDeviceInfo.
|
** As the default stream latency in PaDeviceInfo.
|
||||||
** Latency can be optionally set by user by setting an environment variable.
|
** Latency can be optionally set by user by setting an environment variable.
|
||||||
** For example, to set latency to 200 msec, put:
|
** For example, to set latency to 200 msec, put:
|
||||||
**
|
**
|
||||||
** set PA_MIN_LATENCY_MSEC=200
|
** set PA_MIN_LATENCY_MSEC=200
|
||||||
|
|
@ -405,7 +405,7 @@ static double PaWinDs_GetMinLatencySeconds( double sampleRate )
|
||||||
static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const wchar_t* src )
|
static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const wchar_t* src )
|
||||||
{
|
{
|
||||||
char *result = 0;
|
char *result = 0;
|
||||||
|
|
||||||
if( src != NULL )
|
if( src != NULL )
|
||||||
{
|
{
|
||||||
size_t len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
|
size_t len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
|
||||||
|
|
@ -466,7 +466,7 @@ static PaError InitializeDSDeviceNameAndGUIDVector(
|
||||||
guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free );
|
guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free );
|
||||||
if( guidVector->items == NULL )
|
if( guidVector->items == NULL )
|
||||||
result = paInsufficientMemory;
|
result = paInsufficientMemory;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,7 +475,7 @@ static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidV
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
DSDeviceNameAndGUID *newItems;
|
DSDeviceNameAndGUID *newItems;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* double size of vector */
|
/* double size of vector */
|
||||||
int size = guidVector->count + guidVector->free;
|
int size = guidVector->count + guidVector->free;
|
||||||
guidVector->free += size;
|
guidVector->free += size;
|
||||||
|
|
@ -504,7 +504,7 @@ static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidV
|
||||||
|
|
||||||
LocalFree( guidVector->items );
|
LocalFree( guidVector->items );
|
||||||
guidVector->items = newItems;
|
guidVector->items = newItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -528,7 +528,7 @@ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *gu
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
** Collect preliminary device information during DirectSound enumeration
|
** Collect preliminary device information during DirectSound enumeration
|
||||||
*/
|
*/
|
||||||
static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
||||||
LPCWSTR lpszDesc,
|
LPCWSTR lpszDesc,
|
||||||
|
|
@ -549,7 +549,7 @@ static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */
|
/* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */
|
||||||
if( lpGUID == NULL )
|
if( lpGUID == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -559,7 +559,7 @@ static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
||||||
{
|
{
|
||||||
namesAndGUIDs->items[namesAndGUIDs->count].lpGUID =
|
namesAndGUIDs->items[namesAndGUIDs->count].lpGUID =
|
||||||
&namesAndGUIDs->items[namesAndGUIDs->count].guid;
|
&namesAndGUIDs->items[namesAndGUIDs->count].guid;
|
||||||
|
|
||||||
memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) );
|
memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -575,7 +575,7 @@ static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
||||||
|
|
||||||
++namesAndGUIDs->count;
|
++namesAndGUIDs->count;
|
||||||
--namesAndGUIDs->free;
|
--namesAndGUIDs->free;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -599,7 +599,7 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
||||||
DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context;
|
DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Apparently data->Interface can be NULL in some cases.
|
Apparently data->Interface can be NULL in some cases.
|
||||||
Possibly virtual devices without hardware.
|
Possibly virtual devices without hardware.
|
||||||
So we check for NULLs now. See mailing list message November 10, 2012:
|
So we check for NULLs now. See mailing list message November 10, 2012:
|
||||||
"[Portaudio] portaudio initialization crash in KsPropertySetEnumerateCallback(pa_win_ds.c)"
|
"[Portaudio] portaudio initialization crash in KsPropertySetEnumerateCallback(pa_win_ds.c)"
|
||||||
|
|
@ -613,7 +613,7 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
||||||
if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID
|
if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID
|
||||||
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
||||||
{
|
{
|
||||||
deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface =
|
deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface =
|
||||||
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
|
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -626,7 +626,7 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
||||||
if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID
|
if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID
|
||||||
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
||||||
{
|
{
|
||||||
deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface =
|
deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface =
|
||||||
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
|
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -638,13 +638,13 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static GUID pawin_CLSID_DirectSoundPrivate =
|
static GUID pawin_CLSID_DirectSoundPrivate =
|
||||||
{ 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca };
|
{ 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca };
|
||||||
|
|
||||||
static GUID pawin_DSPROPSETID_DirectSoundDevice =
|
static GUID pawin_DSPROPSETID_DirectSoundDevice =
|
||||||
{ 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca };
|
{ 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x00, 0xc0, 0x4f, 0xc2, 0x8a, 0xca };
|
||||||
|
|
||||||
static GUID pawin_IID_IKsPropertySet =
|
static GUID pawin_IID_IKsPropertySet =
|
||||||
{ 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93 };
|
{ 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93 };
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -652,17 +652,17 @@ static GUID pawin_IID_IKsPropertySet =
|
||||||
FindDevicePnpInterfaces fills in the pnpInterface fields in deviceNamesAndGUIDs
|
FindDevicePnpInterfaces fills in the pnpInterface fields in deviceNamesAndGUIDs
|
||||||
with UNICODE file paths to the devices. The DS documentation mentions
|
with UNICODE file paths to the devices. The DS documentation mentions
|
||||||
at least two techniques by which these Interface paths can be found using IKsPropertySet on
|
at least two techniques by which these Interface paths can be found using IKsPropertySet on
|
||||||
the DirectSound class object. One is using the DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION
|
the DirectSound class object. One is using the DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION
|
||||||
property, and the other is using DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE.
|
property, and the other is using DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE.
|
||||||
I tried both methods and only the second worked. I found two postings on the
|
I tried both methods and only the second worked. I found two postings on the
|
||||||
net from people who had the same problem with the first method, so I think the method used here is
|
net from people who had the same problem with the first method, so I think the method used here is
|
||||||
more common/likely to work. The problem is that IKsPropertySet_Get returns S_OK
|
more common/likely to work. The problem is that IKsPropertySet_Get returns S_OK
|
||||||
but the fields of the device description are not filled in.
|
but the fields of the device description are not filled in.
|
||||||
|
|
||||||
The mechanism we use works by registering an enumeration callback which is called for
|
The mechanism we use works by registering an enumeration callback which is called for
|
||||||
every DSound device. Our callback searches for a device in our deviceNamesAndGUIDs list
|
every DSound device. Our callback searches for a device in our deviceNamesAndGUIDs list
|
||||||
with the matching GUID and copies the pointer to the Interface path.
|
with the matching GUID and copies the pointer to the Interface path.
|
||||||
Note that we could have used this enumeration callback to perform the original
|
Note that we could have used this enumeration callback to perform the original
|
||||||
device enumeration, however we choose not to so we can disable this step easily.
|
device enumeration, however we choose not to so we can disable this step easily.
|
||||||
|
|
||||||
Apparently the IKsPropertySet mechanism was added in DirectSound 9c 2004
|
Apparently the IKsPropertySet mechanism was added in DirectSound 9c 2004
|
||||||
|
|
@ -673,11 +673,11 @@ static GUID pawin_IID_IKsPropertySet =
|
||||||
static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs )
|
static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs )
|
||||||
{
|
{
|
||||||
IClassFactory *pClassFactory;
|
IClassFactory *pClassFactory;
|
||||||
|
|
||||||
if( paWinDsDSoundEntryPoints.DllGetClassObject(&pawin_CLSID_DirectSoundPrivate, &IID_IClassFactory, (PVOID *) &pClassFactory) == S_OK ){
|
if( paWinDsDSoundEntryPoints.DllGetClassObject(&pawin_CLSID_DirectSoundPrivate, &IID_IClassFactory, (PVOID *) &pClassFactory) == S_OK ){
|
||||||
IKsPropertySet *pPropertySet;
|
IKsPropertySet *pPropertySet;
|
||||||
if( pClassFactory->lpVtbl->CreateInstance( pClassFactory, NULL, &pawin_IID_IKsPropertySet, (PVOID *) &pPropertySet) == S_OK ){
|
if( pClassFactory->lpVtbl->CreateInstance( pClassFactory, NULL, &pawin_IID_IKsPropertySet, (PVOID *) &pPropertySet) == S_OK ){
|
||||||
|
|
||||||
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
|
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
|
||||||
ULONG bytesReturned;
|
ULONG bytesReturned;
|
||||||
|
|
||||||
|
|
@ -693,14 +693,14 @@ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs
|
||||||
sizeof(data),
|
sizeof(data),
|
||||||
&bytesReturned
|
&bytesReturned
|
||||||
);
|
);
|
||||||
|
|
||||||
IKsPropertySet_Release( pPropertySet );
|
IKsPropertySet_Release( pPropertySet );
|
||||||
}
|
}
|
||||||
pClassFactory->lpVtbl->Release( pClassFactory );
|
pClassFactory->lpVtbl->Release( pClassFactory );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The following code fragment, which I chose not to use, queries for the
|
The following code fragment, which I chose not to use, queries for the
|
||||||
device interface for a device with a specific GUID:
|
device interface for a device with a specific GUID:
|
||||||
|
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
|
|
@ -708,7 +708,7 @@ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs
|
||||||
|
|
||||||
memset (&Property, 0, sizeof(Property));
|
memset (&Property, 0, sizeof(Property));
|
||||||
Property.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
|
Property.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
|
||||||
Property.DeviceId = *lpGUID;
|
Property.DeviceId = *lpGUID;
|
||||||
|
|
||||||
hr = IKsPropertySet_Get( pPropertySet,
|
hr = IKsPropertySet_Get( pPropertySet,
|
||||||
&pawin_DSPROPSETID_DirectSoundDevice,
|
&pawin_DSPROPSETID_DirectSoundDevice,
|
||||||
|
|
@ -729,7 +729,7 @@ static void FindDevicePnpInterfaces( DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs
|
||||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GUIDs for emulated devices which we blacklist below.
|
GUIDs for emulated devices which we blacklist below.
|
||||||
are there more than two of them??
|
are there more than two of them??
|
||||||
*/
|
*/
|
||||||
|
|
@ -773,7 +773,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
|
memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
|
||||||
winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
|
winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( lpGUID )
|
if( lpGUID )
|
||||||
{
|
{
|
||||||
if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) ||
|
if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) ||
|
||||||
|
|
@ -804,7 +804,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
hr = IDirectSound_Initialize( lpDirectSound, lpGUID );
|
hr = IDirectSound_Initialize( lpDirectSound, lpGUID );
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( hr != DS_OK )
|
if( hr != DS_OK )
|
||||||
{
|
{
|
||||||
if (hr == DSERR_ALLOCATED)
|
if (hr == DSERR_ALLOCATED)
|
||||||
|
|
@ -830,7 +830,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Query device characteristics. */
|
/* Query device characteristics. */
|
||||||
memset( &caps, 0, sizeof(caps) );
|
memset( &caps, 0, sizeof(caps) );
|
||||||
caps.dwSize = sizeof(caps);
|
caps.dwSize = sizeof(caps);
|
||||||
hr = IDirectSound_GetCaps( lpDirectSound, &caps );
|
hr = IDirectSound_GetCaps( lpDirectSound, &caps );
|
||||||
if( hr != DS_OK )
|
if( hr != DS_OK )
|
||||||
|
|
@ -861,7 +861,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
set deviceOutputChannelCountIsKnown to 0 (unknown).
|
set deviceOutputChannelCountIsKnown to 0 (unknown).
|
||||||
In this case OpenStream will try to open the device
|
In this case OpenStream will try to open the device
|
||||||
when the user requests more than 2 channels, rather than
|
when the user requests more than 2 channels, rather than
|
||||||
returning an error.
|
returning an error.
|
||||||
*/
|
*/
|
||||||
if( caps.dwFlags & DSCAPS_PRIMARYSTEREO )
|
if( caps.dwFlags & DSCAPS_PRIMARYSTEREO )
|
||||||
{
|
{
|
||||||
|
|
@ -874,7 +874,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1;
|
winDsDeviceInfo->deviceOutputChannelCountIsKnown = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Guess channels count from speaker configuration. We do it only when
|
/* Guess channels count from speaker configuration. We do it only when
|
||||||
pnpInterface is NULL or when PAWIN_USE_WDMKS_DEVICE_INFO is undefined.
|
pnpInterface is NULL or when PAWIN_USE_WDMKS_DEVICE_INFO is undefined.
|
||||||
*/
|
*/
|
||||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
||||||
|
|
@ -899,7 +899,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
case DSSPEAKER_7POINT1: count = 8; break;
|
case DSSPEAKER_7POINT1: count = 8; break;
|
||||||
#ifndef DSSPEAKER_7POINT1_SURROUND
|
#ifndef DSSPEAKER_7POINT1_SURROUND
|
||||||
#define DSSPEAKER_7POINT1_SURROUND 0x00000008
|
#define DSSPEAKER_7POINT1_SURROUND 0x00000008
|
||||||
#endif
|
#endif
|
||||||
case DSSPEAKER_7POINT1_SURROUND: count = 8; break;
|
case DSSPEAKER_7POINT1_SURROUND: count = 8; break;
|
||||||
#ifndef DSSPEAKER_5POINT1_SURROUND
|
#ifndef DSSPEAKER_5POINT1_SURROUND
|
||||||
#define DSSPEAKER_5POINT1_SURROUND 0x00000009
|
#define DSSPEAKER_5POINT1_SURROUND 0x00000009
|
||||||
|
|
@ -927,7 +927,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
||||||
|
|
||||||
/* initialize defaultSampleRate */
|
/* initialize defaultSampleRate */
|
||||||
|
|
||||||
if( caps.dwFlags & DSCAPS_CONTINUOUSRATE )
|
if( caps.dwFlags & DSCAPS_CONTINUOUSRATE )
|
||||||
{
|
{
|
||||||
/* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */
|
/* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */
|
||||||
|
|
@ -973,7 +973,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
|
else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
|
||||||
|
|
||||||
//printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate );
|
//printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate );
|
||||||
// dwFlags | DSCAPS_CONTINUOUSRATE
|
// dwFlags | DSCAPS_CONTINUOUSRATE
|
||||||
|
|
||||||
deviceInfo->defaultLowInputLatency = 0.;
|
deviceInfo->defaultLowInputLatency = 0.;
|
||||||
deviceInfo->defaultHighInputLatency = 0.;
|
deviceInfo->defaultHighInputLatency = 0.;
|
||||||
|
|
@ -992,7 +992,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
||||||
|
|
||||||
if( lpGUID == NULL )
|
if( lpGUID == NULL )
|
||||||
hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
|
hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
|
||||||
|
|
||||||
hostApi->info.deviceCount++;
|
hostApi->info.deviceCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1018,7 +1018,7 @@ static PaError AddInputDeviceInfoFromDirectSoundCapture(
|
||||||
DSCCAPS caps;
|
DSCCAPS caps;
|
||||||
int deviceOK = TRUE;
|
int deviceOK = TRUE;
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
|
|
||||||
/* Copy GUID to the device info structure. Set pointer. */
|
/* Copy GUID to the device info structure. Set pointer. */
|
||||||
if( lpGUID == NULL )
|
if( lpGUID == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -1150,12 +1150,12 @@ static PaError AddInputDeviceInfoFromDirectSoundCapture(
|
||||||
|
|
||||||
deviceInfo->defaultLowInputLatency = PaWinDs_GetMinLatencySeconds( deviceInfo->defaultSampleRate );
|
deviceInfo->defaultLowInputLatency = PaWinDs_GetMinLatencySeconds( deviceInfo->defaultSampleRate );
|
||||||
deviceInfo->defaultHighInputLatency = deviceInfo->defaultLowInputLatency * 2;
|
deviceInfo->defaultHighInputLatency = deviceInfo->defaultLowInputLatency * 2;
|
||||||
|
|
||||||
deviceInfo->defaultLowOutputLatency = 0.;
|
deviceInfo->defaultLowOutputLatency = 0.;
|
||||||
deviceInfo->defaultHighOutputLatency = 0.;
|
deviceInfo->defaultHighOutputLatency = 0.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirectSoundCapture_Release( lpDirectSoundCapture );
|
IDirectSoundCapture_Release( lpDirectSoundCapture );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1215,12 +1215,12 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
||||||
(*hostApi)->info.structVersion = 1;
|
(*hostApi)->info.structVersion = 1;
|
||||||
(*hostApi)->info.type = paDirectSound;
|
(*hostApi)->info.type = paDirectSound;
|
||||||
(*hostApi)->info.name = "Windows DirectSound";
|
(*hostApi)->info.name = "Windows DirectSound";
|
||||||
|
|
||||||
(*hostApi)->info.deviceCount = 0;
|
(*hostApi)->info.deviceCount = 0;
|
||||||
(*hostApi)->info.defaultInputDevice = paNoDevice;
|
(*hostApi)->info.defaultInputDevice = paNoDevice;
|
||||||
(*hostApi)->info.defaultOutputDevice = paNoDevice;
|
(*hostApi)->info.defaultOutputDevice = paNoDevice;
|
||||||
|
|
||||||
|
|
||||||
/* DSound - enumerate devices to count them and to gather their GUIDs */
|
/* DSound - enumerate devices to count them and to gather their GUIDs */
|
||||||
|
|
||||||
result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs, winDsHostApi->allocations );
|
result = InitializeDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs, winDsHostApi->allocations );
|
||||||
|
|
@ -1305,7 +1305,7 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
||||||
if( result != paNoError )
|
if( result != paNoError )
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
result = TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||||
if( result != paNoError )
|
if( result != paNoError )
|
||||||
|
|
@ -1315,7 +1315,7 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
||||||
if( result != paNoError )
|
if( result != paNoError )
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
|
||||||
(*hostApi)->Terminate = Terminate;
|
(*hostApi)->Terminate = Terminate;
|
||||||
(*hostApi)->OpenStream = OpenStream;
|
(*hostApi)->OpenStream = OpenStream;
|
||||||
(*hostApi)->IsFormatSupported = IsFormatSupported;
|
(*hostApi)->IsFormatSupported = IsFormatSupported;
|
||||||
|
|
@ -1435,7 +1435,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
|
||||||
outputChannelCount = outputParameters->channelCount;
|
outputChannelCount = outputParameters->channelCount;
|
||||||
outputSampleFormat = outputParameters->sampleFormat;
|
outputSampleFormat = outputParameters->sampleFormat;
|
||||||
|
|
||||||
/* unless alternate device specification is supported, reject the use of
|
/* unless alternate device specification is supported, reject the use of
|
||||||
paUseHostApiSpecificDeviceSpecification */
|
paUseHostApiSpecificDeviceSpecification */
|
||||||
|
|
||||||
|
|
@ -1456,7 +1456,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
{
|
{
|
||||||
outputChannelCount = 0;
|
outputChannelCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
IMPLEMENT ME:
|
IMPLEMENT ME:
|
||||||
|
|
||||||
|
|
@ -1486,12 +1486,12 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
PaWinDsDeviceInfo *inputDevice,
|
PaWinDsDeviceInfo *inputDevice,
|
||||||
PaSampleFormat hostInputSampleFormat,
|
PaSampleFormat hostInputSampleFormat,
|
||||||
WORD inputChannelCount,
|
WORD inputChannelCount,
|
||||||
int bytesPerInputBuffer,
|
int bytesPerInputBuffer,
|
||||||
PaWinWaveFormatChannelMask inputChannelMask,
|
PaWinWaveFormatChannelMask inputChannelMask,
|
||||||
PaWinDsDeviceInfo *outputDevice,
|
PaWinDsDeviceInfo *outputDevice,
|
||||||
PaSampleFormat hostOutputSampleFormat,
|
PaSampleFormat hostOutputSampleFormat,
|
||||||
WORD outputChannelCount,
|
WORD outputChannelCount,
|
||||||
int bytesPerOutputBuffer,
|
int bytesPerOutputBuffer,
|
||||||
PaWinWaveFormatChannelMask outputChannelMask,
|
PaWinWaveFormatChannelMask outputChannelMask,
|
||||||
unsigned long nFrameRate
|
unsigned long nFrameRate
|
||||||
|
|
@ -1508,7 +1508,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
// capture buffer description
|
// capture buffer description
|
||||||
|
|
||||||
// only try wave format extensible. assume it's available on all ds 8 systems
|
// only try wave format extensible. assume it's available on all ds 8 systems
|
||||||
PaWin_InitializeWaveFormatExtensible( &captureWaveFormat, inputChannelCount,
|
PaWin_InitializeWaveFormatExtensible( &captureWaveFormat, inputChannelCount,
|
||||||
hostInputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostInputSampleFormat ),
|
hostInputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostInputSampleFormat ),
|
||||||
nFrameRate, inputChannelMask );
|
nFrameRate, inputChannelMask );
|
||||||
|
|
||||||
|
|
@ -1520,7 +1520,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
|
|
||||||
// render buffer description
|
// render buffer description
|
||||||
|
|
||||||
PaWin_InitializeWaveFormatExtensible( &renderWaveFormat, outputChannelCount,
|
PaWin_InitializeWaveFormatExtensible( &renderWaveFormat, outputChannelCount,
|
||||||
hostOutputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostOutputSampleFormat ),
|
hostOutputSampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( hostOutputSampleFormat ),
|
||||||
nFrameRate, outputChannelMask );
|
nFrameRate, outputChannelMask );
|
||||||
|
|
||||||
|
|
@ -1532,7 +1532,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
|
|
||||||
/* note that we don't create a primary buffer here at all */
|
/* note that we don't create a primary buffer here at all */
|
||||||
|
|
||||||
hr = paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8(
|
hr = paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8(
|
||||||
inputDevice->lpGUID, outputDevice->lpGUID,
|
inputDevice->lpGUID, outputDevice->lpGUID,
|
||||||
&captureDesc, &secondaryRenderDesc,
|
&captureDesc, &secondaryRenderDesc,
|
||||||
GetDesktopWindow(), /* see InitOutputBuffer() for a discussion of whether this is a good idea */
|
GetDesktopWindow(), /* see InitOutputBuffer() for a discussion of whether this is a good idea */
|
||||||
|
|
@ -1540,7 +1540,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
&stream->pDirectSoundFullDuplex8,
|
&stream->pDirectSoundFullDuplex8,
|
||||||
&pCaptureBuffer8,
|
&pCaptureBuffer8,
|
||||||
&pRenderBuffer8,
|
&pRenderBuffer8,
|
||||||
NULL /* pUnkOuter must be NULL */
|
NULL /* pUnkOuter must be NULL */
|
||||||
);
|
);
|
||||||
|
|
||||||
if( hr == DS_OK )
|
if( hr == DS_OK )
|
||||||
|
|
@ -1550,7 +1550,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
/* retrieve the pre ds 8 buffer interfaces which are used by the rest of the code */
|
/* retrieve the pre ds 8 buffer interfaces which are used by the rest of the code */
|
||||||
|
|
||||||
hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, (LPVOID *)&stream->pDirectSoundInputBuffer );
|
hr = IUnknown_QueryInterface( pCaptureBuffer8, &IID_IDirectSoundCaptureBuffer, (LPVOID *)&stream->pDirectSoundInputBuffer );
|
||||||
|
|
||||||
if( hr == DS_OK )
|
if( hr == DS_OK )
|
||||||
hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, (LPVOID *)&stream->pDirectSoundOutputBuffer );
|
hr = IUnknown_QueryInterface( pRenderBuffer8, &IID_IDirectSoundBuffer, (LPVOID *)&stream->pDirectSoundOutputBuffer );
|
||||||
|
|
||||||
|
|
@ -1571,7 +1571,7 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
IUnknown_Release( stream->pDirectSoundOutputBuffer );
|
IUnknown_Release( stream->pDirectSoundOutputBuffer );
|
||||||
stream->pDirectSoundOutputBuffer = NULL;
|
stream->pDirectSoundOutputBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IUnknown_Release( stream->pDirectSoundFullDuplex8 );
|
IUnknown_Release( stream->pDirectSoundFullDuplex8 );
|
||||||
stream->pDirectSoundFullDuplex8 = NULL;
|
stream->pDirectSoundFullDuplex8 = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -1586,22 +1586,22 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
||||||
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
|
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
|
||||||
|
|
||||||
|
|
||||||
static HRESULT InitInputBuffer( PaWinDsStream *stream,
|
static HRESULT InitInputBuffer( PaWinDsStream *stream,
|
||||||
PaWinDsDeviceInfo *device,
|
PaWinDsDeviceInfo *device,
|
||||||
PaSampleFormat sampleFormat,
|
PaSampleFormat sampleFormat,
|
||||||
unsigned long nFrameRate,
|
unsigned long nFrameRate,
|
||||||
WORD nChannels,
|
WORD nChannels,
|
||||||
int bytesPerBuffer,
|
int bytesPerBuffer,
|
||||||
PaWinWaveFormatChannelMask channelMask )
|
PaWinWaveFormatChannelMask channelMask )
|
||||||
{
|
{
|
||||||
DSCBUFFERDESC captureDesc;
|
DSCBUFFERDESC captureDesc;
|
||||||
PaWinWaveFormat waveFormat;
|
PaWinWaveFormat waveFormat;
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
||||||
if( (result = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate(
|
if( (result = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate(
|
||||||
device->lpGUID, &stream->pDirectSoundCapture, NULL) ) != DS_OK ){
|
device->lpGUID, &stream->pDirectSoundCapture, NULL) ) != DS_OK ){
|
||||||
ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));
|
ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the secondary buffer description
|
// Setup the secondary buffer description
|
||||||
|
|
@ -1610,18 +1610,18 @@ static HRESULT InitInputBuffer( PaWinDsStream *stream,
|
||||||
captureDesc.dwFlags = 0;
|
captureDesc.dwFlags = 0;
|
||||||
captureDesc.dwBufferBytes = bytesPerBuffer;
|
captureDesc.dwBufferBytes = bytesPerBuffer;
|
||||||
captureDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat;
|
captureDesc.lpwfxFormat = (WAVEFORMATEX*)&waveFormat;
|
||||||
|
|
||||||
// Create the capture buffer
|
// Create the capture buffer
|
||||||
|
|
||||||
// first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX
|
// first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX
|
||||||
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
|
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
|
||||||
sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ),
|
sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ),
|
||||||
nFrameRate, channelMask );
|
nFrameRate, channelMask );
|
||||||
|
|
||||||
if( IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
|
if( IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
|
||||||
&captureDesc, &stream->pDirectSoundInputBuffer, NULL) != DS_OK )
|
&captureDesc, &stream->pDirectSoundInputBuffer, NULL) != DS_OK )
|
||||||
{
|
{
|
||||||
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
|
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
|
||||||
PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate );
|
PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate );
|
||||||
|
|
||||||
if ((result = IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
|
if ((result = IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
|
||||||
|
|
@ -1633,9 +1633,9 @@ static HRESULT InitInputBuffer( PaWinDsStream *stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device,
|
static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device,
|
||||||
PaSampleFormat sampleFormat, unsigned long nFrameRate,
|
PaSampleFormat sampleFormat, unsigned long nFrameRate,
|
||||||
WORD nChannels, int bytesPerBuffer,
|
WORD nChannels, int bytesPerBuffer,
|
||||||
PaWinWaveFormatChannelMask channelMask )
|
PaWinWaveFormatChannelMask channelMask )
|
||||||
{
|
{
|
||||||
HRESULT result;
|
HRESULT result;
|
||||||
|
|
@ -1644,8 +1644,8 @@ static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *devic
|
||||||
PaWinWaveFormat waveFormat;
|
PaWinWaveFormat waveFormat;
|
||||||
DSBUFFERDESC primaryDesc;
|
DSBUFFERDESC primaryDesc;
|
||||||
DSBUFFERDESC secondaryDesc;
|
DSBUFFERDESC secondaryDesc;
|
||||||
|
|
||||||
if( (hr = paWinDsDSoundEntryPoints.DirectSoundCreate(
|
if( (hr = paWinDsDSoundEntryPoints.DirectSoundCreate(
|
||||||
device->lpGUID, &stream->pDirectSound, NULL )) != DS_OK ){
|
device->lpGUID, &stream->pDirectSound, NULL )) != DS_OK ){
|
||||||
ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));
|
ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));
|
||||||
return hr;
|
return hr;
|
||||||
|
|
@ -1688,13 +1688,13 @@ static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *devic
|
||||||
// Set the primary buffer's format
|
// Set the primary buffer's format
|
||||||
|
|
||||||
// first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX
|
// first try WAVEFORMATEXTENSIBLE. if this fails, fall back to WAVEFORMATEX
|
||||||
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
|
PaWin_InitializeWaveFormatExtensible( &waveFormat, nChannels,
|
||||||
sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ),
|
sampleFormat, PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ),
|
||||||
nFrameRate, channelMask );
|
nFrameRate, channelMask );
|
||||||
|
|
||||||
if( IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat) != DS_OK )
|
if( IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat) != DS_OK )
|
||||||
{
|
{
|
||||||
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
|
PaWin_InitializeWaveFormatEx( &waveFormat, nChannels, sampleFormat,
|
||||||
PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate );
|
PaWin_SampleFormatToLinearWaveFormatTag( sampleFormat ), nFrameRate );
|
||||||
|
|
||||||
if((result = IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat)) != DS_OK)
|
if((result = IDirectSoundBuffer_SetFormat( stream->pDirectSoundPrimaryBuffer, (WAVEFORMATEX*)&waveFormat)) != DS_OK)
|
||||||
|
|
@ -1711,8 +1711,8 @@ static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *devic
|
||||||
// Create the secondary buffer
|
// Create the secondary buffer
|
||||||
if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound,
|
if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound,
|
||||||
&secondaryDesc, &stream->pDirectSoundOutputBuffer, NULL)) != DS_OK)
|
&secondaryDesc, &stream->pDirectSoundOutputBuffer, NULL)) != DS_OK)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|
@ -1727,7 +1727,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
||||||
unsigned long *pollingPeriodFrames,
|
unsigned long *pollingPeriodFrames,
|
||||||
int isFullDuplex,
|
int isFullDuplex,
|
||||||
unsigned long suggestedInputLatencyFrames,
|
unsigned long suggestedInputLatencyFrames,
|
||||||
|
|
@ -1737,7 +1737,7 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
||||||
unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS);
|
unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS);
|
||||||
unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS);
|
unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS);
|
||||||
unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS);
|
unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS);
|
||||||
|
|
||||||
if( userFramesPerBuffer == paFramesPerBufferUnspecified )
|
if( userFramesPerBuffer == paFramesPerBufferUnspecified )
|
||||||
{
|
{
|
||||||
unsigned long targetBufferingLatencyFrames = max( suggestedInputLatencyFrames, suggestedOutputLatencyFrames );
|
unsigned long targetBufferingLatencyFrames = max( suggestedInputLatencyFrames, suggestedOutputLatencyFrames );
|
||||||
|
|
@ -1752,7 +1752,7 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
||||||
*pollingPeriodFrames = maximumPollingPeriodFrames;
|
*pollingPeriodFrames = maximumPollingPeriodFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
*hostBufferSizeFrames = *pollingPeriodFrames
|
*hostBufferSizeFrames = *pollingPeriodFrames
|
||||||
+ max( *pollingPeriodFrames + pollingJitterFrames, targetBufferingLatencyFrames);
|
+ max( *pollingPeriodFrames + pollingJitterFrames, targetBufferingLatencyFrames);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1763,14 +1763,14 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
||||||
/* In full duplex streams we know that the buffer adapter adds userFramesPerBuffer
|
/* In full duplex streams we know that the buffer adapter adds userFramesPerBuffer
|
||||||
extra fixed latency. so we subtract it here as a fixed latency before computing
|
extra fixed latency. so we subtract it here as a fixed latency before computing
|
||||||
the buffer size. being careful not to produce an unrepresentable negative result.
|
the buffer size. being careful not to produce an unrepresentable negative result.
|
||||||
|
|
||||||
Note: this only works as expected if output latency is greater than input latency.
|
Note: this only works as expected if output latency is greater than input latency.
|
||||||
Otherwise we use input latency anyway since we do max(in,out).
|
Otherwise we use input latency anyway since we do max(in,out).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( userFramesPerBuffer < suggestedOutputLatencyFrames )
|
if( userFramesPerBuffer < suggestedOutputLatencyFrames )
|
||||||
{
|
{
|
||||||
unsigned long adjustedSuggestedOutputLatencyFrames =
|
unsigned long adjustedSuggestedOutputLatencyFrames =
|
||||||
suggestedOutputLatencyFrames - userFramesPerBuffer;
|
suggestedOutputLatencyFrames - userFramesPerBuffer;
|
||||||
|
|
||||||
/* maximum of input and adjusted output suggested latency */
|
/* maximum of input and adjusted output suggested latency */
|
||||||
|
|
@ -1783,9 +1783,9 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
||||||
/* maximum of input and output suggested latency */
|
/* maximum of input and output suggested latency */
|
||||||
if( suggestedOutputLatencyFrames > suggestedInputLatencyFrames )
|
if( suggestedOutputLatencyFrames > suggestedInputLatencyFrames )
|
||||||
targetBufferingLatencyFrames = suggestedOutputLatencyFrames;
|
targetBufferingLatencyFrames = suggestedOutputLatencyFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
*hostBufferSizeFrames = userFramesPerBuffer
|
*hostBufferSizeFrames = userFramesPerBuffer
|
||||||
+ max( userFramesPerBuffer + pollingJitterFrames, targetBufferingLatencyFrames);
|
+ max( userFramesPerBuffer + pollingJitterFrames, targetBufferingLatencyFrames);
|
||||||
|
|
||||||
*pollingPeriodFrames = max( max(1, userFramesPerBuffer / 4), targetBufferingLatencyFrames / 16 );
|
*pollingPeriodFrames = max( max(1, userFramesPerBuffer / 4), targetBufferingLatencyFrames / 16 );
|
||||||
|
|
@ -1794,11 +1794,11 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
||||||
{
|
{
|
||||||
*pollingPeriodFrames = maximumPollingPeriodFrames;
|
*pollingPeriodFrames = maximumPollingPeriodFrames;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void CalculatePollingPeriodFrames( unsigned long hostBufferSizeFrames,
|
static void CalculatePollingPeriodFrames( unsigned long hostBufferSizeFrames,
|
||||||
unsigned long *pollingPeriodFrames,
|
unsigned long *pollingPeriodFrames,
|
||||||
double sampleRate, unsigned long userFramesPerBuffer )
|
double sampleRate, unsigned long userFramesPerBuffer )
|
||||||
{
|
{
|
||||||
|
|
@ -1815,12 +1815,12 @@ static void CalculatePollingPeriodFrames( unsigned long hostBufferSizeFrames,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void SetStreamInfoLatencies( PaWinDsStream *stream,
|
static void SetStreamInfoLatencies( PaWinDsStream *stream,
|
||||||
unsigned long userFramesPerBuffer,
|
unsigned long userFramesPerBuffer,
|
||||||
unsigned long pollingPeriodFrames,
|
unsigned long pollingPeriodFrames,
|
||||||
double sampleRate )
|
double sampleRate )
|
||||||
{
|
{
|
||||||
/* compute the stream info actual latencies based on framesPerBuffer, polling period, hostBufferSizeFrames,
|
/* compute the stream info actual latencies based on framesPerBuffer, polling period, hostBufferSizeFrames,
|
||||||
and the configuration of the buffer processor */
|
and the configuration of the buffer processor */
|
||||||
|
|
||||||
unsigned long effectiveFramesPerBuffer = (userFramesPerBuffer == paFramesPerBufferUnspecified)
|
unsigned long effectiveFramesPerBuffer = (userFramesPerBuffer == paFramesPerBufferUnspecified)
|
||||||
|
|
@ -1829,7 +1829,7 @@ static void SetStreamInfoLatencies( PaWinDsStream *stream,
|
||||||
|
|
||||||
if( stream->bufferProcessor.inputChannelCount > 0 )
|
if( stream->bufferProcessor.inputChannelCount > 0 )
|
||||||
{
|
{
|
||||||
/* stream info input latency is the minimum buffering latency
|
/* stream info input latency is the minimum buffering latency
|
||||||
(unlike suggested and default which are *maximums*) */
|
(unlike suggested and default which are *maximums*) */
|
||||||
stream->streamRepresentation.streamInfo.inputLatency =
|
stream->streamRepresentation.streamInfo.inputLatency =
|
||||||
(double)(PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor)
|
(double)(PaUtil_GetBufferProcessorInputLatencyFrames(&stream->bufferProcessor)
|
||||||
|
|
@ -1894,7 +1894,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
|
||||||
/* IDEA: the following 3 checks could be performed by default by pa_front
|
/* IDEA: the following 3 checks could be performed by default by pa_front
|
||||||
unless some flag indicated otherwise */
|
unless some flag indicated otherwise */
|
||||||
|
|
||||||
/* unless alternate device specification is supported, reject the use of
|
/* unless alternate device specification is supported, reject the use of
|
||||||
paUseHostApiSpecificDeviceSpecification */
|
paUseHostApiSpecificDeviceSpecification */
|
||||||
if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
|
if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
|
||||||
|
|
@ -1904,7 +1904,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown
|
if( inputWinDsDeviceInfo->deviceInputChannelCountIsKnown
|
||||||
&& inputChannelCount > inputDeviceInfo->maxInputChannels )
|
&& inputChannelCount > inputDeviceInfo->maxInputChannels )
|
||||||
return paInvalidChannelCount;
|
return paInvalidChannelCount;
|
||||||
|
|
||||||
/* validate hostApiSpecificStreamInfo */
|
/* validate hostApiSpecificStreamInfo */
|
||||||
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
|
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
|
||||||
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
|
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
|
||||||
|
|
@ -1948,7 +1948,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
/* validate hostApiSpecificStreamInfo */
|
/* validate hostApiSpecificStreamInfo */
|
||||||
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
|
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
|
||||||
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
|
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
|
||||||
if( result != paNoError ) return result;
|
if( result != paNoError ) return result;
|
||||||
|
|
||||||
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
|
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
|
||||||
userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer;
|
userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer;
|
||||||
|
|
@ -2025,7 +2025,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
|
PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
|
||||||
&winDsHostApi->blockingStreamInterface, streamCallback, userData );
|
&winDsHostApi->blockingStreamInterface, streamCallback, userData );
|
||||||
}
|
}
|
||||||
|
|
||||||
streamRepresentationIsInitialized = 1;
|
streamRepresentationIsInitialized = 1;
|
||||||
|
|
||||||
stream->streamFlags = streamFlags;
|
stream->streamFlags = streamFlags;
|
||||||
|
|
@ -2074,12 +2074,12 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
|
||||||
bufferProcessorIsInitialized = 1;
|
bufferProcessorIsInitialized = 1;
|
||||||
|
|
||||||
|
|
||||||
/* DirectSound specific initialization */
|
/* DirectSound specific initialization */
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
unsigned long integerSampleRate = (unsigned long) (sampleRate + 0.5);
|
unsigned long integerSampleRate = (unsigned long) (sampleRate + 0.5);
|
||||||
|
|
||||||
stream->processingCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL );
|
stream->processingCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL );
|
||||||
if( stream->processingCompleted == NULL )
|
if( stream->processingCompleted == NULL )
|
||||||
{
|
{
|
||||||
|
|
@ -2122,7 +2122,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
*/
|
*/
|
||||||
stream->hostBufferSizeFrames = max( userRequestedHostInputBufferSizeFrames, userRequestedHostOutputBufferSizeFrames );
|
stream->hostBufferSizeFrames = max( userRequestedHostInputBufferSizeFrames, userRequestedHostOutputBufferSizeFrames );
|
||||||
|
|
||||||
CalculatePollingPeriodFrames(
|
CalculatePollingPeriodFrames(
|
||||||
stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
||||||
sampleRate, framesPerBuffer );
|
sampleRate, framesPerBuffer );
|
||||||
}
|
}
|
||||||
|
|
@ -2131,13 +2131,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
CalculateBufferSettings( (unsigned long*)&stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
CalculateBufferSettings( (unsigned long*)&stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
||||||
/* isFullDuplex = */ (inputParameters && outputParameters),
|
/* isFullDuplex = */ (inputParameters && outputParameters),
|
||||||
suggestedInputLatencyFrames,
|
suggestedInputLatencyFrames,
|
||||||
suggestedOutputLatencyFrames,
|
suggestedOutputLatencyFrames,
|
||||||
sampleRate, framesPerBuffer );
|
sampleRate, framesPerBuffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->pollingPeriodSeconds = pollingPeriodFrames / sampleRate;
|
stream->pollingPeriodSeconds = pollingPeriodFrames / sampleRate;
|
||||||
|
|
||||||
DBUG(("DirectSound host buffer size frames: %d, polling period seconds: %f, @ sr: %f\n",
|
DBUG(("DirectSound host buffer size frames: %d, polling period seconds: %f, @ sr: %f\n",
|
||||||
stream->hostBufferSizeFrames, stream->pollingPeriodSeconds, sampleRate ));
|
stream->hostBufferSizeFrames, stream->pollingPeriodSeconds, sampleRate ));
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2150,7 +2150,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ];
|
PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ];
|
||||||
DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device));
|
DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int sampleSizeBytes = Pa_GetSampleSize(hostOutputSampleFormat);
|
int sampleSizeBytes = Pa_GetSampleSize(hostOutputSampleFormat);
|
||||||
stream->outputFrameSizeBytes = outputParameters->channelCount * sampleSizeBytes;
|
stream->outputFrameSizeBytes = outputParameters->channelCount * sampleSizeBytes;
|
||||||
|
|
||||||
|
|
@ -2173,7 +2173,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
|
|
||||||
stream->outputIsRunning = FALSE;
|
stream->outputIsRunning = FALSE;
|
||||||
stream->outputUnderflowCount = 0;
|
stream->outputUnderflowCount = 0;
|
||||||
|
|
||||||
/* perfCounterTicksPerBuffer is used by QueryOutputSpace for overflow detection */
|
/* perfCounterTicksPerBuffer is used by QueryOutputSpace for overflow detection */
|
||||||
if( QueryPerformanceFrequency( &counterFrequency ) )
|
if( QueryPerformanceFrequency( &counterFrequency ) )
|
||||||
{
|
{
|
||||||
|
|
@ -2192,7 +2192,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ];
|
PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ];
|
||||||
DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device));
|
DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device));
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int sampleSizeBytes = Pa_GetSampleSize(hostInputSampleFormat);
|
int sampleSizeBytes = Pa_GetSampleSize(hostInputSampleFormat);
|
||||||
stream->inputFrameSizeBytes = inputParameters->channelCount * sampleSizeBytes;
|
stream->inputFrameSizeBytes = inputParameters->channelCount * sampleSizeBytes;
|
||||||
|
|
||||||
|
|
@ -2217,7 +2217,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
assert( stream->pDirectSound == NULL );
|
assert( stream->pDirectSound == NULL );
|
||||||
assert( stream->pDirectSoundPrimaryBuffer == NULL );
|
assert( stream->pDirectSoundPrimaryBuffer == NULL );
|
||||||
assert( stream->pDirectSoundOutputBuffer == NULL );
|
assert( stream->pDirectSoundOutputBuffer == NULL );
|
||||||
|
|
||||||
|
|
||||||
if( inputParameters && outputParameters )
|
if( inputParameters && outputParameters )
|
||||||
{
|
{
|
||||||
|
|
@ -2237,14 +2237,14 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
||||||
integerSampleRate
|
integerSampleRate
|
||||||
);
|
);
|
||||||
DBUG(("InitFullDuplexInputOutputBuffers() returns %x\n", hr));
|
DBUG(("InitFullDuplexInputOutputBuffers() returns %x\n", hr));
|
||||||
/* ignore any error returned by InitFullDuplexInputOutputBuffers.
|
/* ignore any error returned by InitFullDuplexInputOutputBuffers.
|
||||||
we retry opening the buffers below */
|
we retry opening the buffers below */
|
||||||
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
|
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create half duplex buffers. also used for full-duplex streams which didn't
|
/* create half duplex buffers. also used for full-duplex streams which didn't
|
||||||
succeed when using the full duplex API. that could happen because
|
succeed when using the full duplex API. that could happen because
|
||||||
DX8 or greater isn't installed, the i/o devices aren't the same
|
DX8 or greater isn't installed, the i/o devices aren't the same
|
||||||
physical device. etc.
|
physical device. etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2426,11 +2426,11 @@ static HRESULT QueryOutputSpace( PaWinDsStream *stream, long *bytesEmpty )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
From MSDN:
|
From MSDN:
|
||||||
The write cursor indicates the position at which it is safe
|
The write cursor indicates the position at which it is safe
|
||||||
to write new data to the buffer. The write cursor always leads the
|
to write new data to the buffer. The write cursor always leads the
|
||||||
play cursor, typically by about 15 milliseconds' worth of audio
|
play cursor, typically by about 15 milliseconds' worth of audio
|
||||||
data.
|
data.
|
||||||
It is always safe to change data that is behind the position
|
It is always safe to change data that is behind the position
|
||||||
indicated by the lpdwCurrentPlayCursor parameter.
|
indicated by the lpdwCurrentPlayCursor parameter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2456,7 +2456,7 @@ static int TimeSlice( PaWinDsStream *stream )
|
||||||
double outputLatency = 0;
|
double outputLatency = 0;
|
||||||
double inputLatency = 0;
|
double inputLatency = 0;
|
||||||
PaStreamCallbackTimeInfo timeInfo = {0,0,0};
|
PaStreamCallbackTimeInfo timeInfo = {0,0,0};
|
||||||
|
|
||||||
/* Input */
|
/* Input */
|
||||||
LPBYTE lpInBuf1 = NULL;
|
LPBYTE lpInBuf1 = NULL;
|
||||||
LPBYTE lpInBuf2 = NULL;
|
LPBYTE lpInBuf2 = NULL;
|
||||||
|
|
@ -2489,7 +2489,7 @@ static int TimeSlice( PaWinDsStream *stream )
|
||||||
}
|
}
|
||||||
// FIXME: what happens if IDirectSoundCaptureBuffer_GetCurrentPosition fails?
|
// FIXME: what happens if IDirectSoundCaptureBuffer_GetCurrentPosition fails?
|
||||||
|
|
||||||
framesToXfer = numInFramesReady = bytesFilled / stream->inputFrameSizeBytes;
|
framesToXfer = numInFramesReady = bytesFilled / stream->inputFrameSizeBytes;
|
||||||
|
|
||||||
/** @todo Check for overflow */
|
/** @todo Check for overflow */
|
||||||
}
|
}
|
||||||
|
|
@ -2502,7 +2502,7 @@ static int TimeSlice( PaWinDsStream *stream )
|
||||||
framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes;
|
framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes;
|
||||||
|
|
||||||
/* Check for underflow */
|
/* Check for underflow */
|
||||||
/* FIXME QueryOutputSpace should not adjust underflow count as a side effect.
|
/* FIXME QueryOutputSpace should not adjust underflow count as a side effect.
|
||||||
A query function should be a const operator on the stream and return a flag on underflow. */
|
A query function should be a const operator on the stream and return a flag on underflow. */
|
||||||
if( stream->outputUnderflowCount != previousUnderflowCount )
|
if( stream->outputUnderflowCount != previousUnderflowCount )
|
||||||
stream->callbackFlags |= paOutputUnderflow;
|
stream->callbackFlags |= paOutputUnderflow;
|
||||||
|
|
@ -2532,11 +2532,11 @@ static int TimeSlice( PaWinDsStream *stream )
|
||||||
|
|
||||||
PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags );
|
PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags );
|
||||||
stream->callbackFlags = 0;
|
stream->callbackFlags = 0;
|
||||||
|
|
||||||
/* Input */
|
/* Input */
|
||||||
if( stream->bufferProcessor.inputChannelCount > 0 )
|
if( stream->bufferProcessor.inputChannelCount > 0 )
|
||||||
{
|
{
|
||||||
timeInfo.inputBufferAdcTime = timeInfo.currentTime - inputLatency;
|
timeInfo.inputBufferAdcTime = timeInfo.currentTime - inputLatency;
|
||||||
|
|
||||||
bytesToXfer = framesToXfer * stream->inputFrameSizeBytes;
|
bytesToXfer = framesToXfer * stream->inputFrameSizeBytes;
|
||||||
hresult = IDirectSoundCaptureBuffer_Lock ( stream->pDirectSoundInputBuffer,
|
hresult = IDirectSoundCaptureBuffer_Lock ( stream->pDirectSoundInputBuffer,
|
||||||
|
|
@ -2603,7 +2603,7 @@ static int TimeSlice( PaWinDsStream *stream )
|
||||||
|
|
||||||
numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &stream->callbackResult );
|
numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &stream->callbackResult );
|
||||||
stream->framesWritten += numFrames;
|
stream->framesWritten += numFrames;
|
||||||
|
|
||||||
if( stream->bufferProcessor.outputChannelCount > 0 )
|
if( stream->bufferProcessor.outputChannelCount > 0 )
|
||||||
{
|
{
|
||||||
/* FIXME: an underflow could happen here */
|
/* FIXME: an underflow could happen here */
|
||||||
|
|
@ -2626,7 +2626,7 @@ error1:
|
||||||
}
|
}
|
||||||
error2:
|
error2:
|
||||||
|
|
||||||
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );
|
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( stream->callbackResult == paComplete && !PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
|
if( stream->callbackResult == paComplete && !PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
|
||||||
|
|
@ -2684,7 +2684,7 @@ static void CALLBACK TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD
|
||||||
(void) uMsg;
|
(void) uMsg;
|
||||||
(void) dw1;
|
(void) dw1;
|
||||||
(void) dw2;
|
(void) dw2;
|
||||||
|
|
||||||
stream = (PaWinDsStream *) dwUser;
|
stream = (PaWinDsStream *) dwUser;
|
||||||
if( stream == NULL ) return;
|
if( stream == NULL ) return;
|
||||||
|
|
||||||
|
|
@ -2715,8 +2715,8 @@ static void CALLBACK TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD
|
||||||
int callbackResult = TimeSlice( stream );
|
int callbackResult = TimeSlice( stream );
|
||||||
if( callbackResult != paContinue )
|
if( callbackResult != paContinue )
|
||||||
{
|
{
|
||||||
/* FIXME implement handling of paComplete and paAbort if possible
|
/* FIXME implement handling of paComplete and paAbort if possible
|
||||||
At the moment this should behave as if paComplete was called and
|
At the moment this should behave as if paComplete was called and
|
||||||
flush the buffer.
|
flush the buffer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2892,7 +2892,7 @@ static HRESULT ClearOutputBuffer( PaWinDsStream *stream )
|
||||||
// Unlock the DS buffer
|
// Unlock the DS buffer
|
||||||
if ((hr = IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK)
|
if ((hr = IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK)
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
// Let DSound set the starting write position because if we set it to zero, it looks like the
|
// Let DSound set the starting write position because if we set it to zero, it looks like the
|
||||||
// buffer is full to begin with. This causes a long pause before sound starts when using large buffers.
|
// buffer is full to begin with. This causes a long pause before sound starts when using large buffers.
|
||||||
if ((hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer,
|
if ((hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer,
|
||||||
|
|
@ -2909,10 +2909,10 @@ static PaError StartStream( PaStream *s )
|
||||||
PaError result = paNoError;
|
PaError result = paNoError;
|
||||||
PaWinDsStream *stream = (PaWinDsStream*)s;
|
PaWinDsStream *stream = (PaWinDsStream*)s;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
stream->callbackResult = paContinue;
|
stream->callbackResult = paContinue;
|
||||||
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
|
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
|
||||||
|
|
||||||
ResetEvent( stream->processingCompleted );
|
ResetEvent( stream->processingCompleted );
|
||||||
|
|
||||||
#ifndef PA_WIN_DS_USE_WMME_TIMER
|
#ifndef PA_WIN_DS_USE_WMME_TIMER
|
||||||
|
|
@ -3017,7 +3017,7 @@ static PaError StartStream( PaStream *s )
|
||||||
*/
|
*/
|
||||||
stream->timerID = timeSetEvent( timerPeriodMs, stream->systemTimerResolutionPeriodMs, (LPTIMECALLBACK) TimerCallback,
|
stream->timerID = timeSetEvent( timerPeriodMs, stream->systemTimerResolutionPeriodMs, (LPTIMECALLBACK) TimerCallback,
|
||||||
(DWORD_PTR) stream, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS );
|
(DWORD_PTR) stream, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS );
|
||||||
|
|
||||||
if( stream->timerID == 0 )
|
if( stream->timerID == 0 )
|
||||||
{
|
{
|
||||||
stream->isActive = 0;
|
stream->isActive = 0;
|
||||||
|
|
@ -3112,7 +3112,7 @@ static PaError StopStream( PaStream *s )
|
||||||
if( stream->systemTimerResolutionPeriodMs > 0 ){
|
if( stream->systemTimerResolutionPeriodMs > 0 ){
|
||||||
timeEndPeriod( stream->systemTimerResolutionPeriodMs );
|
timeEndPeriod( stream->systemTimerResolutionPeriodMs );
|
||||||
stream->systemTimerResolutionPeriodMs = 0;
|
stream->systemTimerResolutionPeriodMs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( stream->bufferProcessor.outputChannelCount > 0 )
|
if( stream->bufferProcessor.outputChannelCount > 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -3252,7 +3252,7 @@ static signed long GetStreamWriteAvailable( PaStream* s )
|
||||||
|
|
||||||
/* suppress unused variable warnings */
|
/* suppress unused variable warnings */
|
||||||
(void) stream;
|
(void) stream;
|
||||||
|
|
||||||
/* IMPLEMENT ME, see portaudio.h for required behavior*/
|
/* IMPLEMENT ME, see portaudio.h for required behavior*/
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
* The text above constitutes the entire PortAudio license; however,
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
* the PortAudio community also makes the following non-binding requests:
|
||||||
*
|
*
|
||||||
* Any person wishing to distribute modifications to the Software is
|
* Any person wishing to distribute modifications to the Software is
|
||||||
* requested to send the modifications to the original developer so that
|
* requested to send the modifications to the original developer so that
|
||||||
* they can be incorporated into the canonical version. It is also
|
* they can be incorporated into the canonical version. It is also
|
||||||
* requested that these non-binding requests be included along with the
|
* requested that these non-binding requests be included along with the
|
||||||
* license above.
|
* license above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -180,7 +180,7 @@ void PaWinDs_InitializeDSoundEntryPoints(void)
|
||||||
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
|
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
|
||||||
paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 =
|
paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 =
|
||||||
(HRESULT (WINAPI *)(LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
|
(HRESULT (WINAPI *)(LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
|
||||||
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
|
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
|
||||||
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN))
|
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN))
|
||||||
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundFullDuplexCreate" );
|
GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundFullDuplexCreate" );
|
||||||
if( paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 == NULL )
|
if( paWinDsDSoundEntryPoints.DirectSoundFullDuplexCreate8 == NULL )
|
||||||
|
|
@ -221,4 +221,4 @@ void PaWinDs_TerminateDSoundEntryPoints(void)
|
||||||
FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ );
|
FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ );
|
||||||
paWinDsDSoundEntryPoints.hInstance_ = NULL;
|
paWinDsDSoundEntryPoints.hInstance_ = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The text above constitutes the entire PortAudio license; however,
|
* The text above constitutes the entire PortAudio license; however,
|
||||||
* the PortAudio community also makes the following non-binding requests:
|
* the PortAudio community also makes the following non-binding requests:
|
||||||
*
|
*
|
||||||
* Any person wishing to distribute modifications to the Software is
|
* Any person wishing to distribute modifications to the Software is
|
||||||
* requested to send the modifications to the original developer so that
|
* requested to send the modifications to the original developer so that
|
||||||
* they can be incorporated into the canonical version. It is also
|
* they can be incorporated into the canonical version. It is also
|
||||||
* requested that these non-binding requests be included along with the
|
* requested that these non-binding requests be included along with the
|
||||||
* license above.
|
* license above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -74,7 +74,7 @@ extern "C"
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HINSTANCE hInstance_;
|
HINSTANCE hInstance_;
|
||||||
|
|
||||||
HRESULT (WINAPI *DllGetClassObject)(REFCLSID , REFIID , LPVOID *);
|
HRESULT (WINAPI *DllGetClassObject)(REFCLSID , REFIID , LPVOID *);
|
||||||
|
|
||||||
HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
|
HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
|
||||||
|
|
@ -88,7 +88,7 @@ typedef struct
|
||||||
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
|
#ifdef PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE
|
||||||
HRESULT (WINAPI *DirectSoundFullDuplexCreate8)(
|
HRESULT (WINAPI *DirectSoundFullDuplexCreate8)(
|
||||||
LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
|
LPCGUID, LPCGUID, LPCDSCBUFFERDESC, LPCDSBUFFERDESC,
|
||||||
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
|
HWND, DWORD, LPDIRECTSOUNDFULLDUPLEX *, LPDIRECTSOUNDCAPTUREBUFFER8 *,
|
||||||
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN );
|
LPDIRECTSOUNDBUFFER8 *, LPUNKNOWN );
|
||||||
#endif
|
#endif
|
||||||
}PaWinDsDSoundEntryPoints;
|
}PaWinDsDSoundEntryPoints;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue