Commit a2f1fd3a authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Add multiple DIRECTSOUND object support (multiple sound cards can play

at the same time). Fix CoCreateInstance when no sound card is present. Fix create bug found by Mike Hearn.
parent bdfcb09c
...@@ -276,7 +276,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency( ...@@ -276,7 +276,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(
oldFreq = This->freq; oldFreq = This->freq;
This->freq = freq; This->freq = freq;
if (freq != oldFreq) { if (freq != oldFreq) {
This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->pwfx->nSamplesPerSec; This->freqAdjust = (freq << DSOUND_FREQSHIFT) / This->dsound->device->pwfx->nSamplesPerSec;
This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign; This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign;
DSOUND_RecalcFormat(This); DSOUND_RecalcFormat(This);
if (!This->hwbuf) if (!This->hwbuf)
...@@ -370,7 +370,7 @@ static ULONG WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface) ...@@ -370,7 +370,7 @@ static ULONG WINAPI IDirectSoundBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface)
if (This->hwbuf) { if (This->hwbuf) {
IDsDriverBuffer_Release(This->hwbuf); IDsDriverBuffer_Release(This->hwbuf);
if (This->dsound->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) { if (This->dsound->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
This->buffer->ref--; This->buffer->ref--;
if (This->buffer->ref==0) { if (This->buffer->ref==0) {
HeapFree(GetProcessHeap(),0,This->buffer->memory); HeapFree(GetProcessHeap(),0,This->buffer->memory);
...@@ -403,17 +403,17 @@ DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD p ...@@ -403,17 +403,17 @@ DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD p
/* the actual primary play position (pplay) is always behind last mixed (pmix), /* the actual primary play position (pplay) is always behind last mixed (pmix),
* unless the computer is too slow or something */ * unless the computer is too slow or something */
/* we need to know how far away we are from there */ /* we need to know how far away we are from there */
if (pmix < pplay) pmix += This->dsound->buflen; /* wraparound */ if (pmix < pplay) pmix += This->dsound->device->buflen; /* wraparound */
pmix -= pplay; pmix -= pplay;
/* detect buffer underrun */ /* detect buffer underrun */
if (pwrite < pplay) pwrite += This->dsound->buflen; /* wraparound */ if (pwrite < pplay) pwrite += This->dsound->device->buflen; /* wraparound */
pwrite -= pplay; pwrite -= pplay;
if (pmix > (ds_snd_queue_max * This->dsound->fraglen + pwrite + This->dsound->writelead)) { if (pmix > (ds_snd_queue_max * This->dsound->device->fraglen + pwrite + This->dsound->device->writelead)) {
WARN("detected an underrun: primary queue was %ld\n",pmix); WARN("detected an underrun: primary queue was %ld\n",pmix);
pmix = 0; pmix = 0;
} }
/* divide the offset by its sample size */ /* divide the offset by its sample size */
pmix /= This->dsound->pwfx->nBlockAlign; pmix /= This->dsound->device->pwfx->nBlockAlign;
TRACE("primary back-samples=%ld\n",pmix); TRACE("primary back-samples=%ld\n",pmix);
/* adjust for our frequency */ /* adjust for our frequency */
pmix = (pmix * This->freqAdjust) >> DSOUND_FREQSHIFT; pmix = (pmix * This->freqAdjust) >> DSOUND_FREQSHIFT;
...@@ -451,13 +451,13 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition( ...@@ -451,13 +451,13 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
} else if (playpos) { } else if (playpos) {
DWORD pplay, pwrite; DWORD pplay, pwrite;
/* let's get this exact; first, recursively call GetPosition on the primary */ /* let's get this exact; first, recursively call GetPosition on the primary */
EnterCriticalSection(&(This->dsound->mixlock)); EnterCriticalSection(&(This->dsound->device->mixlock));
if (DSOUND_PrimaryGetPosition(This->dsound, &pplay, &pwrite) != DS_OK) if (DSOUND_PrimaryGetPosition(This->dsound->device, &pplay, &pwrite) != DS_OK)
WARN("DSOUND_PrimaryGetPosition failed\n"); WARN("DSOUND_PrimaryGetPosition failed\n");
/* detect HEL mode underrun */ /* detect HEL mode underrun */
if (!(This->dsound->hwbuf || This->dsound->pwqueue)) if (!(This->dsound->device->hwbuf || This->dsound->device->pwqueue))
TRACE("detected an underrun\n"); TRACE("detected an underrun\n");
if ((This->dsbd.dwFlags & DSBCAPS_GETCURRENTPOSITION2) || This->dsound->hwbuf) { if ((This->dsbd.dwFlags & DSBCAPS_GETCURRENTPOSITION2) || This->dsound->device->hwbuf) {
/* calculate play position using this */ /* calculate play position using this */
*playpos = DSOUND_CalcPlayPosition(This, pplay, pwrite); *playpos = DSOUND_CalcPlayPosition(This, pplay, pwrite);
} else { } else {
...@@ -467,11 +467,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition( ...@@ -467,11 +467,11 @@ static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(
* behind write cursor, hmm... */ * behind write cursor, hmm... */
/* let's just do what might work for Half-Life */ /* let's just do what might work for Half-Life */
DWORD wp; DWORD wp;
wp = (This->dsound->pwplay + ds_hel_margin) * This->dsound->fraglen; wp = (This->dsound->device->pwplay + ds_hel_margin) * This->dsound->device->fraglen;
wp %= This->dsound->buflen; wp %= This->dsound->device->buflen;
*playpos = DSOUND_CalcPlayPosition(This, wp, pwrite); *playpos = DSOUND_CalcPlayPosition(This, wp, pwrite);
} }
LeaveCriticalSection(&(This->dsound->mixlock)); LeaveCriticalSection(&(This->dsound->device->mixlock));
} }
if (writepos) if (writepos)
*writepos = This->buf_mixpos; *writepos = This->buf_mixpos;
...@@ -594,7 +594,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock( ...@@ -594,7 +594,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
else else
This->probably_valid_to = writecursor; This->probably_valid_to = writecursor;
if (!(This->dsound->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) { if (!(This->dsound->device->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
hres = IDsDriverBuffer_Lock(This->hwbuf, hres = IDsDriverBuffer_Lock(This->hwbuf,
lplpaudioptr1, audiobytes1, lplpaudioptr1, audiobytes1,
lplpaudioptr2, audiobytes2, lplpaudioptr2, audiobytes2,
...@@ -747,7 +747,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock( ...@@ -747,7 +747,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(
/* **** */ /* **** */
EnterCriticalSection(&(This->lock)); EnterCriticalSection(&(This->lock));
if (!(This->dsound->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) { if (!(This->dsound->device->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2); hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2);
if (hres != DS_OK) if (hres != DS_OK)
WARN("IDsDriverBuffer_Unlock failed\n"); WARN("IDsDriverBuffer_Unlock failed\n");
...@@ -1055,8 +1055,8 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create( ...@@ -1055,8 +1055,8 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT; if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT;
else capf |= DSCAPS_SECONDARY8BIT; else capf |= DSCAPS_SECONDARY8BIT;
use_hw = (ds->drvcaps.dwFlags & capf) == capf; use_hw = (ds->device->drvcaps.dwFlags & capf) == capf;
TRACE("use_hw = 0x%08x, capf = 0x%08lx, ds->drvcaps.dwFlags = 0x%08lx\n", use_hw, capf, ds->drvcaps.dwFlags); TRACE("use_hw = 0x%08x, capf = 0x%08lx, ds->drvcaps.dwFlags = 0x%08lx\n", use_hw, capf, ds->device->drvcaps.dwFlags);
/* FIXME: check hardware sample rate mixing capabilities */ /* FIXME: check hardware sample rate mixing capabilities */
/* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */ /* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */
...@@ -1074,7 +1074,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create( ...@@ -1074,7 +1074,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
} }
/* Allocate system memory for buffer if applicable */ /* Allocate system memory for buffer if applicable */
if ((ds->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) { if ((ds->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) {
dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen); dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
if (dsb->buffer->memory == NULL) { if (dsb->buffer->memory == NULL) {
WARN("out of memory\n"); WARN("out of memory\n");
...@@ -1090,14 +1090,14 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create( ...@@ -1090,14 +1090,14 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
/* Allocate the hardware buffer */ /* Allocate the hardware buffer */
if (use_hw) { if (use_hw) {
err = IDsDriver_CreateSoundBuffer(ds->driver,wfex,dsbd->dwFlags,0, err = IDsDriver_CreateSoundBuffer(ds->device->driver,wfex,dsbd->dwFlags,0,
&(dsb->buflen),&(dsb->buffer->memory), &(dsb->buflen),&(dsb->buffer->memory),
(LPVOID*)&(dsb->hwbuf)); (LPVOID*)&(dsb->hwbuf));
/* fall back to software buffer on failure */ /* fall back to software buffer on failure */
if (err != DS_OK) { if (err != DS_OK) {
TRACE("IDsDriver_CreateSoundBuffer failed, falling back to software buffer\n"); TRACE("IDsDriver_CreateSoundBuffer failed, falling back to software buffer\n");
use_hw = 0; use_hw = 0;
if (ds->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) { if (ds->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen); dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
if (dsb->buffer->memory == NULL) { if (dsb->buffer->memory == NULL) {
WARN("out of memory\n"); WARN("out of memory\n");
...@@ -1124,7 +1124,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create( ...@@ -1124,7 +1124,7 @@ HRESULT WINAPI IDirectSoundBufferImpl_Create(
dsb->state = STATE_STOPPED; dsb->state = STATE_STOPPED;
dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) / dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) /
ds->pwfx->nSamplesPerSec; ds->device->pwfx->nSamplesPerSec;
dsb->nAvgBytesPerSec = dsb->freq * dsb->nAvgBytesPerSec = dsb->freq *
dsbd->lpwfxFormat->nBlockAlign; dsbd->lpwfxFormat->nBlockAlign;
......
...@@ -68,7 +68,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound); ...@@ -68,7 +68,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound);
#define DS_SND_QUEUE_MAX 28 /* max number of fragments to prebuffer */ #define DS_SND_QUEUE_MAX 28 /* max number of fragments to prebuffer */
#define DS_SND_QUEUE_MIN 12 /* min number of fragments to prebuffer */ #define DS_SND_QUEUE_MIN 12 /* min number of fragments to prebuffer */
IDirectSoundImpl* DSOUND_renderer = NULL; DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]; GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
GUID DSOUND_capture_guids[MAXWAVEDRIVERS]; GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
...@@ -460,10 +460,10 @@ static HRESULT WINAPI DSCF_CreateInstance( ...@@ -460,10 +460,10 @@ static HRESULT WINAPI DSCF_CreateInstance(
*ppobj = NULL; *ppobj = NULL;
if ( IsEqualIID( &IID_IDirectSound, riid ) ) if ( IsEqualIID( &IID_IDirectSound, riid ) )
return DSOUND_Create(0,(LPDIRECTSOUND*)ppobj,pOuter); return DSOUND_Create((LPDIRECTSOUND*)ppobj,pOuter);
if ( IsEqualIID( &IID_IDirectSound8, riid ) ) if ( IsEqualIID( &IID_IDirectSound8, riid ) )
return DSOUND_Create8(0,(LPDIRECTSOUND8*)ppobj,pOuter); return DSOUND_Create8((LPDIRECTSOUND8*)ppobj,pOuter);
WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj); WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
return E_NOINTERFACE; return E_NOINTERFACE;
...@@ -664,6 +664,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved) ...@@ -664,6 +664,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
TRACE("DLL_PROCESS_ATTACH\n"); TRACE("DLL_PROCESS_ATTACH\n");
for (i = 0; i < MAXWAVEDRIVERS; i++) { for (i = 0; i < MAXWAVEDRIVERS; i++) {
DSOUND_renderer[i] = NULL;
INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i); INIT_GUID(DSOUND_renderer_guids[i], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i); INIT_GUID(DSOUND_capture_guids[i], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + i);
} }
......
...@@ -63,6 +63,7 @@ typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl; ...@@ -63,6 +63,7 @@ typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
typedef struct PrimaryBufferImpl PrimaryBufferImpl; typedef struct PrimaryBufferImpl PrimaryBufferImpl;
typedef struct SecondaryBufferImpl SecondaryBufferImpl; typedef struct SecondaryBufferImpl SecondaryBufferImpl;
typedef struct IClassFactoryImpl IClassFactoryImpl; typedef struct IClassFactoryImpl IClassFactoryImpl;
typedef struct DirectSoundDevice DirectSoundDevice;
/***************************************************************************** /*****************************************************************************
* IDirectSound implementation structure * IDirectSound implementation structure
...@@ -72,7 +73,17 @@ struct IDirectSoundImpl ...@@ -72,7 +73,17 @@ struct IDirectSoundImpl
/* IUnknown fields */ /* IUnknown fields */
IDirectSound8Vtbl *lpVtbl; IDirectSound8Vtbl *lpVtbl;
DWORD ref; DWORD ref;
/* IDirectSoundImpl fields */
DirectSoundDevice *device;
LPUNKNOWN pUnknown;
LPDIRECTSOUND pDS;
LPDIRECTSOUND8 pDS8;
};
struct DirectSoundDevice
{
DWORD ref;
GUID guid; GUID guid;
PIDSDRIVER driver; PIDSDRIVER driver;
DSDRIVERDESC drvdesc; DSDRIVERDESC drvdesc;
...@@ -94,7 +105,6 @@ struct IDirectSoundImpl ...@@ -94,7 +105,6 @@ struct IDirectSoundImpl
PrimaryBufferImpl* primary; PrimaryBufferImpl* primary;
DSBUFFERDESC dsbd; DSBUFFERDESC dsbd;
DWORD speaker_config; DWORD speaker_config;
BOOL initialized;
LPBYTE tmp_buffer; LPBYTE tmp_buffer;
DWORD tmp_buffer_len; DWORD tmp_buffer_len;
...@@ -102,10 +112,6 @@ struct IDirectSoundImpl ...@@ -102,10 +112,6 @@ struct IDirectSoundImpl
IDirectSound3DListenerImpl* listener; IDirectSound3DListenerImpl* listener;
DS3DLISTENER ds3dl; DS3DLISTENER ds3dl;
BOOL ds3dl_need_recalc; BOOL ds3dl_need_recalc;
LPUNKNOWN pUnknown;
LPDIRECTSOUND pDS;
LPDIRECTSOUND8 pDS8;
}; };
/* reference counted buffer memory for duplicated buffer memory */ /* reference counted buffer memory for duplicated buffer memory */
...@@ -116,16 +122,13 @@ typedef struct BufferMemory ...@@ -116,16 +122,13 @@ typedef struct BufferMemory
} BufferMemory; } BufferMemory;
HRESULT WINAPI IDirectSoundImpl_Create( HRESULT WINAPI IDirectSoundImpl_Create(
LPCGUID lpcGUID,
LPDIRECTSOUND8 * ppds); LPDIRECTSOUND8 * ppds);
HRESULT WINAPI DSOUND_Create( HRESULT WINAPI DSOUND_Create(
LPCGUID lpcGUID,
LPDIRECTSOUND *ppDS, LPDIRECTSOUND *ppDS,
IUnknown *pUnkOuter); IUnknown *pUnkOuter);
HRESULT WINAPI DSOUND_Create8( HRESULT WINAPI DSOUND_Create8(
LPCGUID lpcGUID,
LPDIRECTSOUND8 *ppDS, LPDIRECTSOUND8 *ppDS,
IUnknown *pUnkOuter); IUnknown *pUnkOuter);
...@@ -461,11 +464,11 @@ HRESULT DSOUND_RemoveBuffer(IDirectSoundImpl * pDS, IDirectSoundBufferImpl * pDS ...@@ -461,11 +464,11 @@ HRESULT DSOUND_RemoveBuffer(IDirectSoundImpl * pDS, IDirectSoundBufferImpl * pDS
/* primary.c */ /* primary.c */
HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This); HRESULT DSOUND_PrimaryCreate(DirectSoundDevice *device);
HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This); HRESULT DSOUND_PrimaryDestroy(DirectSoundDevice *device);
HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This); HRESULT DSOUND_PrimaryPlay(DirectSoundDevice *device);
HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This); HRESULT DSOUND_PrimaryStop(DirectSoundDevice *device);
HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos); HRESULT DSOUND_PrimaryGetPosition(DirectSoundDevice *device, LPDWORD playpos, LPDWORD writepos);
/* buffer.c */ /* buffer.c */
...@@ -476,8 +479,8 @@ DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD p ...@@ -476,8 +479,8 @@ DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This, DWORD pplay, DWORD p
void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len); void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb); void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos); void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq); void DSOUND_WaveQueue(DirectSoundDevice *device, DWORD mixq);
void DSOUND_PerformMix(IDirectSoundImpl *dsound); void DSOUND_PerformMix(DirectSoundDevice *device);
void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2); void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2); void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
...@@ -493,7 +496,7 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb); ...@@ -493,7 +496,7 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
#define DSOUND_FREQSHIFT (14) #define DSOUND_FREQSHIFT (14)
extern IDirectSoundImpl* DSOUND_renderer; extern DirectSoundDevice* DSOUND_renderer[MAXWAVEDRIVERS];
extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS]; extern GUID DSOUND_renderer_guids[MAXWAVEDRIVERS];
extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS]; extern GUID DSOUND_capture_guids[MAXWAVEDRIVERS];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment