mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
dsound-EAX: Various improvements to EAX support (fixes Wine-Staging bug 195).
This commit is contained in:
parent
f925ee9336
commit
e5a4f11591
@ -0,0 +1,268 @@
|
||||
From 3b8dcd1ce62f9eed3e3571288101b4897ed42fc0 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 4 Apr 2015 21:09:18 +0200
|
||||
Subject: dsound: Various improvements to EAX support.
|
||||
|
||||
The previous version had several problems (see wine-staging bug 195):
|
||||
* IDirectSoundBufferImpl_Duplicate doesn't initialize EAX properties
|
||||
* Various race-conditions between initializing EAX and setting buffer properties
|
||||
* Missing locks while iterating through the list of sound buffers
|
||||
|
||||
To fix problems 2 and 3 it might seem useful to introduce additional locking,
|
||||
but testing reveals that it slows down the mixer thread too much. Some applications
|
||||
use a huge amount of buffers, and its a waste of time to update them all immediately.
|
||||
Thats why this patch adds a 'reverb_update' variable, the mixer thread will
|
||||
update it later when necessary (-> much faster). Moreover, to avoid unnecessary
|
||||
locking, we initialize the EAX-specific properties always (for both the device and
|
||||
the buffers).
|
||||
---
|
||||
dlls/dsound/buffer.c | 11 ++++----
|
||||
dlls/dsound/dsound.c | 2 ++
|
||||
dlls/dsound/dsound_eax.h | 1 +
|
||||
dlls/dsound/dsound_private.h | 1 +
|
||||
dlls/dsound/eax.c | 66 +++++++++++++++++++-------------------------
|
||||
5 files changed, 38 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index c098043..3641e32 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1092,8 +1092,6 @@ HRESULT IDirectSoundBufferImpl_Create(
|
||||
/* calculate fragment size and write lead */
|
||||
DSOUND_RecalcFormat(dsb);
|
||||
|
||||
- dsb->eax.reverb_mix = EAX_REVERBMIX_USEDISTANCE;
|
||||
-
|
||||
if (dsb->dsbd.dwFlags & DSBCAPS_CTRL3D) {
|
||||
dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
|
||||
dsb->ds3db_ds3db.vPosition.x = 0.0;
|
||||
@@ -1121,6 +1119,8 @@ HRESULT IDirectSoundBufferImpl_Create(
|
||||
|
||||
/* register buffer if not primary */
|
||||
if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
|
||||
+ init_eax_buffer(dsb);
|
||||
+
|
||||
err = DirectSoundDevice_AddBuffer(device, dsb);
|
||||
if (err != DS_OK) {
|
||||
HeapFree(GetProcessHeap(),0,dsb->buffer->memory);
|
||||
@@ -1130,9 +1130,6 @@ HRESULT IDirectSoundBufferImpl_Create(
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
dsb = NULL;
|
||||
}
|
||||
-
|
||||
- if (dsb->device->eax.using_eax)
|
||||
- init_eax_buffer(dsb);
|
||||
}
|
||||
|
||||
IDirectSoundBuffer8_AddRef(&dsb->IDirectSoundBuffer8_iface);
|
||||
@@ -1188,7 +1185,7 @@ HRESULT IDirectSoundBufferImpl_Duplicate(
|
||||
HRESULT hres = DS_OK;
|
||||
TRACE("(%p,%p,%p)\n", device, ppdsb, pdsb);
|
||||
|
||||
- dsb = HeapAlloc(GetProcessHeap(),0,sizeof(*dsb));
|
||||
+ dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
|
||||
if (dsb == NULL) {
|
||||
WARN("out of memory\n");
|
||||
*ppdsb = NULL;
|
||||
@@ -1225,6 +1222,8 @@ HRESULT IDirectSoundBufferImpl_Duplicate(
|
||||
|
||||
RtlInitializeResource(&dsb->lock);
|
||||
|
||||
+ init_eax_buffer(dsb); /* FIXME: should we duplicate EAX properties? */
|
||||
+
|
||||
/* register buffer */
|
||||
hres = DirectSoundDevice_AddBuffer(device, dsb);
|
||||
if (hres != DS_OK) {
|
||||
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
|
||||
index ed0bbba..48470b7 100644
|
||||
--- a/dlls/dsound/dsound.c
|
||||
+++ b/dlls/dsound/dsound.c
|
||||
@@ -186,6 +186,8 @@ static HRESULT DirectSoundDevice_Create(DirectSoundDevice ** ppDevice)
|
||||
|
||||
RtlInitializeResource(&(device->buffer_list_lock));
|
||||
|
||||
+ init_eax_device(device);
|
||||
+
|
||||
*ppDevice = device;
|
||||
|
||||
return DS_OK;
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index a650108..a555a75 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -134,6 +134,7 @@ typedef struct {
|
||||
} eax_info;
|
||||
|
||||
typedef struct {
|
||||
+ BOOL reverb_update;
|
||||
float reverb_mix;
|
||||
|
||||
float *SampleBuffer;
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index cc55d70..a9987d0 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -240,6 +240,7 @@ HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
ULONG cbPropData) DECLSPEC_HIDDEN;
|
||||
+void init_eax_device(DirectSoundDevice *dev) DECLSPEC_HIDDEN;
|
||||
void free_eax_buffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
|
||||
void init_eax_buffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
|
||||
void process_eax_buffer(IDirectSoundBufferImpl *dsb, float *buf, DWORD count) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index a05b00e..4e98812 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -114,6 +114,8 @@ static const float LATE_LINE_MULTIPLIER = 4.0f;
|
||||
|
||||
#define SPEEDOFSOUNDMETRESPERSEC 343.3f
|
||||
|
||||
+static void ReverbUpdate(IDirectSoundBufferImpl *dsb);
|
||||
+
|
||||
static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
{
|
||||
float *history = &iir->history[offset*2];
|
||||
@@ -360,6 +362,11 @@ void process_eax_buffer(IDirectSoundBufferImpl *dsb, float *buf, DWORD count)
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (dsb->eax.reverb_update) {
|
||||
+ dsb->eax.reverb_update = FALSE;
|
||||
+ ReverbUpdate(dsb);
|
||||
+ }
|
||||
+
|
||||
out = HeapAlloc(GetProcessHeap(), 0, sizeof(float)*count*4);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -572,7 +579,7 @@ static unsigned int CalcLineLength(float length, unsigned int offset, unsigned i
|
||||
|
||||
static void RealizeLineOffset(float *sampleBuffer, DelayLine *Delay)
|
||||
{
|
||||
- Delay->Line = &sampleBuffer[(unsigned int)Delay->Line];
|
||||
+ Delay->Line = &sampleBuffer[(unsigned int)(ULONG_PTR)Delay->Line];
|
||||
}
|
||||
|
||||
static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl *dsb)
|
||||
@@ -679,13 +686,9 @@ static void ReverbUpdate(IDirectSoundBufferImpl *dsb)
|
||||
unsigned int index;
|
||||
float cw, hfRatio, x, y;
|
||||
|
||||
- /* avoid segfaults in mixing thread when we recalculate the line offsets */
|
||||
- EnterCriticalSection(&dsb->device->mixlock);
|
||||
-
|
||||
+ /* only called from the mixer thread, no race-conditions possible */
|
||||
AllocLines(dsb->device->pwfx->nSamplesPerSec, dsb);
|
||||
|
||||
- LeaveCriticalSection(&dsb->device->mixlock);
|
||||
-
|
||||
for(index = 0; index < 4; index++)
|
||||
{
|
||||
dsb->eax.Early.Offset[index] = fastf2u(EARLY_LINE_LENGTH[index] * dsb->device->pwfx->nSamplesPerSec);
|
||||
@@ -725,19 +728,33 @@ static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
+ RtlAcquireResourceShared(&dev->buffer_list_lock, TRUE);
|
||||
for (i = 0; i < dev->nrofbuffers; i++) {
|
||||
- ReverbUpdate(dev->buffers[i]);
|
||||
+ dev->buffers[i]->eax.reverb_update = TRUE;
|
||||
}
|
||||
+ RtlReleaseResource(&dev->buffer_list_lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+void init_eax_device(DirectSoundDevice *dev)
|
||||
+{
|
||||
+ dev->eax.environment = presets[0].environment;
|
||||
+ dev->eax.volume = presets[0].fVolume;
|
||||
+ dev->eax.damping = presets[0].fDamping;
|
||||
+ memcpy(&dev->eax.eax_props, &efx_presets[0], sizeof(dev->eax.eax_props));
|
||||
+ dev->eax.eax_props.flDecayTime = presets[0].fDecayTime_sec;
|
||||
+}
|
||||
+
|
||||
void init_eax_buffer(IDirectSoundBufferImpl *dsb)
|
||||
{
|
||||
unsigned int index;
|
||||
|
||||
- dsb->eax.TotalSamples = 0;
|
||||
+ dsb->eax.reverb_update = TRUE;
|
||||
+ dsb->eax.reverb_mix = EAX_REVERBMIX_USEDISTANCE;
|
||||
+
|
||||
dsb->eax.SampleBuffer = NULL;
|
||||
+ dsb->eax.TotalSamples = 0;
|
||||
|
||||
dsb->eax.LpFilter.coeff = 0.0f;
|
||||
dsb->eax.LpFilter.history[0] = 0.0f;
|
||||
@@ -784,24 +801,6 @@ void init_eax_buffer(IDirectSoundBufferImpl *dsb)
|
||||
}
|
||||
|
||||
dsb->eax.Offset = 0;
|
||||
-
|
||||
- ReverbUpdate(dsb);
|
||||
-}
|
||||
-
|
||||
-static void init_eax(DirectSoundDevice *dev)
|
||||
-{
|
||||
- int i;
|
||||
-
|
||||
- dev->eax.using_eax = TRUE;
|
||||
- dev->eax.environment = presets[0].environment;
|
||||
- dev->eax.volume = presets[0].fVolume;
|
||||
- dev->eax.damping = presets[0].fDamping;
|
||||
- memcpy(&dev->eax.eax_props, &efx_presets[0], sizeof(dev->eax.eax_props));
|
||||
- dev->eax.eax_props.flDecayTime = presets[0].fDecayTime_sec;
|
||||
-
|
||||
- for (i = 0; i < dev->nrofbuffers; i++) {
|
||||
- init_eax_buffer(dev->buffers[i]);
|
||||
- }
|
||||
}
|
||||
|
||||
void free_eax_buffer(IDirectSoundBufferImpl *dsb)
|
||||
@@ -821,9 +820,7 @@ HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
|
||||
if (IsEqualGUID(&DSPROPSETID_EAX_ReverbProperties, guidPropSet)) {
|
||||
EAX_REVERBPROPERTIES *props;
|
||||
-
|
||||
- if (!buf->device->eax.using_eax)
|
||||
- init_eax(buf->device);
|
||||
+ buf->device->eax.using_eax = TRUE;
|
||||
|
||||
switch (dwPropID) {
|
||||
case DSPROPERTY_EAX_ALL:
|
||||
@@ -883,9 +880,7 @@ HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
return S_OK;
|
||||
} else if (IsEqualGUID(&DSPROPSETID_EAXBUFFER_ReverbProperties, guidPropSet)) {
|
||||
EAXBUFFER_REVERBPROPERTIES *props;
|
||||
-
|
||||
- if (!buf->device->eax.using_eax)
|
||||
- init_eax(buf->device);
|
||||
+ buf->device->eax.using_eax = TRUE;
|
||||
|
||||
switch (dwPropID) {
|
||||
case DSPROPERTY_EAXBUFFER_ALL:
|
||||
@@ -928,8 +923,7 @@ HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
buf, debugstr_guid(guidPropSet), dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData);
|
||||
|
||||
if (IsEqualGUID(&DSPROPSETID_EAX_ReverbProperties, guidPropSet)) {
|
||||
- if (!buf->device->eax.using_eax)
|
||||
- init_eax(buf->device);
|
||||
+ buf->device->eax.using_eax = TRUE;
|
||||
|
||||
switch (dwPropID) {
|
||||
case DSPROPERTY_EAX_ALL:
|
||||
@@ -1012,9 +1006,7 @@ HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
return S_OK;
|
||||
} else if (IsEqualGUID(&DSPROPSETID_EAXBUFFER_ReverbProperties, guidPropSet)) {
|
||||
EAXBUFFER_REVERBPROPERTIES *props;
|
||||
-
|
||||
- if (!buf->device->eax.using_eax)
|
||||
- init_eax(buf->device);
|
||||
+ buf->device->eax.using_eax = TRUE;
|
||||
|
||||
switch (dwPropID) {
|
||||
case DSPROPERTY_EAXBUFFER_ALL:
|
||||
--
|
||||
2.3.3
|
||||
|
@ -1920,6 +1920,7 @@ if test "$enable_dsound_EAX" -eq 1; then
|
||||
patch_apply dsound-EAX/0015-dsound-Implement-EAX-decorrelator.patch
|
||||
patch_apply dsound-EAX/0016-dsound-Implement-EAX-late-reverb.patch
|
||||
patch_apply dsound-EAX/0017-dsound-Implement-EAX-late-all-pass-filter.patch
|
||||
patch_apply dsound-EAX/0018-dsound-Various-improvements-to-EAX-support.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "dsound: Apply filters before sound is multiplied to speakers.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add EAX v1 constants and structs.", 1 },';
|
||||
@ -1938,6 +1939,7 @@ if test "$enable_dsound_EAX" -eq 1; then
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX decorrelator.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX late reverb.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX late all-pass filter.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "dsound: Various improvements to EAX support.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user