aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-06-17 23:09:51 -0700
committerChris Robinson <[email protected]>2017-06-17 23:09:51 -0700
commit2b013fc54e8cf9be2184e20a6cd17c4696401ca9 (patch)
tree3889fa5bd352b53848b68608ebc68c706a392446
parente3a825b37c5f43593467f2df3cd225904a259cf8 (diff)
Make the dithering depth configurable
-rw-r--r--Alc/ALc.c35
-rw-r--r--Alc/ALu.c18
-rw-r--r--OpenAL32/Include/alMain.h2
-rw-r--r--alsoftrc.sample13
4 files changed, 44 insertions, 24 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index b31c4f08..7f6cf279 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2222,6 +2222,35 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
device->SourcesMax, device->NumMonoSources, device->NumStereoSources,
device->AuxiliaryEffectSlotMax, device->NumAuxSends);
+ if(!GetConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "dither", 1))
+ device->DitherDepth = 0.0f;
+ else
+ {
+ ALint depth = 0;
+ ConfigValueInt(alstr_get_cstr(device->DeviceName), NULL, "dither-depth", &depth);
+ if(depth <= 0)
+ {
+ switch(device->FmtType)
+ {
+ case DevFmtByte:
+ case DevFmtUByte:
+ depth = 8;
+ break;
+ case DevFmtShort:
+ case DevFmtUShort:
+ depth = 16;
+ break;
+ case DevFmtInt:
+ case DevFmtUInt:
+ case DevFmtFloat:
+ break;
+ }
+ }
+ else if(depth > 24)
+ depth = 24;
+ device->DitherDepth = (depth > 0) ? powf(2.0f, (ALfloat)(depth-1)) : 0.0f;
+ }
+
if(ConfigValueBool(alstr_get_cstr(device->DeviceName), NULL, "output-limiter", &val))
gainLimiter = val ? ALC_TRUE : ALC_FALSE;
/* Valid values for gainLimiter are ALC_DONT_CARE_SOFT, ALC_TRUE, and
@@ -4026,10 +4055,6 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
ERR("Unsupported ambi-format: %s\n", fmt);
}
- device->DitherEnabled = GetConfigValueBool(
- alstr_get_cstr(device->DeviceName), NULL, "dither", 1
- );
-
device->Limiter = CreateDeviceLimiter(device);
if(DefaultEffect.type != AL_EFFECT_NULL)
@@ -4450,8 +4475,6 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
// Open the "backend"
V(device->Backend,open)("Loopback");
- device->DitherEnabled = GetConfigValueBool(NULL, NULL, "dither", 1);
-
device->Limiter = CreateDeviceLimiter(device);
{
diff --git a/Alc/ALu.c b/Alc/ALu.c
index c398dc2b..f6e5cb12 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1786,12 +1786,10 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
if(Limiter)
ApplyCompression(Limiter, OutChannels, SamplesToDo, OutBuffer);
- /* Dither only applies to 8- and 16-bit output for now, as 32-bit
- * int and float are at the limits of the rendered sample depth.
- * This can change if the dithering bit depth becomes configurable
- * (effectively quantizing to a lower bit depth than the output is
- * capable of).
- */
+ if(device->DitherDepth > 0.0f)
+ ApplyDither(OutBuffer, &device->DitherSeed, device->DitherDepth, SamplesToDo,
+ OutChannels);
+
#define WRITE(T, a, b, c, d) do { \
Write##T(SAFE_CONST(ALfloatBUFFERSIZE*,(a)), (b), (c), (d)); \
buffer = (T*)buffer + (c)*(d); \
@@ -1799,23 +1797,15 @@ void aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
switch(device->FmtType)
{
case DevFmtByte:
- if(device->DitherEnabled)
- ApplyDither(OutBuffer, &device->DitherSeed, 128.0f, SamplesToDo, OutChannels);
WRITE(ALbyte, OutBuffer, buffer, SamplesToDo, OutChannels);
break;
case DevFmtUByte:
- if(device->DitherEnabled)
- ApplyDither(OutBuffer, &device->DitherSeed, 128.0f, SamplesToDo, OutChannels);
WRITE(ALubyte, OutBuffer, buffer, SamplesToDo, OutChannels);
break;
case DevFmtShort:
- if(device->DitherEnabled)
- ApplyDither(OutBuffer, &device->DitherSeed, 32768.0f, SamplesToDo, OutChannels);
WRITE(ALshort, OutBuffer, buffer, SamplesToDo, OutChannels);
break;
case DevFmtUShort:
- if(device->DitherEnabled)
- ApplyDither(OutBuffer, &device->DitherSeed, 32768.0f, SamplesToDo, OutChannels);
WRITE(ALushort, OutBuffer, buffer, SamplesToDo, OutChannels);
break;
case DevFmtInt:
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 6e17651f..e5dd8c26 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -794,7 +794,7 @@ struct ALCdevice_struct
DistanceComp ChannelDelay[MAX_OUTPUT_CHANNELS];
/* Dithering control. */
- bool DitherEnabled;
+ ALfloat DitherDepth;
ALuint DitherSeed;
/* Running count of the mixer invocations, in 31.1 fixed point. This
diff --git a/alsoftrc.sample b/alsoftrc.sample
index 26d494f9..3e7d0eec 100644
--- a/alsoftrc.sample
+++ b/alsoftrc.sample
@@ -188,11 +188,18 @@
#output-limiter = true
## dither:
-# Applies dithering on the final mix for 8- and 16-bit output. This replaces
-# the distortion created by nearest-value quantization with low-level
-# whitenoise.
+# Applies dithering on the final mix, for 8- and 16-bit output by default.
+# This replaces the distortion created by nearest-value quantization with low-
+# level whitenoise.
#dither = true
+## dither-depth:
+# Quantization bit-depth for dithered output. A value of 0 (or less) will
+# match the output sample depth. For int32, uint32, and float32 output, 0 will
+# disable dithering because they're at or beyond the rendered precision. The
+# maximum dither depth is 24.
+#dither-depth = 0
+
## volume-adjust:
# A global volume adjustment for source output, expressed in decibels. The
# value is logarithmic, so +6 will be a scale of (approximately) 2x, +12 will