Added offset for track seeking, wav impl. only rn

custom
ailurux 1 year ago
parent e466522c25
commit 62f6179abe
  1. 11
      src/audio/audio_decoder.cpp
  2. 12
      src/audio/audio_fsm.cpp
  3. 9
      src/audio/audio_source.cpp
  4. 8
      src/audio/fatfs_audio_input.cpp
  5. 2
      src/audio/include/audio_decoder.hpp
  6. 5
      src/audio/include/audio_events.hpp
  7. 3
      src/audio/include/audio_fsm.hpp
  8. 6
      src/audio/include/audio_source.hpp
  9. 4
      src/audio/include/fatfs_audio_input.hpp
  10. 2
      src/codecs/include/codec.hpp
  11. 2
      src/codecs/include/mad.hpp
  12. 2
      src/codecs/include/miniflac.hpp
  13. 2
      src/codecs/include/opus.hpp
  14. 2
      src/codecs/include/vorbis.hpp
  15. 2
      src/codecs/include/wav.hpp
  16. 2
      src/codecs/mad.cpp
  17. 2
      src/codecs/miniflac.cpp
  18. 2
      src/codecs/opus.cpp
  19. 2
      src/codecs/vorbis.cpp
  20. 6
      src/codecs/wav.cpp

@ -51,9 +51,10 @@ static constexpr std::size_t kCodecBufferLength =
drivers::kI2SBufferLengthFrames * sizeof(sample::Sample);
Timer::Timer(std::shared_ptr<Track> t,
const codecs::ICodec::OutputFormat& format)
const codecs::ICodec::OutputFormat& format,
uint32_t current_seconds)
: track_(t),
current_seconds_(0),
current_seconds_(current_seconds),
current_sample_in_second_(0),
samples_per_second_(format.sample_rate_hz * format.num_channels),
total_duration_seconds_(format.total_samples.value_or(0) /
@ -131,7 +132,7 @@ auto Decoder::BeginDecoding(std::shared_ptr<TaggedStream> stream) -> bool {
return false;
}
auto open_res = codec_->OpenStream(stream);
auto open_res = codec_->OpenStream(stream, stream->Offset());
if (open_res.has_error()) {
ESP_LOGE(kTag, "codec failed to start: %s",
codecs::ICodec::ErrorString(open_res.error()).c_str());
@ -147,6 +148,7 @@ auto Decoder::BeginDecoding(std::shared_ptr<TaggedStream> stream) -> bool {
ESP_LOGI(kTag, "stream started ok");
events::Audio().Dispatch(internal::InputFileOpened{});
// TODO: How does this need to change?
auto tags = std::make_shared<Track>(Track{
.tags = stream->tags(),
.db_info = {},
@ -155,7 +157,8 @@ auto Decoder::BeginDecoding(std::shared_ptr<TaggedStream> stream) -> bool {
});
timer_.reset(new Timer(tags, open_res.value()));
PlaybackUpdate ev{.seconds_elapsed = 0, .track = tags};
// TODO: How does *this?* need to change?
PlaybackUpdate ev{.seconds_elapsed = stream->Offset(), .track = tags};
events::Audio().Dispatch(ev);
events::Ui().Dispatch(ev);

@ -244,11 +244,19 @@ void Uninitialised::react(const system_fsm::BootComplete& ev) {
}
void Standby::react(const PlayFile& ev) {
sFileSource->SetPath(ev.filename);
sFileSource->SetPath(ev.filename, 10);
}
void Playback::react(const PlayFile& ev) {
sFileSource->SetPath(ev.filename);
sFileSource->SetPath(ev.filename, 15);
}
void Standby::react(const SeekFile& ev) {
sFileSource->SetPath(ev.filename, ev.offset);
}
void Playback::react(const SeekFile& ev) {
sFileSource->SetPath(ev.filename, ev.offset);
}
void Standby::react(const internal::InputFileOpened& ev) {

@ -11,8 +11,9 @@
namespace audio {
TaggedStream::TaggedStream(std::shared_ptr<database::TrackTags> t,
std::unique_ptr<codecs::IStream> w)
: codecs::IStream(w->type()), tags_(t), wrapped_(std::move(w)) {}
std::unique_ptr<codecs::IStream> w,
uint32_t offset)
: codecs::IStream(w->type()), tags_(t), wrapped_(std::move(w)), offset_(offset) {}
auto TaggedStream::tags() -> std::shared_ptr<database::TrackTags> {
return tags_;
@ -38,6 +39,10 @@ auto TaggedStream::Size() -> std::optional<int64_t> {
return wrapped_->Size();
}
auto TaggedStream::Offset() -> uint32_t {
return offset_;
}
auto TaggedStream::SetPreambleFinished() -> void {
wrapped_->SetPreambleFinished();
}

@ -62,9 +62,9 @@ auto FatfsAudioInput::SetPath(std::optional<std::string> path) -> void {
}
}
auto FatfsAudioInput::SetPath(const std::string& path) -> void {
auto FatfsAudioInput::SetPath(const std::string& path,uint32_t offset) -> void {
std::lock_guard<std::mutex> guard{new_stream_mutex_};
if (OpenFile(path)) {
if (OpenFile(path, offset)) {
has_new_stream_ = true;
has_new_stream_.notify_one();
}
@ -103,7 +103,7 @@ auto FatfsAudioInput::NextStream() -> std::shared_ptr<TaggedStream> {
}
}
auto FatfsAudioInput::OpenFile(const std::string& path) -> bool {
auto FatfsAudioInput::OpenFile(const std::string& path,uint32_t offset) -> bool {
ESP_LOGI(kTag, "opening file %s", path.c_str());
auto tags = tag_parser_.ReadAndParseTags(path);
@ -136,7 +136,7 @@ auto FatfsAudioInput::OpenFile(const std::string& path) -> bool {
auto source =
std::make_unique<FatfsSource>(stream_type.value(), std::move(file));
new_stream_.reset(new TaggedStream(tags, std::move(source)));
new_stream_.reset(new TaggedStream(tags, std::move(source), offset));
return true;
}

@ -24,7 +24,7 @@ namespace audio {
*/
class Timer {
public:
Timer(std::shared_ptr<Track>, const codecs::ICodec::OutputFormat& format);
Timer(std::shared_ptr<Track>, const codecs::ICodec::OutputFormat& format, uint32_t current_seconds = 0);
auto AddSamples(std::size_t) -> void;

@ -45,6 +45,11 @@ struct PlayFile : tinyfsm::Event {
std::string filename;
};
struct SeekFile : tinyfsm::Event {
std::string filename;
uint32_t offset;
};
struct StepUpVolume : tinyfsm::Event {};
struct StepDownVolume : tinyfsm::Event {};
struct SetVolume : tinyfsm::Event {

@ -57,6 +57,7 @@ class AudioState : public tinyfsm::Fsm<AudioState> {
virtual void react(const system_fsm::BluetoothEvent&);
virtual void react(const PlayFile&) {}
virtual void react(const SeekFile&) {}
virtual void react(const QueueUpdate&) {}
virtual void react(const PlaybackUpdate&) {}
void react(const TogglePlayPause&);
@ -99,6 +100,7 @@ class Uninitialised : public AudioState {
class Standby : public AudioState {
public:
void react(const PlayFile&) override;
void react(const SeekFile&) override;
void react(const internal::InputFileOpened&) override;
void react(const QueueUpdate&) override;
void react(const system_fsm::KeyLockChanged&) override;
@ -115,6 +117,7 @@ class Playback : public AudioState {
void react(const system_fsm::HasPhonesChanged&) override;
void react(const PlayFile&) override;
void react(const SeekFile&) override;
void react(const QueueUpdate&) override;
void react(const PlaybackUpdate&) override;

@ -16,7 +16,8 @@ namespace audio {
class TaggedStream : public codecs::IStream {
public:
TaggedStream(std::shared_ptr<database::TrackTags>,
std::unique_ptr<codecs::IStream> wrapped);
std::unique_ptr<codecs::IStream> wrapped,
uint32_t offset = 0);
auto tags() -> std::shared_ptr<database::TrackTags>;
@ -30,11 +31,14 @@ class TaggedStream : public codecs::IStream {
auto Size() -> std::optional<int64_t> override;
auto Offset() -> uint32_t;
auto SetPreambleFinished() -> void override;
private:
std::shared_ptr<database::TrackTags> tags_;
std::unique_ptr<codecs::IStream> wrapped_;
int32_t offset_;
};
class IAudioSource {

@ -39,7 +39,7 @@ class FatfsAudioInput : public IAudioSource {
* given file path.
*/
auto SetPath(std::optional<std::string>) -> void;
auto SetPath(const std::string&) -> void;
auto SetPath(const std::string&,uint32_t offset = 0) -> void;
auto SetPath() -> void;
auto HasNewStream() -> bool override;
@ -49,7 +49,7 @@ class FatfsAudioInput : public IAudioSource {
FatfsAudioInput& operator=(const FatfsAudioInput&) = delete;
private:
auto OpenFile(const std::string& path) -> bool;
auto OpenFile(const std::string& path,uint32_t offset) -> bool;
auto ContainerToStreamType(database::Container)
-> std::optional<codecs::StreamType>;

@ -117,7 +117,7 @@ class ICodec {
* Decodes metadata or headers from the given input stream, and returns the
* format for the samples that will be decoded from it.
*/
virtual auto OpenStream(std::shared_ptr<IStream> input)
virtual auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> = 0;
struct OutputInfo {

@ -26,7 +26,7 @@ class MadMp3Decoder : public ICodec {
MadMp3Decoder();
~MadMp3Decoder();
auto OpenStream(std::shared_ptr<IStream> input)
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)

@ -28,7 +28,7 @@ class MiniFlacDecoder : public ICodec {
MiniFlacDecoder();
~MiniFlacDecoder();
auto OpenStream(std::shared_ptr<IStream> input)
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)

@ -26,7 +26,7 @@ class XiphOpusDecoder : public ICodec {
XiphOpusDecoder();
~XiphOpusDecoder();
auto OpenStream(std::shared_ptr<IStream> input)
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)

@ -28,7 +28,7 @@ class TremorVorbisDecoder : public ICodec {
TremorVorbisDecoder();
~TremorVorbisDecoder();
auto OpenStream(std::shared_ptr<IStream> input)
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)

@ -31,7 +31,7 @@ class WavDecoder : public ICodec {
WavDecoder();
~WavDecoder();
auto OpenStream(std::shared_ptr<IStream> input)
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)

@ -58,7 +58,7 @@ auto MadMp3Decoder::GetBytesUsed() -> std::size_t {
}
}
auto MadMp3Decoder::OpenStream(std::shared_ptr<IStream> input)
auto MadMp3Decoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, ICodec::Error> {
input_ = input;

@ -42,7 +42,7 @@ MiniFlacDecoder::~MiniFlacDecoder() {
}
}
auto MiniFlacDecoder::OpenStream(std::shared_ptr<IStream> input)
auto MiniFlacDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> {
input_ = input;

@ -78,7 +78,7 @@ XiphOpusDecoder::~XiphOpusDecoder() {
}
}
auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> input)
auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> {
input_ = input;

@ -84,7 +84,7 @@ TremorVorbisDecoder::~TremorVorbisDecoder() {
ov_clear(&vorbis_);
}
auto TremorVorbisDecoder::OpenStream(std::shared_ptr<IStream> input)
auto TremorVorbisDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> {
int res = ov_open_callbacks(input.get(), &vorbis_, NULL, 0, kCallbacks);
if (res < 0) {

@ -84,7 +84,7 @@ WavDecoder::WavDecoder() : input_(), buffer_() {}
WavDecoder::~WavDecoder() {}
auto WavDecoder::OpenStream(std::shared_ptr<IStream> input)
auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> {
input_ = input;
@ -199,8 +199,10 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input)
return cpp::fail(Error::kUnsupportedFormat);
}
auto data_offset = offset * samples_per_second * bits_per_sample;
// Seek track to start of data
input->SeekTo(data_chunk_index + 8, IStream::SeekFrom::kStartOfStream);
input->SeekTo(data_chunk_index + 8 + data_offset, IStream::SeekFrom::kStartOfStream);
output_format_ = {.num_channels = (uint8_t)num_channels_,
.sample_rate_hz = samples_per_second,

Loading…
Cancel
Save