summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhaslersn <sebastian.hasler@gmx.net>2020-06-07 18:55:51 +0200
committerhaslersn <sebastian.hasler@gmx.net>2020-06-07 21:29:53 +0200
commit080d336106dd9560b3d6f4d6e9ff59fd6c6f710e (patch)
tree6c13f08bb7a3092b1604cd6626002f3bc4fe4d88
parent8d6ca822074e33f8189d22ccdab565f88e5db7b0 (diff)
enginelibrary: Check that encoded and subsequently decoded perfdata matches the original
-rw-r--r--include/djinterop/performance_data.hpp42
-rw-r--r--src/djinterop/enginelibrary/el_track_impl.cpp6
-rw-r--r--src/djinterop/enginelibrary/el_track_impl.hpp13
-rw-r--r--src/djinterop/enginelibrary/performance_data_format.hpp72
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);
};