Minor cleanup

This commit is contained in:
emeric
2026-06-21 13:34:18 +02:00
parent 62f4766f82
commit 52b6af434d
4 changed files with 86 additions and 47 deletions
@@ -32,7 +32,7 @@ namespace lms::audio
namespace 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); 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) for (std::size_t i{}; i < data.size(); ++i)
{ {
uint32_t bits{ std::bit_cast<uint32_t>(data[i]) }; std::uint32_t bits{ std::bit_cast<std::uint32_t>(data[i]) };
if constexpr (std::endian::native == std::endian::little) if constexpr (std::endian::native == std::endian::little)
bits = byteswap32(bits); bits = byteswap32(bits);
std::memcpy(blob.data() + i * 4, &bits, 4); std::memcpy(blob.data() + i * 4, &bits, 4);
@@ -58,7 +58,7 @@ namespace lms::audio
for (std::size_t i{}; i < data.size(); ++i) for (std::size_t i{}; i < data.size(); ++i)
{ {
uint32_t bits{}; std::uint32_t bits{};
std::memcpy(&bits, blob.data() + i * 4, 4); std::memcpy(&bits, blob.data() + i * 4, 4);
if constexpr (std::endian::native == std::endian::little) if constexpr (std::endian::native == std::endian::little)
bits = byteswap32(bits); bits = byteswap32(bits);
+37 -14
View File
@@ -162,22 +162,23 @@ namespace lms::ui
if (trackResults.empty()) if (trackResults.empty())
return; return;
std::vector<float> rtFactors; const std::size_t n{ trackResults.size() };
rtFactors.reserve(trackResults.size()); const float mean{ std::accumulate(trackResults.begin(), trackResults.end(), 0.F, [](float acc, const PcmDecodingBenchmark::TrackDecodeResult& t) {
for (const auto& t : trackResults) return acc + t.realTimeFactor;
rtFactors.push_back(t.realTimeFactor); })
/ static_cast<float>(n) };
const float mean{ std::accumulate(rtFactors.begin(), rtFactors.end(), 0.F) / static_cast<float>(rtFactors.size()) }; const float variance{ std::accumulate(trackResults.begin(), trackResults.end(), 0.F, [mean](float acc, const PcmDecodingBenchmark::TrackDecodeResult& t) {
const float variance{ std::accumulate(rtFactors.begin(), rtFactors.end(), 0.F, [mean](float acc, float v) { return acc + (t.realTimeFactor - mean) * (t.realTimeFactor - mean);
return acc + (v - mean) * (v - mean); })
}) / static_cast<float>(rtFactors.size()) }; / static_cast<float>(n) };
const auto [minIt, maxIt]{ std::minmax_element(trackResults.begin(), trackResults.end(), [](const PcmDecodingBenchmark::TrackDecodeResult& a, const PcmDecodingBenchmark::TrackDecodeResult& b) {
const auto [minIt, maxIt]{ std::minmax_element(rtFactors.begin(), rtFactors.end()) }; return a.realTimeFactor < b.realTimeFactor;
}) };
allResults.push_back(PcmDecodingBenchmark::CodecResult{ allResults.push_back(PcmDecodingBenchmark::CodecResult{
.codecName = std::string{ codecDesc.name.str() }, .codecName = std::string{ codecDesc.name.str() },
.tracks = std::move(trackResults), .tracks = std::move(trackResults),
.minRealTimeFactor = *minIt, .minRealTimeFactor = minIt->realTimeFactor,
.maxRealTimeFactor = *maxIt, .maxRealTimeFactor = maxIt->realTimeFactor,
.meanRealTimeFactor = mean, .meanRealTimeFactor = mean,
.stdDevRealTimeFactor = std::sqrt(variance), .stdDevRealTimeFactor = std::sqrt(variance),
}); });
@@ -199,6 +200,24 @@ namespace lms::ui
return _state; return _state;
} }
std::vector<PcmDecodingBenchmark::CodecResult> 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) void PcmDecodingBenchmark::start(db::IDb& db)
{ {
{ {
@@ -250,7 +269,11 @@ namespace lms::ui
void PcmDecodingBenchmark::postStateToAllSessions(State oldState, State newState) 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) if (!LmsApp)
return; return;
@@ -23,7 +23,6 @@
#include <filesystem> #include <filesystem>
#include <functional> #include <functional>
#include <mutex> #include <mutex>
#include <span>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@@ -40,7 +39,12 @@ namespace lms::ui
class PcmDecodingBenchmark class PcmDecodingBenchmark
{ {
public: public:
enum class State { Idle, Running, Completed }; enum class State
{
Idle,
Running,
Completed
};
struct TrackDecodeResult struct TrackDecodeResult
{ {
@@ -64,9 +68,9 @@ namespace lms::ui
static PcmDecodingBenchmark& instance(); static PcmDecodingBenchmark& instance();
State getState() const; State getState() const;
std::span<const CodecResult> getResults() const { return _results; } std::vector<CodecResult> getResults() const;
std::chrono::milliseconds getElapsed() const { return _elapsed; } std::chrono::milliseconds getElapsed() const;
std::string_view getReportFilename() const { return _reportFilename; } std::string getReportFilename() const;
void start(db::IDb& db); void start(db::IDb& db);
+36 -24
View File
@@ -21,9 +21,9 @@
#include <algorithm> #include <algorithm>
#include <chrono> #include <chrono>
#include <span>
#include <cmath> #include <cmath>
#include <numeric> #include <iomanip>
#include <limits>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
@@ -48,8 +48,8 @@ namespace lms::ui
class PcmDecodingStatsResource : public Wt::WResource class PcmDecodingStatsResource : public Wt::WResource
{ {
public: public:
PcmDecodingStatsResource(std::span<const PcmDecodingBenchmark::CodecResult> results, std::chrono::milliseconds elapsed, std::string filename) PcmDecodingStatsResource(std::vector<PcmDecodingBenchmark::CodecResult> results, std::chrono::milliseconds elapsed, std::string filename)
: _results{ results.begin(), results.end() } : _results{ std::move(results) }
, _elapsed{ elapsed } , _elapsed{ elapsed }
, _filename{ std::move(filename) } , _filename{ std::move(filename) }
{ {
@@ -75,9 +75,14 @@ namespace lms::ui
const std::string cdp{ encodeHttpHeaderField("filename", _filename) }; const std::string cdp{ encodeHttpHeaderField("filename", _filename) };
response.addHeader("Content-Disposition", "attachment; " + cdp); response.addHeader("Content-Disposition", "attachment; " + cdp);
response.out() << std::fixed << std::setprecision(1);
response.out() << "PCM decoding bench (elapsed: " << std::chrono::duration_cast<std::chrono::seconds>(_elapsed).count() << "s)\n\n"; response.out() << "PCM decoding bench (elapsed: " << std::chrono::duration_cast<std::chrono::seconds>(_elapsed).count() << "s)\n\n";
std::vector<float> allRtFactors; std::size_t totalTracks{};
float globalMin{ std::numeric_limits<float>::max() };
float globalMax{ std::numeric_limits<float>::lowest() };
float weightedMeanSum{};
for (const PcmDecodingBenchmark::CodecResult& r : _results) for (const PcmDecodingBenchmark::CodecResult& r : _results)
{ {
response.out() << "=== " << r.codecName << " (" << r.tracks.size() << " track(s)) ===\n"; response.out() << "=== " << r.codecName << " (" << r.tracks.size() << " track(s)) ===\n";
@@ -88,32 +93,39 @@ namespace lms::ui
response.out() << " " << t.path response.out() << " " << t.path
<< " bitrate=" << t.bitrate / 1000 << " kbps" << " bitrate=" << t.bitrate / 1000 << " kbps"
<< " duration=" << durationSec / 60 << "m" << durationSec % 60 << "s" << " duration=" << durationSec / 60 << "m" << durationSec % 60 << "s"
<< " real_time_factor=" << static_cast<long>(t.realTimeFactor) << "x" << " real_time_factor=" << t.realTimeFactor << "x"
<< " speed=" << static_cast<long>(t.speedKBs) << " KB/s\n"; << " speed=" << t.speedKBs << " KB/s\n";
allRtFactors.push_back(t.realTimeFactor);
} }
response.out() << " real_time_factor summary:" response.out() << " real_time_factor summary:"
<< " min=" << static_cast<long>(r.minRealTimeFactor) << "x" << " min=" << r.minRealTimeFactor << "x"
<< " max=" << static_cast<long>(r.maxRealTimeFactor) << "x" << " max=" << r.maxRealTimeFactor << "x"
<< " mean=" << static_cast<long>(r.meanRealTimeFactor) << "x" << " mean=" << r.meanRealTimeFactor << "x"
<< " stddev=" << static_cast<long>(r.stdDevRealTimeFactor) << "x\n\n"; << " 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<float>(r.tracks.size());
} }
if (!allRtFactors.empty()) if (totalTracks > 0)
{ {
const float mean{ std::accumulate(allRtFactors.begin(), allRtFactors.end(), 0.F) / static_cast<float>(allRtFactors.size()) }; const float globalMean{ weightedMeanSum / static_cast<float>(totalTracks) };
const float variance{ std::accumulate(allRtFactors.begin(), allRtFactors.end(), 0.F, [mean](float acc, float v) {
return acc + (v - mean) * (v - mean);
}) / static_cast<float>(allRtFactors.size()) };
response.out() << "=== OVERALL (" << allRtFactors.size() << " track(s)) ===\n"; float weightedVarianceSum{};
const auto [minIt, maxIt]{ std::minmax_element(allRtFactors.begin(), allRtFactors.end()) }; for (const PcmDecodingBenchmark::CodecResult& r : _results)
{
const float d{ r.meanRealTimeFactor - globalMean };
weightedVarianceSum += static_cast<float>(r.tracks.size()) * (r.stdDevRealTimeFactor * r.stdDevRealTimeFactor + d * d);
}
response.out() << "=== OVERALL (" << totalTracks << " track(s)) ===\n";
response.out() << " real_time_factor summary:" response.out() << " real_time_factor summary:"
<< " min=" << static_cast<long>(*minIt) << "x" << " min=" << globalMin << "x"
<< " max=" << static_cast<long>(*maxIt) << "x" << " max=" << globalMax << "x"
<< " mean=" << static_cast<long>(mean) << "x" << " mean=" << globalMean << "x"
<< " stddev=" << static_cast<long>(std::sqrtf(variance)) << "x\n"; << " stddev=" << std::sqrt(weightedVarianceSum / static_cast<float>(totalTracks)) << "x\n";
} }
} }
@@ -190,7 +202,7 @@ namespace lms::ui
void PcmDecodingStats::setupDownloadButton() void PcmDecodingStats::setupDownloadButton()
{ {
auto& bench{ PcmDecodingBenchmark::instance() }; auto& bench{ PcmDecodingBenchmark::instance() };
auto resource{ std::make_shared<PcmDecodingStatsResource>(bench.getResults(), bench.getElapsed(), std::string{ bench.getReportFilename() } ) }; auto resource{ std::make_shared<PcmDecodingStatsResource>(bench.getResults(), bench.getElapsed(), bench.getReportFilename()) };
Wt::WLink link{ resource }; Wt::WLink link{ resource };
link.setTarget(Wt::LinkTarget::NewWindow); link.setTarget(Wt::LinkTarget::NewWindow);