Commit 89b469fe authored by Robert Reif's avatar Robert Reif Committed by Alexandre Julliard

Added support for multiple direct sound devices.

parent 2e24a148
......@@ -84,7 +84,7 @@ static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface) {
if (This->dsb)
IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
else if (This->dscb)
IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb);
IDirectSoundCaptureBuffer8_Release((LPDIRECTSOUNDCAPTUREBUFFER8)This->dscb);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
......@@ -543,6 +543,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
assert(audiobytes1!=audiobytes2);
assert(lplpaudioptr1!=lplpaudioptr2);
EnterCriticalSection(&(This->lock));
if ((writebytes == This->buflen) &&
((This->state == STATE_STARTING) ||
(This->state == STATE_PLAYING)))
......@@ -601,6 +603,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_Lock(
}
}
}
LeaveCriticalSection(&(This->lock));
return DS_OK;
}
......
......@@ -20,8 +20,6 @@
*/
/*
* TODO:
* Fix Enumerate for multiple sound devices.
* Handle device GUIDs properly.
* Implement DirectSoundFullDuplex support.
* Implement FX support.
*/
......@@ -97,6 +95,7 @@ DirectSoundCaptureCreate8(
LPDIRECTSOUNDCAPTURE* lplpDSC,
LPUNKNOWN pUnkOuter )
{
IDirectSoundCaptureImpl** ippDSC=(IDirectSoundCaptureImpl**)lplpDSC;
TRACE("(%s,%p,%p)\n", debugstr_guid(lpcGUID), lplpDSC, pUnkOuter);
if ( pUnkOuter ) {
......@@ -110,43 +109,33 @@ DirectSoundCaptureCreate8(
}
/* Default device? */
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) ||
IsEqualGUID(lpcGUID, &DSDEVID_DefaultCapture) ||
IsEqualGUID(lpcGUID, &DSDEVID_DefaultVoiceCapture) ) {
IDirectSoundCaptureImpl** ippDSC=(IDirectSoundCaptureImpl**)lplpDSC;
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
lpcGUID = &DSDEVID_DefaultCapture;
*ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
*ippDSC = (IDirectSoundCaptureImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundCaptureImpl));
if (*ippDSC == NULL) {
TRACE("couldn't allocate memory\n");
return DSERR_OUTOFMEMORY;
}
else
{
ICOM_THIS(IDirectSoundCaptureImpl, *ippDSC);
This->ref = 1;
This->state = STATE_STOPPED;
if (*ippDSC == NULL) {
TRACE("couldn't allocate memory\n");
return DSERR_OUTOFMEMORY;
}
else
{
ICOM_THIS(IDirectSoundCaptureImpl, *ippDSC);
if (lpcGUID)
This->guid = *lpcGUID;
else
This->guid = GUID_NULL;
This->ref = 1;
This->state = STATE_STOPPED;
InitializeCriticalSection( &(This->lock) );
InitializeCriticalSection( &(This->lock) );
ICOM_VTBL(This) = &dscvt;
dsound_capture = This;
ICOM_VTBL(This) = &dscvt;
dsound_capture = This;
return IDirectSoundCaptureImpl_Initialize( (LPDIRECTSOUNDCAPTURE)This, lpcGUID );
}
if (GetDeviceID(lpcGUID, &This->guid) == DS_OK)
return IDirectSoundCaptureImpl_Initialize( (LPDIRECTSOUNDCAPTURE)This, &This->guid);
}
FIXME( "Unknown GUID %s\n", debugstr_guid(lpcGUID) );
*lplpDSC = NULL;
return DSERR_OUTOFMEMORY;
WARN("invalid GUID\n");
return DSERR_INVALIDPARAM;
}
/***************************************************************************
......@@ -163,8 +152,10 @@ DirectSoundCaptureEnumerateA(
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
WAVEINCAPSA wcaps;
unsigned devs, wid;
DSDRIVERDESC desc;
GUID guid;
int err;
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
......@@ -174,15 +165,37 @@ DirectSoundCaptureEnumerateA(
}
devs = waveInGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
GUID temp;
for (wid = 0; wid < devs; ++wid) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
if (err == DS_OK) {
if (IsEqualGUID( &guid, &temp ) ) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, "Primary Sound Capture Driver", desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
}
for (wid = 0; wid < devs; ++wid) {
waveInGetDevCapsA(wid, &wcaps, sizeof(wcaps));
if (lpDSEnumCallback) {
TRACE("calling lpDSEnumCallback(%s,\"WINE DirectSound\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),wcaps.szPname,lpContext);
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, "WINE DirectSound",
wcaps.szPname ,lpContext);
return DS_OK;
}
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
if (lpDSEnumCallback(&guid, desc.szDesc, desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
return DS_OK;
......@@ -202,9 +215,12 @@ DirectSoundCaptureEnumerateW(
LPDSENUMCALLBACKW lpDSEnumCallback,
LPVOID lpContext)
{
WAVEINCAPSW wcaps;
unsigned devs, wid;
WCHAR desc[MAXPNAMELEN];
DSDRIVERDESC desc;
GUID guid;
int err;
WCHAR wDesc[MAXPNAMELEN];
WCHAR wName[MAXPNAMELEN];
TRACE("(%p,%p)\n", lpDSEnumCallback, lpContext );
......@@ -214,14 +230,45 @@ DirectSoundCaptureEnumerateW(
}
devs = waveInGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) {
GUID temp;
for (wid = 0; wid < devs; ++wid) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
if (err == DS_OK) {
if (IsEqualGUID( &guid, &temp ) ) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),"Primary Sound Capture Driver",desc.szDrvName,lpContext);
MultiByteToWideChar( CP_ACP, 0, "Primary Sound Capture Driver", -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
}
for (wid = 0; wid < devs; ++wid) {
waveInGetDevCapsW(wid, &wcaps, sizeof(wcaps));
if (lpDSEnumCallback) {
MultiByteToWideChar( CP_ACP, 0, "WINE Sound Capture Driver", -1,
desc, sizeof(desc)/sizeof(WCHAR) );
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, desc, wcaps.szPname ,lpContext);
return DS_OK;
}
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultCapture),desc.szDesc,desc.szDrvName,lpContext);
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
wDesc, sizeof(wDesc)/sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
wName, sizeof(wName)/sizeof(WCHAR) );
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultCapture, wDesc, wName, lpContext) == FALSE)
return DS_OK;
}
}
}
return DS_OK;
......@@ -402,7 +449,7 @@ IDirectSoundCaptureImpl_Initialize(
LPDIRECTSOUNDCAPTURE iface,
LPCGUID lpcGUID )
{
HRESULT err = DS_OK;
HRESULT err = DSERR_INVALIDPARAM;
unsigned wid, widn;
ICOM_THIS(IDirectSoundCaptureImpl,iface);
TRACE("(%p)\n", This);
......@@ -427,8 +474,24 @@ IDirectSoundCaptureImpl_Initialize(
/* Get dsound configuration */
setup_dsound_options();
/* FIXME: should enumerate WINMM audio devices and find the one we want */
wid = 0;
/* enumerate WINMM audio devices and find the one we want */
for (wid=0; wid<widn; wid++) {
GUID guid;
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
if (err != DS_OK) {
WARN("waveInMessage failed; err=%lx\n",err);
return err;
}
if (IsEqualGUID( lpcGUID, &guid) ) {
err = DS_OK;
break;
}
}
if (err != DS_OK) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&(This->driver),0));
if ( (err != DS_OK) && (err != DSERR_UNSUPPORTED) ) {
......@@ -443,9 +506,6 @@ IDirectSoundCaptureImpl_Initialize(
/* Get driver description */
if (This->driver) {
ERR("You have a sound card that is Direct Sound Capture capable but the driver is not finished. You can add a line to the wine config file in [dsound]: \"HardwareAcceleration\" = \"Emulation\" to force emulation mode.\n");
/* FIXME: remove this return to test driver */
return DSERR_NODRIVER;
TRACE("using DirectSound driver\n");
err = IDsCaptureDriver_GetDriverDesc(This->driver, &(This->drvdesc));
if (err != DS_OK) {
......@@ -484,11 +544,9 @@ IDirectSoundCaptureImpl_Initialize(
strncpy(This->drvdesc.szDrvName, wic.szPname,
sizeof(This->drvdesc.szDrvName));
This->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
This->drvcaps.dwFormats = wic.dwFormats;
This->drvcaps.dwChannels = wic.wChannels;
if (ds_emuldriver)
This->drvcaps.dwFlags |= DSCCAPS_EMULDRIVER;
}
}
}
......@@ -656,7 +714,7 @@ IDirectSoundCaptureBufferImpl_QueryInterface(
return NO_ERROR;
}
FIXME("(%p,%s,%p)\n", This, debugstr_guid(riid), ppobj);
FIXME("(%p,%s,%p) unsupported GUID\n", This, debugstr_guid(riid), ppobj);
return E_FAIL;
}
......@@ -1226,7 +1284,7 @@ DirectSoundFullDuplexCreate8(
}
*ippDSFD = (IDirectSoundFullDuplexImpl*)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
HEAP_ZERO_MEMORY, sizeof(IDirectSoundFullDuplexImpl));
if (*ippDSFD == NULL) {
TRACE("couldn't allocate memory\n");
......
......@@ -6,7 +6,7 @@
6 stdcall DirectSoundCaptureCreate(ptr ptr ptr) DirectSoundCaptureCreate8
7 stdcall DirectSoundCaptureEnumerateA(ptr ptr) DirectSoundCaptureEnumerateA
8 stdcall DirectSoundCaptureEnumerateW(ptr ptr) DirectSoundCaptureEnumerateW
9 stub GetDeviceID
9 stdcall GetDeviceID(ptr ptr) GetDeviceID
10 stub DirectSoundFullDuplexCreate
11 stdcall DirectSoundCreate8(ptr ptr ptr) DirectSoundCreate8
12 stdcall DirectSoundCaptureCreate8(ptr ptr ptr) DirectSoundCaptureCreate8
......@@ -116,23 +116,8 @@ int ds_hel_queue = DS_HEL_QUEUE;
int ds_snd_queue_max = DS_SND_QUEUE_MAX;
int ds_snd_queue_min = DS_SND_QUEUE_MIN;
int ds_hw_accel = DS_HW_ACCEL_FULL;
/*
* Call the callback provided to DirectSoundEnumerateA.
*/
inline static void enumerate_devices(LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
if (lpDSEnumCallback != NULL) {
TRACE("calling lpDSEnumCallback(%s,\"WINE DirectSound\",\"sound\",%p)\n",
debugstr_guid(&DSDEVID_DefaultPlayback),lpContext);
lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback,
"WINE DirectSound", "sound", lpContext);
}
}
int ds_default_playback = 0;
int ds_default_capture = 0;
/*
* Get a config key from either the app-specific or the default config
......@@ -211,6 +196,12 @@ void setup_dsound_options(void)
ds_hw_accel = DS_HW_ACCEL_EMULATION;
}
if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
ds_default_playback = atoi(buffer);
if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
ds_default_capture = atoi(buffer);
if (appkey) RegCloseKey( appkey );
RegCloseKey( hkey );
......@@ -231,11 +222,57 @@ void setup_dsound_options(void)
ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
"Unknown");
if (ds_default_playback != 0)
WARN("ds_default_playback = %d (default=0)\n",ds_default_playback);
if (ds_default_capture != 0)
WARN("ds_default_capture = %d (default=0)\n",ds_default_playback);
}
/***************************************************************************
* GetDeviceId [DSOUND.2]
*
* Retrieves unique identifier of default device specified
*
* RETURNS
* Success: DS_OK
* Failure: DSERR_INVALIDPARAM
*/
HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
{
if ( ( pGuidSrc == NULL) || (pGuidDest == NULL) ) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
GUID guid;
int err = mmErr(waveOutMessage((HWAVEOUT)ds_default_playback,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
memcpy(pGuidDest, &guid, sizeof(GUID));
return DS_OK;
}
}
if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
GUID guid;
int err = mmErr(waveInMessage((HWAVEIN)ds_default_capture,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
memcpy(pGuidDest, &guid, sizeof(GUID));
return DS_OK;
}
}
memcpy(pGuidDest, pGuidSrc, sizeof(GUID));
return DS_OK;
}
/***************************************************************************
* DirectSoundEnumerateA [DSOUND.2]
*
* Enumerate all DirectSound drivers installed in the system
......@@ -245,25 +282,56 @@ void setup_dsound_options(void)
* Failure: DSERR_INVALIDPARAM
*/
HRESULT WINAPI DirectSoundEnumerateA(
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
LPDSENUMCALLBACKA lpDSEnumCallback,
LPVOID lpContext)
{
WAVEOUTCAPSA wcaps;
unsigned devs, wod;
TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
lpDSEnumCallback, lpContext);
devs = waveOutGetNumDevs();
for (wod = 0; wod < devs; ++wod) {
waveOutGetDevCapsA(wod, &wcaps, sizeof(wcaps));
if (wcaps.dwSupport & WAVECAPS_DIRECTSOUND) {
TRACE("- Device %u supports DirectSound\n", wod);
enumerate_devices(lpDSEnumCallback, lpContext);
return DS_OK;
}
}
return DS_OK;
unsigned devs, wod;
DSDRIVERDESC desc;
GUID guid;
int err;
TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
lpDSEnumCallback, lpContext);
if (lpDSEnumCallback == NULL) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
devs = waveOutGetNumDevs();
if (devs > 0) {
if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
GUID temp;
for (wod = 0; wod < devs; ++wod) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
if (err == DS_OK) {
if (IsEqualGUID( &guid, &temp ) ) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&DSDEVID_DefaultPlayback),"Primary Sound Driver",desc.szDrvName,lpContext);
if (lpDSEnumCallback((LPGUID)&DSDEVID_DefaultPlayback, "Primary Sound Driver", desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
}
}
}
for (wod = 0; wod < devs; ++wod) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
if (err == DS_OK) {
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
if (err == DS_OK) {
TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
if (lpDSEnumCallback(&guid, desc.szDesc, desc.szDrvName, lpContext) == FALSE)
return DS_OK;
}
}
}
return DS_OK;
}
/***************************************************************************
......@@ -588,36 +656,62 @@ static ICOM_VTABLE(IDirectSound8) dsvt =
/*******************************************************************************
* DirectSoundCreate (DSOUND.1)
*/
HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
{
IDirectSoundImpl** ippDS=(IDirectSoundImpl**)ppDS;
PIDSDRIVER drv = NULL;
unsigned wod, wodn;
HRESULT err = DS_OK;
if (lpGUID)
TRACE("(%p,%p,%p)\n",lpGUID,ippDS,pUnkOuter);
else
TRACE("DirectSoundCreate (%p)\n", ippDS);
HRESULT err = DSERR_INVALIDPARAM;
GUID devGuid;
TRACE("(%p,%p,%p)\n",lpcGUID,ippDS,pUnkOuter);
if (ippDS == NULL)
return DSERR_INVALIDPARAM;
if (dsound) {
IDirectSound_AddRef((LPDIRECTSOUND)dsound);
*ippDS = dsound;
return DS_OK;
}
/* Get dsound configuration */
setup_dsound_options();
/* Default device? */
if ( !lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL) )
lpcGUID = &DSDEVID_DefaultPlayback;
if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
if (dsound && IsEqualGUID(&devGuid, &dsound->guid) ) {
ERR("dsound already opened\n");
if (IsEqualGUID(&devGuid, &dsound->guid) ) {
IDirectSound_AddRef((LPDIRECTSOUND)dsound);
*ippDS = dsound;
return DS_OK;
} else {
ERR("different dsound already opened\n");
}
}
/* Enumerate WINMM audio devices and find the one we want */
wodn = waveOutGetNumDevs();
if (!wodn) return DSERR_NODRIVER;
/* FIXME: How do we find the GUID of an audio device? */
wod = 0; /* start at the first audio device */
for (wod=0; wod<wodn; wod++) {
GUID guid;
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
if (err != DS_OK) {
WARN("waveOutMessage failed; err=%lx\n",err);
return err;
}
if (IsEqualGUID( &devGuid, &guid) ) {
err = DS_OK;
break;
}
}
if (err != DS_OK) {
WARN("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
/* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
......@@ -648,6 +742,7 @@ HRESULT WINAPI DirectSoundCreate8(REFGUID lpGUID,LPDIRECTSOUND8 *ppDS,IUnknown *
(*ippDS)->listener = NULL;
(*ippDS)->prebuf = ds_snd_queue_max;
(*ippDS)->guid = devGuid;
/* Get driver description */
if (drv) {
......
......@@ -38,6 +38,8 @@ extern int ds_hel_queue;
extern int ds_snd_queue_max;
extern int ds_snd_queue_min;
extern int ds_hw_accel;
extern int ds_default_playback;
extern int ds_default_capture;
/*****************************************************************************
* Predeclare the interface implementation structures
......@@ -62,6 +64,7 @@ struct IDirectSoundImpl
ICOM_VFIELD(IDirectSound8);
DWORD ref;
/* IDirectSoundImpl fields */
GUID guid;
PIDSDRIVER driver;
DSDRIVERDESC drvdesc;
DSDRIVERCAPS drvcaps;
......
......@@ -983,7 +983,9 @@ void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWOR
void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
IDirectSoundImpl* This = (IDirectSoundImpl*)dwUser;
TRACE("entering at %ld, msg=%08x\n", GetTickCount(), msg);
TRACE("entering at %ld, msg=%08x(%s)\n", GetTickCount(), msg,
msg==MM_WOM_DONE ? "MM_WOM_DONE" : msg==MM_WOM_CLOSE ? "MM_WOM_CLOSE" :
msg==MM_WOM_OPEN ? "MM_WOM_OPEN" : "UNKNOWN");
if (msg == MM_WOM_DONE) {
DWORD inq, mixq, fraglen, buflen, pwplay, playpos, mixpos;
if (This->pwqueue == (DWORD)-1) {
......
......@@ -184,7 +184,8 @@ HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This)
{
DSOUND_PrimaryClose(This);
if (This->hwbuf) {
IDsDriverBuffer_Release(This->hwbuf);
if (IDsDriverBuffer_Release(This->hwbuf) == 0)
This->hwbuf = 0;
} else {
unsigned c;
for (c=0; c<DS_HEL_FRAGS; c++) {
......
......@@ -488,6 +488,12 @@ UINT MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg, DWORD dwParam1,
case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
case DRV_QUERYDSOUNDDESC: /* Wine-specific: Retrieve DirectSound driver description*/
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
case DRV_QUERYDSOUNDGUID: /* Wine-specific: Retrieve DirectSound driver GUID */
return MMDRV_Message(mld, uMsg, dwParam1, dwParam2, TRUE);
default:
WARN("Unknown call %04x\n", uMsg);
return MMSYSERR_INVALPARAM;
......
......@@ -4,7 +4,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = winealsa.drv
IMPORTS = winmm user32 kernel32 ntdll
EXTRALIBS = @ALSALIBS@
EXTRALIBS = $(LIBUUID) @ALSALIBS@
LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o
......
......@@ -149,13 +149,16 @@ typedef struct {
ALSA_MSG_RING msgRing;
/* DirectSound stuff */
DSDRIVERDESC ds_desc;
GUID ds_guid;
} WINE_WAVEOUT;
static WINE_WAVEOUT WOutDev [MAX_WAVEOUTDRV];
static DWORD ALSA_WodNumDevs;
static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc);
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid);
/* These strings used only for tracing */
#if 0
......@@ -412,6 +415,9 @@ LONG ALSA_WaveInit(void)
wwo->caps.vDriverVersion = 0x0100;
wwo->caps.dwFormats = 0x00000000;
wwo->caps.dwSupport = WAVECAPS_VOLUME;
strcpy(wwo->ds_desc.szDesc, "WineALSA DirectSound Driver");
strcpy(wwo->ds_desc.szDrvName, "winealsa.drv");
wwo->ds_guid = DSDEVID_DefaultPlayback;
if (!wine_dlopen("libasound.so.2", RTLD_LAZY|RTLD_GLOBAL, NULL, 0))
{
......@@ -1572,7 +1578,10 @@ DWORD WINAPI ALSA_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
case WODM_SETVOLUME: return wodSetVolume (wDevID, dwParam1);
case WODM_RESTART: return wodRestart (wDevID);
case WODM_RESET: return wodReset (wDevID);
case DRV_QUERYDSOUNDIFACE: return wodDsCreate(wDevID, (PIDSDRIVER*)dwParam1);
case DRV_QUERYDSOUNDIFACE: return wodDsCreate (wDevID, (PIDSDRIVER*)dwParam1);
case DRV_QUERYDSOUNDDESC: return wodDsDesc (wDevID, (PDSDRIVERDESC)dwParam1);
case DRV_QUERYDSOUNDGUID: return wodDsGuid (wDevID, (LPGUID)dwParam1);
default:
FIXME("unknown message %d!\n", wMsg);
}
......@@ -1947,10 +1956,9 @@ static HRESULT WINAPI IDsDriverImpl_GetDriverDesc(PIDSDRIVER iface, PDSDRIVERDES
{
ICOM_THIS(IDsDriverImpl,iface);
TRACE("(%p,%p)\n",iface,pDesc);
memcpy(pDesc, &(WOutDev[This->wDevID].ds_desc), sizeof(DSDRIVERDESC));
pDesc->dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
DSDDESC_USESYSTEMMEMORY;
strcpy(pDesc->szDesc, "WineALSA DirectSound Driver");
strcpy(pDesc->szDrvName, "winealsa.drv");
pDesc->dnDevNode = WOutDev[This->wDevID].waveDesc.dnDevNode;
pDesc->wVxdId = 0;
pDesc->wReserved = 0;
......@@ -2094,6 +2102,22 @@ static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
(*idrv)->primary = NULL;
return MMSYSERR_NOERROR;
}
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
memcpy(desc, &(WOutDev[wDevID].ds_desc), sizeof(DSDRIVERDESC));
return MMSYSERR_NOERROR;
}
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid)
{
TRACE("(%d,%p)\n",wDevID,pGuid);
memcpy(pGuid, &(WOutDev[wDevID].ds_guid), sizeof(GUID));
return MMSYSERR_NOERROR;
}
#endif
#ifndef HAVE_ALSA
......
......@@ -73,7 +73,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wave);
#ifdef HAVE_OSS
#define MAX_WAVEDRV (3)
#define MAX_WAVEDRV (6)
/* state diagram for waveOut writing:
*
......@@ -145,8 +145,8 @@ typedef struct {
} OSS_MSG_RING;
typedef struct tagOSS_DEVICE {
const char* dev_name;
const char* mixer_name;
char dev_name[32];
char mixer_name[32];
unsigned open_count;
WAVEOUTCAPSA out_caps;
WAVEINCAPSA in_caps;
......@@ -162,6 +162,11 @@ typedef struct tagOSS_DEVICE {
BOOL bTriggerSupport;
BOOL bOutputEnabled;
BOOL bInputEnabled;
DSDRIVERDESC ds_desc;
DSDRIVERCAPS ds_caps;
DSCDRIVERCAPS dsc_caps;
GUID ds_guid;
GUID dsc_guid;
} OSS_DEVICE;
static OSS_DEVICE OSS_Devices[MAX_WAVEDRV];
......@@ -226,6 +231,10 @@ static unsigned numInDev;
static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv);
static DWORD widDsCreate(UINT wDevID, PIDSCDRIVER* drv);
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc);
static DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc);
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid);
static DWORD widDsGuid(UINT wDevID, LPGUID pGuid);
/* These strings used only for tracing */
static const char *wodPlayerCmdString[] = {
......@@ -258,6 +267,7 @@ static int getEnables(OSS_DEVICE *ossdev)
static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format)
{
int fd, val, rc;
TRACE("(%p,%d)\n",ossdev,strict_format);
if ((fd = open(ossdev->dev_name, ossdev->open_access|O_NDELAY, 0)) == -1)
{
......@@ -266,12 +276,20 @@ static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format)
}
fcntl(fd, F_SETFD, 1); /* set close on exec flag */
/* turn full duplex on if it has been requested */
if (ossdev->open_access == O_RDWR && ossdev->full_duplex)
ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
if (ossdev->open_access == O_RDWR && ossdev->full_duplex) {
rc = ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0);
if (rc != 0) {
ERR("ioctl(%s, SNDCTL_DSP_SETDUPLEX) failed (%s)\n", ossdev->dev_name, strerror(errno));
goto error;
}
}
if (ossdev->audio_fragment)
{
ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &ossdev->audio_fragment);
if (ossdev->audio_fragment) {
rc = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &ossdev->audio_fragment);
if (rc != 0) {
ERR("ioctl(%s, SNDCTL_DSP_SETFRAGMENT) failed (%s)\n", ossdev->dev_name, strerror(errno));
goto error;
}
}
/* First size and stereo then samplerate */
......@@ -306,8 +324,22 @@ static DWORD OSS_RawOpenDevice(OSS_DEVICE* ossdev, int strict_format)
}
}
ossdev->fd = fd;
ossdev->bOutputEnabled = TRUE; /* OSS enables by default */
ossdev->bInputEnabled = TRUE; /* OSS enables by default */
if (ossdev->bTriggerSupport) {
int trigger;
rc = ioctl(fd, SNDCTL_DSP_GETTRIGGER, &trigger);
if (rc != 0) {
ERR("ioctl(%s, SNDCTL_DSP_GETTRIGGER) failed (%s)\n",
ossdev->dev_name, strerror(errno));
goto error;
}
ossdev->bOutputEnabled = ((trigger & PCM_ENABLE_OUTPUT) == PCM_ENABLE_OUTPUT);
ossdev->bInputEnabled = ((trigger & PCM_ENABLE_INPUT) == PCM_ENABLE_INPUT);
} else {
ossdev->bOutputEnabled = TRUE; /* OSS enables by default */
ossdev->bInputEnabled = TRUE; /* OSS enables by default */
}
return MMSYSERR_NOERROR;
......@@ -328,6 +360,7 @@ static DWORD OSS_OpenDevice(OSS_DEVICE* ossdev, unsigned req_access,
int sample_rate, int stereo, int fmt)
{
DWORD ret;
TRACE("(%p,%u,%p,%d,%d,%d,%x)\n",ossdev,req_access,frag,strict_format,sample_rate,stereo,fmt);
if (ossdev->full_duplex && (req_access == O_RDONLY || req_access == O_WRONLY))
req_access = O_RDWR;
......@@ -354,6 +387,7 @@ static DWORD OSS_OpenDevice(OSS_DEVICE* ossdev, unsigned req_access,
WARN("Mismatch in access...\n");
return WAVERR_BADFORMAT;
}
/* FIXME: if really needed, we could do, in this case, on the fly
* PCM conversion (using the MSACM ad hoc driver)
*/
......@@ -390,6 +424,7 @@ static DWORD OSS_OpenDevice(OSS_DEVICE* ossdev, unsigned req_access,
*/
static void OSS_CloseDevice(OSS_DEVICE* ossdev)
{
TRACE("(%p)\n",ossdev);
if (ossdev->open_count>0) {
ossdev->open_count--;
} else {
......@@ -456,10 +491,33 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
{
int rc,arg;
int f,c,r;
int mixer;
TRACE("(%p) %s\n", ossdev, ossdev->dev_name);
if (OSS_OpenDevice(ossdev, O_WRONLY, NULL, 0,-1,-1,-1) != 0) return FALSE;
ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
if ((mixer = open(ossdev->mixer_name, O_RDONLY|O_NDELAY)) >= 0) {
mixer_info info;
if (ioctl(mixer, SOUND_MIXER_INFO, &info) >= 0) {
close(mixer);
strncpy(ossdev->ds_desc.szDesc, info.name, sizeof(info.name));
strcpy(ossdev->ds_desc.szDrvName, "wineoss.drv");
strncpy(ossdev->out_caps.szPname, info.name, sizeof(info.name));
TRACE("%s\n", ossdev->ds_desc.szDesc);
} else {
ERR("%s: can't read info!\n", ossdev->mixer_name);
OSS_CloseDevice(ossdev);
close(mixer);
return FALSE;
}
} else {
ERR("%s: not found!\n", ossdev->mixer_name);
OSS_CloseDevice(ossdev);
return FALSE;
}
close(mixer);
/* FIXME: some programs compare this string against the content of the
* registry for MM drivers. The names have to match in order for the
* program to work (e.g. MS win9x mplayer.exe)
......@@ -471,8 +529,6 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
#else
ossdev->out_caps.wMid = 0x00FF; /* Manufac ID */
ossdev->out_caps.wPid = 0x0001; /* Product ID */
/* strcpy(ossdev->out_caps.szPname, "OpenSoundSystem WAVOUT Driver");*/
strcpy(ossdev->out_caps.szPname, "CS4236/37/38");
#endif
ossdev->out_caps.vDriverVersion = 0x0100;
ossdev->out_caps.wChannels = 1;
......@@ -480,6 +536,10 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
ossdev->out_caps.wReserved1 = 0;
ossdev->out_caps.dwSupport = WAVECAPS_VOLUME;
/* direct sound caps */
ossdev->ds_caps.dwFlags = 0;
ossdev->ds_caps.dwPrimaryBuffers = 1;
if (WINE_TRACE_ON(wave)) {
/* Note that this only reports the formats supported by the hardware.
* The driver may support other formats and do the conversions in
......@@ -501,10 +561,14 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
arg=win_std_oss_fmts[f];
rc=ioctl(ossdev->fd, SNDCTL_DSP_SAMPLESIZE, &arg);
if (rc!=0 || arg!=win_std_oss_fmts[f]) {
TRACE("DSP_SAMPLESIZE: rc=%d returned 0x%x for 0x%x\n",
TRACE("DSP_SAMPLESIZE: rc=%d returned %d for %d\n",
rc,arg,win_std_oss_fmts[f]);
continue;
}
if (f == 0)
ossdev->ds_caps.dwFlags |= DSCAPS_PRIMARY8BIT;
else if (f == 1)
ossdev->ds_caps.dwFlags |= DSCAPS_PRIMARY16BIT;
for (c=0;c<2;c++) {
arg=c;
......@@ -513,9 +577,12 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
TRACE("DSP_STEREO: rc=%d returned %d for %d\n",rc,arg,c);
continue;
}
if (c==1) {
if (c == 0) {
ossdev->ds_caps.dwFlags |= DSCAPS_PRIMARYMONO;
} else if (c==1) {
ossdev->out_caps.wChannels=2;
ossdev->out_caps.dwSupport|=WAVECAPS_LRVOLUME;
ossdev->ds_caps.dwFlags |= DSCAPS_PRIMARYSTEREO;
}
for (r=0;r<sizeof(win_std_rates)/sizeof(*win_std_rates);r++) {
......@@ -536,8 +603,11 @@ static BOOL OSS_WaveOutInit(OSS_DEVICE* ossdev)
}
/* well, might as well use the DirectSound cap flag for something */
if ((arg & DSP_CAP_TRIGGER) && (arg & DSP_CAP_MMAP) &&
!(arg & DSP_CAP_BATCH))
!(arg & DSP_CAP_BATCH)) {
ossdev->out_caps.dwSupport |= WAVECAPS_DIRECTSOUND;
} else {
ossdev->ds_caps.dwFlags |= DSCAPS_EMULDRIVER;
}
}
OSS_CloseDevice(ossdev);
TRACE("out dwFormats = %08lX, dwSupport = %08lX\n",
......@@ -554,10 +624,31 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
{
int rc,arg;
int f,c,r;
int mixer;
TRACE("(%p) %s\n", ossdev, ossdev->dev_name);
if (OSS_OpenDevice(ossdev, O_RDONLY, NULL, 0,-1,-1,-1) != 0) return FALSE;
ioctl(ossdev->fd, SNDCTL_DSP_RESET, 0);
if ((mixer = open(ossdev->mixer_name, O_RDONLY|O_NDELAY)) >= 0) {
mixer_info info;
if (ioctl(mixer, SOUND_MIXER_INFO, &info) >= 0) {
close(mixer);
strncpy(ossdev->in_caps.szPname, info.name, sizeof(info.name));
TRACE("%s\n", ossdev->ds_desc.szDesc);
} else {
ERR("%s: can't read info!\n", ossdev->mixer_name);
OSS_CloseDevice(ossdev);
close(mixer);
return FALSE;
}
} else {
ERR("%s: not found!\n", ossdev->mixer_name);
OSS_CloseDevice(ossdev);
return FALSE;
}
close(mixer);
/* See comment in OSS_WaveOutInit */
#ifdef EMULATE_SB16
ossdev->in_caps.wMid = 0x0002;
......@@ -566,13 +657,18 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
#else
ossdev->in_caps.wMid = 0x00FF; /* Manufac ID */
ossdev->in_caps.wPid = 0x0001; /* Product ID */
strcpy(ossdev->in_caps.szPname, "OpenSoundSystem WAVIN Driver");
#endif
ossdev->in_caps.dwFormats = 0x00000000;
ossdev->in_caps.wChannels = 1;
ossdev->in_caps.wReserved1 = 0;
ossdev->bTriggerSupport = FALSE;
/* direct sound caps */
ossdev->dsc_caps.dwSize = sizeof(ossdev->dsc_caps);
ossdev->dsc_caps.dwFlags = 0;
ossdev->dsc_caps.dwFormats = 0x00000000;
ossdev->dsc_caps.dwChannels = 1;
if (WINE_TRACE_ON(wave)) {
/* Note that this only reports the formats supported by the hardware.
* The driver may support other formats and do the conversions in
......@@ -602,6 +698,7 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
}
if (c==1) {
ossdev->in_caps.wChannels=2;
ossdev->dsc_caps.dwChannels=2;
}
for (r=0;r<sizeof(win_std_rates)/sizeof(*win_std_rates);r++) {
......@@ -610,6 +707,7 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
TRACE("DSP_SPEED: rc=%d returned %d for %dx%dx%d\n",rc,arg,win_std_rates[r],win_std_oss_fmts[f],c+1);
if (rc==0 && NEAR_MATCH(arg,win_std_rates[r]))
ossdev->in_caps.dwFormats|=win_std_formats[f][c][r];
ossdev->dsc_caps.dwFormats|=win_std_formats[f][c][r];
}
}
}
......@@ -619,8 +717,12 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
if (arg & DSP_CAP_TRIGGER)
ossdev->bTriggerSupport = TRUE;
if ((arg & DSP_CAP_TRIGGER) && (arg & DSP_CAP_MMAP) &&
!(arg & DSP_CAP_BATCH))
!(arg & DSP_CAP_BATCH)) {
/* FIXME: enable the next statement if you want to work on the driver */
#if 0
ossdev->in_caps_support |= WAVECAPS_DIRECTSOUND;
#endif
}
if ((arg & DSP_CAP_REALTIME) && !(arg & DSP_CAP_BATCH))
ossdev->in_caps_support |= WAVECAPS_SAMPLEACCURATE;
}
......@@ -637,6 +739,7 @@ static BOOL OSS_WaveInInit(OSS_DEVICE* ossdev)
static void OSS_WaveFullDuplexInit(OSS_DEVICE* ossdev)
{
int caps;
TRACE("(%p)\n",ossdev);
if (OSS_OpenDevice(ossdev, O_RDWR, NULL, 0,-1,-1,-1) != 0) return;
if (ioctl(ossdev->fd, SNDCTL_DSP_GETCAPS, &caps) == 0)
......@@ -646,6 +749,11 @@ static void OSS_WaveFullDuplexInit(OSS_DEVICE* ossdev)
OSS_CloseDevice(ossdev);
}
#define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
guid.Data1 = l; guid.Data2 = w1; guid.Data3 = w2; \
guid.Data4[0] = b1; guid.Data4[1] = b2; guid.Data4[2] = b3; \
guid.Data4[3] = b4; guid.Data4[4] = b5; guid.Data4[5] = b6; \
guid.Data4[6] = b7; guid.Data4[7] = b8;
/******************************************************************
* OSS_WaveInit
*
......@@ -654,6 +762,7 @@ static void OSS_WaveFullDuplexInit(OSS_DEVICE* ossdev)
LONG OSS_WaveInit(void)
{
int i;
TRACE("()\n");
/* FIXME: only one device is supported */
memset(&OSS_Devices, 0, sizeof(OSS_Devices));
......@@ -661,12 +770,19 @@ LONG OSS_WaveInit(void)
* we should also be able to configure (bitmap) which devices we want to use...
* - or even store the name of all drivers in our configuration
*/
OSS_Devices[0].dev_name = "/dev/dsp";
OSS_Devices[0].mixer_name = "/dev/mixer";
OSS_Devices[1].dev_name = "/dev/dsp1";
OSS_Devices[1].mixer_name = "/dev/mixer1";
OSS_Devices[2].dev_name = "/dev/dsp2";
OSS_Devices[2].mixer_name = "/dev/mixer2";
for (i = 0; i < MAX_WAVEDRV; ++i)
{
if (i == 0) {
sprintf((char *)OSS_Devices[i].dev_name, "/dev/dsp");
sprintf((char *)OSS_Devices[i].mixer_name, "/dev/mixer");
} else {
sprintf((char *)OSS_Devices[i].dev_name, "/dev/dsp%d", i);
sprintf((char *)OSS_Devices[i].mixer_name, "/dev/mixer%d", i);
}
INIT_GUID(OSS_Devices[i].ds_guid, 0xe437ebb6, 0x534f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70 + i);
INIT_GUID(OSS_Devices[i].dsc_guid, 0xe437ebb6, 0x534f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x80 + i);
}
/* start with output device */
for (i = 0; i < MAX_WAVEDRV; ++i)
......@@ -882,7 +998,7 @@ static BOOL wodUpdatePlayedTotal(WINE_WAVEOUT* wwo, audio_buf_info* info)
if (!info) info = &dspspace;
if (ioctl(wwo->ossdev->fd, SNDCTL_DSP_GETOSPACE, info) < 0) {
ERR("ioctl can't 'SNDCTL_DSP_GETOSPACE' !\n");
ERR("ioctl(%s, SNDCTL_DSP_GETOSPACE) failed (%s)\n", wwo->ossdev->dev_name, strerror(errno));
return FALSE;
}
wwo->dwPlayedTotal = wwo->dwWrittenTotal - (wwo->dwBufferSize - info->bytes);
......@@ -1419,7 +1535,7 @@ static DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
}
/* Read output space info for future reference */
if (ioctl(wwo->ossdev->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
ERR("ioctl can't 'SNDCTL_DSP_GETOSPACE' !\n");
ERR("ioctl(%s, SNDCTL_DSP_GETOSPACE) failed (%s)\n", wwo->ossdev->dev_name, strerror(errno));
OSS_CloseDevice(wwo->ossdev);
wwo->state = WINE_WS_CLOSED;
return MMSYSERR_NOTENABLED;
......@@ -1731,7 +1847,7 @@ static DWORD wodGetVolume(WORD wDevID, LPDWORD lpdwVol)
return MMSYSERR_NOTENABLED;
}
if (ioctl(mixer, SOUND_MIXER_READ_PCM, &volume) == -1) {
WARN("unable to read mixer !\n");
WARN("ioctl(%s, SOUND_MIXER_READ_PCM) failed (%s)n", WOutDev[wDevID].ossdev->mixer_name, strerror(errno));
return MMSYSERR_NOTENABLED;
}
close(mixer);
......@@ -1764,7 +1880,7 @@ static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
return MMSYSERR_NOTENABLED;
}
if (ioctl(mixer, SOUND_MIXER_WRITE_PCM, &volume) == -1) {
WARN("unable to set mixer !\n");
WARN("ioctl(%s, SOUND_MIXER_WRITE_PCM) failed (%s)\n", WOutDev[wDevID].ossdev->mixer_name, strerror(errno));
return MMSYSERR_NOTENABLED;
} else {
TRACE("volume=%04x\n", (unsigned)volume);
......@@ -1808,7 +1924,9 @@ DWORD WINAPI OSS_wodMessage(UINT wDevID, UINT wMsg, DWORD dwUser,
case WODM_RESTART: return wodRestart (wDevID);
case WODM_RESET: return wodReset (wDevID);
case DRV_QUERYDSOUNDIFACE: return wodDsCreate(wDevID, (PIDSDRIVER*)dwParam1);
case DRV_QUERYDSOUNDIFACE: return wodDsCreate (wDevID, (PIDSDRIVER*)dwParam1);
case DRV_QUERYDSOUNDDESC: return wodDsDesc (wDevID, (PDSDRIVERDESC)dwParam1);
case DRV_QUERYDSOUNDGUID: return wodDsGuid (wDevID, (LPGUID)dwParam1);
default:
FIXME("unknown message %d!\n", wMsg);
}
......@@ -1845,6 +1963,7 @@ struct IDsDriverBufferImpl
static HRESULT DSDB_MapPrimary(IDsDriverBufferImpl *dsdb)
{
WINE_WAVEOUT *wwo = &(WOutDev[dsdb->drv->wDevID]);
TRACE("(%p)\n",dsdb);
if (!wwo->mapping) {
wwo->mapping = mmap(NULL, wwo->maplen, PROT_WRITE, MAP_SHARED,
wwo->ossdev->fd, 0);
......@@ -1887,9 +2006,10 @@ static HRESULT DSDB_MapPrimary(IDsDriverBufferImpl *dsdb)
static HRESULT DSDB_UnmapPrimary(IDsDriverBufferImpl *dsdb)
{
WINE_WAVEOUT *wwo = &(WOutDev[dsdb->drv->wDevID]);
TRACE("(%p)\n",dsdb);
if (wwo->mapping) {
if (munmap(wwo->mapping, wwo->maplen) < 0) {
ERR("(%p): Could not unmap sound device (errno=%d)\n", dsdb, errno);
ERR("(%p): Could not unmap sound device (%s)\n", dsdb, strerror(errno));
return DSERR_GENERIC;
}
wwo->mapping = NULL;
......@@ -1908,19 +2028,25 @@ static HRESULT WINAPI IDsDriverBufferImpl_QueryInterface(PIDSDRIVERBUFFER iface,
static ULONG WINAPI IDsDriverBufferImpl_AddRef(PIDSDRIVERBUFFER iface)
{
ICOM_THIS(IDsDriverBufferImpl,iface);
TRACE("(%p)\n",This);
This->ref++;
TRACE("ref=%ld\n",This->ref);
return This->ref;
}
static ULONG WINAPI IDsDriverBufferImpl_Release(PIDSDRIVERBUFFER iface)
{
ICOM_THIS(IDsDriverBufferImpl,iface);
if (--This->ref)
TRACE("(%p)\n",This);
if (--This->ref) {
TRACE("ref=%ld\n",This->ref);
return This->ref;
}
if (This == This->drv->primary)
This->drv->primary = NULL;
DSDB_UnmapPrimary(This);
HeapFree(GetProcessHeap(),0,This);
TRACE("ref=0\n");
return 0;
}
......@@ -1995,7 +2121,7 @@ static HRESULT WINAPI IDsDriverBufferImpl_GetPosition(PIDSDRIVERBUFFER iface,
return DSERR_UNINITIALIZED;
}
if (ioctl(WOutDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_GETOPTR, &info) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_GETOPTR) failed (%s)\n", WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
ptr = info.ptr & ~3; /* align the pointer, just in case */
......@@ -2021,7 +2147,7 @@ static HRESULT WINAPI IDsDriverBufferImpl_Play(PIDSDRIVERBUFFER iface, DWORD dwR
WOutDev[This->drv->wDevID].ossdev->bOutputEnabled = TRUE;
enable = getEnables(WOutDev[This->drv->wDevID].ossdev);
if (ioctl(WOutDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
WOutDev[This->drv->wDevID].ossdev->bOutputEnabled = FALSE;
return DSERR_GENERIC;
}
......@@ -2037,13 +2163,13 @@ static HRESULT WINAPI IDsDriverBufferImpl_Stop(PIDSDRIVERBUFFER iface)
WOutDev[This->drv->wDevID].ossdev->bOutputEnabled = FALSE;
enable = getEnables(WOutDev[This->drv->wDevID].ossdev);
if (ioctl(WOutDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
#if 0
/* the play position must be reset to the beginning of the buffer */
if (ioctl(WOutDev[This->drv->wDevID].unixdev, SNDCTL_DSP_RESET, 0) < 0) {
ERR("ioctl failed (%d)\n", errno);
if (ioctl(WOutDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_RESET, 0) < 0) {
ERR("ioctl(%s, SNDCTL_DSP_RESET) failed (%s)\n", WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
#endif
......@@ -2081,16 +2207,22 @@ static HRESULT WINAPI IDsDriverImpl_QueryInterface(PIDSDRIVER iface, REFIID riid
static ULONG WINAPI IDsDriverImpl_AddRef(PIDSDRIVER iface)
{
ICOM_THIS(IDsDriverImpl,iface);
TRACE("(%p)\n",This);
This->ref++;
TRACE("ref=%ld\n",This->ref);
return This->ref;
}
static ULONG WINAPI IDsDriverImpl_Release(PIDSDRIVER iface)
{
ICOM_THIS(IDsDriverImpl,iface);
if (--This->ref)
TRACE("(%p)\n",This);
if (--This->ref) {
TRACE("ref=%ld\n",This->ref);
return This->ref;
}
HeapFree(GetProcessHeap(),0,This);
TRACE("ref=0\n");
return 0;
}
......@@ -2098,10 +2230,12 @@ static HRESULT WINAPI IDsDriverImpl_GetDriverDesc(PIDSDRIVER iface, PDSDRIVERDES
{
ICOM_THIS(IDsDriverImpl,iface);
TRACE("(%p,%p)\n",iface,pDesc);
pDesc->dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
/* copy version from driver */
memcpy(pDesc, &(WOutDev[This->wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));
pDesc->dwFlags |= DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
DSDDESC_USESYSTEMMEMORY | DSDDESC_DONTNEEDPRIMARYLOCK;
strcpy(pDesc->szDesc,"WineOSS DirectSound Driver");
strcpy(pDesc->szDrvName,"wineoss.drv");
pDesc->dnDevNode = WOutDev[This->wDevID].waveDesc.dnDevNode;
pDesc->wVxdId = 0;
pDesc->wReserved = 0;
......@@ -2126,7 +2260,7 @@ static HRESULT WINAPI IDsDriverImpl_Open(PIDSDRIVER iface)
WOutDev[This->wDevID].ossdev->bOutputEnabled = FALSE;
enable = getEnables(WOutDev[This->wDevID].ossdev);
if (ioctl(WOutDev[This->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",WOutDev[This->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
return DS_OK;
......@@ -2145,15 +2279,9 @@ static HRESULT WINAPI IDsDriverImpl_Close(PIDSDRIVER iface)
static HRESULT WINAPI IDsDriverImpl_GetCaps(PIDSDRIVER iface, PDSDRIVERCAPS pCaps)
{
/* ICOM_THIS(IDsDriverImpl,iface); */
ICOM_THIS(IDsDriverImpl,iface);
TRACE("(%p,%p)\n",iface,pCaps);
memset(pCaps, 0, sizeof(*pCaps));
/* FIXME: need to check actual capabilities */
pCaps->dwFlags = DSCAPS_PRIMARYMONO | DSCAPS_PRIMARYSTEREO |
DSCAPS_PRIMARY8BIT | DSCAPS_PRIMARY16BIT;
pCaps->dwPrimaryBuffers = 1;
/* the other fields only apply to secondary buffers, which we don't support
* (unless we want to mess with wavetable synthesizers and MIDI) */
memcpy(pCaps, &(WOutDev[This->wDevID].ossdev->ds_caps), sizeof(DSDRIVERCAPS));
return DS_OK;
}
......@@ -2169,8 +2297,8 @@ static HRESULT WINAPI IDsDriverImpl_CreateSoundBuffer(PIDSDRIVER iface,
HRESULT err;
audio_buf_info info;
int enable = 0;
TRACE("(%p,%p,%lx,%lx)\n",iface,pwfx,dwFlags,dwCardAddress);
/* we only support primary buffers */
if (!(dwFlags & DSBCAPS_PRIMARYBUFFER))
return DSERR_UNSUPPORTED;
......@@ -2188,7 +2316,7 @@ static HRESULT WINAPI IDsDriverImpl_CreateSoundBuffer(PIDSDRIVER iface,
/* check how big the DMA buffer is now */
if (ioctl(WOutDev[This->wDevID].ossdev->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_GETOSPACE) failed (%s)\n", WOutDev[This->wDevID].ossdev->dev_name, strerror(errno));
HeapFree(GetProcessHeap(),0,*ippdsdb);
*ippdsdb = NULL;
return DSERR_GENERIC;
......@@ -2211,7 +2339,7 @@ static HRESULT WINAPI IDsDriverImpl_CreateSoundBuffer(PIDSDRIVER iface,
WOutDev[This->wDevID].ossdev->bOutputEnabled = FALSE;
enable = getEnables(WOutDev[This->wDevID].ossdev);
if (ioctl(WOutDev[This->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", WOutDev[This->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
......@@ -2246,6 +2374,7 @@ static ICOM_VTABLE(IDsDriver) dsdvt =
static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
{
IDsDriverImpl** idrv = (IDsDriverImpl**)drv;
TRACE("(%d,%p)\n",wDevID,drv);
/* the HAL isn't much better than the HEL if we can't do mmap() */
if (!(WOutDev[wDevID].ossdev->out_caps.dwSupport & WAVECAPS_DIRECTSOUND)) {
......@@ -2266,6 +2395,20 @@ static DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
return MMSYSERR_NOERROR;
}
static DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
TRACE("(%d,%p)\n",wDevID,desc);
memcpy(desc, &(WOutDev[wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));
return MMSYSERR_NOERROR;
}
static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid)
{
TRACE("(%d,%p)\n",wDevID,pGuid);
memcpy(pGuid, &(WOutDev[wDevID].ossdev->ds_guid), sizeof(GUID));
return MMSYSERR_NOERROR;
}
/*======================================================================*
* Low level WAVE IN implementation *
*======================================================================*/
......@@ -2343,7 +2486,7 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
wwi->ossdev->bInputEnabled = FALSE;
enable = getEnables(wwi->ossdev);
if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0)
ERR("ioctl(SNDCTL_DSP_SETTRIGGER) failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
/* the soundblaster live needs a micro wake to get its recording started
* (or GETISPACE will have 0 frags all the time)
......@@ -2499,7 +2642,7 @@ static DWORD CALLBACK widRecorder(LPVOID pmt)
enable = getEnables(wwi->ossdev);
if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
wwi->ossdev->bInputEnabled = FALSE;
ERR("ioctl(SNDCTL_DSP_SETTRIGGER) failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
}
}
else
......@@ -2650,7 +2793,7 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
ioctl(wwi->ossdev->fd, SNDCTL_DSP_GETBLKSIZE, &fragment_size);
if (fragment_size == -1) {
WARN("IOCTL can't 'SNDCTL_DSP_GETBLKSIZE' !\n");
WARN("ioctl(%s, SNDCTL_DSP_GETBLKSIZE) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno));
OSS_CloseDevice(wwi->ossdev);
wwi->state = WINE_WS_CLOSED;
return MMSYSERR_NOTENABLED;
......@@ -2899,6 +3042,8 @@ DWORD WINAPI OSS_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser,
case WIDM_START: return widStart (wDevID);
case WIDM_STOP: return widStop (wDevID);
case DRV_QUERYDSOUNDIFACE: return widDsCreate (wDevID, (PIDSCDRIVER*)dwParam1);
case DRV_QUERYDSOUNDDESC: return widDsDesc (wDevID, (PDSDRIVERDESC)dwParam1);
case DRV_QUERYDSOUNDGUID: return widDsGuid (wDevID, (LPGUID)dwParam1);
default:
FIXME("unknown message %u!\n", wMsg);
}
......@@ -3047,7 +3192,7 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetPosition(PIDSCDRIVERBUFFER i
return DSERR_UNINITIALIZED;
}
if (ioctl(WInDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_GETIPTR, &info) < 0) {
ERR("ioctl failed (%s)\n", strerror(errno));
ERR("ioctl(%s, SNDCTL_DSP_GETIPTR) failed (%s)\n", WInDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
ptr = info.ptr & ~3; /* align the pointer, just in case */
......@@ -3080,7 +3225,7 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_Start(PIDSCDRIVERBUFFER iface,
WInDev[This->drv->wDevID].ossdev->bInputEnabled = TRUE;
enable = getEnables(WInDev[This->drv->wDevID].ossdev);
if (ioctl(WInDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", WInDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
WInDev[This->drv->wDevID].ossdev->bInputEnabled = FALSE;
return DSERR_GENERIC;
}
......@@ -3096,7 +3241,7 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_Stop(PIDSCDRIVERBUFFER iface)
WInDev[This->drv->wDevID].ossdev->bInputEnabled = FALSE;
enable = getEnables(WInDev[This->drv->wDevID].ossdev);
if (ioctl(WInDev[This->drv->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", WInDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
......@@ -3139,16 +3284,22 @@ static HRESULT WINAPI IDsCaptureDriverImpl_QueryInterface(PIDSCDRIVER iface, REF
static ULONG WINAPI IDsCaptureDriverImpl_AddRef(PIDSCDRIVER iface)
{
ICOM_THIS(IDsCaptureDriverImpl,iface);
TRACE("(%p)\n",This);
This->ref++;
TRACE("ref=%ld\n",This->ref);
return This->ref;
}
static ULONG WINAPI IDsCaptureDriverImpl_Release(PIDSCDRIVER iface)
{
ICOM_THIS(IDsCaptureDriverImpl,iface);
if (--This->ref)
TRACE("(%p)\n",This);
if (--This->ref) {
TRACE("ref=%ld\n",This->ref);
return This->ref;
}
HeapFree(GetProcessHeap(),0,This);
TRACE("ref=0\n");
return 0;
}
......@@ -3162,11 +3313,12 @@ static HRESULT WINAPI IDsCaptureDriverImpl_GetDriverDesc(PIDSCDRIVER iface, PDSD
return DSERR_INVALIDPARAM;
}
pDesc->dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
/* copy version from driver */
memcpy(pDesc, &(WInDev[This->wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));
pDesc->dwFlags |= DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
DSDDESC_USESYSTEMMEMORY | DSDDESC_DONTNEEDPRIMARYLOCK |
DSDDESC_DONTNEEDSECONDARYLOCK;
strcpy(pDesc->szDesc,"WineOSS DirectSound Driver");
strcpy(pDesc->szDrvName,"wineoss.drv");
pDesc->dnDevNode = WInDev[This->wDevID].waveDesc.dnDevNode;
pDesc->wVxdId = 0;
pDesc->wReserved = 0;
......@@ -3203,16 +3355,7 @@ static HRESULT WINAPI IDsCaptureDriverImpl_GetCaps(PIDSCDRIVER iface, PDSCDRIVER
{
ICOM_THIS(IDsCaptureDriverImpl,iface);
TRACE("(%p,%p)\n",This,pCaps);
if ( !pCaps || (pCaps->dwSize != sizeof(*pCaps)) ) {
TRACE("invalid parameter\n");
return DSERR_INVALIDPARAM;
}
pCaps->dwFlags = 0;
pCaps->dwChannels = WInDev[This->wDevID].ossdev->in_caps.wChannels;
pCaps->dwFormats = WInDev[This->wDevID].ossdev->in_caps.dwFormats;
memcpy(pCaps, &(WInDev[This->wDevID].ossdev->dsc_caps), sizeof(DSCDRIVERCAPS));
return DS_OK;
}
......@@ -3263,7 +3406,7 @@ static HRESULT WINAPI IDsCaptureDriverImpl_CreateCaptureBuffer(PIDSCDRIVER iface
/* check how big the DMA buffer is now */
if (ioctl(WInDev[This->wDevID].ossdev->fd, SNDCTL_DSP_GETISPACE, &info) < 0) {
ERR("ioctl failed (%s)\n", strerror(errno));
ERR("ioctl(%s, SNDCTL_DSP_GETISPACE) failed (%s)\n", WInDev[This->wDevID].ossdev->dev_name, strerror(errno));
HeapFree(GetProcessHeap(),0,*ippdscdb);
*ippdscdb = NULL;
return DSERR_GENERIC;
......@@ -3286,7 +3429,7 @@ static HRESULT WINAPI IDsCaptureDriverImpl_CreateCaptureBuffer(PIDSCDRIVER iface
WInDev[This->wDevID].ossdev->bInputEnabled = FALSE;
enable = getEnables(WInDev[This->wDevID].ossdev);
if (ioctl(WInDev[This->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
ERR("ioctl failed (%d)\n", errno);
ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", WInDev[This->wDevID].ossdev->dev_name, strerror(errno));
return DSERR_GENERIC;
}
......@@ -3332,6 +3475,21 @@ static DWORD widDsCreate(UINT wDevID, PIDSCDRIVER* drv)
return MMSYSERR_NOERROR;
}
static DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
memcpy(desc, &(WInDev[wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));
return MMSYSERR_NOERROR;
}
static DWORD widDsGuid(UINT wDevID, LPGUID pGuid)
{
TRACE("(%d,%p)\n",wDevID,pGuid);
memcpy(pGuid, &(WInDev[wDevID].ossdev->dsc_guid), sizeof(GUID));
return MMSYSERR_NOERROR;
}
#else /* !HAVE_OSS */
/**************************************************************************
......
......@@ -267,6 +267,16 @@ WINE REGISTRY Version 2
;"SndQueueMax" = "28"
;; Min number of fragments to prebuffer
;"SndQueueMin" = "12"
;; Forces emulation mode (using wave api)
;"HardwareAcceleration" = "Emulation"
;; Sets default playback device (0 - number of devices - 1)
;"DefaultPlayback" = "0" ; use first device (/dev/dsp)
;"DefaultPlayback" = "1" ; use second device (/dev/dsp1)
;"DefaultPlayback" = "2" ; use third device (/dev/dsp2)
;; Sets default capture device (0 - number of devices - 1)
;"DefaultCapture" = "0" ; use first device (/dev/dsp)
;"DefaultCapture" = "1" ; use second device (/dev/dsp1)
;"DefaultCapture" = "2" ; use third device (/dev/dsp2)
[Network]
;; Use the DNS (Unix) host name always as NetBIOS "ComputerName" (boolean, default "Y").
......
......@@ -81,6 +81,8 @@ typedef struct {
#define DRV_QUERYMAPPABLE (DRV_RESERVED + 5)
#ifdef __WINESRC__
#define DRV_QUERYDSOUNDIFACE (DRV_RESERVED + 10)
#define DRV_QUERYDSOUNDDESC (DRV_RESERVED + 11)
#define DRV_QUERYDSOUNDGUID (DRV_RESERVED + 12)
#endif
#define WODM_INIT DRVM_INIT
......
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