diff --git a/src/codecs/dr_flac.cpp b/src/codecs/dr_flac.cpp index cacf7a6e..2f9acf8c 100644 --- a/src/codecs/dr_flac.cpp +++ b/src/codecs/dr_flac.cpp @@ -112,8 +112,4 @@ auto DrFlacDecoder::DecodeTo(cpp::span output) .is_stream_finished = frames_written < frames_to_read}; } -auto DrFlacDecoder::SeekTo(size_t target) -> cpp::result { - return {}; -} - } // namespace codecs diff --git a/src/codecs/include/codec.hpp b/src/codecs/include/codec.hpp index fb1ec771..e48e3c58 100644 --- a/src/codecs/include/codec.hpp +++ b/src/codecs/include/codec.hpp @@ -130,8 +130,6 @@ class ICodec { */ virtual auto DecodeTo(cpp::span destination) -> cpp::result = 0; - - virtual auto SeekTo(size_t target_sample) -> cpp::result = 0; }; auto CreateCodecForType(StreamType type) -> std::optional; diff --git a/src/codecs/include/dr_flac.hpp b/src/codecs/include/dr_flac.hpp index 8dcfdaf5..547876f4 100644 --- a/src/codecs/include/dr_flac.hpp +++ b/src/codecs/include/dr_flac.hpp @@ -33,8 +33,6 @@ class DrFlacDecoder : public ICodec { auto DecodeTo(cpp::span destination) -> cpp::result override; - auto SeekTo(std::size_t target_sample) -> cpp::result override; - DrFlacDecoder(const DrFlacDecoder&) = delete; DrFlacDecoder& operator=(const DrFlacDecoder&) = delete; diff --git a/src/codecs/include/mad.hpp b/src/codecs/include/mad.hpp index 35e3284d..ead0b2a2 100644 --- a/src/codecs/include/mad.hpp +++ b/src/codecs/include/mad.hpp @@ -32,8 +32,6 @@ class MadMp3Decoder : public ICodec { auto DecodeTo(cpp::span destination) -> cpp::result override; - auto SeekTo(std::size_t target_sample) -> cpp::result override; - MadMp3Decoder(const MadMp3Decoder&) = delete; MadMp3Decoder& operator=(const MadMp3Decoder&) = delete; diff --git a/src/codecs/include/opus.hpp b/src/codecs/include/opus.hpp index 1431fa54..de2f7131 100644 --- a/src/codecs/include/opus.hpp +++ b/src/codecs/include/opus.hpp @@ -32,8 +32,6 @@ class XiphOpusDecoder : public ICodec { auto DecodeTo(cpp::span destination) -> cpp::result override; - auto SeekTo(std::size_t target_sample) -> cpp::result override; - XiphOpusDecoder(const XiphOpusDecoder&) = delete; XiphOpusDecoder& operator=(const XiphOpusDecoder&) = delete; diff --git a/src/codecs/include/vorbis.hpp b/src/codecs/include/vorbis.hpp index 94868c1a..3cf0f9ce 100644 --- a/src/codecs/include/vorbis.hpp +++ b/src/codecs/include/vorbis.hpp @@ -32,8 +32,6 @@ class TremorVorbisDecoder : public ICodec { auto DecodeTo(cpp::span destination) -> cpp::result override; - auto SeekTo(std::size_t target_sample) -> cpp::result override; - TremorVorbisDecoder(const TremorVorbisDecoder&) = delete; TremorVorbisDecoder& operator=(const TremorVorbisDecoder&) = delete; diff --git a/src/codecs/include/wav.hpp b/src/codecs/include/wav.hpp index e884a9bb..40138968 100644 --- a/src/codecs/include/wav.hpp +++ b/src/codecs/include/wav.hpp @@ -37,8 +37,6 @@ class WavDecoder : public ICodec { auto DecodeTo(cpp::span destination) -> cpp::result override; - auto SeekTo(std::size_t target_sample) -> cpp::result override; - WavDecoder(const WavDecoder&) = delete; WavDecoder& operator=(const WavDecoder&) = delete; diff --git a/src/codecs/mad.cpp b/src/codecs/mad.cpp index b11821f0..e44e9922 100644 --- a/src/codecs/mad.cpp +++ b/src/codecs/mad.cpp @@ -230,11 +230,6 @@ auto MadMp3Decoder::DecodeTo(cpp::span output) .is_stream_finished = is_eos_}; } -auto MadMp3Decoder::SeekTo(std::size_t target_sample) - -> cpp::result { - return {}; -} - auto MadMp3Decoder::SkipID3Tags(IStream& stream) -> void { // First check that the file actually does start with ID3 tags. std::array magic_buf{}; diff --git a/src/codecs/miniflac copy.cpp b/src/codecs/miniflac copy.cpp deleted file mode 100644 index 866cb49b..00000000 --- a/src/codecs/miniflac copy.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2023 jacqueline - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#include "miniflac.hpp" - -#include -#include - -#include "esp_heap_caps.h" -#include "esp_log.h" -#include "miniflac.h" -#include "result.hpp" -#include "sample.hpp" - -namespace codecs { - -[[maybe_unused]] static const char kTag[] = "flac"; - -static constexpr size_t kMaxFrameSize = 4608; - -MiniFlacDecoder::MiniFlacDecoder() - : input_(), - buffer_(), - flac_(reinterpret_cast( - heap_caps_malloc(sizeof(miniflac_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT))), - current_sample_() { - miniflac_init(flac_.get(), MINIFLAC_CONTAINER_UNKNOWN); - for (int i = 0; i < samples_by_channel_.size(); i++) { - uint32_t caps; - if (i == 0) { - caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL; - } else { - // FIXME: We can *almost* fit two channels into internal ram, but we're a - // few KiB shy of being able to do it safely. - caps = MALLOC_CAP_SPIRAM; - } - samples_by_channel_[i] = reinterpret_cast( - heap_caps_malloc(kMaxFrameSize * sizeof(int32_t), caps)); - } -} - -MiniFlacDecoder::~MiniFlacDecoder() { - for (int i = 0; i < samples_by_channel_.size(); i++) { - heap_caps_free(samples_by_channel_[i]); - } -} - -auto MiniFlacDecoder::OpenStream(std::shared_ptr input,uint32_t offset) - -> cpp::result { - input_ = input; - - MINIFLAC_RESULT res; - auto read_until_result = [&](auto fn) { - while (true) { - bool eof = buffer_.Refill(input_.get()); - buffer_.ConsumeBytes(fn); - if (res == MINIFLAC_CONTINUE && !eof) { - continue; - } - break; - } - }; - - uint32_t sample_rate = 0; - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_sample_rate( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &sample_rate); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - uint8_t channels = 0; - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_channels( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &channels); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - uint64_t total_samples = 0; - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_total_samples( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &total_samples); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - if (channels == 0 || channels > 2) { - return cpp::fail(Error::kMalformedData); - } - - if (offset) { - uint64_t samples_count = 0; - uint32_t offset_count = 0; - while (offset_count < offset) { - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_sync( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used); - return bytes_used; - }); - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - uint32_t frame_samplerate = flac_.get()->frame.header.sample_rate; - uint16_t frame_blocksize = flac_.get()->frame.header.block_size; - if (!frame_samplerate || !frame_blocksize) { - continue; - } - - samples_count += frame_blocksize; - offset_count = samples_count / sample_rate; - } - } - - OutputFormat format{ - .num_channels = static_cast(channels), - .sample_rate_hz = static_cast(sample_rate), - .total_samples = total_samples * channels, - }; - - return format; -} - -auto MiniFlacDecoder::DecodeTo(cpp::span output) - -> cpp::result { - bool is_eof = false; - - if (!current_sample_) { - MINIFLAC_RESULT res = MINIFLAC_CONTINUE; - while (res == MINIFLAC_CONTINUE && !is_eof) { - is_eof = buffer_.Refill(input_.get()); - buffer_.ConsumeBytes([&](cpp::span buf) -> size_t { - // FIXME: We should do a miniflac_sync first, in order to check that - // our sample buffers have enough space for the next frame. - uint32_t bytes_read = 0; - res = miniflac_decode( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_read, samples_by_channel_.data()); - return bytes_read; - }); - } - - if (res == MINIFLAC_OK) { - current_sample_ = 0; - } else if (is_eof) { - return OutputInfo{ - .samples_written = 0, - .is_stream_finished = true, - }; - } else { - return cpp::fail(Error::kMalformedData); - } - } - - size_t samples_written = 0; - if (current_sample_) { - while (*current_sample_ < flac_->frame.header.block_size) { - if (samples_written + flac_->frame.header.channels >= output.size()) { - // We can't fit the next full PCM frame into the buffer. - return OutputInfo{.samples_written = samples_written, - .is_stream_finished = false}; - } - - for (int channel = 0; channel < flac_->frame.header.channels; channel++) { - output[samples_written++] = - sample::FromSigned(samples_by_channel_[channel][*current_sample_], - flac_->frame.header.bps); - } - (*current_sample_)++; - } - } - - current_sample_.reset(); - return OutputInfo{.samples_written = samples_written, - .is_stream_finished = samples_written == 0 && is_eof}; -} - -auto MiniFlacDecoder::SeekTo(size_t target) -> cpp::result { - return {}; -} - -} // namespace codecs diff --git a/src/codecs/miniflac.cpp.bak2 b/src/codecs/miniflac.cpp.bak2 deleted file mode 100644 index 843c3003..00000000 --- a/src/codecs/miniflac.cpp.bak2 +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2023 jacqueline - * - * SPDX-License-Identifier: GPL-3.0-only - */ - -#include "miniflac.hpp" - -#include -#include - -#include "esp_heap_caps.h" -#include "esp_log.h" -#include "miniflac.h" -#include "result.hpp" -#include "sample.hpp" - -namespace codecs { - -[[maybe_unused]] static const char kTag[] = "flac"; - -static constexpr size_t kMaxFrameSize = 4608; - -MiniFlacDecoder::MiniFlacDecoder() - : input_(), - buffer_(), - flac_(reinterpret_cast( - heap_caps_malloc(sizeof(miniflac_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT))), - current_sample_() { - miniflac_init(flac_.get(), MINIFLAC_CONTAINER_UNKNOWN); - for (int i = 0; i < samples_by_channel_.size(); i++) { - uint32_t caps; - if (i == 0) { - caps = MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL; - } else { - // FIXME: We can *almost* fit two channels into internal ram, but we're a - // few KiB shy of being able to do it safely. - caps = MALLOC_CAP_SPIRAM; - } - samples_by_channel_[i] = reinterpret_cast( - heap_caps_malloc(kMaxFrameSize * sizeof(int32_t), caps)); - } -} - -MiniFlacDecoder::~MiniFlacDecoder() { - for (int i = 0; i < samples_by_channel_.size(); i++) { - heap_caps_free(samples_by_channel_[i]); - } -} - -auto MiniFlacDecoder::OpenStream(std::shared_ptr input,uint32_t offset) - -> cpp::result { - input_ = input; - - MINIFLAC_RESULT res; - bool is_eof; - auto read_until_result = [&](auto fn) { - while (true) { - is_eof = buffer_.Refill(input_.get()); - buffer_.ConsumeBytes(fn); - if (res == MINIFLAC_CONTINUE && !eof) { - continue; - } - break; - } - }; - - uint16_t min_block_size = 0; // In samples - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_min_block_size( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &min_block_size); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - uint16_t max_block_size = 0; // In samples - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_min_block_size( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &max_block_size); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - ESP_LOGI(kTag, "Blocksize min: %u max %u", min_block_size, max_block_size); - - uint32_t sample_rate = 0; - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_sample_rate( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &sample_rate); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - uint8_t channels = 0; - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_channels( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &channels); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - uint64_t total_samples = 0; - - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_streaminfo_total_samples( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used, &total_samples); - return bytes_used; - }); - - if (res != MINIFLAC_OK) { - return cpp::fail(Error::kMalformedData); - } - - if (channels == 0 || channels > 2) { - return cpp::fail(Error::kMalformedData); - } - - // Seeking - offset = 0; - if (offset) { - // Super dumb approach, but lets try it first - // Go to the first frame - while(flac_.get()->state == MINIFLAC_METADATA) { - read_until_result([&](cpp::span buf) -> size_t { - uint32_t bytes_used = 0; - res = miniflac_sync( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_used); - return bytes_used; - }); - if (res != MINIFLAC_OK) { - ESP_LOGI(kTag, "IT HAPPENED"); - } - } - ESP_LOGI(kTag, "Flac state: %d", flac_->state); - - // Naive approach - uint64_t byte_offset = offset; // TODO - - ESP_LOGI(kTag, "Going to skip forward %llu bytes", byte_offset); - if (input_.get()->CanSeek()) { - ESP_LOGI(kTag, "Skipping forward %llu bytes", byte_offset); - buffer_.Empty(); - input_.get()->SeekTo(byte_offset, IStream::SeekFrom::kCurrentPosition); - } - // buffer_.Refill(input_.get()); - - // // Sync again - // read_until_result([&](cpp::span buf) -> size_t { - // uint32_t bytes_used = 0; - // res = miniflac_sync( - // flac_.get(), reinterpret_cast(buf.data()), - // buf.size_bytes(), &bytes_used); - // return bytes_used; - // }); - // if (res != MINIFLAC_OK) { - // ESP_LOGI(kTag, "IT HAPPENED HERE! %d", res); - // } - - // ESP_LOGI(kTag, "Decoder state: %d", flac_->state); - // ESP_LOGI(kTag, "Frame header state: %d", flac_->frame.header.state); - - // // TODO: Sample number is not guaranteed, could be block index. - // ESP_LOGI(kTag, "Ended up... at sample %llu", flac_->frame.header.sample_number); - // ESP_LOGI(kTag, "and block index: %lu", flac_->frame.header.frame_number); - // ESP_LOGI(kTag, "total samples: %llu", total_samples); - } - - - OutputFormat format{ - .num_channels = static_cast(channels), - .sample_rate_hz = static_cast(sample_rate), - .total_samples = total_samples * channels, - }; - - return format; -} - -auto MiniFlacDecoder::DecodeTo(cpp::span output) - -> cpp::result { - bool is_eof = false; - - if (!current_sample_) { - MINIFLAC_RESULT res = MINIFLAC_CONTINUE; - while (res == MINIFLAC_CONTINUE && !is_eof) { - is_eof = buffer_.Refill(input_.get()); - ESP_LOGI(kTag, "EOF? %s", is_eof ? "true" : "false"); - buffer_.ConsumeBytes([&](cpp::span buf) -> size_t { - // FIXME: We should do a miniflac_sync first, in order to check that - // our sample buffers have enough space for the next frame. - uint32_t bytes_read = 0; - res = miniflac_decode( - flac_.get(), reinterpret_cast(buf.data()), - buf.size_bytes(), &bytes_read, samples_by_channel_.data()); - return bytes_read; - }); - } - - if (res == MINIFLAC_OK) { - current_sample_ = 0; - } else if (is_eof) { - return OutputInfo{ - .samples_written = 0, - .is_stream_finished = true, - }; - } else { - ESP_LOGI(kTag, "Failed: decoder result: %d", res); - return cpp::fail(Error::kMalformedData); - } - } - - size_t samples_written = 0; - if (current_sample_) { - while (*current_sample_ < flac_->frame.header.block_size) { - if (samples_written + flac_->frame.header.channels >= output.size()) { - // We can't fit the next full PCM frame into the buffer. - return OutputInfo{.samples_written = samples_written, - .is_stream_finished = false}; - } - - for (int channel = 0; channel < flac_->frame.header.channels; channel++) { - output[samples_written++] = - sample::FromSigned(samples_by_channel_[channel][*current_sample_], - flac_->frame.header.bps); - } - (*current_sample_)++; - } - } - - current_sample_.reset(); - ESP_LOGI(kTag, "Samples written %lu", (uint32_t)samples_written); - return OutputInfo{.samples_written = samples_written, - .is_stream_finished = samples_written == 0 && is_eof}; -} - -auto MiniFlacDecoder::SeekTo(size_t target) -> cpp::result { - return {}; -} - -} // namespace codecs diff --git a/src/codecs/opus.cpp b/src/codecs/opus.cpp index ec587bc7..a5220c4b 100644 --- a/src/codecs/opus.cpp +++ b/src/codecs/opus.cpp @@ -78,7 +78,8 @@ XiphOpusDecoder::~XiphOpusDecoder() { } } -auto XiphOpusDecoder::OpenStream(std::shared_ptr input,uint32_t offset) +auto XiphOpusDecoder::OpenStream(std::shared_ptr input, + uint32_t offset) -> cpp::result { input_ = input; @@ -128,8 +129,8 @@ auto XiphOpusDecoder::OpenStream(std::shared_ptr input,uint32_t offset) length = l * 2; } - if (offset) { - SeekTo(offset * 48000); + if (offset && op_pcm_seek(opus_, offset * 48000) != 0) { + return cpp::fail(Error::kInternalError); } return OutputFormat{ @@ -155,11 +156,4 @@ auto XiphOpusDecoder::DecodeTo(cpp::span output) }; } -auto XiphOpusDecoder::SeekTo(size_t target) -> cpp::result { - if (op_pcm_seek(opus_, target) != 0) { - return cpp::fail(Error::kInternalError); - } - return {}; -} - } // namespace codecs diff --git a/src/codecs/vorbis.cpp b/src/codecs/vorbis.cpp index ada92fb6..9131451b 100644 --- a/src/codecs/vorbis.cpp +++ b/src/codecs/vorbis.cpp @@ -77,7 +77,8 @@ TremorVorbisDecoder::~TremorVorbisDecoder() { ov_clear(vorbis_.get()); } -auto TremorVorbisDecoder::OpenStream(std::shared_ptr input,uint32_t offset) +auto TremorVorbisDecoder::OpenStream(std::shared_ptr input, + uint32_t offset) -> cpp::result { int res = ov_open_callbacks(input.get(), vorbis_.get(), NULL, 0, kCallbacks); if (res < 0) { @@ -117,8 +118,8 @@ auto TremorVorbisDecoder::OpenStream(std::shared_ptr input,uint32_t off length = l * info->channels; } - if (offset) { - ov_time_seek(vorbis_.get(), offset*1000); + if (offset && ov_time_seek(vorbis_.get(), offset * 1000) != 0) { + return cpp::fail(Error::kInternalError); } return OutputFormat{ @@ -149,11 +150,4 @@ auto TremorVorbisDecoder::DecodeTo(cpp::span output) }; } -auto TremorVorbisDecoder::SeekTo(size_t target) -> cpp::result { - if (ov_pcm_seek(vorbis_.get(), target) != 0) { - return cpp::fail(Error::kInternalError); - } - return {}; -} - } // namespace codecs diff --git a/src/codecs/wav.cpp b/src/codecs/wav.cpp index 5dd6f031..143a7a4b 100644 --- a/src/codecs/wav.cpp +++ b/src/codecs/wav.cpp @@ -248,10 +248,6 @@ auto WavDecoder::DecodeTo(cpp::span output) .is_stream_finished = samples_written == 0 && is_eof}; } -auto WavDecoder::SeekTo(size_t target) -> cpp::result { - return {}; -} - auto codecs::WavDecoder::GetFormat() const -> uint16_t { if (wave_format_ == kWaveFormatExtensible) { return subformat_;