use libtag duration where available
This commit is contained in:
@@ -112,17 +112,13 @@ int CmdPlayFile(int argc, char** argv) {
|
||||
database::TrackId id = std::atoi(argv[1]);
|
||||
AppConsole::sTrackQueue->AddLast(id);
|
||||
} else {
|
||||
// TODO.
|
||||
/*
|
||||
std::ostringstream path;
|
||||
path << '/' << argv[1];
|
||||
for (int i = 2; i < argc; i++) {
|
||||
path << ' ' << argv[i];
|
||||
}
|
||||
|
||||
events::Dispatch<audio::PlayFile, audio::AudioState>(
|
||||
audio::PlayFile{.filename = path.str()});
|
||||
*/
|
||||
events::Audio().Dispatch(audio::PlayFile{.filename = path.str()});
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -93,6 +93,10 @@ void Uninitialised::react(const system_fsm::BootComplete&) {
|
||||
transit<Standby>();
|
||||
}
|
||||
|
||||
void Standby::react(const PlayFile& ev) {
|
||||
sFileSource->SetPath(ev.filename);
|
||||
}
|
||||
|
||||
void Standby::react(const internal::InputFileOpened& ev) {
|
||||
transit<Playback>();
|
||||
}
|
||||
@@ -161,6 +165,9 @@ void Playback::react(const internal::InputFileClosed& ev) {}
|
||||
void Playback::react(const internal::InputFileFinished& ev) {
|
||||
ESP_LOGI(kTag, "finished playing file");
|
||||
sTrackQueue->Next();
|
||||
if (!sTrackQueue->GetCurrent()) {
|
||||
transit<Standby>();
|
||||
}
|
||||
}
|
||||
|
||||
void Playback::react(const internal::AudioPipelineIdle& ev) {
|
||||
|
||||
@@ -61,10 +61,12 @@ Timer::Timer(StreamInfo::Pcm format)
|
||||
|
||||
auto Timer::SetLengthSeconds(uint32_t len) -> void {
|
||||
total_duration_seconds_ = len;
|
||||
has_duration_ = true;
|
||||
}
|
||||
|
||||
auto Timer::SetLengthBytes(uint32_t len) -> void {
|
||||
total_duration_seconds_ = bytes_to_samples(len) / format_.sample_rate;
|
||||
has_duration_ = true;
|
||||
}
|
||||
|
||||
auto Timer::AddBytes(std::size_t bytes) -> void {
|
||||
@@ -135,8 +137,14 @@ void AudioTask::Main() {
|
||||
if (ForwardPcmStream(*pcm, stream.data())) {
|
||||
stream.consume(stream.data().size_bytes());
|
||||
}
|
||||
timer_->SetLengthBytes(
|
||||
stream.info().total_length_bytes().value_or(0));
|
||||
if (!timer_->has_duration()) {
|
||||
if (stream.info().total_length_seconds()) {
|
||||
timer_->SetLengthSeconds(*stream.info().total_length_seconds());
|
||||
} else {
|
||||
timer_->SetLengthBytes(
|
||||
stream.info().total_length_bytes().value_or(0));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,6 +241,8 @@ auto AudioTask::BeginDecoding(InputStream& stream) -> bool {
|
||||
|
||||
if (format.duration_seconds) {
|
||||
timer_->SetLengthSeconds(*format.duration_seconds);
|
||||
} else if (stream.info().total_length_seconds()) {
|
||||
timer_->SetLengthSeconds(*stream.info().total_length_seconds());
|
||||
} else {
|
||||
timer_->SetLengthBytes(stream.info().total_length_bytes().value_or(0));
|
||||
}
|
||||
|
||||
@@ -283,6 +283,9 @@ auto FatfsAudioInput::OpenFile(const std::string& path) -> void {
|
||||
|
||||
OutputStream writer{input_buffer_.get()};
|
||||
writer.prepare(format, info.fsize);
|
||||
if (tags.duration) {
|
||||
writer.info().total_length_seconds() = *tags.duration;
|
||||
}
|
||||
|
||||
streamer_->Restart(std::move(file));
|
||||
is_first_read_ = true;
|
||||
|
||||
@@ -30,6 +30,10 @@ struct QueueUpdate : tinyfsm::Event {
|
||||
bool current_changed;
|
||||
};
|
||||
|
||||
struct PlayFile : tinyfsm::Event {
|
||||
std::string filename;
|
||||
};
|
||||
|
||||
struct VolumeChanged : tinyfsm::Event {};
|
||||
|
||||
namespace internal {
|
||||
|
||||
@@ -51,6 +51,7 @@ class AudioState : public tinyfsm::Fsm<AudioState> {
|
||||
|
||||
virtual void react(const system_fsm::BootComplete&) {}
|
||||
|
||||
virtual void react(const PlayFile&) {}
|
||||
virtual void react(const QueueUpdate&) {}
|
||||
virtual void react(const PlaybackUpdate&) {}
|
||||
|
||||
@@ -82,6 +83,7 @@ class Uninitialised : public AudioState {
|
||||
|
||||
class Standby : public AudioState {
|
||||
public:
|
||||
void react(const PlayFile&) override;
|
||||
void react(const internal::InputFileOpened&) override;
|
||||
void react(const QueueUpdate&) override;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ class Timer {
|
||||
auto SetLengthBytes(uint32_t) -> void;
|
||||
|
||||
auto AddBytes(std::size_t) -> void;
|
||||
auto has_duration() const -> bool { return has_duration_; }
|
||||
|
||||
private:
|
||||
auto bytes_to_samples(uint32_t) -> uint32_t;
|
||||
@@ -35,6 +36,7 @@ class Timer {
|
||||
uint32_t current_seconds_;
|
||||
uint32_t current_sample_in_second_;
|
||||
|
||||
bool has_duration_;
|
||||
uint32_t total_duration_seconds_;
|
||||
};
|
||||
|
||||
|
||||
@@ -42,6 +42,13 @@ class StreamInfo {
|
||||
return total_length_bytes_;
|
||||
}
|
||||
|
||||
auto total_length_seconds() -> std::optional<std::uint32_t>& {
|
||||
return total_length_seconds_;
|
||||
}
|
||||
auto total_length_seconds() const -> std::optional<std::uint32_t> {
|
||||
return total_length_seconds_;
|
||||
}
|
||||
|
||||
struct Encoded {
|
||||
// The codec that this stream is associated with.
|
||||
codecs::StreamType type;
|
||||
@@ -77,6 +84,7 @@ class StreamInfo {
|
||||
private:
|
||||
std::size_t bytes_in_stream_;
|
||||
std::optional<std::uint32_t> total_length_bytes_;
|
||||
std::optional<std::uint32_t> total_length_seconds_;
|
||||
Format format_{};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user