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