Minor cleanup
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user