From 52b6af434da0ebf42ccf97dad0f9617bd468d725 Mon Sep 17 00:00:00 2001 From: emeric Date: Sun, 21 Jun 2026 13:34:18 +0200 Subject: [PATCH] Minor cleanup --- .../audio/impl/musicnn/MusicNNEmbeddings.cpp | 6 +- .../ui/admin/debug/PcmDecodingBenchmark.cpp | 53 +++++++++++----- .../ui/admin/debug/PcmDecodingBenchmark.hpp | 14 +++-- src/lms/ui/admin/debug/PcmDecodingStats.cpp | 60 +++++++++++-------- 4 files changed, 86 insertions(+), 47 deletions(-) diff --git a/src/libs/audio/impl/musicnn/MusicNNEmbeddings.cpp b/src/libs/audio/impl/musicnn/MusicNNEmbeddings.cpp index 59eb1cbb..e2066957 100644 --- a/src/libs/audio/impl/musicnn/MusicNNEmbeddings.cpp +++ b/src/libs/audio/impl/musicnn/MusicNNEmbeddings.cpp @@ -32,7 +32,7 @@ namespace lms::audio namespace { - constexpr uint32_t byteswap32(uint32_t x) + constexpr std::uint32_t byteswap32(uint32_t x) { return (x >> 24) | ((x >> 8) & 0x0000FF00u) | ((x << 8) & 0x00FF0000u) | (x << 24); } @@ -44,7 +44,7 @@ namespace lms::audio for (std::size_t i{}; i < data.size(); ++i) { - uint32_t bits{ std::bit_cast(data[i]) }; + std::uint32_t bits{ std::bit_cast(data[i]) }; if constexpr (std::endian::native == std::endian::little) bits = byteswap32(bits); std::memcpy(blob.data() + i * 4, &bits, 4); @@ -58,7 +58,7 @@ namespace lms::audio for (std::size_t i{}; i < data.size(); ++i) { - uint32_t bits{}; + std::uint32_t bits{}; std::memcpy(&bits, blob.data() + i * 4, 4); if constexpr (std::endian::native == std::endian::little) bits = byteswap32(bits); diff --git a/src/lms/ui/admin/debug/PcmDecodingBenchmark.cpp b/src/lms/ui/admin/debug/PcmDecodingBenchmark.cpp index a34f0ac1..329a3f33 100644 --- a/src/lms/ui/admin/debug/PcmDecodingBenchmark.cpp +++ b/src/lms/ui/admin/debug/PcmDecodingBenchmark.cpp @@ -162,22 +162,23 @@ namespace lms::ui if (trackResults.empty()) return; - std::vector rtFactors; - rtFactors.reserve(trackResults.size()); - for (const auto& t : trackResults) - rtFactors.push_back(t.realTimeFactor); - - const float mean{ std::accumulate(rtFactors.begin(), rtFactors.end(), 0.F) / static_cast(rtFactors.size()) }; - const float variance{ std::accumulate(rtFactors.begin(), rtFactors.end(), 0.F, [mean](float acc, float v) { - return acc + (v - mean) * (v - mean); - }) / static_cast(rtFactors.size()) }; - - const auto [minIt, maxIt]{ std::minmax_element(rtFactors.begin(), rtFactors.end()) }; + const std::size_t n{ trackResults.size() }; + const float mean{ std::accumulate(trackResults.begin(), trackResults.end(), 0.F, [](float acc, const PcmDecodingBenchmark::TrackDecodeResult& t) { + return acc + t.realTimeFactor; + }) + / static_cast(n) }; + const float variance{ std::accumulate(trackResults.begin(), trackResults.end(), 0.F, [mean](float acc, const PcmDecodingBenchmark::TrackDecodeResult& t) { + return acc + (t.realTimeFactor - mean) * (t.realTimeFactor - mean); + }) + / static_cast(n) }; + const auto [minIt, maxIt]{ std::minmax_element(trackResults.begin(), trackResults.end(), [](const PcmDecodingBenchmark::TrackDecodeResult& a, const PcmDecodingBenchmark::TrackDecodeResult& b) { + return a.realTimeFactor < b.realTimeFactor; + }) }; allResults.push_back(PcmDecodingBenchmark::CodecResult{ .codecName = std::string{ codecDesc.name.str() }, .tracks = std::move(trackResults), - .minRealTimeFactor = *minIt, - .maxRealTimeFactor = *maxIt, + .minRealTimeFactor = minIt->realTimeFactor, + .maxRealTimeFactor = maxIt->realTimeFactor, .meanRealTimeFactor = mean, .stdDevRealTimeFactor = std::sqrt(variance), }); @@ -199,6 +200,24 @@ namespace lms::ui return _state; } + std::vector PcmDecodingBenchmark::getResults() const + { + std::scoped_lock lock{ _mutex }; + return _results; + } + + std::chrono::milliseconds PcmDecodingBenchmark::getElapsed() const + { + std::scoped_lock lock{ _mutex }; + return _elapsed; + } + + std::string PcmDecodingBenchmark::getReportFilename() const + { + std::scoped_lock lock{ _mutex }; + return _reportFilename; + } + void PcmDecodingBenchmark::start(db::IDb& db) { { @@ -208,7 +227,7 @@ namespace lms::ui if (_state == State::Running) return; - + _reportFilename = "LMS_pcm_decoding_stats_" + core::stringUtils::toISO8601String(Wt::WDateTime::currentDateTime()) + ".txt"; prevState = _state; _state = State::Running; @@ -250,7 +269,11 @@ namespace lms::ui void PcmDecodingBenchmark::postStateToAllSessions(State oldState, State newState) { - Wt::WServer::instance()->postAll([this, oldState, newState] { + auto* server{ Wt::WServer::instance() }; + if (!server) + return; + + server->postAll([this, oldState, newState] { if (!LmsApp) return; diff --git a/src/lms/ui/admin/debug/PcmDecodingBenchmark.hpp b/src/lms/ui/admin/debug/PcmDecodingBenchmark.hpp index 3a18e238..8c096438 100644 --- a/src/lms/ui/admin/debug/PcmDecodingBenchmark.hpp +++ b/src/lms/ui/admin/debug/PcmDecodingBenchmark.hpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -40,7 +39,12 @@ namespace lms::ui class PcmDecodingBenchmark { public: - enum class State { Idle, Running, Completed }; + enum class State + { + Idle, + Running, + Completed + }; struct TrackDecodeResult { @@ -64,9 +68,9 @@ namespace lms::ui static PcmDecodingBenchmark& instance(); State getState() const; - std::span getResults() const { return _results; } - std::chrono::milliseconds getElapsed() const { return _elapsed; } - std::string_view getReportFilename() const { return _reportFilename; } + std::vector getResults() const; + std::chrono::milliseconds getElapsed() const; + std::string getReportFilename() const; void start(db::IDb& db); diff --git a/src/lms/ui/admin/debug/PcmDecodingStats.cpp b/src/lms/ui/admin/debug/PcmDecodingStats.cpp index 6c13eb29..4b906d27 100644 --- a/src/lms/ui/admin/debug/PcmDecodingStats.cpp +++ b/src/lms/ui/admin/debug/PcmDecodingStats.cpp @@ -21,9 +21,9 @@ #include #include -#include #include -#include +#include +#include #include #include @@ -48,8 +48,8 @@ namespace lms::ui class PcmDecodingStatsResource : public Wt::WResource { public: - PcmDecodingStatsResource(std::span results, std::chrono::milliseconds elapsed, std::string filename) - : _results{ results.begin(), results.end() } + PcmDecodingStatsResource(std::vector results, std::chrono::milliseconds elapsed, std::string filename) + : _results{ std::move(results) } , _elapsed{ elapsed } , _filename{ std::move(filename) } { @@ -75,9 +75,14 @@ namespace lms::ui const std::string cdp{ encodeHttpHeaderField("filename", _filename) }; response.addHeader("Content-Disposition", "attachment; " + cdp); + response.out() << std::fixed << std::setprecision(1); response.out() << "PCM decoding bench (elapsed: " << std::chrono::duration_cast(_elapsed).count() << "s)\n\n"; - std::vector allRtFactors; + std::size_t totalTracks{}; + float globalMin{ std::numeric_limits::max() }; + float globalMax{ std::numeric_limits::lowest() }; + float weightedMeanSum{}; + for (const PcmDecodingBenchmark::CodecResult& r : _results) { response.out() << "=== " << r.codecName << " (" << r.tracks.size() << " track(s)) ===\n"; @@ -88,32 +93,39 @@ namespace lms::ui response.out() << " " << t.path << " bitrate=" << t.bitrate / 1000 << " kbps" << " duration=" << durationSec / 60 << "m" << durationSec % 60 << "s" - << " real_time_factor=" << static_cast(t.realTimeFactor) << "x" - << " speed=" << static_cast(t.speedKBs) << " KB/s\n"; - allRtFactors.push_back(t.realTimeFactor); + << " real_time_factor=" << t.realTimeFactor << "x" + << " speed=" << t.speedKBs << " KB/s\n"; } response.out() << " real_time_factor summary:" - << " min=" << static_cast(r.minRealTimeFactor) << "x" - << " max=" << static_cast(r.maxRealTimeFactor) << "x" - << " mean=" << static_cast(r.meanRealTimeFactor) << "x" - << " stddev=" << static_cast(r.stdDevRealTimeFactor) << "x\n\n"; + << " min=" << r.minRealTimeFactor << "x" + << " max=" << r.maxRealTimeFactor << "x" + << " mean=" << r.meanRealTimeFactor << "x" + << " stddev=" << r.stdDevRealTimeFactor << "x\n\n"; + + totalTracks += r.tracks.size(); + globalMin = std::min(globalMin, r.minRealTimeFactor); + globalMax = std::max(globalMax, r.maxRealTimeFactor); + weightedMeanSum += r.meanRealTimeFactor * static_cast(r.tracks.size()); } - if (!allRtFactors.empty()) + if (totalTracks > 0) { - const float mean{ std::accumulate(allRtFactors.begin(), allRtFactors.end(), 0.F) / static_cast(allRtFactors.size()) }; - const float variance{ std::accumulate(allRtFactors.begin(), allRtFactors.end(), 0.F, [mean](float acc, float v) { - return acc + (v - mean) * (v - mean); - }) / static_cast(allRtFactors.size()) }; + const float globalMean{ weightedMeanSum / static_cast(totalTracks) }; - response.out() << "=== OVERALL (" << allRtFactors.size() << " track(s)) ===\n"; - const auto [minIt, maxIt]{ std::minmax_element(allRtFactors.begin(), allRtFactors.end()) }; + float weightedVarianceSum{}; + for (const PcmDecodingBenchmark::CodecResult& r : _results) + { + const float d{ r.meanRealTimeFactor - globalMean }; + weightedVarianceSum += static_cast(r.tracks.size()) * (r.stdDevRealTimeFactor * r.stdDevRealTimeFactor + d * d); + } + + response.out() << "=== OVERALL (" << totalTracks << " track(s)) ===\n"; response.out() << " real_time_factor summary:" - << " min=" << static_cast(*minIt) << "x" - << " max=" << static_cast(*maxIt) << "x" - << " mean=" << static_cast(mean) << "x" - << " stddev=" << static_cast(std::sqrtf(variance)) << "x\n"; + << " min=" << globalMin << "x" + << " max=" << globalMax << "x" + << " mean=" << globalMean << "x" + << " stddev=" << std::sqrt(weightedVarianceSum / static_cast(totalTracks)) << "x\n"; } } @@ -190,7 +202,7 @@ namespace lms::ui void PcmDecodingStats::setupDownloadButton() { auto& bench{ PcmDecodingBenchmark::instance() }; - auto resource{ std::make_shared(bench.getResults(), bench.getElapsed(), std::string{ bench.getReportFilename() } ) }; + auto resource{ std::make_shared(bench.getResults(), bench.getElapsed(), bench.getReportFilename()) }; Wt::WLink link{ resource }; link.setTarget(Wt::LinkTarget::NewWindow);