diff options
author | haslersn <sebastian.hasler@gmx.net> | 2020-06-07 18:55:51 +0200 |
---|---|---|
committer | haslersn <sebastian.hasler@gmx.net> | 2020-06-07 21:29:53 +0200 |
commit | 080d336106dd9560b3d6f4d6e9ff59fd6c6f710e (patch) | |
tree | 6c13f08bb7a3092b1604cd6626002f3bc4fe4d88 | |
parent | 8d6ca822074e33f8189d22ccdab565f88e5db7b0 (diff) |
enginelibrary: Check that encoded and subsequently decoded perfdata matches the original
-rw-r--r-- | include/djinterop/performance_data.hpp | 42 | ||||
-rw-r--r-- | src/djinterop/enginelibrary/el_track_impl.cpp | 6 | ||||
-rw-r--r-- | src/djinterop/enginelibrary/el_track_impl.hpp | 13 | ||||
-rw-r--r-- | src/djinterop/enginelibrary/performance_data_format.hpp | 72 |
4 files changed, 118 insertions, 15 deletions
diff --git a/include/djinterop/performance_data.hpp b/include/djinterop/performance_data.hpp index 67e22e2..620e676 100644 --- a/include/djinterop/performance_data.hpp +++ b/include/djinterop/performance_data.hpp @@ -35,12 +35,26 @@ struct sampling_info { double sample_rate = 0; // usually 44100.0 or 48000.0 int64_t sample_count = 0; + + friend bool operator==( + const sampling_info& first, const sampling_info& second) noexcept + { + return first.sample_rate == second.sample_rate && + first.sample_count == second.sample_count; + } }; struct beatgrid_marker { int32_t index = 0; double sample_offset = 0; + + friend bool operator==( + const beatgrid_marker& first, const beatgrid_marker& second) noexcept + { + return first.index == second.index && + first.sample_offset == second.sample_offset; + } }; struct hot_cue @@ -48,6 +62,13 @@ struct hot_cue std::string label; double sample_offset = 0; pad_color color; + + friend bool operator==(const hot_cue& first, const hot_cue& second) noexcept + { + return first.label == second.label && + first.sample_offset == second.sample_offset && + first.color == second.color; + } }; struct loop @@ -56,12 +77,26 @@ struct loop double start_sample_offset = 0; double end_sample_offset = 0; pad_color color; + + friend bool operator==(const loop& first, const loop& second) noexcept + { + return first.label == second.label && + first.start_sample_offset == second.start_sample_offset && + first.end_sample_offset == second.end_sample_offset && + first.color == second.color; + } }; struct waveform_point { uint8_t value = 0; uint8_t opacity = 255; + + friend bool operator==( + const waveform_point& first, const waveform_point& second) noexcept + { + return first.value == second.value && first.opacity == second.opacity; + } }; /** @@ -82,6 +117,13 @@ struct waveform_entry waveform_point low; waveform_point mid; waveform_point high; + + friend bool operator==( + const waveform_entry& first, const waveform_entry& second) noexcept + { + return first.low == second.low && first.mid == second.mid && + first.high == second.high; + } }; } // namespace djinterop diff --git a/src/djinterop/enginelibrary/el_track_impl.cpp b/src/djinterop/enginelibrary/el_track_impl.cpp index fe1ddca..61fc142 100644 --- a/src/djinterop/enginelibrary/el_track_impl.cpp +++ b/src/djinterop/enginelibrary/el_track_impl.cpp @@ -201,6 +201,12 @@ overview_waveform_data el_track_impl::get_overview_waveform_data() void el_track_impl::set_overview_waveform_data(overview_waveform_data data) { + for (auto&& entry : data.waveform) + { + entry.low.opacity = 255; + entry.mid.opacity = 255; + entry.high.opacity = 255; + } set_perfdata("overviewWaveFormData", data); } diff --git a/src/djinterop/enginelibrary/el_track_impl.hpp b/src/djinterop/enginelibrary/el_track_impl.hpp index bd934e1..f1964ae 100644 --- a/src/djinterop/enginelibrary/el_track_impl.hpp +++ b/src/djinterop/enginelibrary/el_track_impl.hpp @@ -135,6 +135,17 @@ public: template <typename T> void set_perfdata(const char* column_name, const T& content) { + auto encoded_content = content.encode(); + // Check that subsequent reads can correctly decode what we are about to + // write. + if (!(T::decode(encoded_content) == content)) + { + throw std::logic_error{ + "Data supplied for column " + std::string(column_name) + + " is not invariant under encoding and subsequent decoding. " + "This is a bug in libdjinterop."}; + } + bool found = false; storage_->db << "SELECT COUNT(*) FROM PerformanceData WHERE id = ?" << id() >> @@ -182,7 +193,7 @@ public: storage_->db << (std::string{"UPDATE PerformanceData SET "} + column_name + " = ?, isAnalyzed = 1 WHERE id = ?") - << content.encode() << id(); + << encoded_content << id(); } beat_data get_beat_data(); diff --git a/src/djinterop/enginelibrary/performance_data_format.hpp b/src/djinterop/enginelibrary/performance_data_format.hpp index e96fb71..acf1cb6 100644 --- a/src/djinterop/enginelibrary/performance_data_format.hpp +++ b/src/djinterop/enginelibrary/performance_data_format.hpp @@ -33,23 +33,39 @@ namespace enginelibrary { struct beat_data { - beat_data() noexcept = default; - boost::optional<sampling_info> sampling; std::vector<beatgrid_marker> default_beatgrid; std::vector<beatgrid_marker> adjusted_beatgrid; + beat_data() noexcept = default; + + friend bool operator==( + const beat_data& first, const beat_data& second) noexcept + { + return first.sampling == second.sampling && + first.default_beatgrid == second.default_beatgrid && + first.adjusted_beatgrid == second.adjusted_beatgrid; + } + std::vector<char> encode() const; static beat_data decode(const std::vector<char>& compressed_data); }; struct high_res_waveform_data { - high_res_waveform_data() noexcept = default; - double samples_per_entry; std::vector<waveform_entry> waveform; + high_res_waveform_data() noexcept = default; + + friend bool operator==( + const high_res_waveform_data& first, + const high_res_waveform_data& second) noexcept + { + return first.samples_per_entry == second.samples_per_entry && + first.waveform == second.waveform; + } + std::vector<char> encode() const; static high_res_waveform_data decode( const std::vector<char>& compressed_data); @@ -57,10 +73,16 @@ struct high_res_waveform_data struct loops_data { - loops_data() = default; - std::array<boost::optional<loop>, 8> loops; // Don't use curly braces here! + loops_data() noexcept = default; + + friend bool operator==( + const loops_data& first, const loops_data& second) noexcept + { + return first.loops == second.loops; + } + std::vector<char> encode() const; static loops_data decode( const std::vector<char>& raw_data); // not compressed @@ -68,11 +90,19 @@ struct loops_data struct overview_waveform_data { - overview_waveform_data() noexcept = default; - double samples_per_entry; std::vector<waveform_entry> waveform; + overview_waveform_data() noexcept = default; + + friend bool operator==( + const overview_waveform_data& first, + const overview_waveform_data& second) noexcept + { + return first.samples_per_entry == second.samples_per_entry && + first.waveform == second.waveform; + } + std::vector<char> encode() const; static overview_waveform_data decode( const std::vector<char>& compressed_data); @@ -80,27 +110,41 @@ struct overview_waveform_data struct quick_cues_data { - quick_cues_data() = default; - std::array<boost::optional<hot_cue>, 8> hot_cues; double adjusted_main_cue = 0; double default_main_cue = 0; - std::vector<char> encode() const; + quick_cues_data() noexcept = default; + + friend bool operator==( + const quick_cues_data& first, const quick_cues_data& second) noexcept + { + return first.hot_cues == second.hot_cues && + first.adjusted_main_cue == second.adjusted_main_cue && + first.default_main_cue == second.default_main_cue; + } + std::vector<char> encode() const; static quick_cues_data decode(const std::vector<char>& compressed_data); }; struct track_data { - track_data() noexcept = default; - boost::optional<sampling_info> sampling; boost::optional<double> average_loudness; // range (0, 1] boost::optional<musical_key> key; - std::vector<char> encode() const; + track_data() noexcept = default; + + friend bool operator==( + const track_data& first, const track_data& second) noexcept + { + return first.sampling == second.sampling && + first.average_loudness == second.average_loudness && + first.key == second.key; + } + std::vector<char> encode() const; static track_data decode(const std::vector<char>& compressed_data); }; |