diff options
| author | ailurux <ailuruxx@gmail.com> | 2024-02-16 17:02:54 +1100 |
|---|---|---|
| committer | ailurux <ailuruxx@gmail.com> | 2024-02-16 17:02:54 +1100 |
| commit | 19f60e33c4ba7eda86c709a8d73ca5e8ab100952 (patch) | |
| tree | 3181edfa09dc38c5cd52a07bcd3f64dfe05a4439 /src/audio/track_queue.cpp | |
| parent | 0baad11b188e7bac6b968017716186d9da0e492f (diff) | |
| parent | 4509ab8d6e341f7f7d92ac6e9d63ad822fe3441b (diff) | |
| download | tangara-fw-19f60e33c4ba7eda86c709a8d73ca5e8ab100952.tar.gz | |
Merge branch 'main' into seek-support
Diffstat (limited to 'src/audio/track_queue.cpp')
| -rw-r--r-- | src/audio/track_queue.cpp | 150 |
1 files changed, 107 insertions, 43 deletions
diff --git a/src/audio/track_queue.cpp b/src/audio/track_queue.cpp index c4c101f6..534da10c 100644 --- a/src/audio/track_queue.cpp +++ b/src/audio/track_queue.cpp @@ -33,6 +33,9 @@ namespace audio { [[maybe_unused]] static constexpr char kTag[] = "tracks"; +RandomIterator::RandomIterator() + : seed_(0), pos_(0), size_(0), replay_(false) {} + RandomIterator::RandomIterator(size_t size) : seed_(), pos_(0), size_(size), replay_(false) { esp_fill_random(&seed_, sizeof(seed_)); @@ -338,66 +341,127 @@ auto TrackQueue::serialise() -> std::string { for (database::TrackId track : tracks_) { tracks.add(cppbor::Uint(track)); } - // FIXME: this should include the RandomIterator's seed as well. - cppbor::Array encoded{ - cppbor::Uint{pos_}, - std::move(tracks), - }; + cppbor::Map encoded; + encoded.add(cppbor::Uint{0}, cppbor::Array{ + cppbor::Uint{pos_}, + cppbor::Bool{repeat_}, + cppbor::Bool{replay_}, + }); + if (shuffle_) { + encoded.add(cppbor::Uint{1}, cppbor::Array{ + cppbor::Uint{shuffle_->size()}, + cppbor::Uint{shuffle_->seed()}, + cppbor::Uint{shuffle_->pos()}, + }); + } + encoded.add(cppbor::Uint{2}, std::move(tracks)); return encoded.toString(); } -class QueueParseClient : public cppbor::ParseClient { - public: - QueueParseClient(size_t& pos, std::pmr::vector<database::TrackId>& tracks) - : pos_(pos), - tracks_(tracks), - in_root_array_(false), - in_track_list_(false) {} - - ParseClient* item(std::unique_ptr<cppbor::Item>& item, - const uint8_t* hdrBegin, - const uint8_t* valueBegin, - const uint8_t* end) override { +TrackQueue::QueueParseClient::QueueParseClient(TrackQueue& queue) + : queue_(queue), state_(State::kInit), i_(0) {} + +cppbor::ParseClient* TrackQueue::QueueParseClient::item( + std::unique_ptr<cppbor::Item>& item, + const uint8_t* hdrBegin, + const uint8_t* valueBegin, + const uint8_t* end) { + if (state_ == State::kInit) { + if (item->type() == cppbor::MAP) { + state_ = State::kRoot; + } + } else if (state_ == State::kRoot) { + if (item->type() == cppbor::UINT) { + switch (item->asUint()->unsignedValue()) { + case 0: + state_ = State::kMetadata; + break; + case 1: + state_ = State::kShuffle; + break; + case 2: + state_ = State::kTracks; + break; + default: + state_ = State::kFinished; + } + } + } else if (state_ == State::kMetadata) { if (item->type() == cppbor::ARRAY) { - if (!in_root_array_) { - in_root_array_ = true; - } else { - in_track_list_ = true; + i_ = 0; + } else if (item->type() == cppbor::UINT) { + queue_.pos_ = item->asUint()->unsignedValue(); + } else if (item->type() == cppbor::SIMPLE) { + bool val = item->asBool()->value(); + if (i_ == 0) { + queue_.repeat_ = val; + } else if (i_ == 1) { + queue_.replay_ = val; } + i_++; + } + } else if (state_ == State::kShuffle) { + if (item->type() == cppbor::ARRAY) { + i_ = 0; + queue_.shuffle_.emplace(); + queue_.shuffle_->replay(queue_.replay_); } else if (item->type() == cppbor::UINT) { auto val = item->asUint()->unsignedValue(); - if (in_track_list_) { - tracks_.push_back(val); - } else { - pos_ = static_cast<size_t>(val); + switch (i_) { + case 0: + queue_.shuffle_->size() = val; + break; + case 1: + queue_.shuffle_->seed() = val; + break; + case 2: + queue_.shuffle_->pos() = val; + break; + default: + break; } + i_++; } - return this; + } else if (state_ == State::kTracks) { + if (item->type() == cppbor::UINT) { + queue_.tracks_.push_back(item->asUint()->unsignedValue()); + } + } else if (state_ == State::kFinished) { } + return this; +} - ParseClient* itemEnd(std::unique_ptr<cppbor::Item>& item, - const uint8_t* hdrBegin, - const uint8_t* valueBegin, - const uint8_t* end) override { - return this; +cppbor::ParseClient* TrackQueue::QueueParseClient::itemEnd( + std::unique_ptr<cppbor::Item>& item, + const uint8_t* hdrBegin, + const uint8_t* valueBegin, + const uint8_t* end) { + if (state_ == State::kInit) { + state_ = State::kFinished; + } else if (state_ == State::kRoot) { + state_ = State::kFinished; + } else if (state_ == State::kMetadata) { + if (item->type() == cppbor::ARRAY) { + state_ = State::kRoot; + } + } else if (state_ == State::kShuffle) { + if (item->type() == cppbor::ARRAY) { + state_ = State::kRoot; + } + } else if (state_ == State::kTracks) { + if (item->type() == cppbor::ARRAY) { + state_ = State::kRoot; + } + } else if (state_ == State::kFinished) { } - - void error(const uint8_t* position, - const std::string& errorMessage) override {} - - private: - size_t& pos_; - std::pmr::vector<database::TrackId>& tracks_; - - bool in_root_array_; - bool in_track_list_; -}; + return this; +} auto TrackQueue::deserialise(const std::string& s) -> void { if (s.empty()) { return; } - QueueParseClient client{pos_, tracks_}; + QueueParseClient client{*this}; const uint8_t* data = reinterpret_cast<const uint8_t*>(s.data()); cppbor::parse(data, data + s.size(), &client); notifyChanged(true); |
