From 3ec9fcfc443a68c9f57e0314c47e70ca02a32530 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 2 Feb 2020 21:21:57 -0800 Subject: [PATCH 1/4] treewide: use boost::lround when std::round is unavailable This is the case with uClibc-ng currently. Signed-off-by: Rosen Penev --- src/Stats.cxx | 4 +-- src/command/PlayerCommands.cxx | 5 ++- src/decoder/plugins/FaadDecoderPlugin.cxx | 2 +- src/mixer/plugins/WinmmMixerPlugin.cxx | 2 +- src/output/plugins/HaikuOutputPlugin.cxx | 3 +- src/pcm/Mix.cxx | 4 +-- src/player/CrossFade.cxx | 4 +-- src/util/Math.hxx | 41 +++++++++++++++++++++++ 8 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 src/util/Math.hxx diff --git a/src/Stats.cxx b/src/Stats.cxx index 2208312d7..7467a3a17 100644 --- a/src/Stats.cxx +++ b/src/Stats.cxx @@ -28,13 +28,13 @@ #include "db/Stats.hxx" #include "Log.hxx" #include "time/ChronoUtil.hxx" +#include "util/Math.hxx" #ifdef _WIN32 #include "system/Clock.hxx" #endif #include -#include #ifndef _WIN32 /** @@ -126,7 +126,7 @@ stats_print(Response &r, const Partition &partition) r.Format("uptime: %u\n" "playtime: %lu\n", (unsigned)std::chrono::duration_cast(uptime).count(), - std::lround(partition.pc.GetTotalPlayTime().count())); + lround(partition.pc.GetTotalPlayTime().count())); #ifdef ENABLE_DATABASE const Database *db = partition.instance.GetDatabase(); diff --git a/src/command/PlayerCommands.cxx b/src/command/PlayerCommands.cxx index 7f3b4f296..4acb8f2ad 100644 --- a/src/command/PlayerCommands.cxx +++ b/src/command/PlayerCommands.cxx @@ -32,13 +32,12 @@ #include "util/StringBuffer.hxx" #include "util/ScopeExit.hxx" #include "util/Exception.hxx" +#include "util/Math.hxx" #ifdef ENABLE_DATABASE #include "db/update/Service.hxx" #endif -#include - #define COMMAND_STATUS_STATE "state" #define COMMAND_STATUS_REPEAT "repeat" #define COMMAND_STATUS_SINGLE "single" @@ -155,7 +154,7 @@ handle_status(Client &client, gcc_unused Request args, Response &r) if (pc.GetCrossFade() > FloatDuration::zero()) r.Format(COMMAND_STATUS_CROSSFADE ": %lu\n", - std::lround(pc.GetCrossFade().count())); + lround(pc.GetCrossFade().count())); if (pc.GetMixRampDelay() > FloatDuration::zero()) r.Format(COMMAND_STATUS_MIXRAMPDELAY ": %f\n", diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx index 5875a743a..40072f953 100644 --- a/src/decoder/plugins/FaadDecoderPlugin.cxx +++ b/src/decoder/plugins/FaadDecoderPlugin.cxx @@ -26,12 +26,12 @@ #include "util/ScopeExit.hxx" #include "util/ConstBuffer.hxx" #include "util/Domain.hxx" +#include "util/Math.hxx" #include "Log.hxx" #include #include -#include #include diff --git a/src/mixer/plugins/WinmmMixerPlugin.cxx b/src/mixer/plugins/WinmmMixerPlugin.cxx index 0bf60f58b..c3ce5827a 100644 --- a/src/mixer/plugins/WinmmMixerPlugin.cxx +++ b/src/mixer/plugins/WinmmMixerPlugin.cxx @@ -20,13 +20,13 @@ #include "mixer/MixerInternal.hxx" #include "output/OutputAPI.hxx" #include "output/plugins/WinmmOutputPlugin.hxx" +#include "util/Math.hxx" #include #include #include -#include #include class WinmmMixer final : public Mixer { diff --git a/src/output/plugins/HaikuOutputPlugin.cxx b/src/output/plugins/HaikuOutputPlugin.cxx index 952fb0c2f..01240aca9 100644 --- a/src/output/plugins/HaikuOutputPlugin.cxx +++ b/src/output/plugins/HaikuOutputPlugin.cxx @@ -22,6 +22,7 @@ #include "../OutputAPI.hxx" #include "mixer/MixerList.hxx" #include "util/Domain.hxx" +#include "util/Math.hxx" #include "system/Error.hxx" #include "Log.hxx" @@ -37,8 +38,6 @@ #include #include -#include - #include #define UTF8_PLAY "\xE2\x96\xB6" diff --git a/src/pcm/Mix.cxx b/src/pcm/Mix.cxx index b17343513..a39a85947 100644 --- a/src/pcm/Mix.cxx +++ b/src/pcm/Mix.cxx @@ -22,11 +22,11 @@ #include "Clamp.hxx" #include "Traits.hxx" #include "util/Clamp.hxx" +#include "util/Math.hxx" #include "Dither.cxx" // including the .cxx file to get inlined templates #include -#include template> static typename Traits::value_type @@ -224,7 +224,7 @@ pcm_mix(PcmDither &dither, void *buffer1, const void *buffer2, size_t size, s = sin(M_PI_2 * portion1); s *= s; - int vol1 = std::lround(s * PCM_VOLUME_1S); + int vol1 = lround(s * PCM_VOLUME_1S); vol1 = Clamp(vol1, 0, PCM_VOLUME_1S); return pcm_add_vol(dither, buffer1, buffer2, size, diff --git a/src/player/CrossFade.cxx b/src/player/CrossFade.cxx index ec8fd334e..e5611f97c 100644 --- a/src/player/CrossFade.cxx +++ b/src/player/CrossFade.cxx @@ -23,10 +23,10 @@ #include "pcm/AudioFormat.hxx" #include "util/NumberParser.hxx" #include "util/Domain.hxx" +#include "util/Math.hxx" #include "Log.hxx" #include -#include static constexpr Domain cross_fade_domain("cross_fade"); @@ -111,7 +111,7 @@ CrossFadeSettings::Calculate(SignedSongTime total_time, if (mixramp_delay <= FloatDuration::zero() || !mixramp_start || !mixramp_prev_end) { - chunks = std::lround(duration / chunk_duration); + chunks = lround(duration / chunk_duration); } else { /* Calculate mixramp overlap. */ const auto mixramp_overlap_current = diff --git a/src/util/Math.hxx b/src/util/Math.hxx new file mode 100644 index 000000000..bd856f5a9 --- /dev/null +++ b/src/util/Math.hxx @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MATH_HXX +#define MATH_HXX + +#ifdef __UCLIBC__ +#include +using boost::math::lround; +#else +#include +using std::lround; +#endif + +#endif From a78841d6a953c4f40e8196e51bdd4aad995b9104 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Mon, 3 Feb 2020 15:26:50 -0800 Subject: [PATCH 2/4] volume_mapping: get rid of exp10 workaround exp10 is a GNU function, is not part of C++, and is not available everywhere. pow(10,x) is an alternative that works just as well. It is used in musl as the implementation of exp10. Signed-off-by: Rosen Penev --- src/mixer/plugins/volume_mapping.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/mixer/plugins/volume_mapping.c b/src/mixer/plugins/volume_mapping.c index 61a7138af..beecce640 100644 --- a/src/mixer/plugins/volume_mapping.c +++ b/src/mixer/plugins/volume_mapping.c @@ -34,11 +34,6 @@ #include #include "volume_mapping.h" -#ifdef __UCLIBC__ -/* 10^x = 10^(log e^x) = (e^x)^log10 = e^(x * log 10) */ -#define exp10(x) (exp((x) * log(10))) -#endif /* __UCLIBC__ */ - #define MAX_LINEAR_DB_SCALE 24 static inline bool use_linear_dB_scale(long dBmin, long dBmax) @@ -111,9 +106,9 @@ static double get_normalized_volume(snd_mixer_elem_t *elem, if (use_linear_dB_scale(min, max)) return (value - min) / (double)(max - min); - normalized = exp10((value - max) / 6000.0); + normalized = pow(10, (value - max) / 6000.0); if (min != SND_CTL_TLV_DB_GAIN_MUTE) { - min_norm = exp10((min - max) / 6000.0); + min_norm = pow(10, (min - max) / 6000.0); normalized = (normalized - min_norm) / (1 - min_norm); } @@ -159,7 +154,7 @@ static int set_normalized_volume(snd_mixer_elem_t *elem, } if (min != SND_CTL_TLV_DB_GAIN_MUTE) { - min_norm = exp10((min - max) / 6000.0); + min_norm = pow(10, (min - max) / 6000.0); volume = volume * (1 - min_norm) + min_norm; } value = lrint_dir(6000.0 * log10(volume), dir) + max; From 177371a00395c37f965714b2191bda12cb6af846 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Mon, 3 Feb 2020 15:50:46 -0800 Subject: [PATCH 3/4] treewide: get rid of C math function usage Boost does not seem to offer an overload for lrint. Signed-off-by: Rosen Penev --- src/ReplayGainGlobal.cxx | 2 +- src/ReplayGainInfo.cxx | 3 +-- src/decoder/Bridge.cxx | 4 ++-- src/decoder/plugins/MpcdecDecoderPlugin.cxx | 3 +-- src/mixer/plugins/AlsaMixerPlugin.cxx | 3 +-- src/mixer/plugins/SoftwareMixerPlugin.cxx | 5 +++-- src/util/Math.hxx | 6 ++++++ 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/ReplayGainGlobal.cxx b/src/ReplayGainGlobal.cxx index 98b8dcda0..af82c2288 100644 --- a/src/ReplayGainGlobal.cxx +++ b/src/ReplayGainGlobal.cxx @@ -20,12 +20,12 @@ #include "ReplayGainGlobal.hxx" #include "ReplayGainConfig.hxx" #include "config/Data.hxx" +#include "util/Math.hxx" #include #include #include -#include static float ParsePreamp(const char *s) diff --git a/src/ReplayGainInfo.cxx b/src/ReplayGainInfo.cxx index a0685507a..76713aded 100644 --- a/src/ReplayGainInfo.cxx +++ b/src/ReplayGainInfo.cxx @@ -19,8 +19,7 @@ #include "ReplayGainInfo.hxx" #include "ReplayGainConfig.hxx" - -#include +#include "util/Math.hxx" float ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const noexcept diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx index b87466798..b7f71c1b8 100644 --- a/src/decoder/Bridge.cxx +++ b/src/decoder/Bridge.cxx @@ -37,9 +37,9 @@ #include "util/StringBuffer.hxx" #include +#include #include -#include DecoderBridge::DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending, std::unique_ptr _tag) noexcept @@ -611,7 +611,7 @@ DecoderBridge::SubmitReplayGain(const ReplayGainInfo *new_replay_gain_info) noex const auto &tuple = new_replay_gain_info->Get(rgm); const auto scale = tuple.CalculateScale(dc.replay_gain_config); - dc.replay_gain_db = 20.0 * log10f(scale); + dc.replay_gain_db = 20.0 * std::log10(scale); } replay_gain_info = *new_replay_gain_info; diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx index c19aee75c..4e9ef798e 100644 --- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx +++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx @@ -25,6 +25,7 @@ #include "tag/Handler.hxx" #include "util/Domain.hxx" #include "util/Clamp.hxx" +#include "util/Math.hxx" #include "util/ScopeExit.hxx" #include "Log.hxx" @@ -32,8 +33,6 @@ #include -#include - struct mpc_decoder_data { InputStream &is; DecoderClient *client; diff --git a/src/mixer/plugins/AlsaMixerPlugin.cxx b/src/mixer/plugins/AlsaMixerPlugin.cxx index e3d774194..4b916319b 100644 --- a/src/mixer/plugins/AlsaMixerPlugin.cxx +++ b/src/mixer/plugins/AlsaMixerPlugin.cxx @@ -26,6 +26,7 @@ #include "event/Call.hxx" #include "util/ASCII.hxx" #include "util/Domain.hxx" +#include "util/Math.hxx" #include "util/RuntimeError.hxx" #include "Log.hxx" @@ -35,8 +36,6 @@ extern "C" { #include -#include - #define VOLUME_MIXER_ALSA_DEFAULT "default" #define VOLUME_MIXER_ALSA_CONTROL_DEFAULT "PCM" static constexpr unsigned VOLUME_MIXER_ALSA_INDEX_DEFAULT = 0; diff --git a/src/mixer/plugins/SoftwareMixerPlugin.cxx b/src/mixer/plugins/SoftwareMixerPlugin.cxx index cb9649017..c62fea986 100644 --- a/src/mixer/plugins/SoftwareMixerPlugin.cxx +++ b/src/mixer/plugins/SoftwareMixerPlugin.cxx @@ -23,8 +23,9 @@ #include "pcm/Volume.hxx" #include +#include -#include +#include class SoftwareMixer final : public Mixer { Filter *filter = nullptr; @@ -74,7 +75,7 @@ PercentVolumeToSoftwareVolume(unsigned volume) noexcept if (volume >= 100) return PCM_VOLUME_1; else if (volume > 0) - return pcm_float_to_volume((exp(volume / 25.0) - 1) / + return pcm_float_to_volume((std::exp(volume / 25.0) - 1) / (54.5981500331F - 1)); else return 0; diff --git a/src/util/Math.hxx b/src/util/Math.hxx index bd856f5a9..2206b045f 100644 --- a/src/util/Math.hxx +++ b/src/util/Math.hxx @@ -31,10 +31,16 @@ #define MATH_HXX #ifdef __UCLIBC__ +#include #include +using boost::math::iround; +using boost::math::pow; using boost::math::lround; +#define lrint iround #else #include +using std::pow; +using std::lrint; using std::lround; #endif From 5e4b7e2fb7796c3eeab6c6230b413d8c20c4ac5c Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Sun, 2 Feb 2020 16:34:09 -0800 Subject: [PATCH 4/4] [clang-tidy] fix incorrect rounding Found with bugprone-incorrect-roundings Signed-off-by: Rosen Penev --- src/decoder/plugins/WavpackDecoderPlugin.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx index 93459f311..0ca4f59cf 100644 --- a/src/decoder/plugins/WavpackDecoderPlugin.cxx +++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx @@ -25,6 +25,7 @@ #include "tag/Handler.hxx" #include "fs/Path.hxx" #include "util/Alloc.hxx" +#include "util/Math.hxx" #include "util/ScopeExit.hxx" #include "util/RuntimeError.hxx" @@ -263,8 +264,7 @@ wavpack_decode(DecoderClient &client, WavpackContext *wpc, bool can_seek) if (samples_got == 0) break; - int bitrate = (int)(WavpackGetInstantBitrate(wpc) / 1000 + - 0.5); + int bitrate = lround(WavpackGetInstantBitrate(wpc) / 1000); format_samples(chunk, samples_got * audio_format.channels); cmd = client.SubmitData(nullptr, chunk,