mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Merge pull request #311 from maharmstone/master
Adds support for Environmental Audio Extensions (EAX).
This commit is contained in:
commit
cd5078fa95
@ -38,13 +38,14 @@ Wine. All those differences are also documented on the
|
||||
Included bug fixes and improvements
|
||||
===================================
|
||||
|
||||
**Bugfixes and features included in the next upcoming release [5]:**
|
||||
**Bugfixes and features included in the next upcoming release [6]:**
|
||||
|
||||
* Add stubs for Power[Set|Clear]Request
|
||||
* Avoid spam of FIXME messages for PsLookupProcessByProcessId stub ([Wine Bug #36821](https://bugs.winehq.org/show_bug.cgi?id=36821))
|
||||
* Fix compatibility of Uplay with gnutls28 ([Wine Bug #38134](https://bugs.winehq.org/show_bug.cgi?id=38134))
|
||||
* Fix handling of ANSI NTLM credentials ([Wine Bug #37063](https://bugs.winehq.org/show_bug.cgi?id=37063))
|
||||
* Implement empty enumerator for IWiaDevMgr::EnumDeviceInfo ([Wine Bug #27775](https://bugs.winehq.org/show_bug.cgi?id=27775))
|
||||
* Software support for Environmental Audio Extensions (EAX)
|
||||
|
||||
|
||||
**Bugs fixed in Wine Staging 1.7.39 [205]:**
|
||||
|
1
debian/changelog
vendored
1
debian/changelog
vendored
@ -5,6 +5,7 @@ wine-staging (1.7.40) UNRELEASED; urgency=low
|
||||
* Added patch to implement empty enumerator for IWiaDevMgr::EnumDeviceInfo.
|
||||
* Added patch to fix handling of ANSI NTLM credentials.
|
||||
* Added patch to fix compatibility of Uplay with gnutls28.
|
||||
* Added patches for Environmental Audio Extensions (EAX), pull request #311 from Mark Harmstone.
|
||||
* Removed patch to fix regression causing black screen on startup (accepted upstream).
|
||||
* Removed patch to fix edge cases in TOOLTIPS_GetTipText (fixed upstream).
|
||||
* Removed patch for IConnectionPoint/INetworkListManagerEvents stub interface (accepted upstream).
|
||||
|
@ -0,0 +1,229 @@
|
||||
From dd8497b40ae145da74ca9aeb8aab274572328bbd Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 28 Mar 2015 08:18:10 +0100
|
||||
Subject: dsound: Apply filters before sound is multiplied to speakers.
|
||||
|
||||
Based on a patch by Mark Harmstone.
|
||||
---
|
||||
dlls/dsound/dsound.c | 1 +
|
||||
dlls/dsound/dsound_private.h | 4 +-
|
||||
dlls/dsound/mixer.c | 104 ++++++++++++++++++++++++++++++-------------
|
||||
3 files changed, 77 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/dlls/dsound/dsound.c b/dlls/dsound/dsound.c
|
||||
index 065c377..ed0bbba 100644
|
||||
--- a/dlls/dsound/dsound.c
|
||||
+++ b/dlls/dsound/dsound.c
|
||||
@@ -238,6 +238,7 @@ static ULONG DirectSoundDevice_Release(DirectSoundDevice * device)
|
||||
if(device->volume)
|
||||
IAudioStreamVolume_Release(device->volume);
|
||||
|
||||
+ HeapFree(GetProcessHeap(), 0, device->dsp_buffer);
|
||||
HeapFree(GetProcessHeap(), 0, device->tmp_buffer);
|
||||
HeapFree(GetProcessHeap(), 0, device->mix_buffer);
|
||||
HeapFree(GetProcessHeap(), 0, device->buffer);
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index 726452c..ed645db 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -91,8 +91,8 @@ struct DirectSoundDevice
|
||||
int speaker_num[DS_MAX_CHANNELS];
|
||||
int num_speakers;
|
||||
int lfe_channel;
|
||||
- float *mix_buffer, *tmp_buffer;
|
||||
- DWORD tmp_buffer_len, mix_buffer_len;
|
||||
+ float *mix_buffer, *tmp_buffer, *dsp_buffer;
|
||||
+ DWORD mix_buffer_len, tmp_buffer_len, dsp_buffer_len;
|
||||
|
||||
DSVOLUMEPAN volpan;
|
||||
|
||||
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
|
||||
index 4f22f85..ff92cc1 100644
|
||||
--- a/dlls/dsound/mixer.c
|
||||
+++ b/dlls/dsound/mixer.c
|
||||
@@ -266,23 +266,22 @@ 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, bitsputfunc put, UINT ostride, UINT count)
|
||||
{
|
||||
UINT istride = dsb->pwfx->nBlockAlign;
|
||||
- UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
DWORD channel, i;
|
||||
for (i = 0; i < count; i++)
|
||||
for (channel = 0; channel < dsb->mix_channels; channel++)
|
||||
- dsb->put(dsb, i * ostride, channel, get_current_sample(dsb,
|
||||
- dsb->sec_mixpos + i * istride, channel));
|
||||
+ put(dsb, i * ostride, channel, get_current_sample(dsb,
|
||||
+ dsb->sec_mixpos + i * istride, channel));
|
||||
return count;
|
||||
}
|
||||
|
||||
-static UINT cp_fields_resample_lq(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
+static UINT cp_fields_resample_lq(IDirectSoundBufferImpl *dsb, bitsputfunc put,
|
||||
+ UINT ostride, UINT count, LONG64 *freqAccNum)
|
||||
{
|
||||
UINT i, channel;
|
||||
UINT istride = dsb->pwfx->nBlockAlign;
|
||||
- UINT ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
UINT channels = dsb->mix_channels;
|
||||
|
||||
LONG64 freqAcc_start = *freqAccNum;
|
||||
@@ -310,7 +309,7 @@ static UINT cp_fields_resample_lq(IDirectSoundBufferImpl *dsb, UINT count, LONG6
|
||||
float s1 = get_current_sample(dsb, idx, channel);
|
||||
float s2 = get_current_sample(dsb, idx + istride, channel);
|
||||
float result = s1 * cur_freqAcc2 + s2 * cur_freqAcc;
|
||||
- dsb->put(dsb, i * ostride, channel, result);
|
||||
+ put(dsb, i * ostride, channel, result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,11 +317,11 @@ static UINT cp_fields_resample_lq(IDirectSoundBufferImpl *dsb, UINT count, LONG6
|
||||
return max_ipos;
|
||||
}
|
||||
|
||||
-static UINT cp_fields_resample_hq(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
+static UINT cp_fields_resample_hq(IDirectSoundBufferImpl *dsb, bitsputfunc put,
|
||||
+ UINT ostride, 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;
|
||||
@@ -372,7 +371,7 @@ static UINT cp_fields_resample_hq(IDirectSoundBufferImpl *dsb, UINT count, LONG6
|
||||
float* cache = &intermediate[channel * required_input + ipos];
|
||||
for (j = 0; j < fir_used; j++)
|
||||
sum += fir_copy[j] * cache[j];
|
||||
- dsb->put(dsb, i * ostride, channel, sum * dsb->firgain);
|
||||
+ put(dsb, i * ostride, channel, sum * dsb->firgain);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,16 +383,17 @@ static UINT cp_fields_resample_hq(IDirectSoundBufferImpl *dsb, UINT count, LONG6
|
||||
return max_ipos;
|
||||
}
|
||||
|
||||
-static void cp_fields(IDirectSoundBufferImpl *dsb, UINT count, LONG64 *freqAccNum)
|
||||
+static void cp_fields(IDirectSoundBufferImpl *dsb, bitsputfunc put,
|
||||
+ UINT ostride, UINT count, LONG64 *freqAccNum)
|
||||
{
|
||||
DWORD ipos, adv;
|
||||
|
||||
if (dsb->freqAdjustNum == dsb->freqAdjustDen)
|
||||
- adv = cp_fields_noresample(dsb, count); /* *freqAcc is unmodified */
|
||||
+ adv = cp_fields_noresample(dsb, put, ostride, count); /* *freqAcc is unmodified */
|
||||
else if (dsb->device->nrofbuffers > ds_hq_buffers_max)
|
||||
- adv = cp_fields_resample_lq(dsb, count, freqAccNum);
|
||||
+ adv = cp_fields_resample_lq(dsb, put, ostride, count, freqAccNum);
|
||||
else
|
||||
- adv = cp_fields_resample_hq(dsb, count, freqAccNum);
|
||||
+ adv = cp_fields_resample_hq(dsb, put, ostride, count, freqAccNum);
|
||||
|
||||
ipos = dsb->sec_mixpos + adv * dsb->pwfx->nBlockAlign;
|
||||
if (ipos >= dsb->buflen) {
|
||||
@@ -423,6 +423,21 @@ static inline DWORD DSOUND_BufPtrDiff(DWORD buflen, DWORD ptr1, DWORD ptr2)
|
||||
return buflen + ptr1 - ptr2;
|
||||
}
|
||||
}
|
||||
+
|
||||
+static float getieee32_dsp(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel)
|
||||
+{
|
||||
+ const BYTE *buf = (BYTE *)dsb->device->dsp_buffer;
|
||||
+ const float *fbuf = (const float*)(buf + pos + sizeof(float) * channel);
|
||||
+ return *fbuf;
|
||||
+}
|
||||
+
|
||||
+static void putieee32_dsp(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD channel, float value)
|
||||
+{
|
||||
+ BYTE *buf = (BYTE *)dsb->device->dsp_buffer;
|
||||
+ float *fbuf = (float*)(buf + pos + sizeof(float) * channel);
|
||||
+ *fbuf = value;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Mix at most the given amount of data into the allocated temporary buffer
|
||||
* of the given secondary buffer, starting from the dsb's first currently
|
||||
@@ -438,32 +453,61 @@ 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;
|
||||
+ BOOL using_filters = dsb->num_filters > 0;
|
||||
+ UINT istride, ostride, size_bytes;
|
||||
+ DWORD channel, i;
|
||||
+ bitsputfunc put;
|
||||
HRESULT hr;
|
||||
- int i;
|
||||
|
||||
- if (dsb->device->tmp_buffer_len < size_bytes || !dsb->device->tmp_buffer)
|
||||
- {
|
||||
- dsb->device->tmp_buffer_len = size_bytes;
|
||||
+ put = dsb->put;
|
||||
+ ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
+ size_bytes = frames * ostride;
|
||||
+
|
||||
+ if (dsb->device->tmp_buffer_len < size_bytes || !dsb->device->tmp_buffer) {
|
||||
if (dsb->device->tmp_buffer)
|
||||
dsb->device->tmp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->tmp_buffer, size_bytes);
|
||||
else
|
||||
dsb->device->tmp_buffer = HeapAlloc(GetProcessHeap(), 0, size_bytes);
|
||||
+ dsb->device->tmp_buffer_len = size_bytes;
|
||||
}
|
||||
|
||||
- cp_fields(dsb, frames, &dsb->freqAccNum);
|
||||
+ if (using_filters) {
|
||||
+ put = putieee32_dsp;
|
||||
+ ostride = dsb->mix_channels * sizeof(float);
|
||||
+ size_bytes = frames * ostride;
|
||||
+
|
||||
+ if (dsb->device->dsp_buffer_len < size_bytes || !dsb->device->dsp_buffer) {
|
||||
+ if (dsb->device->dsp_buffer)
|
||||
+ dsb->device->dsp_buffer = HeapReAlloc(GetProcessHeap(), 0, dsb->device->dsp_buffer, size_bytes);
|
||||
+ else
|
||||
+ dsb->device->dsp_buffer = HeapAlloc(GetProcessHeap(), 0, size_bytes);
|
||||
+ dsb->device->dsp_buffer_len = size_bytes;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- 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);
|
||||
+ cp_fields(dsb, put, ostride, frames, &dsb->freqAccNum);
|
||||
+
|
||||
+ if (using_filters) {
|
||||
+ if (frames > 0) {
|
||||
+ for (i = 0; i < dsb->num_filters; i++) {
|
||||
+ if (dsb->filters[i].inplace) {
|
||||
+ hr = IMediaObjectInPlace_Process(dsb->filters[i].inplace, frames * sizeof(float) * dsb->mix_channels,
|
||||
+ (BYTE *)dsb->device->dsp_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);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (FAILED(hr))
|
||||
- WARN("IMediaObjectInPlace_Process failed for filter %u\n", i);
|
||||
- } else
|
||||
- WARN("filter %u has no inplace object - unsupported\n", i);
|
||||
- }
|
||||
- }
|
||||
+ istride = ostride;
|
||||
+ ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
+ for (i = 0; i < frames; i++) {
|
||||
+ for (channel = 0; channel < dsb->mix_channels; channel++) {
|
||||
+ dsb->put(dsb, i * ostride, channel, getieee32_dsp(dsb, i * istride, channel));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
|
||||
--
|
||||
2.3.3
|
||||
|
@ -0,0 +1,121 @@
|
||||
From b95848a7794ff437b58f1a307da8c8fdca6a362f Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 15 Mar 2015 18:04:16 +0000
|
||||
Subject: dsound: Add EAX v1 constants and structs.
|
||||
|
||||
---
|
||||
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
|
||||
|
||||
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 ed645db..3c7dc7a 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.3.3
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 8d33bbc39a573848f00c95699ec8c0eee9fdb416 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 15 Mar 2015 18:04:38 +0000
|
||||
Subject: dsound: Report that we support EAX v1.
|
||||
|
||||
---
|
||||
dlls/dsound/buffer.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index d735dc3..9eff140 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1319,6 +1319,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.3.3
|
||||
|
131
patches/dsound-EAX/0004-dsound-Add-EAX-propset-stubs.patch
Normal file
131
patches/dsound-EAX/0004-dsound-Add-EAX-propset-stubs.patch
Normal file
@ -0,0 +1,131 @@
|
||||
From 601e237d1321fcdea3a678c31fd9eac62b89cfb4 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 13:58:53 +0000
|
||||
Subject: dsound: Add EAX propset stubs.
|
||||
|
||||
---
|
||||
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
|
||||
|
||||
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 9eff140..0596ce3 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1298,6 +1298,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;
|
||||
}
|
||||
|
||||
@@ -1309,6 +1312,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 3c7dc7a..e4495b2 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -229,6 +229,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.3.3
|
||||
|
149
patches/dsound-EAX/0005-dsound-Add-EAX-presets.patch
Normal file
149
patches/dsound-EAX/0005-dsound-Add-EAX-presets.patch
Normal file
@ -0,0 +1,149 @@
|
||||
From e46e2000764539dab113dd508b6a20beba953c87 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 14:10:06 +0000
|
||||
Subject: dsound: Add EAX presets.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 29 +++++++++++++++++++++++
|
||||
dlls/dsound/eax.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 90 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 600029f..06d961e 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
+ * Copyright (c) 2008-2009 Christopher Fitzgerald
|
||||
* Copyright (c) 2015 Mark Harmstone
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -16,6 +17,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 +85,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..57d88e7 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
+ * Copyright (c) 2008-2009 Christopher Fitzgerald
|
||||
* Copyright (c) 2015 Mark Harmstone
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -16,6 +17,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 +34,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.3.3
|
||||
|
@ -0,0 +1,240 @@
|
||||
From fe1de4d0856517f1ce59a3a5eb15a13f6ce4a9e6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 14:22:02 +0000
|
||||
Subject: dsound: Support getting and setting EAX properties.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 8 +++
|
||||
dlls/dsound/dsound_private.h | 2 +
|
||||
dlls/dsound/eax.c | 167 +++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 177 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 06d961e..c90d82d 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -111,6 +111,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 e4495b2..c16f770 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -99,6 +99,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 57d88e7..cdd03be 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,6 +92,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)
|
||||
@@ -101,6 +117,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;
|
||||
}
|
||||
|
||||
@@ -108,8 +188,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.3.3
|
||||
|
@ -0,0 +1,138 @@
|
||||
From 43637cb46c48e84e7f1b127ba4427900c76f2470 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:48:19 +0000
|
||||
Subject: dsound: Support getting and setting EAX buffer properties.
|
||||
|
||||
---
|
||||
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(+)
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index 0596ce3..1c318f5 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1092,6 +1092,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 c90d82d..2ee83b9 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -119,6 +119,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 c16f770..c732b52 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -176,6 +176,8 @@ struct IDirectSoundBufferImpl
|
||||
int num_filters;
|
||||
DSFilter* filters;
|
||||
|
||||
+ eax_buffer_info eax;
|
||||
+
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index cdd03be..3931681 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -179,6 +179,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;
|
||||
@@ -276,6 +308,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.3.3
|
||||
|
102
patches/dsound-EAX/0008-dsound-Add-EAX-init-and-free-stubs.patch
Normal file
102
patches/dsound-EAX/0008-dsound-Add-EAX-init-and-free-stubs.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 76cd66f5f32045665fe392401b63738a5a089072 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:58:37 +0000
|
||||
Subject: dsound: Add EAX init and free stubs.
|
||||
|
||||
---
|
||||
dlls/dsound/buffer.c | 5 +++++
|
||||
dlls/dsound/dsound_private.h | 2 ++
|
||||
dlls/dsound/eax.c | 28 +++++++++++++++++++++++++++-
|
||||
3 files changed, 34 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c
|
||||
index 1c318f5..c098043 100644
|
||||
--- a/dlls/dsound/buffer.c
|
||||
+++ b/dlls/dsound/buffer.c
|
||||
@@ -1130,6 +1130,9 @@ HRESULT IDirectSoundBufferImpl_Create(
|
||||
HeapFree(GetProcessHeap(),0,dsb);
|
||||
dsb = NULL;
|
||||
}
|
||||
+
|
||||
+ if (dsb->device->eax.using_eax)
|
||||
+ init_eax_buffer(dsb);
|
||||
}
|
||||
|
||||
IDirectSoundBuffer8_AddRef(&dsb->IDirectSoundBuffer8_iface);
|
||||
@@ -1169,6 +1172,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 c732b52..a918cd2 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -240,6 +240,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 3931681..c0afb0f 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,20 +92,46 @@ 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);
|
||||
+}
|
||||
+
|
||||
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,
|
||||
--
|
||||
2.3.3
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 735da63bda0fed9b01779bd8922a4cc13b05d598 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 20:59:57 +0000
|
||||
Subject: dsound: Feed data through EAX function.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_private.h | 1 +
|
||||
dlls/dsound/eax.c | 5 +++++
|
||||
dlls/dsound/mixer.c | 5 ++++-
|
||||
3 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h
|
||||
index a918cd2..cc55d70 100644
|
||||
--- a/dlls/dsound/dsound_private.h
|
||||
+++ b/dlls/dsound/dsound_private.h
|
||||
@@ -242,6 +242,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 c0afb0f..4368594 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 */
|
||||
};
|
||||
|
||||
+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 ff92cc1..b159834 100644
|
||||
--- a/dlls/dsound/mixer.c
|
||||
+++ b/dlls/dsound/mixer.c
|
||||
@@ -453,7 +453,7 @@ static void putieee32_dsp(const IDirectSoundBufferImpl *dsb, DWORD pos, DWORD ch
|
||||
*/
|
||||
static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
|
||||
{
|
||||
- BOOL using_filters = dsb->num_filters > 0;
|
||||
+ BOOL using_filters = dsb->num_filters > 0 || dsb->device->eax.using_eax;
|
||||
UINT istride, ostride, size_bytes;
|
||||
DWORD channel, i;
|
||||
bitsputfunc put;
|
||||
@@ -500,6 +500,9 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
|
||||
}
|
||||
}
|
||||
|
||||
+ if (dsb->device->eax.using_eax)
|
||||
+ process_eax_buffer(dsb, dsb->device->dsp_buffer, frames * dsb->mix_channels);
|
||||
+
|
||||
istride = ostride;
|
||||
ostride = dsb->device->pwfx->nChannels * sizeof(float);
|
||||
for (i = 0; i < frames; i++) {
|
||||
--
|
||||
2.3.3
|
||||
|
184
patches/dsound-EAX/0010-dsound-Allocate-EAX-delay-lines.patch
Normal file
184
patches/dsound-EAX/0010-dsound-Allocate-EAX-delay-lines.patch
Normal file
@ -0,0 +1,184 @@
|
||||
From 213aef0ba57c925f48c36e6167584a4ee0b7587b Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Fri, 27 Mar 2015 21:06:42 +0000
|
||||
Subject: dsound: Allocate EAX delay lines.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 16 ++++++++
|
||||
dlls/dsound/eax.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 112 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 2ee83b9..132f060 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -85,6 +85,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;
|
||||
@@ -111,6 +114,12 @@ typedef struct {
|
||||
int iDecayHFLimit;
|
||||
} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
|
||||
|
||||
+typedef struct DelayLine
|
||||
+{
|
||||
+ unsigned int Mask;
|
||||
+ float *Line;
|
||||
+} DelayLine;
|
||||
+
|
||||
typedef struct {
|
||||
BOOL using_eax;
|
||||
unsigned long environment;
|
||||
@@ -121,6 +130,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 4368594..babc2a7 100644
|
||||
--- a/dlls/dsound/eax.c
|
||||
+++ b/dlls/dsound/eax.c
|
||||
@@ -92,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)
|
||||
@@ -115,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);
|
||||
}
|
||||
|
||||
@@ -136,7 +229,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.3.3
|
||||
|
67
patches/dsound-EAX/0011-dsound-Add-EAX-VerbPass-stub.patch
Normal file
67
patches/dsound-EAX/0011-dsound-Add-EAX-VerbPass-stub.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From de72257b18ac1a07ed770f20bede6b42e5baa99b Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 15:38:15 +0000
|
||||
Subject: dsound: Add EAX VerbPass stub.
|
||||
|
||||
---
|
||||
dlls/dsound/eax.c | 37 ++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 36 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
|
||||
index babc2a7..6ac4cdf 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.3.3
|
||||
|
@ -0,0 +1,126 @@
|
||||
From 858f3b43a1197c3b9a8e6f2228995451776b29b4 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 17:57:38 +0000
|
||||
Subject: dsound: Implement EAX lowpass filter.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 7 +++++++
|
||||
dlls/dsound/eax.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 54 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 132f060..82b1408 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -121,6 +121,11 @@ typedef struct DelayLine
|
||||
} DelayLine;
|
||||
|
||||
typedef struct {
|
||||
+ float coeff;
|
||||
+ float history[2];
|
||||
+} FILTER;
|
||||
+
|
||||
+typedef struct {
|
||||
BOOL using_eax;
|
||||
unsigned long environment;
|
||||
float volume;
|
||||
@@ -134,6 +139,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 6ac4cdf..bbb5dad 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.3.3
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 687ccff7f8b336d29eb72b7975500de8cedbae93 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:00:10 +0000
|
||||
Subject: dsound: Add delay line EAX functions.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 1 +
|
||||
dlls/dsound/eax.c | 27 +++++++++++++++++++++++++++
|
||||
2 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 82b1408..bd002d7 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -142,6 +142,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 bbb5dad..9569c33 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.3.3
|
||||
|
@ -0,0 +1,227 @@
|
||||
From bb7edc0e1283a60b1cfc121356d6a8702f96f689 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:09:34 +0000
|
||||
Subject: dsound: Implement EAX early reflections.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 7 +++
|
||||
dlls/dsound/eax.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 121 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index bd002d7..184f7ce 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -144,6 +144,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 9569c33..964e5f8 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.3.3
|
||||
|
124
patches/dsound-EAX/0015-dsound-Implement-EAX-decorrelator.patch
Normal file
124
patches/dsound-EAX/0015-dsound-Implement-EAX-decorrelator.patch
Normal file
@ -0,0 +1,124 @@
|
||||
From 51655ef153a69a2cd2e34e8791a4e3b9088962fe Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:19:17 +0000
|
||||
Subject: dsound: Implement EAX decorrelator.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 3 +++
|
||||
dlls/dsound/eax.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 49 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index 184f7ce..c33a2ff 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -151,6 +151,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 964e5f8..d40b7d6 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.3.3
|
||||
|
372
patches/dsound-EAX/0016-dsound-Implement-EAX-late-reverb.patch
Normal file
372
patches/dsound-EAX/0016-dsound-Implement-EAX-late-reverb.patch
Normal file
@ -0,0 +1,372 @@
|
||||
From 03930e42e47619af1b84a11aa21b937404e290fc Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:21:02 +0000
|
||||
Subject: dsound: Implement EAX late reverb.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 13 +++
|
||||
dlls/dsound/eax.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 268 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index c33a2ff..fac4d9b 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -154,6 +154,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 d40b7d6..c9a5eb6 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.3.3
|
||||
|
@ -0,0 +1,151 @@
|
||||
From 510838b8d83a085bda82ac87c0f22ee856eb0f67 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Harmstone <mark@harmstone.com>
|
||||
Date: Sun, 22 Mar 2015 18:21:18 +0000
|
||||
Subject: dsound: Implement EAX late all-pass filter.
|
||||
|
||||
---
|
||||
dlls/dsound/dsound_eax.h | 5 +++++
|
||||
dlls/dsound/eax.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 60 insertions(+)
|
||||
|
||||
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
|
||||
index fac4d9b..a650108 100644
|
||||
--- a/dlls/dsound/dsound_eax.h
|
||||
+++ b/dlls/dsound/dsound_eax.h
|
||||
@@ -157,8 +157,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 c9a5eb6..a05b00e 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.3.3
|
||||
|
2
patches/dsound-EAX/definition
Normal file
2
patches/dsound-EAX/definition
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes: Software support for Environmental Audio Extensions (EAX)
|
||||
Depends: dsound-Fast_Mixer
|
@ -94,6 +94,7 @@ patch_enable_all ()
|
||||
enable_ddraw_Hotpatch="$1"
|
||||
enable_ddraw_d3d_execute_buffer="$1"
|
||||
enable_dinput_Events="$1"
|
||||
enable_dsound_EAX="$1"
|
||||
enable_dsound_Fast_Mixer="$1"
|
||||
enable_dxgi_GetDesc="$1"
|
||||
enable_dxva2_Video_Decoder="$1"
|
||||
@ -340,6 +341,9 @@ patch_enable ()
|
||||
dinput-Events)
|
||||
enable_dinput_Events="$2"
|
||||
;;
|
||||
dsound-EAX)
|
||||
enable_dsound_EAX="$2"
|
||||
;;
|
||||
dsound-Fast_Mixer)
|
||||
enable_dsound_Fast_Mixer="$2"
|
||||
;;
|
||||
@ -1170,6 +1174,13 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then
|
||||
enable_wined3d_DXTn=1
|
||||
fi
|
||||
|
||||
if test "$enable_dsound_EAX" -eq 1; then
|
||||
if test "$enable_dsound_Fast_Mixer" -gt 1; then
|
||||
abort "Patchset dsound-Fast_Mixer disabled, but dsound-EAX depends on that."
|
||||
fi
|
||||
enable_dsound_Fast_Mixer=1
|
||||
fi
|
||||
|
||||
if test "$enable_d3dx9_36_AnimationController" -eq 1; then
|
||||
if test "$enable_d3dx9_36_DXTn" -gt 1; then
|
||||
abort "Patchset d3dx9_36-DXTn disabled, but d3dx9_36-AnimationController depends on that."
|
||||
@ -1797,6 +1808,51 @@ if test "$enable_dsound_Fast_Mixer" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset dsound-EAX
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dsound/Makefile.in, dlls/dsound/buffer.c, dlls/dsound/dsound.c, dlls/dsound/dsound_eax.h,
|
||||
# | dlls/dsound/dsound_private.h, dlls/dsound/eax.c, dlls/dsound/mixer.c
|
||||
# |
|
||||
if test "$enable_dsound_EAX" -eq 1; then
|
||||
patch_apply dsound-EAX/0001-dsound-Apply-filters-before-sound-is-multiplied-to-s.patch
|
||||
patch_apply dsound-EAX/0002-dsound-Add-EAX-v1-constants-and-structs.patch
|
||||
patch_apply dsound-EAX/0003-dsound-Report-that-we-support-EAX-v1.patch
|
||||
patch_apply dsound-EAX/0004-dsound-Add-EAX-propset-stubs.patch
|
||||
patch_apply dsound-EAX/0005-dsound-Add-EAX-presets.patch
|
||||
patch_apply dsound-EAX/0006-dsound-Support-getting-and-setting-EAX-properties.patch
|
||||
patch_apply dsound-EAX/0007-dsound-Support-getting-and-setting-EAX-buffer-proper.patch
|
||||
patch_apply dsound-EAX/0008-dsound-Add-EAX-init-and-free-stubs.patch
|
||||
patch_apply dsound-EAX/0009-dsound-Feed-data-through-EAX-function.patch
|
||||
patch_apply dsound-EAX/0010-dsound-Allocate-EAX-delay-lines.patch
|
||||
patch_apply dsound-EAX/0011-dsound-Add-EAX-VerbPass-stub.patch
|
||||
patch_apply dsound-EAX/0012-dsound-Implement-EAX-lowpass-filter.patch
|
||||
patch_apply dsound-EAX/0013-dsound-Add-delay-line-EAX-functions.patch
|
||||
patch_apply dsound-EAX/0014-dsound-Implement-EAX-early-reflections.patch
|
||||
patch_apply dsound-EAX/0015-dsound-Implement-EAX-decorrelator.patch
|
||||
patch_apply dsound-EAX/0016-dsound-Implement-EAX-late-reverb.patch
|
||||
patch_apply dsound-EAX/0017-dsound-Implement-EAX-late-all-pass-filter.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "dsound: Apply filters before sound is multiplied to speakers.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add EAX v1 constants and structs.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Report that we support EAX.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add EAX propset stubs.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add EAX presets.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Support getting and setting EAX properties.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Support getting and setting EAX buffer properties.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add EAX init and free stubs.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Feed data through EAX function.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Allocate EAX delay lines.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add EAX VerbPass stub.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX lowpass filter.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Add delay line EAX functions.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX early reflections.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX decorrelator.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX late reverb.", 1 },';
|
||||
echo '+ { "Mark Harmstone", "dsound: Implement EAX late all-pass filter.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset dxgi-GetDesc
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
@ -2486,6 +2542,20 @@ if test "$enable_kernel32_Console_Handles" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset kernel32-SetFileInformationByHandle
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/file.c, include/winbase.h
|
||||
# |
|
||||
if test "$enable_kernel32_SetFileInformationByHandle" -eq 1; then
|
||||
patch_apply kernel32-SetFileInformationByHandle/0001-include-Declare-a-couple-more-file-information-class.patch
|
||||
patch_apply kernel32-SetFileInformationByHandle/0002-kernel32-Implement-SetFileInformationByHandle.patch
|
||||
(
|
||||
echo '+ { "Michael Müller", "include: Declare a couple more file information class structures.", 1 },';
|
||||
echo '+ { "Michael Müller", "kernel32: Implement SetFileInformationByHandle.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-FileDispositionInformation
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
@ -2505,20 +2575,6 @@ if test "$enable_ntdll_FileDispositionInformation" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset kernel32-SetFileInformationByHandle
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/file.c, include/winbase.h
|
||||
# |
|
||||
if test "$enable_kernel32_SetFileInformationByHandle" -eq 1; then
|
||||
patch_apply kernel32-SetFileInformationByHandle/0001-include-Declare-a-couple-more-file-information-class.patch
|
||||
patch_apply kernel32-SetFileInformationByHandle/0002-kernel32-Implement-SetFileInformationByHandle.patch
|
||||
(
|
||||
echo '+ { "Michael Müller", "include: Declare a couple more file information class structures.", 1 },';
|
||||
echo '+ { "Michael Müller", "kernel32: Implement SetFileInformationByHandle.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset kernel32-CopyFileEx
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
Reference in New Issue
Block a user