diff options
author | Chris Robinson <[email protected]> | 2017-06-17 23:09:51 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-06-17 23:09:51 -0700 |
commit | 2b013fc54e8cf9be2184e20a6cd17c4696401ca9 (patch) | |
tree | 3889fa5bd352b53848b68608ebc68c706a392446 | |
parent | e3a825b37c5f43593467f2df3cd225904a259cf8 (diff) |
Make the dithering depth configurable
-rw-r--r-- | Alc/ALc.c | 35 | ||||
-rw-r--r-- | Alc/ALu.c | 18 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 2 | ||||
-rw-r--r-- | alsoftrc.sample | 13 |
4 files changed, 44 insertions, 24 deletions
@@ -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); { @@ -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 |