mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Added patch to implement EAX support in dsound.
This commit is contained in:
parent
f3032f5a57
commit
cc21d373b5
@ -0,0 +1,107 @@
|
||||
From d417a8b92faa9cef33db57fc259186facce51c12 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:27:37 +0000
|
||||
Subject: [PATCH 01/18] dsound: Add cp_fields_proc variable for buffers.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_private.h | 3 +++
|
||||
dlls/dsound/mixer.c | 20 +++++++++++++++-----
|
||||
2 files changed, 18 insertions(+), 5 deletions(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0001-dsound-Add-cp_fields_proc-variable-for-buffers.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0001-dsound-Add-cp_fields_proc-variable-for-buffers.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index 9c001ed..c10f1dc 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -126,6 +126,8 @@ HRESULT DirectSoundDevice_AddBuffer(
|
||||
IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
|
||||
void DirectSoundDevice_RemoveBuffer(DirectSoundDevice * device, IDirectSoundBufferImpl * pDSB) DECLSPEC_HIDDEN;
|
||||
|
||||
+typedef UINT (*CPFIELDSPROC)(IDirectSoundBufferImpl*, UINT, LONG64*);
|
||||
+
|
||||
/*****************************************************************************
|
||||
* IDirectSoundBuffer implementation structure
|
||||
*/
|
||||
@@ -171,6 +173,7 @@ struct IDirectSoundBufferImpl
|
||||
bitsputfunc put, put_aux;
|
||||
int num_filters;
|
||||
DSFilter* filters;
|
||||
+ CPFIELDSPROC cp_fields_proc;
|
||||
|
||||
struct list entry;
|
||||
};
|
||||
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
|
||||
index 85ab14a..ef8f053 100644
|
||||
--- a/dlls/dsound/mixer.c
|
||||
+++ b/dlls/dsound/mixer.c
|
||||
@@ -43,6 +43,9 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
||||
|
||||
+static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum);
|
||||
+static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum);
|
||||
+
|
||||
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
|
||||
{
|
||||
double temp;
|
||||
@@ -87,6 +90,14 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
|
||||
TRACE("Vol=%d Pan=%d\n", volpan->lVolume, volpan->lPan);
|
||||
}
|
||||
|
||||
+static void DSOUND_RefreshCPFieldsProc(IDirectSoundBufferImpl *dsb)
|
||||
+{
|
||||
+ if (dsb->freqAdjustNum == dsb->freqAdjustDen)
|
||||
+ dsb->cp_fields_proc = cp_fields_noresample;
|
||||
+ else
|
||||
+ dsb->cp_fields_proc = cp_fields_resample;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Recalculate the size for temporary buffer, and new writelead
|
||||
* Should be called when one of the following things occur:
|
||||
@@ -179,6 +190,8 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
|
||||
FIXME("Conversion from %u to %u channels is not implemented, falling back to stereo\n", ichannels, ochannels);
|
||||
dsb->mix_channels = 2;
|
||||
}
|
||||
+
|
||||
+ DSOUND_RefreshCPFieldsProc(dsb);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +279,7 @@ static inline float get_current_sample(const IDirectSoundBufferImpl *dsb,
|
||||
return dsb->get(dsb, mixpos % dsb->buflen, channel);
|
||||
}
|
||||
|
||||
-static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count)
|
||||
+static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
{
|
||||
UINT istride = dsb->pwfx->nBlockAlign;
|
||||
UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
@@ -348,10 +361,7 @@ static void cp_fields(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNu
|
||||
{
|
||||
DWORD ipos, adv;
|
||||
|
||||
- if (dsb->freqAdjustNum == dsb->freqAdjustDen)
|
||||
- adv = cp_fields_noresample(dsb, count); /* *freqAccNum is unmodified */
|
||||
- else
|
||||
- adv = cp_fields_resample(dsb, count, freqAccNum);
|
||||
+ adv = dsb->cp_fields_proc(dsb, count, freqAccNum);
|
||||
|
||||
ipos = dsb->sec_mixpos + adv * dsb->pwfx->nBlockAlign;
|
||||
if (ipos >= dsb->buflen) {
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,270 @@
|
||||
From bb619d6e5ee74714f2f524fb91dbe1da697dc977 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:39:43 +0000
|
||||
Subject: [PATCH 02/18] dsound: Apply filters before sound is multiplied to
|
||||
speakers.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/buffer.c | 3 +
|
||||
dlls/dsound/dsound_private.h | 1 +
|
||||
dlls/dsound/mixer.c | 151 ++++++++++++++++++++++++++++++++++++++-----
|
||||
3 files changed, 138 insertions(+), 17 deletions(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0002-dsound-Apply-filters-before-sound-is-multiplied-to-s.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0002-dsound-Apply-filters-before-sound-is-multiplied-to-s.patch"
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index 4e84d17..7df6348 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -739,6 +739,7 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(IDirectSoundBuffer8 *iface, D
|
||||
This->num_filters = 0;
|
||||
}
|
||||
|
||||
+ DSOUND_RefreshCPFieldsProc(This);
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
@@ -824,6 +825,8 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(IDirectSoundBuffer8 *iface, D
|
||||
This->num_filters = dwEffectsCount;
|
||||
}
|
||||
|
||||
+ DSOUND_RefreshCPFieldsProc(This);
|
||||
+
|
||||
return hr;
|
||||
}
|
||||
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index c10f1dc..5219dbb 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -236,6 +236,7 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
|
||||
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
|
||||
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
|
||||
DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, float *overshot) DECLSPEC_HIDDEN;
|
||||
+void DSOUND_RefreshCPFieldsProc(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN;
|
||||
|
||||
DWORD CALLBACK DSOUND_mixthread(void *ptr) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
|
||||
index ef8f053..7327b5f 100644
|
||||
--- a/dlls/dsound/mixer.c
|
||||
+++ b/dlls/dsound/mixer.c
|
||||
@@ -44,7 +44,9 @@
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dsound);
|
||||
|
||||
static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum);
|
||||
+static UINT cp_fields_noresample_dsp(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum);
|
||||
static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum);
|
||||
+static UINT cp_fields_resample_dsp(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum);
|
||||
|
||||
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
|
||||
{
|
||||
@@ -90,12 +92,14 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
|
||||
TRACE("Vol=%d Pan=%d\n", volpan->lVolume, volpan->lPan);
|
||||
}
|
||||
|
||||
-static void DSOUND_RefreshCPFieldsProc(IDirectSoundBufferImpl *dsb)
|
||||
+void DSOUND_RefreshCPFieldsProc(IDirectSoundBufferImpl *dsb)
|
||||
{
|
||||
+ BOOL using_filters = dsb->num_filters > 0;
|
||||
+
|
||||
if (dsb->freqAdjustNum == dsb->freqAdjustDen)
|
||||
- dsb->cp_fields_proc = cp_fields_noresample;
|
||||
+ dsb->cp_fields_proc = using_filters ? cp_fields_noresample_dsp : cp_fields_noresample;
|
||||
else
|
||||
- dsb->cp_fields_proc = cp_fields_resample;
|
||||
+ dsb->cp_fields_proc = using_filters ? cp_fields_resample_dsp : cp_fields_resample;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,6 +283,25 @@ static inline float get_current_sample(const IDirectSoundBufferImpl *dsb,
|
||||
return dsb->get(dsb, mixpos % dsb->buflen, channel);
|
||||
}
|
||||
|
||||
+static void apply_filters(IDirectSoundBufferImpl *dsb, float* buf, UINT count)
|
||||
+{
|
||||
+ int i;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (count > 0) {
|
||||
+ for (i = 0; i < dsb->num_filters; i++) {
|
||||
+ if (dsb->filters[i].inplace) {
|
||||
+ hr = IMediaObjectInPlace_Process(dsb->filters[i].inplace, count * dsb->mix_channels * sizeof(float),
|
||||
+ (BYTE*)buf, 0, DMO_INPLACE_NORMAL);
|
||||
+
|
||||
+ if (FAILED(hr))
|
||||
+ WARN("IMediaObjectInPlace_Process failed for filter %u\n", i);
|
||||
+ } else
|
||||
+ WARN("filter %u has no inplace object - unsupported\n", i);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
{
|
||||
UINT istride = dsb->pwfx->nBlockAlign;
|
||||
@@ -291,6 +314,33 @@ static UINT cp_fields_noresample(IDirectSoundBufferImpl *dsb, UINT count, LONG64
|
||||
return count;
|
||||
}
|
||||
|
||||
+static UINT cp_fields_noresample_dsp(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
+{
|
||||
+ UINT istride = dsb->pwfx->nBlockAlign;
|
||||
+ UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
+ DWORD channel, i;
|
||||
+ float* buf;
|
||||
+
|
||||
+ buf = HeapAlloc(GetProcessHeap(), 0, count * dsb->mix_channels * sizeof(float));
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ for (channel = 0; channel < dsb->mix_channels; channel++) {
|
||||
+ buf[(i*dsb->mix_channels)+channel] = get_current_sample(dsb, dsb->sec_mixpos + i*istride, channel);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ apply_filters(dsb, buf, count);
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ for (channel = 0; channel < dsb->mix_channels; channel++) {
|
||||
+ dsb->put(dsb, i * ostride, channel, buf[(i*dsb->mix_channels)+channel]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, buf);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
{
|
||||
UINT i, channel;
|
||||
@@ -357,6 +407,87 @@ static UINT cp_fields_resample(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *
|
||||
return max_ipos;
|
||||
}
|
||||
|
||||
+static UINT cp_fields_resample_dsp(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
+{
|
||||
+ UINT i, channel;
|
||||
+ UINT istride = dsb->pwfx->nBlockAlign;
|
||||
+ UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
+
|
||||
+ LONG64 freqAcc_start = *freqAccNum;
|
||||
+ LONG64 freqAcc_end = freqAcc_start + count * dsb->freqAdjustNum;
|
||||
+ UINT dsbfirstep = dsb->firstep;
|
||||
+ UINT channels = dsb->mix_channels;
|
||||
+ UINT max_ipos = (freqAcc_start + count * dsb->freqAdjustNum) / dsb->freqAdjustDen;
|
||||
+
|
||||
+ UINT fir_cachesize = (fir_len + dsbfirstep - 2) / dsbfirstep;
|
||||
+ UINT required_input = max_ipos + fir_cachesize;
|
||||
+
|
||||
+ float* intermediate = HeapAlloc(GetProcessHeap(), 0,
|
||||
+ sizeof(float) * required_input * channels);
|
||||
+
|
||||
+ float* fir_copy = HeapAlloc(GetProcessHeap(), 0,
|
||||
+ sizeof(float) * fir_cachesize);
|
||||
+
|
||||
+ float* buf = HeapAlloc(GetProcessHeap(), 0,
|
||||
+ sizeof(float) * count * dsb->mix_channels);
|
||||
+ float* buftmp = buf;
|
||||
+
|
||||
+ /* Important: this buffer MUST be non-interleaved
|
||||
+ * if you want -msse3 to have any effect.
|
||||
+ * This is good for CPU cache effects, too.
|
||||
+ */
|
||||
+ float* itmp = intermediate;
|
||||
+ for (channel = 0; channel < channels; channel++)
|
||||
+ for (i = 0; i < required_input; i++)
|
||||
+ *(itmp++) = get_current_sample(dsb,
|
||||
+ dsb->sec_mixpos + i * istride, channel);
|
||||
+
|
||||
+ for(i = 0; i < count; ++i) {
|
||||
+ UINT int_fir_steps = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep / dsb->freqAdjustDen;
|
||||
+ float total_fir_steps = (freqAcc_start + i * dsb->freqAdjustNum) * dsbfirstep / (float)dsb->freqAdjustDen;
|
||||
+ UINT ipos = int_fir_steps / dsbfirstep;
|
||||
+
|
||||
+ UINT idx = (ipos + 1) * dsbfirstep - int_fir_steps - 1;
|
||||
+ float rem = int_fir_steps + 1.0 - total_fir_steps;
|
||||
+
|
||||
+ int fir_used = 0;
|
||||
+ while (idx < fir_len - 1) {
|
||||
+ fir_copy[fir_used++] = fir[idx] * (1.0 - rem) + fir[idx + 1] * rem;
|
||||
+ idx += dsb->firstep;
|
||||
+ }
|
||||
+
|
||||
+ assert(fir_used <= fir_cachesize);
|
||||
+ assert(ipos + fir_used <= required_input);
|
||||
+
|
||||
+ for (channel = 0; channel < dsb->mix_channels; channel++) {
|
||||
+ int j;
|
||||
+ float sum = 0.0;
|
||||
+ float* cache = &intermediate[channel * required_input + ipos];
|
||||
+ for (j = 0; j < fir_used; j++)
|
||||
+ sum += fir_copy[j] * cache[j];
|
||||
+ *(buftmp++) = sum * dsb->firgain;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ apply_filters(dsb, buf, count);
|
||||
+
|
||||
+ buftmp = buf;
|
||||
+ for(i = 0; i < count; ++i) {
|
||||
+ for (channel = 0; channel < dsb->mix_channels; channel++) {
|
||||
+ dsb->put(dsb, i * ostride, channel, *buftmp);
|
||||
+ buftmp++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *freqAccNum = freqAcc_end % dsb->freqAdjustDen;
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, fir_copy);
|
||||
+ HeapFree(GetProcessHeap(), 0, intermediate);
|
||||
+ HeapFree(GetProcessHeap(), 0, buf);
|
||||
+
|
||||
+ return max_ipos;
|
||||
+}
|
||||
+
|
||||
static void cp_fields(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
{
|
||||
DWORD ipos, adv;
|
||||
@@ -407,8 +538,6 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2)
|
||||
static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
|
||||
{
|
||||
UINT size_bytes = frames * sizeof(float) * dsb->device->pwfx->nChannels;
|
||||
- HRESULT hr;
|
||||
- int i;
|
||||
|
||||
if (dsb->device->tmp_buffer_len < size_bytes || !dsb->device->tmp_buffer)
|
||||
{
|
||||
@@ -420,18 +549,6 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
|
||||
}
|
||||
|
||||
cp_fields(dsb, frames, &dsb->freqAccNum);
|
||||
-
|
||||
- if (size_bytes > 0) {
|
||||
- for (i = 0; i < dsb->num_filters; i++) {
|
||||
- if (dsb->filters[i].inplace) {
|
||||
- hr = IMediaObjectInPlace_Process(dsb->filters[i].inplace, size_bytes, (BYTE*)dsb->device->tmp_buffer, 0, DMO_INPLACE_NORMAL);
|
||||
-
|
||||
- if (FAILED(hr))
|
||||
- WARN("IMediaObjectInPlace_Process failed for filter %u\n", i);
|
||||
- } else
|
||||
- WARN("filter %u has no inplace object - unsupported\n", i);
|
||||
- }
|
||||
- }
|
||||
}
|
||||
|
||||
static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,135 @@
|
||||
From a76952522ebce6b2c0e08cb98baa4cd6a261975a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 15 Mar 2015 18:04:16 +0000
|
||||
Subject: [PATCH 03/18] dsound: Add EAX v1 constants and structs.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 89 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/dsound/dsound_private.h | 1 +
|
||||
2 files changed, 90 insertions(+)
|
||||
create mode 100644 dlls/dsound/dsound_eax.h
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0003-dsound-Add-EAX-v1-constants-and-structs.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0003-dsound-Add-EAX-v1-constants-and-structs.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
new file mode 100644
|
||||
index 0000000..600029f
|
||||
--- /dev/null
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -0,0 +1,89 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Mark Harmstone
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#ifndef DSOUND_EAX_H_DEFINED
|
||||
+#define DSOUND_EAX_H_DEFINED
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+DEFINE_GUID(DSPROPSETID_EAX_ReverbProperties, 0x4a4e6fc1, 0xc341, 0x11d1, 0xb7, 0x3a, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
|
||||
+DEFINE_GUID(DSPROPSETID_EAXBUFFER_ReverbProperties, 0x4a4e6fc0, 0xc341, 0x11d1, 0xb7, 0x3a, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00);
|
||||
+
|
||||
+typedef enum {
|
||||
+ DSPROPERTY_EAX_ALL,
|
||||
+ DSPROPERTY_EAX_ENVIRONMENT,
|
||||
+ DSPROPERTY_EAX_VOLUME,
|
||||
+ DSPROPERTY_EAX_DECAYTIME,
|
||||
+ DSPROPERTY_EAX_DAMPING
|
||||
+} DSPROPERTY_EAX_REVERBPROPERTY;
|
||||
+
|
||||
+typedef struct {
|
||||
+ unsigned long environment;
|
||||
+ float fVolume;
|
||||
+ float fDecayTime_sec;
|
||||
+ float fDamping;
|
||||
+} EAX_REVERBPROPERTIES;
|
||||
+
|
||||
+enum {
|
||||
+ EAX_ENVIRONMENT_GENERIC,
|
||||
+ EAX_ENVIRONMENT_PADDEDCELL,
|
||||
+ EAX_ENVIRONMENT_ROOM,
|
||||
+ EAX_ENVIRONMENT_BATHROOM,
|
||||
+ EAX_ENVIRONMENT_LIVINGROOM,
|
||||
+ EAX_ENVIRONMENT_STONEROOM,
|
||||
+ EAX_ENVIRONMENT_AUDITORIUM,
|
||||
+ EAX_ENVIRONMENT_CONCERTHALL,
|
||||
+ EAX_ENVIRONMENT_CAVE,
|
||||
+ EAX_ENVIRONMENT_ARENA,
|
||||
+ EAX_ENVIRONMENT_HANGAR,
|
||||
+ EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
+ EAX_ENVIRONMENT_HALLWAY,
|
||||
+ EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
+ EAX_ENVIRONMENT_ALLEY,
|
||||
+ EAX_ENVIRONMENT_FOREST,
|
||||
+ EAX_ENVIRONMENT_CITY,
|
||||
+ EAX_ENVIRONMENT_MOUNTAINS,
|
||||
+ EAX_ENVIRONMENT_QUARRY,
|
||||
+ EAX_ENVIRONMENT_PLAIN,
|
||||
+ EAX_ENVIRONMENT_PARKINGLOT,
|
||||
+ EAX_ENVIRONMENT_SEWERPIPE,
|
||||
+ EAX_ENVIRONMENT_UNDERWATER,
|
||||
+ EAX_ENVIRONMENT_DRUGGED,
|
||||
+ EAX_ENVIRONMENT_DIZZY,
|
||||
+ EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
+ EAX_ENVIRONMENT_COUNT
|
||||
+};
|
||||
+
|
||||
+typedef enum {
|
||||
+ DSPROPERTY_EAXBUFFER_ALL,
|
||||
+ DSPROPERTY_EAXBUFFER_REVERBMIX
|
||||
+} DSPROPERTY_EAXBUFFER_REVERBPROPERTY;
|
||||
+
|
||||
+typedef struct {
|
||||
+ float fMix;
|
||||
+} EAXBUFFER_REVERBPROPERTIES;
|
||||
+
|
||||
+#define EAX_REVERBMIX_USEDISTANCE -1.0f
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index 5219dbb..b52cc31 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "mediaobj.h"
|
||||
#include "mmsystem.h"
|
||||
#include "uuids.h"
|
||||
+#include "dsound_eax.h"
|
||||
|
||||
#include "wine/list.h"
|
||||
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
From 293bff08260858a815cf2acc863da482bc53522a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 15 Mar 2015 18:04:38 +0000
|
||||
Subject: [PATCH 04/18] dsound: Report that we support EAX v1.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/buffer.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0004-dsound-Report-that-we-support-EAX-v1.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0004-dsound-Report-that-we-support-EAX-v1.patch"
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index 7df6348..a0db5db 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1322,6 +1322,18 @@ static HRESULT WINAPI IKsPropertySetImpl_QuerySupport(IKsPropertySet *iface, REF
|
||||
|
||||
TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
|
||||
|
||||
+ if (IsEqualGUID(&DSPROPSETID_EAX_ReverbProperties, guidPropSet)) {
|
||||
+ if (dwPropID <= DSPROPERTY_EAX_DAMPING) {
|
||||
+ *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ } else if (IsEqualGUID(&DSPROPSETID_EAXBUFFER_ReverbProperties, guidPropSet)) {
|
||||
+ if (dwPropID <= DSPROPERTY_EAXBUFFER_REVERBMIX) {
|
||||
+ *pTypeSupport = KSPROPERTY_SUPPORT_GET | KSPROPERTY_SUPPORT_SET;
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
145
patches/dsound-EAX/0005-dsound-Add-EAX-propset-stubs.patch
Normal file
145
patches/dsound-EAX/0005-dsound-Add-EAX-propset-stubs.patch
Normal file
@ -0,0 +1,145 @@
|
||||
From 4b43643b83bfa1a69232bbc8489b116feb8c61bc Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 13:58:53 +0000
|
||||
Subject: [PATCH 05/18] dsound: Add EAX propset stubs.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/Makefile.in | 1 +
|
||||
dlls/dsound/buffer.c | 6 +++++
|
||||
dlls/dsound/dsound_private.h | 8 +++++++
|
||||
dlls/dsound/eax.c | 54 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 69 insertions(+)
|
||||
create mode 100644 dlls/dsound/eax.c
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0005-dsound-Add-EAX-propset-stubs.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0005-dsound-Add-EAX-propset-stubs.patch"
|
||||
|
||||
diff --git a/dlls/dsound/Makefile.in b/dlls/dsound/Makefile.in
|
||||
index 6cb653f..1c04bf3 100644
|
||||
--- a/dlls/dsound/Makefile.in
|
||||
+++ b/dlls/dsound/Makefile.in
|
||||
@@ -9,6 +9,7 @@ C_SRCS = \
|
||||
dsound_convert.c \
|
||||
dsound_main.c \
|
||||
duplex.c \
|
||||
+ eax.c \
|
||||
mixer.c \
|
||||
primary.c \
|
||||
propset.c \
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index a0db5db..4ceb176 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1301,6 +1301,9 @@ static HRESULT WINAPI IKsPropertySetImpl_Get(IKsPropertySet *iface, REFGUID guid
|
||||
TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
|
||||
This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
|
||||
|
||||
+ if (IsEqualGUID(&DSPROPSETID_EAX_ReverbProperties, guidPropSet) || IsEqualGUID(&DSPROPSETID_EAXBUFFER_ReverbProperties, guidPropSet))
|
||||
+ return EAX_Get(This, guidPropSet, dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
|
||||
+
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@@ -1312,6 +1315,9 @@ static HRESULT WINAPI IKsPropertySetImpl_Set(IKsPropertySet *iface, REFGUID guid
|
||||
|
||||
TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
|
||||
|
||||
+ if (IsEqualGUID(&DSPROPSETID_EAX_ReverbProperties, guidPropSet) || IsEqualGUID(&DSPROPSETID_EAXBUFFER_ReverbProperties, guidPropSet))
|
||||
+ return EAX_Set(This, guidPropSet, dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData);
|
||||
+
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index b52cc31..72ac025 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -231,6 +231,14 @@ LONG capped_refcount_dec(LONG *ref) DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT DSOUND_FullDuplexCreate(REFIID riid, void **ppv) DECLSPEC_HIDDEN;
|
||||
|
||||
+/* eax.c */
|
||||
+HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
+ ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
+ ULONG cbPropData, ULONG *pcbReturned) DECLSPEC_HIDDEN;
|
||||
+HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
+ ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
+ ULONG cbPropData) DECLSPEC_HIDDEN;
|
||||
+
|
||||
/* mixer.c */
|
||||
void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
|
||||
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
new file mode 100644
|
||||
index 0000000..c30c7e1
|
||||
--- /dev/null
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -0,0 +1,54 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Mark Harmstone
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#include <stdarg.h>
|
||||
+#include <math.h>
|
||||
+
|
||||
+#include "windef.h"
|
||||
+#include "winbase.h"
|
||||
+#include "winuser.h"
|
||||
+#include "mmsystem.h"
|
||||
+#include "winternl.h"
|
||||
+#include "vfwmsgs.h"
|
||||
+#include "wine/debug.h"
|
||||
+#include "dsound.h"
|
||||
+#include "dsound_private.h"
|
||||
+
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(eax);
|
||||
+
|
||||
+HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
+ ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
+ ULONG cbPropData, ULONG *pcbReturned)
|
||||
+{
|
||||
+ TRACE("(buf=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
|
||||
+ buf, debugstr_guid(guidPropSet), dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
|
||||
+
|
||||
+ *pcbReturned = 0;
|
||||
+
|
||||
+ return E_PROP_ID_UNSUPPORTED;
|
||||
+}
|
||||
+
|
||||
+HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
+ ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
+ ULONG cbPropData)
|
||||
+{
|
||||
+ TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",
|
||||
+ buf, debugstr_guid(guidPropSet), dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData);
|
||||
+
|
||||
+ return E_PROP_ID_UNSUPPORTED;
|
||||
+}
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
151
patches/dsound-EAX/0006-dsound-Add-EAX-presets.patch
Normal file
151
patches/dsound-EAX/0006-dsound-Add-EAX-presets.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From ac35ac1bf501d36b32ec3be2b2e73b4506932435 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 14:10:06 +0000
|
||||
Subject: [PATCH 06/18] dsound: Add EAX presets.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 28 ++++++++++++++++++++++
|
||||
dlls/dsound/eax.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 88 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0006-dsound-Add-EAX-presets.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0006-dsound-Add-EAX-presets.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 600029f..9c29385 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -16,6 +16,8 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
+/* Taken in large part from OpenAL. */
|
||||
+
|
||||
#ifndef DSOUND_EAX_H_DEFINED
|
||||
#define DSOUND_EAX_H_DEFINED
|
||||
|
||||
@@ -82,6 +84,32 @@ typedef struct {
|
||||
|
||||
#define EAX_REVERBMIX_USEDISTANCE -1.0f
|
||||
|
||||
+typedef struct {
|
||||
+ float flDensity;
|
||||
+ float flDiffusion;
|
||||
+ float flGain;
|
||||
+ float flGainHF;
|
||||
+ float flGainLF;
|
||||
+ float flDecayTime;
|
||||
+ float flDecayHFRatio;
|
||||
+ float flDecayLFRatio;
|
||||
+ float flReflectionsGain;
|
||||
+ float flReflectionsDelay;
|
||||
+ float flReflectionsPan[3];
|
||||
+ float flLateReverbGain;
|
||||
+ float flLateReverbDelay;
|
||||
+ float flLateReverbPan[3];
|
||||
+ float flEchoTime;
|
||||
+ float flEchoDepth;
|
||||
+ float flModulationTime;
|
||||
+ float flModulationDepth;
|
||||
+ float flAirAbsorptionGainHF;
|
||||
+ float flHFReference;
|
||||
+ float flLFReference;
|
||||
+ float flRoomRolloffFactor;
|
||||
+ int iDecayHFLimit;
|
||||
+} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index c30c7e1..525875c 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -16,6 +16,8 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
+/* Taken in large part from OpenAL's Alc/alcReverb.c. */
|
||||
+
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -31,6 +33,64 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(eax);
|
||||
|
||||
+static const EAX_REVERBPROPERTIES presets[] = {
|
||||
+ { EAX_ENVIRONMENT_GENERIC, 0.5f, 1.493f, 0.5f },
|
||||
+ { EAX_ENVIRONMENT_PADDEDCELL, 0.25f, 0.1f, 0.0f },
|
||||
+ { EAX_ENVIRONMENT_ROOM, 0.417f, 0.4f, 0.666f },
|
||||
+ { EAX_ENVIRONMENT_BATHROOM, 0.653f, 1.499f, 0.166f },
|
||||
+ { EAX_ENVIRONMENT_LIVINGROOM, 0.208f, 0.478f, 0.0f },
|
||||
+ { EAX_ENVIRONMENT_STONEROOM, 0.5f, 2.309f, 0.888f },
|
||||
+ { EAX_ENVIRONMENT_AUDITORIUM, 0.403f, 4.279f, 0.5f },
|
||||
+ { EAX_ENVIRONMENT_CONCERTHALL, 0.5f, 3.961f, 0.5f },
|
||||
+ { EAX_ENVIRONMENT_CAVE, 0.5f, 2.886f, 1.304f },
|
||||
+ { EAX_ENVIRONMENT_ARENA, 0.361f, 7.284f, 0.332f },
|
||||
+ { EAX_ENVIRONMENT_HANGAR, 0.5f, 10.0f, 0.3f },
|
||||
+ { EAX_ENVIRONMENT_CARPETEDHALLWAY, 0.153f, 0.259f, 2.0f },
|
||||
+ { EAX_ENVIRONMENT_HALLWAY, 0.361f, 1.493f, 0.0f },
|
||||
+ { EAX_ENVIRONMENT_STONECORRIDOR, 0.444f, 2.697f, 0.638f },
|
||||
+ { EAX_ENVIRONMENT_ALLEY, 0.25f, 1.752f, 0.776f },
|
||||
+ { EAX_ENVIRONMENT_FOREST, 0.111f, 3.145f, 0.472f },
|
||||
+ { EAX_ENVIRONMENT_CITY, 0.111f, 2.767f, 0.224f },
|
||||
+ { EAX_ENVIRONMENT_MOUNTAINS, 0.194f, 7.841f, 0.472f },
|
||||
+ { EAX_ENVIRONMENT_QUARRY, 1.0f, 1.499f, 0.5f },
|
||||
+ { EAX_ENVIRONMENT_PLAIN, 0.097f, 2.767f, 0.224f },
|
||||
+ { EAX_ENVIRONMENT_PARKINGLOT, 0.208f, 1.652f, 1.5f },
|
||||
+ { EAX_ENVIRONMENT_SEWERPIPE, 0.652f, 2.886f, 0.25f },
|
||||
+ { EAX_ENVIRONMENT_UNDERWATER, 1.0f, 1.499f, 0.0f },
|
||||
+ { EAX_ENVIRONMENT_DRUGGED, 0.875f, 8.392f, 1.388f },
|
||||
+ { EAX_ENVIRONMENT_DIZZY, 0.139f, 17.234f, 0.666f },
|
||||
+ { EAX_ENVIRONMENT_PSYCHOTIC, 0.486f, 7.563f, 0.806f }
|
||||
+};
|
||||
+
|
||||
+static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* generic */
|
||||
+ { 0.1715f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.1700f, 0.1000f, 1.0000f, 0.2500f, 0.0010f, { 0.0000f, 0.0000f, 0.0000f }, 1.2691f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* padded cell */
|
||||
+ { 0.4287f, 1.0000f, 0.3162f, 0.5929f, 1.0000f, 0.4000f, 0.8300f, 1.0000f, 0.1503f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 1.0629f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* room */
|
||||
+ { 0.1715f, 1.0000f, 0.3162f, 0.2512f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.6531f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 3.2734f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* bathroom */
|
||||
+ { 0.9766f, 1.0000f, 0.3162f, 0.0010f, 1.0000f, 0.5000f, 0.1000f, 1.0000f, 0.2051f, 0.0030f, { 0.0000f, 0.0000f, 0.0000f }, 0.2805f, 0.0040f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* living room */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 2.3100f, 0.6400f, 1.0000f, 0.4411f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 1.1003f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* stone room */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.5781f, 1.0000f, 4.3200f, 0.5900f, 1.0000f, 0.4032f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.7170f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* auditorium */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.5623f, 1.0000f, 3.9200f, 0.7000f, 1.0000f, 0.2427f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.9977f, 0.0290f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* concert hall */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 2.9100f, 1.3000f, 1.0000f, 0.5000f, 0.0150f, { 0.0000f, 0.0000f, 0.0000f }, 0.7063f, 0.0220f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }, /* cave */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.4477f, 1.0000f, 7.2400f, 0.3300f, 1.0000f, 0.2612f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.0186f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* arena */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 10.0500f, 0.2300f, 1.0000f, 0.5000f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.2560f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* hangar */
|
||||
+ { 0.4287f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 0.3000f, 0.1000f, 1.0000f, 0.1215f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 0.1531f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* carpeted hallway */
|
||||
+ { 0.3645f, 1.0000f, 0.3162f, 0.7079f, 1.0000f, 1.4900f, 0.5900f, 1.0000f, 0.2458f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.6615f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* hallway */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.7612f, 1.0000f, 2.7000f, 0.7900f, 1.0000f, 0.2472f, 0.0130f, { 0.0000f, 0.0000f, 0.0000f }, 1.5758f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* stone corridor */
|
||||
+ { 1.0000f, 0.3000f, 0.3162f, 0.7328f, 1.0000f, 1.4900f, 0.8600f, 1.0000f, 0.2500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.9954f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.9500f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* alley */
|
||||
+ { 1.0000f, 0.3000f, 0.3162f, 0.0224f, 1.0000f, 1.4900f, 0.5400f, 1.0000f, 0.0525f, 0.1620f, { 0.0000f, 0.0000f, 0.0000f }, 0.7682f, 0.0880f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* forest */
|
||||
+ { 1.0000f, 0.5000f, 0.3162f, 0.3981f, 1.0000f, 1.4900f, 0.6700f, 1.0000f, 0.0730f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 0.1427f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* city */
|
||||
+ { 1.0000f, 0.2700f, 0.3162f, 0.0562f, 1.0000f, 1.4900f, 0.2100f, 1.0000f, 0.0407f, 0.3000f, { 0.0000f, 0.0000f, 0.0000f }, 0.1919f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }, /* mountains */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 0.3162f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0000f, 0.0610f, { 0.0000f, 0.0000f, 0.0000f }, 1.7783f, 0.0250f, { 0.0000f, 0.0000f, 0.0000f }, 0.1250f, 0.7000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* quarry */
|
||||
+ { 1.0000f, 0.2100f, 0.3162f, 0.1000f, 1.0000f, 1.4900f, 0.5000f, 1.0000f, 0.0585f, 0.1790f, { 0.0000f, 0.0000f, 0.0000f }, 0.1089f, 0.1000f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* plain */
|
||||
+ { 1.0000f, 1.0000f, 0.3162f, 1.0000f, 1.0000f, 1.6500f, 1.5000f, 1.0000f, 0.2082f, 0.0080f, { 0.0000f, 0.0000f, 0.0000f }, 0.2652f, 0.0120f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }, /* parking lot */
|
||||
+ { 0.3071f, 0.8000f, 0.3162f, 0.3162f, 1.0000f, 2.8100f, 0.1400f, 1.0000f, 1.6387f, 0.0140f, { 0.0000f, 0.0000f, 0.0000f }, 3.2471f, 0.0210f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* sewer pipe */
|
||||
+ { 0.3645f, 1.0000f, 0.3162f, 0.0100f, 1.0000f, 1.4900f, 0.1000f, 1.0000f, 0.5963f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 7.0795f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 1.1800f, 0.3480f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }, /* underwater */
|
||||
+ { 0.4287f, 0.5000f, 0.3162f, 1.0000f, 1.0000f, 8.3900f, 1.3900f, 1.0000f, 0.8760f, 0.0020f, { 0.0000f, 0.0000f, 0.0000f }, 3.1081f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }, /* drugged */
|
||||
+ { 0.3645f, 0.6000f, 0.3162f, 0.6310f, 1.0000f, 17.2300f, 0.5600f, 1.0000f, 0.1392f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 0.4937f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.8100f, 0.3100f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }, /* dizzy */
|
||||
+ { 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
+};
|
||||
+
|
||||
HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
ULONG cbPropData, ULONG *pcbReturned)
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,254 @@
|
||||
From 563415997a8a95b87c47ea8fe72e172aae5cd3d5 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 14:22:02 +0000
|
||||
Subject: [PATCH 07/18] dsound: Support getting and setting EAX properties.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 8 +++
|
||||
dlls/dsound/dsound_private.h | 2 +
|
||||
dlls/dsound/eax.c | 167 +++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 177 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0007-dsound-Support-getting-and-setting-EAX-properties.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0007-dsound-Support-getting-and-setting-EAX-properties.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 9c29385..d9e88f4 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -110,6 +110,14 @@ typedef struct {
|
||||
int iDecayHFLimit;
|
||||
} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
|
||||
|
||||
+typedef struct {
|
||||
+ BOOL using_eax;
|
||||
+ unsigned long environment;
|
||||
+ float volume;
|
||||
+ float damping;
|
||||
+ EFXEAXREVERBPROPERTIES eax_props;
|
||||
+} eax_info;
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index 72ac025..d9be65b 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -98,6 +98,8 @@ struct DirectSoundDevice
|
||||
|
||||
normfunc normfunction;
|
||||
|
||||
+ eax_info eax;
|
||||
+
|
||||
/* DirectSound3DListener fields */
|
||||
DS3DLISTENER ds3dl;
|
||||
BOOL ds3dl_need_recalc;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 525875c..3b06495 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -91,6 +91,22 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
+{
|
||||
+ /* stub */
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+static void init_eax(DirectSoundDevice *dev)
|
||||
+{
|
||||
+ 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;
|
||||
+}
|
||||
+
|
||||
HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
ULONG cbPropData, ULONG *pcbReturned)
|
||||
@@ -100,6 +116,70 @@ HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
|
||||
*pcbReturned = 0;
|
||||
|
||||
+ if (IsEqualGUID(&DSPROPSETID_EAX_ReverbProperties, guidPropSet)) {
|
||||
+ EAX_REVERBPROPERTIES *props;
|
||||
+
|
||||
+ if (!buf->device->eax.using_eax)
|
||||
+ init_eax(buf->device);
|
||||
+
|
||||
+ switch (dwPropID) {
|
||||
+ case DSPROPERTY_EAX_ALL:
|
||||
+ if (cbPropData < sizeof(EAX_REVERBPROPERTIES))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ props = pPropData;
|
||||
+
|
||||
+ props->environment = buf->device->eax.environment;
|
||||
+ props->fVolume = buf->device->eax.volume;
|
||||
+ props->fDecayTime_sec = buf->device->eax.eax_props.flDecayTime;
|
||||
+ props->fDamping = buf->device->eax.damping;
|
||||
+
|
||||
+ *pcbReturned = sizeof(EAX_REVERBPROPERTIES);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_ENVIRONMENT:
|
||||
+ if (cbPropData < sizeof(unsigned long))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ *(unsigned long*)pPropData = buf->device->eax.environment;
|
||||
+
|
||||
+ *pcbReturned = sizeof(unsigned long);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_VOLUME:
|
||||
+ if (cbPropData < sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ *(float*)pPropData = buf->device->eax.volume;
|
||||
+
|
||||
+ *pcbReturned = sizeof(float);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_DECAYTIME:
|
||||
+ if (cbPropData < sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ *(float*)pPropData = buf->device->eax.eax_props.flDecayTime;
|
||||
+
|
||||
+ *pcbReturned = sizeof(float);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_DAMPING:
|
||||
+ if (cbPropData < sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ *(float*)pPropData = buf->device->eax.damping;
|
||||
+
|
||||
+ *pcbReturned = sizeof(float);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return E_PROP_ID_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@@ -107,8 +187,95 @@ HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
ULONG dwPropID, void *pInstanceData, ULONG cbInstanceData, void *pPropData,
|
||||
ULONG cbPropData)
|
||||
{
|
||||
+ EAX_REVERBPROPERTIES *props;
|
||||
+
|
||||
TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",
|
||||
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);
|
||||
+
|
||||
+ switch (dwPropID) {
|
||||
+ case DSPROPERTY_EAX_ALL:
|
||||
+ if (cbPropData != sizeof(EAX_REVERBPROPERTIES))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ props = pPropData;
|
||||
+
|
||||
+ TRACE("setting environment = %lu, fVolume = %f, fDecayTime_sec = %f, fDamping = %f\n",
|
||||
+ props->environment, props->fVolume, props->fDecayTime_sec,
|
||||
+ props->fDamping);
|
||||
+
|
||||
+ buf->device->eax.environment = props->environment;
|
||||
+
|
||||
+ if (buf->device->eax.environment < EAX_ENVIRONMENT_COUNT)
|
||||
+ memcpy(&buf->device->eax.eax_props, &efx_presets[buf->device->eax.environment], sizeof(buf->device->eax.eax_props));
|
||||
+
|
||||
+ buf->device->eax.volume = props->fVolume;
|
||||
+ buf->device->eax.eax_props.flDecayTime = props->fDecayTime_sec;
|
||||
+ buf->device->eax.damping = props->fDamping;
|
||||
+
|
||||
+ ReverbDeviceUpdate(buf->device);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_ENVIRONMENT:
|
||||
+ if (cbPropData != sizeof(unsigned long))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ TRACE("setting environment to %lu\n", *(unsigned long*)pPropData);
|
||||
+
|
||||
+ buf->device->eax.environment = *(unsigned long*)pPropData;
|
||||
+
|
||||
+ if (buf->device->eax.environment < EAX_ENVIRONMENT_COUNT) {
|
||||
+ memcpy(&buf->device->eax.eax_props, &efx_presets[buf->device->eax.environment], sizeof(buf->device->eax.eax_props));
|
||||
+ buf->device->eax.volume = presets[buf->device->eax.environment].fVolume;
|
||||
+ buf->device->eax.eax_props.flDecayTime = presets[buf->device->eax.environment].fDecayTime_sec;
|
||||
+ buf->device->eax.damping = presets[buf->device->eax.environment].fDamping;
|
||||
+ }
|
||||
+
|
||||
+ ReverbDeviceUpdate(buf->device);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_VOLUME:
|
||||
+ if (cbPropData != sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ TRACE("setting volume to %f\n", *(float*)pPropData);
|
||||
+
|
||||
+ buf->device->eax.volume = *(float*)pPropData;
|
||||
+
|
||||
+ ReverbDeviceUpdate(buf->device);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_DECAYTIME:
|
||||
+ if (cbPropData != sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ TRACE("setting decay time to %f\n", *(float*)pPropData);
|
||||
+
|
||||
+ buf->device->eax.eax_props.flDecayTime = *(float*)pPropData;
|
||||
+
|
||||
+ ReverbDeviceUpdate(buf->device);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAX_DAMPING:
|
||||
+ if (cbPropData != sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ TRACE("setting damping to %f\n", *(float*)pPropData);
|
||||
+
|
||||
+ buf->device->eax.damping = *(float*)pPropData;
|
||||
+
|
||||
+ ReverbDeviceUpdate(buf->device);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return E_PROP_ID_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,153 @@
|
||||
From 3765b43e4c646b3cbbcfbec79a2e84791d88349e Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:48:19 +0000
|
||||
Subject: [PATCH 08/18] dsound: Support getting and setting EAX buffer
|
||||
properties.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/buffer.c | 2 ++
|
||||
dlls/dsound/dsound_eax.h | 4 +++
|
||||
dlls/dsound/dsound_private.h | 2 ++
|
||||
dlls/dsound/eax.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 72 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0008-dsound-Support-getting-and-setting-EAX-buffer-proper.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0008-dsound-Support-getting-and-setting-EAX-buffer-proper.patch"
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index 4ceb176..9ebf213 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1095,6 +1095,8 @@ 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;
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index d9e88f4..56b4263 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -118,6 +118,10 @@ typedef struct {
|
||||
EFXEAXREVERBPROPERTIES eax_props;
|
||||
} eax_info;
|
||||
|
||||
+typedef struct {
|
||||
+ float reverb_mix;
|
||||
+} eax_buffer_info;
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index d9be65b..0aef20f 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -178,6 +178,8 @@ struct IDirectSoundBufferImpl
|
||||
DSFilter* filters;
|
||||
CPFIELDSPROC cp_fields_proc;
|
||||
|
||||
+ eax_buffer_info eax;
|
||||
+
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 3b06495..56a76f6 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -178,6 +178,38 @@ 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);
|
||||
+
|
||||
+ switch (dwPropID) {
|
||||
+ case DSPROPERTY_EAXBUFFER_ALL:
|
||||
+ if (cbPropData < sizeof(EAXBUFFER_REVERBPROPERTIES))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ props = pPropData;
|
||||
+
|
||||
+ props->fMix = buf->eax.reverb_mix;
|
||||
+
|
||||
+ *pcbReturned = sizeof(EAXBUFFER_REVERBPROPERTIES);
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAXBUFFER_REVERBMIX:
|
||||
+ if (cbPropData < sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ *(float*)pPropData = buf->eax.reverb_mix;
|
||||
+
|
||||
+ *pcbReturned = sizeof(float);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return E_PROP_ID_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
@@ -275,6 +307,38 @@ 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);
|
||||
+
|
||||
+ switch (dwPropID) {
|
||||
+ case DSPROPERTY_EAXBUFFER_ALL:
|
||||
+ if (cbPropData != sizeof(EAXBUFFER_REVERBPROPERTIES))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ props = pPropData;
|
||||
+
|
||||
+ TRACE("setting reverb mix to %f\n", props->fMix);
|
||||
+
|
||||
+ buf->eax.reverb_mix = props->fMix;
|
||||
+ break;
|
||||
+
|
||||
+ case DSPROPERTY_EAXBUFFER_REVERBMIX:
|
||||
+ if (cbPropData != sizeof(float))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ TRACE("setting reverb mix to %f\n", *(float*)pPropData);
|
||||
+
|
||||
+ buf->eax.reverb_mix = *(float*)pPropData;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return E_PROP_ID_UNSUPPORTED;
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
133
patches/dsound-EAX/0009-dsound-Add-EAX-init-and-free-stubs.patch
Normal file
133
patches/dsound-EAX/0009-dsound-Add-EAX-init-and-free-stubs.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From 5b3eccbf7a66a21dbb38d4115f01389102775116 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:58:37 +0000
|
||||
Subject: [PATCH 09/18] dsound: Add EAX init and free stubs.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/buffer.c | 6 ++++++
|
||||
dlls/dsound/dsound_private.h | 2 ++
|
||||
dlls/dsound/eax.c | 30 +++++++++++++++++++++++++++++-
|
||||
dlls/dsound/mixer.c | 2 +-
|
||||
4 files changed, 38 insertions(+), 2 deletions(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0009-dsound-Add-EAX-init-and-free-stubs.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0009-dsound-Add-EAX-init-and-free-stubs.patch"
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index 9ebf213..a62ca40 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1133,6 +1133,10 @@ HRESULT IDirectSoundBufferImpl_Create(
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
dsb = NULL;
|
||||
}
|
||||
+
|
||||
+ if (dsb->device->eax.using_eax) {
|
||||
+ init_eax_buffer(dsb);
|
||||
+ }
|
||||
}
|
||||
|
||||
IDirectSoundBuffer8_AddRef(&dsb->IDirectSoundBuffer8_iface);
|
||||
@@ -1172,6 +1176,8 @@ void secondarybuffer_destroy(IDirectSoundBufferImpl *This)
|
||||
HeapFree(GetProcessHeap(), 0, This->filters);
|
||||
}
|
||||
|
||||
+ free_eax_buffer(This);
|
||||
+
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
|
||||
TRACE("(%p) released\n", This);
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index 0aef20f..e041526 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -242,6 +242,8 @@ 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 free_eax_buffer(IDirectSoundBufferImpl* dsb) DECLSPEC_HIDDEN;
|
||||
+void init_eax_buffer(IDirectSoundBufferImpl* dsb) DECLSPEC_HIDDEN;
|
||||
|
||||
/* mixer.c */
|
||||
void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 56a76f6..f0c17ff 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -91,20 +91,48 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
-static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
+static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
/* stub */
|
||||
+}
|
||||
+
|
||||
+static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < dev->nrofbuffers; i++) {
|
||||
+ ReverbUpdate(dev->buffers[i]);
|
||||
+ }
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
+{
|
||||
+ ReverbUpdate(dsb);
|
||||
+
|
||||
+ DSOUND_RefreshCPFieldsProc(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)
|
||||
+{
|
||||
+ /* stub */
|
||||
}
|
||||
|
||||
HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
|
||||
index 7327b5f..da5a174 100644
|
||||
--- a/dlls/dsound/mixer.c
|
||||
+++ b/dlls/dsound/mixer.c
|
||||
@@ -94,7 +94,7 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
|
||||
|
||||
void DSOUND_RefreshCPFieldsProc(IDirectSoundBufferImpl *dsb)
|
||||
{
|
||||
- BOOL using_filters = dsb->num_filters > 0;
|
||||
+ BOOL using_filters = dsb->num_filters > 0 || dsb->device->eax.using_eax;
|
||||
|
||||
if (dsb->freqAdjustNum == dsb->freqAdjustDen)
|
||||
dsb->cp_fields_proc = using_filters ? cp_fields_noresample_dsp : cp_fields_noresample;
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,70 @@
|
||||
From 94026d1694362d5f94f74e8f0c362a1c1efe4bec Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:59:57 +0000
|
||||
Subject: [PATCH 10/18] dsound: Feed data through EAX function.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_private.h | 1 +
|
||||
dlls/dsound/eax.c | 5 +++++
|
||||
dlls/dsound/mixer.c | 3 +++
|
||||
3 files changed, 9 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0010-dsound-Feed-data-through-EAX-function.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0010-dsound-Feed-data-through-EAX-function.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index e041526..aabb36f 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -244,6 +244,7 @@ HRESULT WINAPI EAX_Set(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
ULONG cbPropData) 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;
|
||||
|
||||
/* mixer.c */
|
||||
void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index f0c17ff..df05f8e 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -91,6 +91,11 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+void process_eax_buffer(IDirectSoundBufferImpl* dsb, float* buf, DWORD count)
|
||||
+{
|
||||
+ /* stub */
|
||||
+}
|
||||
+
|
||||
static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
/* stub */
|
||||
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
|
||||
index da5a174..a737707 100644
|
||||
--- a/dlls/dsound/mixer.c
|
||||
+++ b/dlls/dsound/mixer.c
|
||||
@@ -299,6 +299,9 @@ static void apply_filters(IDirectSoundBufferImpl *dsb, float* buf, UINT count)
|
||||
} else
|
||||
WARN("filter %u has no inplace object - unsupported\n", i);
|
||||
}
|
||||
+
|
||||
+ if (dsb->device->eax.using_eax)
|
||||
+ process_eax_buffer(dsb, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
205
patches/dsound-EAX/0011-dsound-Allocate-EAX-delay-lines.patch
Normal file
205
patches/dsound-EAX/0011-dsound-Allocate-EAX-delay-lines.patch
Normal file
@ -0,0 +1,205 @@
|
||||
From b8a5fe26a390ced4438df0e50b7c93fd4150ed06 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 21:06:42 +0000
|
||||
Subject: [PATCH 11/18] dsound: Allocate EAX delay lines.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 16 ++++++++
|
||||
dlls/dsound/eax.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 113 insertions(+), 2 deletions(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0011-dsound-Allocate-EAX-delay-lines.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0011-dsound-Allocate-EAX-delay-lines.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 56b4263..7565233 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -84,6 +84,9 @@ typedef struct {
|
||||
|
||||
#define EAX_REVERBMIX_USEDISTANCE -1.0f
|
||||
|
||||
+#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
|
||||
+#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
|
||||
+
|
||||
typedef struct {
|
||||
float flDensity;
|
||||
float flDiffusion;
|
||||
@@ -110,6 +113,12 @@ typedef struct {
|
||||
int iDecayHFLimit;
|
||||
} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
|
||||
|
||||
+typedef struct DelayLine
|
||||
+{
|
||||
+ unsigned int Mask;
|
||||
+ float *Line;
|
||||
+} DelayLine;
|
||||
+
|
||||
typedef struct {
|
||||
BOOL using_eax;
|
||||
unsigned long environment;
|
||||
@@ -120,6 +129,13 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
float reverb_mix;
|
||||
+
|
||||
+ float *SampleBuffer;
|
||||
+ unsigned int TotalSamples;
|
||||
+
|
||||
+ DelayLine Delay;
|
||||
+
|
||||
+ unsigned int Offset;
|
||||
} eax_buffer_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index df05f8e..d12cdd0 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Mark Harmstone
|
||||
+ * Copyright (c) 2008-9 Christopher Fitzgerald
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -91,14 +92,99 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+static unsigned int fastf2u(float f)
|
||||
+{
|
||||
+ return (unsigned int)f;
|
||||
+}
|
||||
+
|
||||
void process_eax_buffer(IDirectSoundBufferImpl* dsb, float* buf, DWORD count)
|
||||
{
|
||||
/* stub */
|
||||
}
|
||||
|
||||
+static unsigned int NextPowerOf2(unsigned int value)
|
||||
+{
|
||||
+ if(value > 0)
|
||||
+ {
|
||||
+ value--;
|
||||
+ value |= value>>1;
|
||||
+ value |= value>>2;
|
||||
+ value |= value>>4;
|
||||
+ value |= value>>8;
|
||||
+ value |= value>>16;
|
||||
+ }
|
||||
+ return value+1;
|
||||
+}
|
||||
+
|
||||
+static unsigned int CalcLineLength(float length, unsigned int offset, unsigned int frequency, DelayLine *Delay)
|
||||
+{
|
||||
+ unsigned int samples;
|
||||
+
|
||||
+ /* All line lengths are powers of 2, calculated from their lengths, with
|
||||
+ * an additional sample in case of rounding errors. */
|
||||
+ samples = NextPowerOf2(fastf2u(length * frequency) + 1);
|
||||
+ /* All lines share a single sample buffer. */
|
||||
+ Delay->Mask = samples - 1;
|
||||
+ Delay->Line = (float*)offset;
|
||||
+ /* Return the sample count for accumulation. */
|
||||
+ return samples;
|
||||
+}
|
||||
+
|
||||
+static void RealizeLineOffset(float *sampleBuffer, DelayLine *Delay)
|
||||
+{
|
||||
+ Delay->Line = &sampleBuffer[(unsigned int)Delay->Line];
|
||||
+}
|
||||
+
|
||||
+static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
+{
|
||||
+ unsigned int totalSamples, index;
|
||||
+ float length;
|
||||
+ float *newBuffer = NULL;
|
||||
+
|
||||
+ /* All delay line lengths are calculated to accomodate the full range of
|
||||
+ * lengths given their respective paramters. */
|
||||
+ totalSamples = 0;
|
||||
+
|
||||
+ /* The initial delay is the sum of the reflections and late reverb
|
||||
+ * delays. */
|
||||
+ length = AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
|
||||
+ AL_EAXREVERB_MAX_LATE_REVERB_DELAY;
|
||||
+ totalSamples += CalcLineLength(length, totalSamples, frequency,
|
||||
+ &dsb->eax.Delay);
|
||||
+
|
||||
+ if(totalSamples != dsb->eax.TotalSamples)
|
||||
+ {
|
||||
+ TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency);
|
||||
+
|
||||
+ if (dsb->eax.SampleBuffer)
|
||||
+ newBuffer = HeapReAlloc(GetProcessHeap(), 0, dsb->eax.SampleBuffer, sizeof(float) * totalSamples);
|
||||
+ else
|
||||
+ newBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(float) * totalSamples);
|
||||
+
|
||||
+ if(newBuffer == NULL)
|
||||
+ return FALSE;
|
||||
+ dsb->eax.SampleBuffer = newBuffer;
|
||||
+ dsb->eax.TotalSamples = totalSamples;
|
||||
+ }
|
||||
+
|
||||
+ /* Update all delays to reflect the new sample buffer. */
|
||||
+ RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Delay);
|
||||
+
|
||||
+ /* Clear the sample buffer. */
|
||||
+ for(index = 0;index < dsb->eax.TotalSamples;index++)
|
||||
+ dsb->eax.SampleBuffer[index] = 0.0f;
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
- /* stub */
|
||||
+ /* avoid segfaults in mixing thread when we recalculate the line offsets */
|
||||
+ EnterCriticalSection(&dsb->device->mixlock);
|
||||
+
|
||||
+ AllocLines(dsb->device->pwfx->nSamplesPerSec, dsb);
|
||||
+
|
||||
+ LeaveCriticalSection(&dsb->device->mixlock);
|
||||
}
|
||||
|
||||
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
@@ -114,6 +200,14 @@ static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
|
||||
void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
+ dsb->eax.TotalSamples = 0;
|
||||
+ dsb->eax.SampleBuffer = NULL;
|
||||
+
|
||||
+ dsb->eax.Delay.Mask = 0;
|
||||
+ dsb->eax.Delay.Line = NULL;
|
||||
+
|
||||
+ dsb->eax.Offset = 0;
|
||||
+
|
||||
ReverbUpdate(dsb);
|
||||
|
||||
DSOUND_RefreshCPFieldsProc(dsb);
|
||||
@@ -137,7 +231,8 @@ static void init_eax(DirectSoundDevice *dev)
|
||||
|
||||
void free_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
- /* stub */
|
||||
+ if (dsb->eax.SampleBuffer)
|
||||
+ HeapFree(GetProcessHeap(), 0, dsb->eax.SampleBuffer);
|
||||
}
|
||||
|
||||
HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
81
patches/dsound-EAX/0012-dsound-Add-EAX-VerbPass-stub.patch
Normal file
81
patches/dsound-EAX/0012-dsound-Add-EAX-VerbPass-stub.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From 035fe59abb8f8e8444421198838619d532ae840e Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 15:38:15 +0000
|
||||
Subject: [PATCH 12/18] dsound: Add EAX VerbPass stub.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/eax.c | 37 ++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 36 insertions(+), 1 deletion(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0012-dsound-Add-EAX-VerbPass-stub.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0012-dsound-Add-EAX-VerbPass-stub.patch"
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index d12cdd0..82b5a6a 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,6 +92,14 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
+{
|
||||
+ /* stub */
|
||||
+
|
||||
+ /* Step all delays forward one sample. */
|
||||
+ dsb->eax.Offset++;
|
||||
+}
|
||||
+
|
||||
static unsigned int fastf2u(float f)
|
||||
{
|
||||
return (unsigned int)f;
|
||||
@@ -99,7 +107,34 @@ static unsigned int fastf2u(float f)
|
||||
|
||||
void process_eax_buffer(IDirectSoundBufferImpl* dsb, float* buf, DWORD count)
|
||||
{
|
||||
- /* stub */
|
||||
+ int i;
|
||||
+ float* out;
|
||||
+ float gain;
|
||||
+
|
||||
+ if (dsb->device->eax.volume == 0.0f)
|
||||
+ return;
|
||||
+
|
||||
+ if (dsb->mix_channels > 1) {
|
||||
+ WARN("EAX not yet supported for non-mono sources\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ out = HeapAlloc(GetProcessHeap(), 0, sizeof(float)*count*4);
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ VerbPass(dsb, buf[i], &out[i*4]);
|
||||
+ }
|
||||
+
|
||||
+ if (dsb->eax.reverb_mix == EAX_REVERBMIX_USEDISTANCE)
|
||||
+ gain = 1.0f; /* FIXME - should be calculated from distance */
|
||||
+ else
|
||||
+ gain = dsb->eax.reverb_mix;
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ buf[i] += gain * out[i*4];
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, out);
|
||||
}
|
||||
|
||||
static unsigned int NextPowerOf2(unsigned int value)
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,140 @@
|
||||
From 0c5e512bfe56e21b71c86744410108ac329099e4 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 17:57:38 +0000
|
||||
Subject: [PATCH 13/18] dsound: Implement EAX lowpass filter.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 7 +++++++
|
||||
dlls/dsound/eax.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 54 insertions(+), 1 deletion(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0013-dsound-Implement-EAX-lowpass-filter.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0013-dsound-Implement-EAX-lowpass-filter.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 7565233..51bafe0 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -120,6 +120,11 @@ typedef struct DelayLine
|
||||
} DelayLine;
|
||||
|
||||
typedef struct {
|
||||
+ float coeff;
|
||||
+ float history[2];
|
||||
+} FILTER;
|
||||
+
|
||||
+typedef struct {
|
||||
BOOL using_eax;
|
||||
unsigned long environment;
|
||||
float volume;
|
||||
@@ -133,6 +138,8 @@ typedef struct {
|
||||
float *SampleBuffer;
|
||||
unsigned int TotalSamples;
|
||||
|
||||
+ FILTER LpFilter;
|
||||
+
|
||||
DelayLine Delay;
|
||||
|
||||
unsigned int Offset;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 82b5a6a..54d90cd 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,9 +92,24 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
+{
|
||||
+ float *history = &iir->history[offset*2];
|
||||
+ float a = iir->coeff;
|
||||
+ float output = input;
|
||||
+
|
||||
+ output = output + (history[0]-output)*a;
|
||||
+ history[0] = output;
|
||||
+ output = output + (history[1]-output)*a;
|
||||
+ history[1] = output;
|
||||
+
|
||||
+ return output;
|
||||
+}
|
||||
+
|
||||
static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
{
|
||||
- /* stub */
|
||||
+ /* Low-pass filter the incoming sample. */
|
||||
+ in = lpFilter2P(&dsb->eax.LpFilter, 0, in);
|
||||
|
||||
/* Step all delays forward one sample. */
|
||||
dsb->eax.Offset++;
|
||||
@@ -137,6 +152,27 @@ void process_eax_buffer(IDirectSoundBufferImpl* dsb, float* buf, DWORD count)
|
||||
HeapFree(GetProcessHeap(), 0, out);
|
||||
}
|
||||
|
||||
+static float lpCoeffCalc(float g, float cw)
|
||||
+{
|
||||
+ float a = 0.0f;
|
||||
+
|
||||
+ if(g < 0.9999f) /* 1-epsilon */
|
||||
+ {
|
||||
+ /* Be careful with gains < 0.001, as that causes the coefficient head
|
||||
+ * towards 1, which will flatten the signal */
|
||||
+ if (g < 0.001f) g = 0.001f;
|
||||
+ a = (1 - g*cw - sqrtf(2*g*(1-cw) - g*g*(1 - cw*cw))) /
|
||||
+ (1 - g);
|
||||
+ }
|
||||
+
|
||||
+ return a;
|
||||
+}
|
||||
+
|
||||
+static float CalcI3DL2HFreq(float hfRef, unsigned int frequency)
|
||||
+{
|
||||
+ return cosf(M_PI*2.0f * hfRef / frequency);
|
||||
+}
|
||||
+
|
||||
static unsigned int NextPowerOf2(unsigned int value)
|
||||
{
|
||||
if(value > 0)
|
||||
@@ -214,12 +250,18 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
|
||||
static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
+ float cw;
|
||||
+
|
||||
/* avoid segfaults in mixing thread when we recalculate the line offsets */
|
||||
EnterCriticalSection(&dsb->device->mixlock);
|
||||
|
||||
AllocLines(dsb->device->pwfx->nSamplesPerSec, dsb);
|
||||
|
||||
LeaveCriticalSection(&dsb->device->mixlock);
|
||||
+
|
||||
+ cw = CalcI3DL2HFreq(dsb->device->eax.eax_props.flHFReference, dsb->device->pwfx->nSamplesPerSec);
|
||||
+
|
||||
+ dsb->eax.LpFilter.coeff = lpCoeffCalc(dsb->device->eax.eax_props.flGainHF, cw);
|
||||
}
|
||||
|
||||
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
@@ -238,6 +280,10 @@ void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
dsb->eax.TotalSamples = 0;
|
||||
dsb->eax.SampleBuffer = NULL;
|
||||
|
||||
+ dsb->eax.LpFilter.coeff = 0.0f;
|
||||
+ dsb->eax.LpFilter.history[0] = 0.0f;
|
||||
+ dsb->eax.LpFilter.history[1] = 0.0f;
|
||||
+
|
||||
dsb->eax.Delay.Mask = 0;
|
||||
dsb->eax.Delay.Line = NULL;
|
||||
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,103 @@
|
||||
From 8bb87c66ab1fc62d21e3b386d81a8269d979f369 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:00:10 +0000
|
||||
Subject: [PATCH 14/18] dsound: Add delay line EAX functions.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 1 +
|
||||
dlls/dsound/eax.c | 27 +++++++++++++++++++++++++++
|
||||
2 files changed, 28 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0014-dsound-Add-delay-line-EAX-functions.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0014-dsound-Add-delay-line-EAX-functions.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 51bafe0..4e7748c 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -141,6 +141,7 @@ typedef struct {
|
||||
FILTER LpFilter;
|
||||
|
||||
DelayLine Delay;
|
||||
+ unsigned int DelayTap[2];
|
||||
|
||||
unsigned int Offset;
|
||||
} eax_buffer_info;
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 54d90cd..8aafb2a 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -106,11 +106,26 @@ static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
return output;
|
||||
}
|
||||
|
||||
+static void DelayLineIn(DelayLine *Delay, unsigned int offset, float in)
|
||||
+{
|
||||
+ Delay->Line[offset&Delay->Mask] = in;
|
||||
+}
|
||||
+
|
||||
+static float DelayLineOut(DelayLine *Delay, unsigned int offset)
|
||||
+{
|
||||
+ return Delay->Line[offset&Delay->Mask];
|
||||
+}
|
||||
+
|
||||
static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
{
|
||||
/* Low-pass filter the incoming sample. */
|
||||
in = lpFilter2P(&dsb->eax.LpFilter, 0, in);
|
||||
|
||||
+ /* Feed the initial delay line. */
|
||||
+ DelayLineIn(&dsb->eax.Delay, dsb->eax.Offset, in);
|
||||
+
|
||||
+ in = DelayLineOut(&dsb->eax.Delay, dsb->eax.Offset - dsb->eax.DelayTap[0]);
|
||||
+
|
||||
/* Step all delays forward one sample. */
|
||||
dsb->eax.Offset++;
|
||||
}
|
||||
@@ -152,6 +167,12 @@ void process_eax_buffer(IDirectSoundBufferImpl* dsb, float* buf, DWORD count)
|
||||
HeapFree(GetProcessHeap(), 0, out);
|
||||
}
|
||||
|
||||
+static void UpdateDelayLine(float earlyDelay, float lateDelay, unsigned int frequency, eax_buffer_info *State)
|
||||
+{
|
||||
+ State->DelayTap[0] = fastf2u(earlyDelay * frequency);
|
||||
+ State->DelayTap[1] = fastf2u((earlyDelay + lateDelay) * frequency);
|
||||
+}
|
||||
+
|
||||
static float lpCoeffCalc(float g, float cw)
|
||||
{
|
||||
float a = 0.0f;
|
||||
@@ -262,6 +283,10 @@ static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
cw = CalcI3DL2HFreq(dsb->device->eax.eax_props.flHFReference, dsb->device->pwfx->nSamplesPerSec);
|
||||
|
||||
dsb->eax.LpFilter.coeff = lpCoeffCalc(dsb->device->eax.eax_props.flGainHF, cw);
|
||||
+
|
||||
+ UpdateDelayLine(dsb->device->eax.eax_props.flReflectionsDelay,
|
||||
+ dsb->device->eax.eax_props.flLateReverbDelay,
|
||||
+ dsb->device->pwfx->nSamplesPerSec, &dsb->eax);
|
||||
}
|
||||
|
||||
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
@@ -286,6 +311,8 @@ void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
|
||||
dsb->eax.Delay.Mask = 0;
|
||||
dsb->eax.Delay.Line = NULL;
|
||||
+ dsb->eax.DelayTap[0] = 0;
|
||||
+ dsb->eax.DelayTap[1] = 0;
|
||||
|
||||
dsb->eax.Offset = 0;
|
||||
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,241 @@
|
||||
From 197e2cef559b2eba88f7446e550e7c0343cfa23f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:09:34 +0000
|
||||
Subject: [PATCH 15/18] dsound: Implement EAX early reflections.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 7 +++
|
||||
dlls/dsound/eax.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 121 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0015-dsound-Implement-EAX-early-reflections.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0015-dsound-Implement-EAX-early-reflections.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 4e7748c..1c5716d 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -143,6 +143,13 @@ typedef struct {
|
||||
DelayLine Delay;
|
||||
unsigned int DelayTap[2];
|
||||
|
||||
+ struct {
|
||||
+ float Gain;
|
||||
+ float Coeff[4];
|
||||
+ DelayLine Delay[4];
|
||||
+ unsigned int Offset[4];
|
||||
+ } Early;
|
||||
+
|
||||
unsigned int Offset;
|
||||
} eax_buffer_info;
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 8aafb2a..5d1eaed 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,6 +92,11 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+static const float EARLY_LINE_LENGTH[4] =
|
||||
+{
|
||||
+ 0.0015f, 0.0045f, 0.0135f, 0.0405f
|
||||
+};
|
||||
+
|
||||
static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
{
|
||||
float *history = &iir->history[offset*2];
|
||||
@@ -116,6 +121,62 @@ static float DelayLineOut(DelayLine *Delay, unsigned int offset)
|
||||
return Delay->Line[offset&Delay->Mask];
|
||||
}
|
||||
|
||||
+static float AttenuatedDelayLineOut(DelayLine *Delay, unsigned int offset, float coeff)
|
||||
+{
|
||||
+ return coeff * Delay->Line[offset&Delay->Mask];
|
||||
+}
|
||||
+
|
||||
+static float EarlyDelayLineOut(IDirectSoundBufferImpl* dsb, unsigned int index)
|
||||
+{
|
||||
+ return AttenuatedDelayLineOut(&dsb->eax.Early.Delay[index],
|
||||
+ dsb->eax.Offset - dsb->eax.Early.Offset[index],
|
||||
+ dsb->eax.Early.Coeff[index]);
|
||||
+}
|
||||
+
|
||||
+static void EarlyReflection(IDirectSoundBufferImpl* dsb, float in, float *out)
|
||||
+{
|
||||
+ float d[4], v, f[4];
|
||||
+
|
||||
+ /* Obtain the decayed results of each early delay line. */
|
||||
+ d[0] = EarlyDelayLineOut(dsb, 0);
|
||||
+ d[1] = EarlyDelayLineOut(dsb, 1);
|
||||
+ d[2] = EarlyDelayLineOut(dsb, 2);
|
||||
+ d[3] = EarlyDelayLineOut(dsb, 3);
|
||||
+
|
||||
+ /* The following uses a lossless scattering junction from waveguide
|
||||
+ * theory. It actually amounts to a householder mixing matrix, which
|
||||
+ * will produce a maximally diffuse response, and means this can probably
|
||||
+ * be considered a simple feed-back delay network (FDN).
|
||||
+ * N
|
||||
+ * ---
|
||||
+ * \
|
||||
+ * v = 2/N / d_i
|
||||
+ * ---
|
||||
+ * i=1
|
||||
+ */
|
||||
+ v = (d[0] + d[1] + d[2] + d[3]) * 0.5f;
|
||||
+ /* The junction is loaded with the input here. */
|
||||
+ v += in;
|
||||
+
|
||||
+ /* Calculate the feed values for the delay lines. */
|
||||
+ f[0] = v - d[0];
|
||||
+ f[1] = v - d[1];
|
||||
+ f[2] = v - d[2];
|
||||
+ f[3] = v - d[3];
|
||||
+
|
||||
+ /* Re-feed the delay lines. */
|
||||
+ DelayLineIn(&dsb->eax.Early.Delay[0], dsb->eax.Offset, f[0]);
|
||||
+ DelayLineIn(&dsb->eax.Early.Delay[1], dsb->eax.Offset, f[1]);
|
||||
+ DelayLineIn(&dsb->eax.Early.Delay[2], dsb->eax.Offset, f[2]);
|
||||
+ DelayLineIn(&dsb->eax.Early.Delay[3], dsb->eax.Offset, f[3]);
|
||||
+
|
||||
+ /* Output the results of the junction for all four channels. */
|
||||
+ out[0] = dsb->eax.Early.Gain * f[0];
|
||||
+ out[1] = dsb->eax.Early.Gain * f[1];
|
||||
+ out[2] = dsb->eax.Early.Gain * f[2];
|
||||
+ out[3] = dsb->eax.Early.Gain * f[3];
|
||||
+}
|
||||
+
|
||||
static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
{
|
||||
/* Low-pass filter the incoming sample. */
|
||||
@@ -124,7 +185,9 @@ static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
/* Feed the initial delay line. */
|
||||
DelayLineIn(&dsb->eax.Delay, dsb->eax.Offset, in);
|
||||
|
||||
+ /* Calculate the early reflection from the first delay tap. */
|
||||
in = DelayLineOut(&dsb->eax.Delay, dsb->eax.Offset - dsb->eax.DelayTap[0]);
|
||||
+ EarlyReflection(dsb, in, out);
|
||||
|
||||
/* Step all delays forward one sample. */
|
||||
dsb->eax.Offset++;
|
||||
@@ -173,6 +236,27 @@ static void UpdateDelayLine(float earlyDelay, float lateDelay, unsigned int freq
|
||||
State->DelayTap[1] = fastf2u((earlyDelay + lateDelay) * frequency);
|
||||
}
|
||||
|
||||
+static float CalcDecayCoeff(float length, float decayTime)
|
||||
+{
|
||||
+ return powf(0.001f/*-60 dB*/, length/decayTime);
|
||||
+}
|
||||
+
|
||||
+static void UpdateEarlyLines(float reverbGain, float earlyGain, float lateDelay, eax_buffer_info *State)
|
||||
+{
|
||||
+ unsigned int index;
|
||||
+
|
||||
+ /* Calculate the early reflections gain (from the master effect gain, and
|
||||
+ * reflections gain parameters) with a constant attenuation of 0.5. */
|
||||
+ State->Early.Gain = 0.5f * reverbGain * earlyGain;
|
||||
+
|
||||
+ /* Calculate the gain (coefficient) for each early delay line using the
|
||||
+ * late delay time. This expands the early reflections to the start of
|
||||
+ * the late reverb. */
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ State->Early.Coeff[index] = CalcDecayCoeff(EARLY_LINE_LENGTH[index],
|
||||
+ lateDelay);
|
||||
+}
|
||||
+
|
||||
static float lpCoeffCalc(float g, float cw)
|
||||
{
|
||||
float a = 0.0f;
|
||||
@@ -244,6 +328,11 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
totalSamples += CalcLineLength(length, totalSamples, frequency,
|
||||
&dsb->eax.Delay);
|
||||
|
||||
+ /* The early reflection lines. */
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ totalSamples += CalcLineLength(EARLY_LINE_LENGTH[index], totalSamples,
|
||||
+ frequency, &dsb->eax.Early.Delay[index]);
|
||||
+
|
||||
if(totalSamples != dsb->eax.TotalSamples)
|
||||
{
|
||||
TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency);
|
||||
@@ -261,6 +350,10 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
|
||||
/* Update all delays to reflect the new sample buffer. */
|
||||
RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Delay);
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ {
|
||||
+ RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Early.Delay[index]);
|
||||
+ }
|
||||
|
||||
/* Clear the sample buffer. */
|
||||
for(index = 0;index < dsb->eax.TotalSamples;index++)
|
||||
@@ -271,6 +364,7 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
|
||||
static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
+ unsigned int index;
|
||||
float cw;
|
||||
|
||||
/* avoid segfaults in mixing thread when we recalculate the line offsets */
|
||||
@@ -280,6 +374,11 @@ static void ReverbUpdate(IDirectSoundBufferImpl* 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);
|
||||
+ }
|
||||
+
|
||||
cw = CalcI3DL2HFreq(dsb->device->eax.eax_props.flHFReference, dsb->device->pwfx->nSamplesPerSec);
|
||||
|
||||
dsb->eax.LpFilter.coeff = lpCoeffCalc(dsb->device->eax.eax_props.flGainHF, cw);
|
||||
@@ -287,6 +386,10 @@ static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
UpdateDelayLine(dsb->device->eax.eax_props.flReflectionsDelay,
|
||||
dsb->device->eax.eax_props.flLateReverbDelay,
|
||||
dsb->device->pwfx->nSamplesPerSec, &dsb->eax);
|
||||
+
|
||||
+ UpdateEarlyLines(dsb->device->eax.eax_props.flGain,
|
||||
+ dsb->device->eax.eax_props.flReflectionsGain,
|
||||
+ dsb->device->eax.eax_props.flLateReverbDelay, &dsb->eax);
|
||||
}
|
||||
|
||||
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
@@ -302,6 +405,8 @@ static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
|
||||
void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
+ unsigned int index;
|
||||
+
|
||||
dsb->eax.TotalSamples = 0;
|
||||
dsb->eax.SampleBuffer = NULL;
|
||||
|
||||
@@ -314,6 +419,15 @@ void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
dsb->eax.DelayTap[0] = 0;
|
||||
dsb->eax.DelayTap[1] = 0;
|
||||
|
||||
+ dsb->eax.Early.Gain = 0.0f;
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ {
|
||||
+ dsb->eax.Early.Coeff[index] = 0.0f;
|
||||
+ dsb->eax.Early.Delay[index].Mask = 0;
|
||||
+ dsb->eax.Early.Delay[index].Line = NULL;
|
||||
+ dsb->eax.Early.Offset[index] = 0;
|
||||
+ }
|
||||
+
|
||||
dsb->eax.Offset = 0;
|
||||
|
||||
ReverbUpdate(dsb);
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
138
patches/dsound-EAX/0016-dsound-Implement-EAX-decorrelator.patch
Normal file
138
patches/dsound-EAX/0016-dsound-Implement-EAX-decorrelator.patch
Normal file
@ -0,0 +1,138 @@
|
||||
From d4203ee7e94bc232202b7e9bcf8a4627086c22e8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:19:17 +0000
|
||||
Subject: [PATCH 16/18] dsound: Implement EAX decorrelator.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 3 +++
|
||||
dlls/dsound/eax.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 49 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0016-dsound-Implement-EAX-decorrelator.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0016-dsound-Implement-EAX-decorrelator.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 1c5716d..ca26dea 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -150,6 +150,9 @@ typedef struct {
|
||||
unsigned int Offset[4];
|
||||
} Early;
|
||||
|
||||
+ DelayLine Decorrelator;
|
||||
+ unsigned int DecoTap[3];
|
||||
+
|
||||
unsigned int Offset;
|
||||
} eax_buffer_info;
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 5d1eaed..43697a6 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,11 +92,21 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
|
||||
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
|
||||
};
|
||||
|
||||
+static const float DECO_FRACTION = 0.15f;
|
||||
+static const float DECO_MULTIPLIER = 2.0f;
|
||||
+
|
||||
static const float EARLY_LINE_LENGTH[4] =
|
||||
{
|
||||
0.0015f, 0.0045f, 0.0135f, 0.0405f
|
||||
};
|
||||
|
||||
+static const float LATE_LINE_LENGTH[4] =
|
||||
+{
|
||||
+ 0.0211f, 0.0311f, 0.0461f, 0.0680f
|
||||
+};
|
||||
+
|
||||
+static const float LATE_LINE_MULTIPLIER = 4.0f;
|
||||
+
|
||||
static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
{
|
||||
float *history = &iir->history[offset*2];
|
||||
@@ -273,6 +283,26 @@ static float lpCoeffCalc(float g, float cw)
|
||||
return a;
|
||||
}
|
||||
|
||||
+static void UpdateDecorrelator(float density, unsigned int frequency, eax_buffer_info *State)
|
||||
+{
|
||||
+ unsigned int index;
|
||||
+ float length;
|
||||
+
|
||||
+ /* The late reverb inputs are decorrelated to smooth the reverb tail and
|
||||
+ * reduce harsh echos. The first tap occurs immediately, while the
|
||||
+ * remaining taps are delayed by multiples of a fraction of the smallest
|
||||
+ * cyclical delay time.
|
||||
+ *
|
||||
+ * offset[index] = (FRACTION (MULTIPLIER^index)) smallest_delay
|
||||
+ */
|
||||
+ for(index = 0;index < 3;index++)
|
||||
+ {
|
||||
+ length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (float)index)) *
|
||||
+ LATE_LINE_LENGTH[0] * (1.0f + (density * LATE_LINE_MULTIPLIER));
|
||||
+ State->DecoTap[index] = fastf2u(length * frequency);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static float CalcI3DL2HFreq(float hfRef, unsigned int frequency)
|
||||
{
|
||||
return cosf(M_PI*2.0f * hfRef / frequency);
|
||||
@@ -333,6 +363,13 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
totalSamples += CalcLineLength(EARLY_LINE_LENGTH[index], totalSamples,
|
||||
frequency, &dsb->eax.Early.Delay[index]);
|
||||
|
||||
+ /* The decorrelator line is calculated from the lowest reverb density (a
|
||||
+ * parameter value of 1). */
|
||||
+ length = (DECO_FRACTION * DECO_MULTIPLIER * DECO_MULTIPLIER) *
|
||||
+ LATE_LINE_LENGTH[0] * (1.0f + LATE_LINE_MULTIPLIER);
|
||||
+ totalSamples += CalcLineLength(length, totalSamples, frequency,
|
||||
+ &dsb->eax.Decorrelator);
|
||||
+
|
||||
if(totalSamples != dsb->eax.TotalSamples)
|
||||
{
|
||||
TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency);
|
||||
@@ -350,6 +387,7 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
|
||||
/* Update all delays to reflect the new sample buffer. */
|
||||
RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Delay);
|
||||
+ RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Decorrelator);
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Early.Delay[index]);
|
||||
@@ -390,6 +428,8 @@ static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
UpdateEarlyLines(dsb->device->eax.eax_props.flGain,
|
||||
dsb->device->eax.eax_props.flReflectionsGain,
|
||||
dsb->device->eax.eax_props.flLateReverbDelay, &dsb->eax);
|
||||
+
|
||||
+ UpdateDecorrelator(dsb->device->eax.eax_props.flDensity, dsb->device->pwfx->nSamplesPerSec, &dsb->eax);
|
||||
}
|
||||
|
||||
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
@@ -428,6 +468,12 @@ void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
dsb->eax.Early.Offset[index] = 0;
|
||||
}
|
||||
|
||||
+ dsb->eax.Decorrelator.Mask = 0;
|
||||
+ dsb->eax.Decorrelator.Line = NULL;
|
||||
+ dsb->eax.DecoTap[0] = 0;
|
||||
+ dsb->eax.DecoTap[1] = 0;
|
||||
+ dsb->eax.DecoTap[2] = 0;
|
||||
+
|
||||
dsb->eax.Offset = 0;
|
||||
|
||||
ReverbUpdate(dsb);
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
386
patches/dsound-EAX/0017-dsound-Implement-EAX-late-reverb.patch
Normal file
386
patches/dsound-EAX/0017-dsound-Implement-EAX-late-reverb.patch
Normal file
@ -0,0 +1,386 @@
|
||||
From d7e40d814a33a3a794e4dabdf0ba78da22d59e4a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:21:02 +0000
|
||||
Subject: [PATCH 17/18] dsound: Implement EAX late reverb.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 13 +++
|
||||
dlls/dsound/eax.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 268 insertions(+), 1 deletion(-)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0017-dsound-Implement-EAX-late-reverb.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0017-dsound-Implement-EAX-late-reverb.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index ca26dea..bb9e529 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -153,6 +153,19 @@ typedef struct {
|
||||
DelayLine Decorrelator;
|
||||
unsigned int DecoTap[3];
|
||||
|
||||
+ struct {
|
||||
+ float Gain;
|
||||
+ float DensityGain;
|
||||
+ float MixCoeff;
|
||||
+
|
||||
+ float Coeff[4];
|
||||
+ DelayLine Delay[4];
|
||||
+ unsigned int Offset[4];
|
||||
+
|
||||
+ float LpCoeff[4];
|
||||
+ float LpSample[4];
|
||||
+ } Late;
|
||||
+
|
||||
unsigned int Offset;
|
||||
} eax_buffer_info;
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 43697a6..178c186 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -107,6 +107,8 @@ static const float LATE_LINE_LENGTH[4] =
|
||||
|
||||
static const float LATE_LINE_MULTIPLIER = 4.0f;
|
||||
|
||||
+#define SPEEDOFSOUNDMETRESPERSEC 343.3f
|
||||
+
|
||||
static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
{
|
||||
float *history = &iir->history[offset*2];
|
||||
@@ -121,6 +123,11 @@ static float lpFilter2P(FILTER *iir, unsigned int offset, float input)
|
||||
return output;
|
||||
}
|
||||
|
||||
+static float lerp(float val1, float val2, float mu)
|
||||
+{
|
||||
+ return val1 + (val2-val1)*mu;
|
||||
+}
|
||||
+
|
||||
static void DelayLineIn(DelayLine *Delay, unsigned int offset, float in)
|
||||
{
|
||||
Delay->Line[offset&Delay->Mask] = in;
|
||||
@@ -187,8 +194,85 @@ static void EarlyReflection(IDirectSoundBufferImpl* dsb, float in, float *out)
|
||||
out[3] = dsb->eax.Early.Gain * f[3];
|
||||
}
|
||||
|
||||
+static float LateDelayLineOut(IDirectSoundBufferImpl* dsb, unsigned int index)
|
||||
+{
|
||||
+ return AttenuatedDelayLineOut(&dsb->eax.Late.Delay[index],
|
||||
+ dsb->eax.Offset - dsb->eax.Late.Offset[index],
|
||||
+ dsb->eax.Late.Coeff[index]);
|
||||
+}
|
||||
+
|
||||
+static float LateLowPassInOut(IDirectSoundBufferImpl* dsb, unsigned int index, float in)
|
||||
+{
|
||||
+ in = lerp(in, dsb->eax.Late.LpSample[index], dsb->eax.Late.LpCoeff[index]);
|
||||
+ dsb->eax.Late.LpSample[index] = in;
|
||||
+ return in;
|
||||
+}
|
||||
+
|
||||
+static void LateReverb(IDirectSoundBufferImpl* dsb, const float *in, float *out)
|
||||
+{
|
||||
+ float d[4], f[4];
|
||||
+
|
||||
+ /* Obtain the decayed results of the cyclical delay lines, and add the
|
||||
+ * corresponding input channels. Then pass the results through the
|
||||
+ * low-pass filters. */
|
||||
+
|
||||
+ /* This is where the feed-back cycles from line 0 to 1 to 3 to 2 and back
|
||||
+ * to 0. */
|
||||
+ d[0] = LateLowPassInOut(dsb, 2, in[2] + LateDelayLineOut(dsb, 2));
|
||||
+ d[1] = LateLowPassInOut(dsb, 0, in[0] + LateDelayLineOut(dsb, 0));
|
||||
+ d[2] = LateLowPassInOut(dsb, 3, in[3] + LateDelayLineOut(dsb, 3));
|
||||
+ d[3] = LateLowPassInOut(dsb, 1, in[1] + LateDelayLineOut(dsb, 1));
|
||||
+
|
||||
+ /* Late reverb is done with a modified feed-back delay network (FDN)
|
||||
+ * topology. Four input lines are each fed through their own all-pass
|
||||
+ * filter and then into the mixing matrix. The four outputs of the
|
||||
+ * mixing matrix are then cycled back to the inputs. Each output feeds
|
||||
+ * a different input to form a circlular feed cycle.
|
||||
+ *
|
||||
+ * The mixing matrix used is a 4D skew-symmetric rotation matrix derived
|
||||
+ * using a single unitary rotational parameter:
|
||||
+ *
|
||||
+ * [ d, a, b, c ] 1 = a^2 + b^2 + c^2 + d^2
|
||||
+ * [ -a, d, c, -b ]
|
||||
+ * [ -b, -c, d, a ]
|
||||
+ * [ -c, b, -a, d ]
|
||||
+ *
|
||||
+ * The rotation is constructed from the effect's diffusion parameter,
|
||||
+ * yielding: 1 = x^2 + 3 y^2; where a, b, and c are the coefficient y
|
||||
+ * with differing signs, and d is the coefficient x. The matrix is thus:
|
||||
+ *
|
||||
+ * [ x, y, -y, y ] n = sqrt(matrix_order - 1)
|
||||
+ * [ -y, x, y, y ] t = diffusion_parameter * atan(n)
|
||||
+ * [ y, -y, x, y ] x = cos(t)
|
||||
+ * [ -y, -y, -y, x ] y = sin(t) / n
|
||||
+ *
|
||||
+ * To reduce the number of multiplies, the x coefficient is applied with
|
||||
+ * the cyclical delay line coefficients. Thus only the y coefficient is
|
||||
+ * applied when mixing, and is modified to be: y / x.
|
||||
+ */
|
||||
+ f[0] = d[0] + (dsb->eax.Late.MixCoeff * ( d[1] + -d[2] + d[3]));
|
||||
+ f[1] = d[1] + (dsb->eax.Late.MixCoeff * (-d[0] + d[2] + d[3]));
|
||||
+ f[2] = d[2] + (dsb->eax.Late.MixCoeff * ( d[0] + -d[1] + d[3]));
|
||||
+ f[3] = d[3] + (dsb->eax.Late.MixCoeff * (-d[0] + -d[1] + -d[2] ));
|
||||
+
|
||||
+ /* Output the results of the matrix for all four channels, attenuated by
|
||||
+ * the late reverb gain (which is attenuated by the 'x' mix coefficient). */
|
||||
+ out[0] = dsb->eax.Late.Gain * f[0];
|
||||
+ out[1] = dsb->eax.Late.Gain * f[1];
|
||||
+ out[2] = dsb->eax.Late.Gain * f[2];
|
||||
+ out[3] = dsb->eax.Late.Gain * f[3];
|
||||
+
|
||||
+ /* Re-feed the cyclical delay lines. */
|
||||
+ DelayLineIn(&dsb->eax.Late.Delay[0], dsb->eax.Offset, f[0]);
|
||||
+ DelayLineIn(&dsb->eax.Late.Delay[1], dsb->eax.Offset, f[1]);
|
||||
+ DelayLineIn(&dsb->eax.Late.Delay[2], dsb->eax.Offset, f[2]);
|
||||
+ DelayLineIn(&dsb->eax.Late.Delay[3], dsb->eax.Offset, f[3]);
|
||||
+}
|
||||
+
|
||||
static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
{
|
||||
+ float feed, late[4], taps[4];
|
||||
+
|
||||
/* Low-pass filter the incoming sample. */
|
||||
in = lpFilter2P(&dsb->eax.LpFilter, 0, in);
|
||||
|
||||
@@ -199,6 +283,25 @@ static void VerbPass(IDirectSoundBufferImpl* dsb, float in, float* out)
|
||||
in = DelayLineOut(&dsb->eax.Delay, dsb->eax.Offset - dsb->eax.DelayTap[0]);
|
||||
EarlyReflection(dsb, in, out);
|
||||
|
||||
+ /* Feed the decorrelator from the energy-attenuated output of the second
|
||||
+ * delay tap. */
|
||||
+ in = DelayLineOut(&dsb->eax.Delay, dsb->eax.Offset - dsb->eax.DelayTap[1]);
|
||||
+ feed = in * dsb->eax.Late.DensityGain;
|
||||
+ DelayLineIn(&dsb->eax.Decorrelator, dsb->eax.Offset, feed);
|
||||
+
|
||||
+ /* Calculate the late reverb from the decorrelator taps. */
|
||||
+ taps[0] = feed;
|
||||
+ taps[1] = DelayLineOut(&dsb->eax.Decorrelator, dsb->eax.Offset - dsb->eax.DecoTap[0]);
|
||||
+ taps[2] = DelayLineOut(&dsb->eax.Decorrelator, dsb->eax.Offset - dsb->eax.DecoTap[1]);
|
||||
+ taps[3] = DelayLineOut(&dsb->eax.Decorrelator, dsb->eax.Offset - dsb->eax.DecoTap[2]);
|
||||
+ LateReverb(dsb, taps, late);
|
||||
+
|
||||
+ /* Mix early reflections and late reverb. */
|
||||
+ out[0] += late[0];
|
||||
+ out[1] += late[1];
|
||||
+ out[2] += late[2];
|
||||
+ out[3] += late[3];
|
||||
+
|
||||
/* Step all delays forward one sample. */
|
||||
dsb->eax.Offset++;
|
||||
}
|
||||
@@ -308,6 +411,95 @@ static float CalcI3DL2HFreq(float hfRef, unsigned int frequency)
|
||||
return cosf(M_PI*2.0f * hfRef / frequency);
|
||||
}
|
||||
|
||||
+static float CalcDensityGain(float a)
|
||||
+{
|
||||
+ return sqrtf(1.0f - (a * a));
|
||||
+}
|
||||
+
|
||||
+static float CalcDampingCoeff(float hfRatio, float length, float decayTime, float decayCoeff, float cw)
|
||||
+{
|
||||
+ float coeff, g;
|
||||
+
|
||||
+ coeff = 0.0f;
|
||||
+ if (hfRatio < 1.0f)
|
||||
+ {
|
||||
+ /* Calculate the low-pass coefficient by dividing the HF decay
|
||||
+ * coefficient by the full decay coefficient. */
|
||||
+ g = CalcDecayCoeff(length, decayTime * hfRatio) / decayCoeff;
|
||||
+
|
||||
+ /* Damping is done with a 1-pole filter, so g needs to be squared. */
|
||||
+ g *= g;
|
||||
+ coeff = lpCoeffCalc(g, cw);
|
||||
+
|
||||
+ /* Very low decay times will produce minimal output, so apply an
|
||||
+ * upper bound to the coefficient. */
|
||||
+ if (coeff > 0.98f) coeff = 0.98f;
|
||||
+ }
|
||||
+ return coeff;
|
||||
+}
|
||||
+
|
||||
+static void UpdateLateLines(float reverbGain, float lateGain, float xMix, float density, float decayTime,
|
||||
+ float diffusion, float hfRatio, float cw, unsigned int frequency, eax_buffer_info *State)
|
||||
+{
|
||||
+ float length;
|
||||
+ unsigned int index;
|
||||
+
|
||||
+ /* Calculate the late reverb gain (from the master effect gain, and late
|
||||
+ * reverb gain parameters). Since the output is tapped prior to the
|
||||
+ * application of the next delay line coefficients, this gain needs to be
|
||||
+ * attenuated by the 'x' mixing matrix coefficient as well.
|
||||
+ */
|
||||
+ State->Late.Gain = reverbGain * lateGain * xMix;
|
||||
+
|
||||
+ /* To compensate for changes in modal density and decay time of the late
|
||||
+ * reverb signal, the input is attenuated based on the maximal energy of
|
||||
+ * the outgoing signal. This approximation is used to keep the apparent
|
||||
+ * energy of the signal equal for all ranges of density and decay time.
|
||||
+ *
|
||||
+ * The average length of the cyclcical delay lines is used to calculate
|
||||
+ * the attenuation coefficient.
|
||||
+ */
|
||||
+ length = (LATE_LINE_LENGTH[0] + LATE_LINE_LENGTH[1] +
|
||||
+ LATE_LINE_LENGTH[2] + LATE_LINE_LENGTH[3]) / 4.0f;
|
||||
+ length *= 1.0f + (density * LATE_LINE_MULTIPLIER);
|
||||
+ State->Late.DensityGain = CalcDensityGain(CalcDecayCoeff(length,
|
||||
+ decayTime));
|
||||
+
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ {
|
||||
+ /* Calculate the length (in seconds) of each cyclical delay line. */
|
||||
+ length = LATE_LINE_LENGTH[index] * (1.0f + (density * LATE_LINE_MULTIPLIER));
|
||||
+
|
||||
+ /* Calculate the delay offset for each cyclical delay line. */
|
||||
+ State->Late.Offset[index] = fastf2u(length * frequency);
|
||||
+
|
||||
+ /* Calculate the gain (coefficient) for each cyclical line. */
|
||||
+ State->Late.Coeff[index] = CalcDecayCoeff(length, decayTime);
|
||||
+
|
||||
+ /* Calculate the damping coefficient for each low-pass filter. */
|
||||
+ State->Late.LpCoeff[index] = CalcDampingCoeff(hfRatio, length, decayTime,
|
||||
+ State->Late.Coeff[index], cw);
|
||||
+
|
||||
+ /* Attenuate the cyclical line coefficients by the mixing coefficient
|
||||
+ * (x). */
|
||||
+ State->Late.Coeff[index] *= xMix;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void CalcMatrixCoeffs(float diffusion, float *x, float *y)
|
||||
+{
|
||||
+ float n, t;
|
||||
+
|
||||
+ /* The matrix is of order 4, so n is sqrt (4 - 1). */
|
||||
+ n = sqrtf(3.0f);
|
||||
+ t = diffusion * atanf(n);
|
||||
+
|
||||
+ /* Calculate the first mixing matrix coefficient. */
|
||||
+ *x = cosf(t);
|
||||
+ /* Calculate the second mixing matrix coefficient. */
|
||||
+ *y = sinf(t) / n;
|
||||
+}
|
||||
+
|
||||
static unsigned int NextPowerOf2(unsigned int value)
|
||||
{
|
||||
if(value > 0)
|
||||
@@ -370,6 +562,14 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
totalSamples += CalcLineLength(length, totalSamples, frequency,
|
||||
&dsb->eax.Decorrelator);
|
||||
|
||||
+ /* The late delay lines are calculated from the lowest reverb density. */
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ {
|
||||
+ length = LATE_LINE_LENGTH[index] * (1.0f + LATE_LINE_MULTIPLIER);
|
||||
+ totalSamples += CalcLineLength(length, totalSamples, frequency,
|
||||
+ &dsb->eax.Late.Delay[index]);
|
||||
+ }
|
||||
+
|
||||
if(totalSamples != dsb->eax.TotalSamples)
|
||||
{
|
||||
TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency);
|
||||
@@ -391,6 +591,7 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Early.Delay[index]);
|
||||
+ RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Late.Delay[index]);
|
||||
}
|
||||
|
||||
/* Clear the sample buffer. */
|
||||
@@ -400,10 +601,35 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static inline float CalcDecayLength(float coeff, float decayTime)
|
||||
+{
|
||||
+ return log10f(coeff) * decayTime / log10f(0.001f)/*-60 dB*/;
|
||||
+}
|
||||
+
|
||||
+static float CalcLimitedHfRatio(float hfRatio, float airAbsorptionGainHF, float decayTime)
|
||||
+{
|
||||
+ float limitRatio;
|
||||
+
|
||||
+ /* Find the attenuation due to air absorption in dB (converting delay
|
||||
+ * time to meters using the speed of sound). Then reversing the decay
|
||||
+ * equation, solve for HF ratio. The delay length is cancelled out of
|
||||
+ * the equation, so it can be calculated once for all lines.
|
||||
+ */
|
||||
+ limitRatio = 1.0f / (CalcDecayLength(airAbsorptionGainHF, decayTime) *
|
||||
+ SPEEDOFSOUNDMETRESPERSEC);
|
||||
+ /* Using the limit calculated above, apply the upper bound to the HF
|
||||
+ * ratio. Also need to limit the result to a minimum of 0.1, just like the
|
||||
+ * HF ratio parameter. */
|
||||
+ if (limitRatio < 0.1f) limitRatio = 0.1f;
|
||||
+ else if (limitRatio > hfRatio) limitRatio = hfRatio;
|
||||
+
|
||||
+ return limitRatio;
|
||||
+}
|
||||
+
|
||||
static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
{
|
||||
unsigned int index;
|
||||
- float cw;
|
||||
+ float cw, hfRatio, x, y;
|
||||
|
||||
/* avoid segfaults in mixing thread when we recalculate the line offsets */
|
||||
EnterCriticalSection(&dsb->device->mixlock);
|
||||
@@ -430,6 +656,20 @@ static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
dsb->device->eax.eax_props.flLateReverbDelay, &dsb->eax);
|
||||
|
||||
UpdateDecorrelator(dsb->device->eax.eax_props.flDensity, dsb->device->pwfx->nSamplesPerSec, &dsb->eax);
|
||||
+
|
||||
+ CalcMatrixCoeffs(dsb->device->eax.eax_props.flDiffusion, &x, &y);
|
||||
+ dsb->eax.Late.MixCoeff = y / x;
|
||||
+
|
||||
+ hfRatio = dsb->device->eax.eax_props.flDecayHFRatio;
|
||||
+
|
||||
+ if (dsb->device->eax.eax_props.iDecayHFLimit && dsb->device->eax.eax_props.flAirAbsorptionGainHF < 1.0f) {
|
||||
+ hfRatio = CalcLimitedHfRatio(hfRatio, dsb->device->eax.eax_props.flAirAbsorptionGainHF,
|
||||
+ dsb->device->eax.eax_props.flDecayTime);
|
||||
+ }
|
||||
+
|
||||
+ UpdateLateLines(dsb->device->eax.eax_props.flGain, dsb->device->eax.eax_props.flLateReverbGain,
|
||||
+ x, dsb->device->eax.eax_props.flDensity, dsb->device->eax.eax_props.flDecayTime,
|
||||
+ dsb->device->eax.eax_props.flDiffusion, hfRatio, cw, dsb->device->pwfx->nSamplesPerSec, &dsb->eax);
|
||||
}
|
||||
|
||||
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
|
||||
@@ -474,6 +714,20 @@ void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
dsb->eax.DecoTap[1] = 0;
|
||||
dsb->eax.DecoTap[2] = 0;
|
||||
|
||||
+ dsb->eax.Late.Gain = 0.0f;
|
||||
+ dsb->eax.Late.DensityGain = 0.0f;
|
||||
+ dsb->eax.Late.MixCoeff = 0.0f;
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ {
|
||||
+ dsb->eax.Late.Coeff[index] = 0.0f;
|
||||
+ dsb->eax.Late.Delay[index].Mask = 0;
|
||||
+ dsb->eax.Late.Delay[index].Line = NULL;
|
||||
+ dsb->eax.Late.Offset[index] = 0;
|
||||
+
|
||||
+ dsb->eax.Late.LpCoeff[index] = 0.0f;
|
||||
+ dsb->eax.Late.LpSample[index] = 0.0f;
|
||||
+ }
|
||||
+
|
||||
dsb->eax.Offset = 0;
|
||||
|
||||
ReverbUpdate(dsb);
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
@ -0,0 +1,165 @@
|
||||
From efae62efac5e05562c8771107d2f6af0bf0e0114 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:21:18 +0000
|
||||
Subject: [PATCH 18/18] dsound: Implement EAX late all-pass filter.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="------------2.0.5"
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
--------------2.0.5
|
||||
Content-Type: text/plain; charset=UTF-8; format=fixed
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 5 +++++
|
||||
dlls/dsound/eax.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 60 insertions(+)
|
||||
|
||||
|
||||
--------------2.0.5
|
||||
Content-Type: text/x-patch; name="0018-dsound-Implement-EAX-late-all-pass-filter.patch"
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Content-Disposition: attachment; filename="0018-dsound-Implement-EAX-late-all-pass-filter.patch"
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index bb9e529..527b081 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -156,8 +156,13 @@ typedef struct {
|
||||
struct {
|
||||
float Gain;
|
||||
float DensityGain;
|
||||
+ float ApFeedCoeff;
|
||||
float MixCoeff;
|
||||
|
||||
+ float ApCoeff[4];
|
||||
+ DelayLine ApDelay[4];
|
||||
+ unsigned int ApOffset[4];
|
||||
+
|
||||
float Coeff[4];
|
||||
DelayLine Delay[4];
|
||||
unsigned int Offset[4];
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index 178c186..aec6e1b 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -100,6 +100,11 @@ static const float EARLY_LINE_LENGTH[4] =
|
||||
0.0015f, 0.0045f, 0.0135f, 0.0405f
|
||||
};
|
||||
|
||||
+static const float ALLPASS_LINE_LENGTH[4] =
|
||||
+{
|
||||
+ 0.0151f, 0.0167f, 0.0183f, 0.0200f,
|
||||
+};
|
||||
+
|
||||
static const float LATE_LINE_LENGTH[4] =
|
||||
{
|
||||
0.0211f, 0.0311f, 0.0461f, 0.0680f
|
||||
@@ -194,6 +199,28 @@ static void EarlyReflection(IDirectSoundBufferImpl* dsb, float in, float *out)
|
||||
out[3] = dsb->eax.Early.Gain * f[3];
|
||||
}
|
||||
|
||||
+static float AllpassInOut(DelayLine *Delay, unsigned int outOffset, unsigned int inOffset, float in, float feedCoeff, float coeff)
|
||||
+{
|
||||
+ float out, feed;
|
||||
+
|
||||
+ out = DelayLineOut(Delay, outOffset);
|
||||
+ feed = feedCoeff * in;
|
||||
+ DelayLineIn(Delay, inOffset, (feedCoeff * (out - feed)) + in);
|
||||
+
|
||||
+ /* The time-based attenuation is only applied to the delay output to
|
||||
+ * keep it from affecting the feed-back path (which is already controlled
|
||||
+ * by the all-pass feed coefficient). */
|
||||
+ return (coeff * out) - feed;
|
||||
+}
|
||||
+
|
||||
+static float LateAllPassInOut(IDirectSoundBufferImpl* dsb, unsigned int index, float in)
|
||||
+{
|
||||
+ return AllpassInOut(&dsb->eax.Late.ApDelay[index],
|
||||
+ dsb->eax.Offset - dsb->eax.Late.ApOffset[index],
|
||||
+ dsb->eax.Offset, in, dsb->eax.Late.ApFeedCoeff,
|
||||
+ dsb->eax.Late.ApCoeff[index]);
|
||||
+}
|
||||
+
|
||||
static float LateDelayLineOut(IDirectSoundBufferImpl* dsb, unsigned int index)
|
||||
{
|
||||
return AttenuatedDelayLineOut(&dsb->eax.Late.Delay[index],
|
||||
@@ -223,6 +250,14 @@ static void LateReverb(IDirectSoundBufferImpl* dsb, const float *in, float *out)
|
||||
d[2] = LateLowPassInOut(dsb, 3, in[3] + LateDelayLineOut(dsb, 3));
|
||||
d[3] = LateLowPassInOut(dsb, 1, in[1] + LateDelayLineOut(dsb, 1));
|
||||
|
||||
+ /* To help increase diffusion, run each line through an all-pass filter.
|
||||
+ * When there is no diffusion, the shortest all-pass filter will feed the
|
||||
+ * shortest delay line. */
|
||||
+ d[0] = LateAllPassInOut(dsb, 0, d[0]);
|
||||
+ d[1] = LateAllPassInOut(dsb, 1, d[1]);
|
||||
+ d[2] = LateAllPassInOut(dsb, 2, d[2]);
|
||||
+ d[3] = LateAllPassInOut(dsb, 3, d[3]);
|
||||
+
|
||||
/* Late reverb is done with a modified feed-back delay network (FDN)
|
||||
* topology. Four input lines are each fed through their own all-pass
|
||||
* filter and then into the mixing matrix. The four outputs of the
|
||||
@@ -465,8 +500,15 @@ static void UpdateLateLines(float reverbGain, float lateGain, float xMix, float
|
||||
State->Late.DensityGain = CalcDensityGain(CalcDecayCoeff(length,
|
||||
decayTime));
|
||||
|
||||
+ /* Calculate the all-pass feed-back and feed-forward coefficient. */
|
||||
+ State->Late.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f);
|
||||
+
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
+ /* Calculate the gain (coefficient) for each all-pass line. */
|
||||
+ State->Late.ApCoeff[index] = CalcDecayCoeff(ALLPASS_LINE_LENGTH[index],
|
||||
+ decayTime);
|
||||
+
|
||||
/* Calculate the length (in seconds) of each cyclical delay line. */
|
||||
length = LATE_LINE_LENGTH[index] * (1.0f + (density * LATE_LINE_MULTIPLIER));
|
||||
|
||||
@@ -562,6 +604,11 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
totalSamples += CalcLineLength(length, totalSamples, frequency,
|
||||
&dsb->eax.Decorrelator);
|
||||
|
||||
+ /* The late all-pass lines. */
|
||||
+ for(index = 0;index < 4;index++)
|
||||
+ totalSamples += CalcLineLength(ALLPASS_LINE_LENGTH[index], totalSamples,
|
||||
+ frequency, &dsb->eax.Late.ApDelay[index]);
|
||||
+
|
||||
/* The late delay lines are calculated from the lowest reverb density. */
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
@@ -591,6 +638,7 @@ static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Early.Delay[index]);
|
||||
+ RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Late.ApDelay[index]);
|
||||
RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Late.Delay[index]);
|
||||
}
|
||||
|
||||
@@ -641,6 +689,7 @@ static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
dsb->eax.Early.Offset[index] = fastf2u(EARLY_LINE_LENGTH[index] * dsb->device->pwfx->nSamplesPerSec);
|
||||
+ dsb->eax.Late.ApOffset[index] = fastf2u(ALLPASS_LINE_LENGTH[index] * dsb->device->pwfx->nSamplesPerSec);
|
||||
}
|
||||
|
||||
cw = CalcI3DL2HFreq(dsb->device->eax.eax_props.flHFReference, dsb->device->pwfx->nSamplesPerSec);
|
||||
@@ -716,9 +765,15 @@ void init_eax_buffer(IDirectSoundBufferImpl* dsb)
|
||||
|
||||
dsb->eax.Late.Gain = 0.0f;
|
||||
dsb->eax.Late.DensityGain = 0.0f;
|
||||
+ dsb->eax.Late.ApFeedCoeff = 0.0f;
|
||||
dsb->eax.Late.MixCoeff = 0.0f;
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
+ dsb->eax.Late.ApCoeff[index] = 0.0f;
|
||||
+ dsb->eax.Late.ApDelay[index].Mask = 0;
|
||||
+ dsb->eax.Late.ApDelay[index].Line = NULL;
|
||||
+ dsb->eax.Late.ApOffset[index] = 0;
|
||||
+
|
||||
dsb->eax.Late.Coeff[index] = 0.0f;
|
||||
dsb->eax.Late.Delay[index].Mask = 0;
|
||||
dsb->eax.Late.Delay[index].Line = NULL;
|
||||
|
||||
--------------2.0.5--
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user