aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-21 16:46:52 -0800
committerChris Robinson <[email protected]>2018-11-21 16:46:52 -0800
commitcc3e2a838f245770af3d773e8d2c461b9912e392 (patch)
tree1731cb65bf0be9f3de38f90f8730059a6c50ff5c
parenteefc379a239820a0711683455f5fadb20c8dbaf9 (diff)
Use a unique_ptr for the Compressor
-rw-r--r--Alc/alc.cpp11
-rw-r--r--Alc/alu.cpp2
-rw-r--r--Alc/mastering.cpp104
-rw-r--r--Alc/mastering.h68
-rw-r--r--OpenAL32/Include/alMain.h2
5 files changed, 95 insertions, 92 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index 2ad6c887..b942064f 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2221,16 +2221,12 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
if(device->DitherDepth > 0.0f)
thrshld -= 1.0f / device->DitherDepth;
- al_free(device->Limiter);
- device->Limiter = CreateDeviceLimiter(device, std::log10(thrshld) * 20.0f);
- device->FixedLatency += (ALuint)(GetCompressorLookAhead(device->Limiter) *
+ device->Limiter.reset(CreateDeviceLimiter(device, std::log10(thrshld) * 20.0f));
+ device->FixedLatency += (ALuint)(GetCompressorLookAhead(device->Limiter.get()) *
DEVICE_CLOCK_RES / device->Frequency);
}
else
- {
- al_free(device->Limiter);
device->Limiter = nullptr;
- }
TRACE("Output limiter %s\n", device->Limiter ? "enabled" : "disabled");
aluSelectPostProcess(device);
@@ -2433,9 +2429,6 @@ ALCdevice_struct::~ALCdevice_struct()
al_free(Stablizer);
Stablizer = nullptr;
-
- al_free(Limiter);
- Limiter = nullptr;
}
diff --git a/Alc/alu.cpp b/Alc/alu.cpp
index a87be0b6..4d3ad9b2 100644
--- a/Alc/alu.cpp
+++ b/Alc/alu.cpp
@@ -1787,7 +1787,7 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
SamplesToDo, device->RealOut.NumChannels);
if(device->Limiter)
- ApplyCompression(device->Limiter, SamplesToDo, device->RealOut.Buffer);
+ ApplyCompression(device->Limiter.get(), SamplesToDo, device->RealOut.Buffer);
if(device->DitherDepth > 0.0f)
ApplyDither(device->RealOut.Buffer, &device->DitherSeed, device->DitherDepth,
diff --git a/Alc/mastering.cpp b/Alc/mastering.cpp
index 131a0330..bf999709 100644
--- a/Alc/mastering.cpp
+++ b/Alc/mastering.cpp
@@ -2,6 +2,8 @@
#include <math.h>
+#include <algorithm>
+
#include "mastering.h"
#include "alu.h"
#include "almalloc.h"
@@ -23,65 +25,13 @@ static double round(double val)
/* These structures assume BUFFERSIZE is a power of 2. */
static_assert((BUFFERSIZE & (BUFFERSIZE-1)) == 0, "BUFFERSIZE is not a power of 2");
-typedef struct SlidingHold {
+struct SlidingHold {
ALfloat Values[BUFFERSIZE];
ALsizei Expiries[BUFFERSIZE];
ALsizei LowerIndex;
ALsizei UpperIndex;
ALsizei Length;
-} SlidingHold;
-
-/* General topology and basic automation was based on the following paper:
- *
- * D. Giannoulis, M. Massberg and J. D. Reiss,
- * "Parameter Automation in a Dynamic Range Compressor,"
- * Journal of the Audio Engineering Society, v61 (10), Oct. 2013
- *
- * Available (along with supplemental reading) at:
- *
- * http://c4dm.eecs.qmul.ac.uk/audioengineering/compressors/
- */
-typedef struct Compressor {
- ALsizei NumChans;
- ALuint SampleRate;
-
- struct {
- ALuint Knee : 1;
- ALuint Attack : 1;
- ALuint Release : 1;
- ALuint PostGain : 1;
- ALuint Declip : 1;
- } Auto;
-
- ALsizei LookAhead;
-
- ALfloat PreGain;
- ALfloat PostGain;
-
- ALfloat Threshold;
- ALfloat Slope;
- ALfloat Knee;
-
- ALfloat Attack;
- ALfloat Release;
-
- alignas(16) ALfloat SideChain[2*BUFFERSIZE];
- alignas(16) ALfloat CrestFactor[BUFFERSIZE];
-
- SlidingHold *Hold;
- ALfloat (*Delay)[BUFFERSIZE];
- ALsizei DelayIndex;
-
- ALfloat CrestCoeff;
- ALfloat GainEstimate;
- ALfloat AdaptCoeff;
-
- ALfloat LastPeakSq;
- ALfloat LastRmsSq;
- ALfloat LastRelease;
- ALfloat LastAttack;
- ALfloat LastGainDev;
-} Compressor;
+};
/* This sliding hold follows the input level with an instant attack and a
@@ -446,7 +396,7 @@ Compressor* CompressorInit(const ALsizei NumChans, const ALuint SampleRate,
size += sizeof(*Comp->Hold);
}
- Comp = static_cast<Compressor*>(al_calloc(16, size));
+ Comp = new (al_calloc(16, size)) Compressor{};
Comp->NumChans = NumChans;
Comp->SampleRate = SampleRate;
Comp->Auto.Knee = AutoKnee;
@@ -474,7 +424,7 @@ Compressor* CompressorInit(const ALsizei NumChans, const ALuint SampleRate,
{
if(hold > 0)
{
- Comp->Hold = (SlidingHold*)(Comp + 1);
+ Comp->Hold = new ((void*)(Comp + 1)) SlidingHold{};
Comp->Hold->Values[0] = -HUGE_VALF;
Comp->Hold->Expiries[0] = hold;
Comp->Hold->Length = hold;
@@ -495,21 +445,23 @@ Compressor* CompressorInit(const ALsizei NumChans, const ALuint SampleRate,
void ApplyCompression(Compressor *Comp, const ALsizei SamplesToDo, ALfloat (*RESTRICT OutBuffer)[BUFFERSIZE])
{
- const ALsizei numChans = Comp->NumChans;
- const ALfloat preGain = Comp->PreGain;
- ALfloat *RESTRICT sideChain;
- ALsizei c, i;
+ const ALsizei numChans{Comp->NumChans};
ASSUME(SamplesToDo > 0);
ASSUME(numChans > 0);
+ const ALfloat preGain{Comp->PreGain};
if(preGain != 1.0f)
{
- for(c = 0;c < numChans;c++)
- {
- for(i = 0;i < SamplesToDo;i++)
- OutBuffer[c][i] *= preGain;
- }
+ std::for_each(OutBuffer, OutBuffer+numChans,
+ [SamplesToDo, preGain](ALfloat *buffer) noexcept -> void
+ {
+ std::for_each(buffer, buffer+SamplesToDo,
+ [preGain](ALfloat &samp) noexcept -> void
+ { samp *= preGain; }
+ );
+ }
+ );
}
LinkChannels(Comp, SamplesToDo, OutBuffer);
@@ -527,14 +479,22 @@ void ApplyCompression(Compressor *Comp, const ALsizei SamplesToDo, ALfloat (*RES
if(Comp->Delay)
SignalDelay(Comp, SamplesToDo, OutBuffer);
- sideChain = Comp->SideChain;
- for(c = 0;c < numChans;c++)
- {
- for(i = 0;i < SamplesToDo;i++)
- OutBuffer[c][i] *= sideChain[i];
- }
+ ALfloat *RESTRICT sideChain{Comp->SideChain};
+ std::for_each(OutBuffer, OutBuffer+numChans,
+ [SamplesToDo, sideChain](ALfloat *buffer) noexcept -> void
+ {
+ /* Mark the sideChain "input-1 type" as restrict, so the compiler
+ * can vectorize this loop (otherwise it assumes a write to
+ * buffer[n] can change sideChain[n+1]).
+ */
+ std::transform<ALfloat*RESTRICT>(sideChain, sideChain+SamplesToDo, buffer, buffer,
+ [](const ALfloat gain, const ALfloat samp) noexcept -> ALfloat
+ { return samp * gain; }
+ );
+ }
+ );
- memmove(sideChain, sideChain+SamplesToDo, Comp->LookAhead*sizeof(ALfloat));
+ std::copy(sideChain+SamplesToDo, sideChain+SamplesToDo+Comp->LookAhead, sideChain);
}
diff --git a/Alc/mastering.h b/Alc/mastering.h
index 7738a4aa..a6cf58ed 100644
--- a/Alc/mastering.h
+++ b/Alc/mastering.h
@@ -3,14 +3,68 @@
#include "AL/al.h"
+#include "almalloc.h"
/* For BUFFERSIZE. */
#include "alMain.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-struct Compressor;
+struct SlidingHold;
+
+/* General topology and basic automation was based on the following paper:
+ *
+ * D. Giannoulis, M. Massberg and J. D. Reiss,
+ * "Parameter Automation in a Dynamic Range Compressor,"
+ * Journal of the Audio Engineering Society, v61 (10), Oct. 2013
+ *
+ * Available (along with supplemental reading) at:
+ *
+ * http://c4dm.eecs.qmul.ac.uk/audioengineering/compressors/
+ */
+struct Compressor {
+ ALsizei NumChans;
+ ALuint SampleRate;
+
+ struct {
+ ALuint Knee : 1;
+ ALuint Attack : 1;
+ ALuint Release : 1;
+ ALuint PostGain : 1;
+ ALuint Declip : 1;
+ } Auto;
+
+ ALsizei LookAhead;
+
+ ALfloat PreGain;
+ ALfloat PostGain;
+
+ ALfloat Threshold;
+ ALfloat Slope;
+ ALfloat Knee;
+
+ ALfloat Attack;
+ ALfloat Release;
+
+ alignas(16) ALfloat SideChain[2*BUFFERSIZE];
+ alignas(16) ALfloat CrestFactor[BUFFERSIZE];
+
+ SlidingHold *Hold;
+ ALfloat (*Delay)[BUFFERSIZE];
+ ALsizei DelayIndex;
+
+ ALfloat CrestCoeff;
+ ALfloat GainEstimate;
+ ALfloat AdaptCoeff;
+
+ ALfloat LastPeakSq;
+ ALfloat LastRmsSq;
+ ALfloat LastRelease;
+ ALfloat LastAttack;
+ ALfloat LastGainDev;
+
+ void *operator new(size_t size) = delete;
+ void *operator new(size_t /*size*/, void *ptr) noexcept { return ptr; }
+ void operator delete(void *block) noexcept { al_free(block); }
+};
/* The compressor is initialized with the following settings:
*
@@ -36,7 +90,7 @@ struct Compressor;
* ReleaseTimeMin - Release time (in seconds). Acts as a maximum when
* automating release time.
*/
-struct Compressor* CompressorInit(const ALsizei NumChans, const ALuint SampleRate,
+Compressor* CompressorInit(const ALsizei NumChans, const ALuint SampleRate,
const ALboolean AutoKnee, const ALboolean AutoAttack,
const ALboolean AutoRelease, const ALboolean AutoPostGain,
const ALboolean AutoDeclip, const ALfloat LookAheadTime,
@@ -50,8 +104,4 @@ void ApplyCompression(struct Compressor *Comp, const ALsizei SamplesToDo,
ALsizei GetCompressorLookAhead(const struct Compressor *Comp);
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
#endif /* MASTERING_H */
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 06ccd574..41465c1d 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -711,7 +711,7 @@ struct ALCdevice_struct {
struct FrontStablizer *Stablizer{nullptr};
- struct Compressor *Limiter{nullptr};
+ std::unique_ptr<Compressor> Limiter;
/* The average speaker distance as determined by the ambdec configuration
* (or alternatively, by the NFC-HOA reference delay). Only used for NFC.