wine-staging/patches/dsound-EAX/0011-dsound-Allocate-EAX-delay-lines.patch

206 lines
6.1 KiB
Diff
Raw Normal View History

From b8a5fe26a390ced4438df0e50b7c93fd4150ed06 Mon Sep 17 00:00:00 2001
From: Mark Harmstone <mark@harmstone.com>
Date: Fri, 27 Mar 2015 21:06:42 +0000
Subject: [PATCH 11/18] dsound: Allocate EAX delay lines.
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.0.5"
This is a multi-part message in MIME format.
--------------2.0.5
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit
---
dlls/dsound/dsound_eax.h | 16 ++++++++
dlls/dsound/eax.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 113 insertions(+), 2 deletions(-)
--------------2.0.5
Content-Type: text/x-patch; name="0011-dsound-Allocate-EAX-delay-lines.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0011-dsound-Allocate-EAX-delay-lines.patch"
diff --git a/dlls/dsound/dsound_eax.h b/dlls/dsound/dsound_eax.h
index 56b4263..7565233 100644
--- a/dlls/dsound/dsound_eax.h
+++ b/dlls/dsound/dsound_eax.h
@@ -84,6 +84,9 @@ typedef struct {
#define EAX_REVERBMIX_USEDISTANCE -1.0f
+#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
+#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
+
typedef struct {
float flDensity;
float flDiffusion;
@@ -110,6 +113,12 @@ typedef struct {
int iDecayHFLimit;
} EFXEAXREVERBPROPERTIES, *LPEFXEAXREVERBPROPERTIES;
+typedef struct DelayLine
+{
+ unsigned int Mask;
+ float *Line;
+} DelayLine;
+
typedef struct {
BOOL using_eax;
unsigned long environment;
@@ -120,6 +129,13 @@ typedef struct {
typedef struct {
float reverb_mix;
+
+ float *SampleBuffer;
+ unsigned int TotalSamples;
+
+ DelayLine Delay;
+
+ unsigned int Offset;
} eax_buffer_info;
#ifdef __cplusplus
diff --git a/dlls/dsound/eax.c b/dlls/dsound/eax.c
index df05f8e..d12cdd0 100644
--- a/dlls/dsound/eax.c
+++ b/dlls/dsound/eax.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2015 Mark Harmstone
+ * Copyright (c) 2008-9 Christopher Fitzgerald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -91,14 +92,99 @@ static const EFXEAXREVERBPROPERTIES efx_presets[] = {
{ 0.0625f, 0.5000f, 0.3162f, 0.8404f, 1.0000f, 7.5600f, 0.9100f, 1.0000f, 0.4864f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 2.4378f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 4.0000f, 1.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } /* psychotic */
};
+static unsigned int fastf2u(float f)
+{
+ return (unsigned int)f;
+}
+
void process_eax_buffer(IDirectSoundBufferImpl* dsb, float* buf, DWORD count)
{
/* stub */
}
+static unsigned int NextPowerOf2(unsigned int value)
+{
+ if(value > 0)
+ {
+ value--;
+ value |= value>>1;
+ value |= value>>2;
+ value |= value>>4;
+ value |= value>>8;
+ value |= value>>16;
+ }
+ return value+1;
+}
+
+static unsigned int CalcLineLength(float length, unsigned int offset, unsigned int frequency, DelayLine *Delay)
+{
+ unsigned int samples;
+
+ /* All line lengths are powers of 2, calculated from their lengths, with
+ * an additional sample in case of rounding errors. */
+ samples = NextPowerOf2(fastf2u(length * frequency) + 1);
+ /* All lines share a single sample buffer. */
+ Delay->Mask = samples - 1;
+ Delay->Line = (float*)offset;
+ /* Return the sample count for accumulation. */
+ return samples;
+}
+
+static void RealizeLineOffset(float *sampleBuffer, DelayLine *Delay)
+{
+ Delay->Line = &sampleBuffer[(unsigned int)Delay->Line];
+}
+
+static BOOL AllocLines(unsigned int frequency, IDirectSoundBufferImpl* dsb)
+{
+ unsigned int totalSamples, index;
+ float length;
+ float *newBuffer = NULL;
+
+ /* All delay line lengths are calculated to accomodate the full range of
+ * lengths given their respective paramters. */
+ totalSamples = 0;
+
+ /* The initial delay is the sum of the reflections and late reverb
+ * delays. */
+ length = AL_EAXREVERB_MAX_REFLECTIONS_DELAY +
+ AL_EAXREVERB_MAX_LATE_REVERB_DELAY;
+ totalSamples += CalcLineLength(length, totalSamples, frequency,
+ &dsb->eax.Delay);
+
+ if(totalSamples != dsb->eax.TotalSamples)
+ {
+ TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency);
+
+ if (dsb->eax.SampleBuffer)
+ newBuffer = HeapReAlloc(GetProcessHeap(), 0, dsb->eax.SampleBuffer, sizeof(float) * totalSamples);
+ else
+ newBuffer = HeapAlloc(GetProcessHeap(), 0, sizeof(float) * totalSamples);
+
+ if(newBuffer == NULL)
+ return FALSE;
+ dsb->eax.SampleBuffer = newBuffer;
+ dsb->eax.TotalSamples = totalSamples;
+ }
+
+ /* Update all delays to reflect the new sample buffer. */
+ RealizeLineOffset(dsb->eax.SampleBuffer, &dsb->eax.Delay);
+
+ /* Clear the sample buffer. */
+ for(index = 0;index < dsb->eax.TotalSamples;index++)
+ dsb->eax.SampleBuffer[index] = 0.0f;
+
+ return TRUE;
+}
+
static void ReverbUpdate(IDirectSoundBufferImpl* dsb)
{
- /* stub */
+ /* avoid segfaults in mixing thread when we recalculate the line offsets */
+ EnterCriticalSection(&dsb->device->mixlock);
+
+ AllocLines(dsb->device->pwfx->nSamplesPerSec, dsb);
+
+ LeaveCriticalSection(&dsb->device->mixlock);
}
static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
@@ -114,6 +200,14 @@ static BOOL ReverbDeviceUpdate(DirectSoundDevice *dev)
void init_eax_buffer(IDirectSoundBufferImpl* dsb)
{
+ dsb->eax.TotalSamples = 0;
+ dsb->eax.SampleBuffer = NULL;
+
+ dsb->eax.Delay.Mask = 0;
+ dsb->eax.Delay.Line = NULL;
+
+ dsb->eax.Offset = 0;
+
ReverbUpdate(dsb);
DSOUND_RefreshCPFieldsProc(dsb);
@@ -137,7 +231,8 @@ static void init_eax(DirectSoundDevice *dev)
void free_eax_buffer(IDirectSoundBufferImpl* dsb)
{
- /* stub */
+ if (dsb->eax.SampleBuffer)
+ HeapFree(GetProcessHeap(), 0, dsb->eax.SampleBuffer);
}
HRESULT WINAPI EAX_Get(IDirectSoundBufferImpl *buf, REFGUID guidPropSet,
--------------2.0.5--