1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 19:37:34 +00:00

Piano+LibDSP: Move Track to LibDSP

This is a tangly commit and it fixes all the bugs that a plain move
would have caused (i.e. we need to touch other logic which had wrong
assumptions).
This commit is contained in:
kleines Filmröllchen 2022-07-13 12:44:19 +02:00 committed by Linus Groh
parent 125122a9ab
commit 4941cffdd0
29 changed files with 322 additions and 413 deletions

View file

@ -60,6 +60,24 @@ struct RollNote {
}
constexpr bool is_playing(u32 time) const { return on_sample <= time && time <= off_sample; }
constexpr bool is_playing_during(u32 start_time, u32 end_time) const
{
// There are three scenarios for a playing note.
return
// 1. The note ends within our time frame.
(this->off_sample >= start_time && this->off_sample < end_time)
// 2. The note starts within our time frame.
|| (this->on_sample >= start_time && this->on_sample < end_time)
// 3. The note starts before our time frame and ends after it.
|| (this->on_sample < start_time && this->off_sample >= end_time);
}
constexpr bool overlaps_with(RollNote const& other) const
{
// Notes don't overlap if one is completely before or behind the other.
return !((this->on_sample < other.on_sample && this->off_sample < other.on_sample)
|| (this->on_sample >= other.off_sample && this->off_sample >= other.off_sample));
}
};
enum class SignalType : u8 {
@ -78,26 +96,6 @@ public:
}
};
using RollNotes = OrderedHashMap<u8, RollNote, PerfectNoteHashTraits>;
struct Signal : public Variant<FixedArray<Sample>, RollNotes> {
using Variant::Variant;
AK_MAKE_NONCOPYABLE(Signal);
public:
Signal& operator=(Signal&&) = default;
Signal(Signal&&) = default;
ALWAYS_INLINE SignalType type() const
{
if (has<FixedArray<Sample>>())
return SignalType::Sample;
if (has<RollNotes>())
return SignalType::Note;
return SignalType::Invalid;
}
};
// Equal temperament, A = 440Hz
// We calculate note frequencies relative to A4:
// 440.0 * pow(pow(2.0, 1.0 / 12.0), N)
@ -196,7 +194,27 @@ constexpr Array<double, 84> note_frequencies = {
3951.0664100489994,
};
using RollNotes = Array<Optional<RollNote>, note_frequencies.size()>;
constexpr size_t const notes_per_octave = 12;
constexpr double const middle_c = note_frequencies[36];
struct Signal : public Variant<FixedArray<Sample>, RollNotes> {
using Variant::Variant;
AK_MAKE_NONCOPYABLE(Signal);
public:
Signal& operator=(Signal&&) = default;
Signal(Signal&&) = default;
ALWAYS_INLINE SignalType type() const
{
if (has<FixedArray<Sample>>())
return SignalType::Sample;
if (has<RollNotes>())
return SignalType::Note;
return SignalType::Invalid;
}
};
}