Implement metadata handling in pcmaudio categorizer

This commit is contained in:
Marcus Holland-Moritz 2023-07-18 15:33:21 +02:00
parent f30910e79b
commit 465f8e090c

View File

@ -30,6 +30,8 @@
#include <fmt/format.h> #include <fmt/format.h>
#include <folly/Synchronized.h>
#include "dwarfs/categorizer.h" #include "dwarfs/categorizer.h"
#include "dwarfs/error.h" #include "dwarfs/error.h"
#include "dwarfs/logger.h" #include "dwarfs/logger.h"
@ -40,8 +42,76 @@ namespace po = boost::program_options;
namespace { namespace {
constexpr std::string_view const AIFF_CATEGORY{"aiff"}; constexpr std::string_view const PCMAUDIO_CATEGORY{"pcmaudio"};
constexpr std::string_view const WAV_CATEGORY{"wav"};
enum class endianness : uint8_t {
BIG,
LITTLE,
};
enum class signedness : uint8_t {
SIGNED,
UNSIGNED,
};
char const* endianness_string(endianness e) {
switch (e) {
case endianness::BIG:
return "big";
case endianness::LITTLE:
return "little";
}
}
char const* signedness_string(signedness s) {
switch (s) {
case signedness::SIGNED:
return "signed";
case signedness::UNSIGNED:
return "unsigned";
}
}
struct pcmaudio_metadata {
endianness sample_endianness;
signedness sample_signedness;
uint8_t bits_per_sample;
uint16_t number_of_channels;
//// Sample rate should be irrelevant
// uint32_t samples_per_second;
auto operator<=>(pcmaudio_metadata const&) const = default;
};
class pcmaudio_metadata_store {
public:
pcmaudio_metadata_store() = default;
size_t add(pcmaudio_metadata const& m) {
auto it = reverse_index_.find(m);
if (it == reverse_index_.end()) {
auto r = reverse_index_.emplace(m, forward_index_.size());
assert(r.second);
forward_index_.emplace_back(m);
it = r.first;
}
return it->second;
}
folly::dynamic lookup(size_t ix) const {
auto const& m = DWARFS_NOTHROW(forward_index_.at(ix));
folly::dynamic obj = folly::dynamic::object;
obj.insert("endianness", endianness_string(m.sample_endianness));
obj.insert("signedness", signedness_string(m.sample_signedness));
obj.insert("bits_per_sample", m.bits_per_sample);
obj.insert("number_of_channels", m.number_of_channels);
return obj;
}
private:
std::vector<pcmaudio_metadata> forward_index_;
std::map<pcmaudio_metadata, size_t> reverse_index_;
};
class pcmaudio_categorizer_base : public random_access_categorizer { class pcmaudio_categorizer_base : public random_access_categorizer {
public: public:
@ -60,20 +130,20 @@ class pcmaudio_categorizer_ final : public pcmaudio_categorizer_base {
bool is_single_fragment() const override { return false; } bool is_single_fragment() const override { return false; }
folly::dynamic category_metadata(fragment_category) const override { folly::dynamic category_metadata(fragment_category c) const override {
// TODO DWARFS_CHECK(c.has_subcategory(), "expected pcmaudio to have subcategory");
return folly::dynamic(); return meta_.rlock()->lookup(c.subcategory());
} }
private: private:
LOG_PROXY_DECL(LoggerPolicy); LOG_PROXY_DECL(LoggerPolicy);
folly::Synchronized<pcmaudio_metadata_store> mutable meta_;
}; };
std::span<std::string_view const> std::span<std::string_view const>
pcmaudio_categorizer_base::categories() const { pcmaudio_categorizer_base::categories() const {
static constexpr std::array const s_categories{ static constexpr std::array const s_categories{
AIFF_CATEGORY, PCMAUDIO_CATEGORY,
WAV_CATEGORY,
}; };
return s_categories; return s_categories;
} }