Remove unused 'SeekTo' method on codecs

custom
jacqueline 1 year ago
parent 7d3ddac0ea
commit e7e6c70fb3
  1. 4
      src/codecs/dr_flac.cpp
  2. 2
      src/codecs/include/codec.hpp
  3. 2
      src/codecs/include/dr_flac.hpp
  4. 2
      src/codecs/include/mad.hpp
  5. 2
      src/codecs/include/opus.hpp
  6. 2
      src/codecs/include/vorbis.hpp
  7. 2
      src/codecs/include/wav.hpp
  8. 5
      src/codecs/mad.cpp
  9. 207
      src/codecs/miniflac copy.cpp
  10. 266
      src/codecs/miniflac.cpp.bak2
  11. 14
      src/codecs/opus.cpp
  12. 14
      src/codecs/vorbis.cpp
  13. 4
      src/codecs/wav.cpp

@ -112,8 +112,4 @@ auto DrFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
.is_stream_finished = frames_written < frames_to_read};
}
auto DrFlacDecoder::SeekTo(size_t target) -> cpp::result<void, Error> {
return {};
}
} // namespace codecs

@ -130,8 +130,6 @@ class ICodec {
*/
virtual auto DecodeTo(cpp::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> = 0;
virtual auto SeekTo(size_t target_sample) -> cpp::result<void, Error> = 0;
};
auto CreateCodecForType(StreamType type) -> std::optional<ICodec*>;

@ -33,8 +33,6 @@ class DrFlacDecoder : public ICodec {
auto DecodeTo(cpp::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
auto SeekTo(std::size_t target_sample) -> cpp::result<void, Error> override;
DrFlacDecoder(const DrFlacDecoder&) = delete;
DrFlacDecoder& operator=(const DrFlacDecoder&) = delete;

@ -32,8 +32,6 @@ class MadMp3Decoder : public ICodec {
auto DecodeTo(cpp::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
auto SeekTo(std::size_t target_sample) -> cpp::result<void, Error> override;
MadMp3Decoder(const MadMp3Decoder&) = delete;
MadMp3Decoder& operator=(const MadMp3Decoder&) = delete;

@ -32,8 +32,6 @@ class XiphOpusDecoder : public ICodec {
auto DecodeTo(cpp::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
auto SeekTo(std::size_t target_sample) -> cpp::result<void, Error> override;
XiphOpusDecoder(const XiphOpusDecoder&) = delete;
XiphOpusDecoder& operator=(const XiphOpusDecoder&) = delete;

@ -32,8 +32,6 @@ class TremorVorbisDecoder : public ICodec {
auto DecodeTo(cpp::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
auto SeekTo(std::size_t target_sample) -> cpp::result<void, Error> override;
TremorVorbisDecoder(const TremorVorbisDecoder&) = delete;
TremorVorbisDecoder& operator=(const TremorVorbisDecoder&) = delete;

@ -37,8 +37,6 @@ class WavDecoder : public ICodec {
auto DecodeTo(cpp::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
auto SeekTo(std::size_t target_sample) -> cpp::result<void, Error> override;
WavDecoder(const WavDecoder&) = delete;
WavDecoder& operator=(const WavDecoder&) = delete;

@ -230,11 +230,6 @@ auto MadMp3Decoder::DecodeTo(cpp::span<sample::Sample> output)
.is_stream_finished = is_eos_};
}
auto MadMp3Decoder::SeekTo(std::size_t target_sample)
-> cpp::result<void, Error> {
return {};
}
auto MadMp3Decoder::SkipID3Tags(IStream& stream) -> void {
// First check that the file actually does start with ID3 tags.
std::array<std::byte, 3> magic_buf{};

@ -1,207 +0,0 @@
/*
* Copyright 2023 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "miniflac.hpp"
#include <cstdint>
#include <cstdlib>
#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<miniflac_t*>(
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<int32_t*>(
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<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> {
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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_sample_rate(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_channels(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_total_samples(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_sync(
flac_.get(), reinterpret_cast<const uint8_t*>(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<uint8_t>(channels),
.sample_rate_hz = static_cast<uint32_t>(sample_rate),
.total_samples = total_samples * channels,
};
return format;
}
auto MiniFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
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<std::byte> 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<const uint8_t*>(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<void, Error> {
return {};
}
} // namespace codecs

@ -1,266 +0,0 @@
/*
* Copyright 2023 jacqueline <me@jacqueline.id.au>
*
* SPDX-License-Identifier: GPL-3.0-only
*/
#include "miniflac.hpp"
#include <cstdint>
#include <cstdlib>
#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<miniflac_t*>(
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<int32_t*>(
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<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> {
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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_min_block_size(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_min_block_size(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_sample_rate(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_channels(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_streaminfo_total_samples(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
uint32_t bytes_used = 0;
res = miniflac_sync(
flac_.get(), reinterpret_cast<const uint8_t*>(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<std::byte> buf) -> size_t {
// uint32_t bytes_used = 0;
// res = miniflac_sync(
// flac_.get(), reinterpret_cast<const uint8_t*>(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<uint8_t>(channels),
.sample_rate_hz = static_cast<uint32_t>(sample_rate),
.total_samples = total_samples * channels,
};
return format;
}
auto MiniFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
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<std::byte> 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<const uint8_t*>(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<void, Error> {
return {};
}
} // namespace codecs

@ -78,7 +78,8 @@ XiphOpusDecoder::~XiphOpusDecoder() {
}
}
auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> input,
uint32_t offset)
-> cpp::result<OutputFormat, Error> {
input_ = input;
@ -128,8 +129,8 @@ auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> 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<sample::Sample> output)
};
}
auto XiphOpusDecoder::SeekTo(size_t target) -> cpp::result<void, Error> {
if (op_pcm_seek(opus_, target) != 0) {
return cpp::fail(Error::kInternalError);
}
return {};
}
} // namespace codecs

@ -77,7 +77,8 @@ TremorVorbisDecoder::~TremorVorbisDecoder() {
ov_clear(vorbis_.get());
}
auto TremorVorbisDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
auto TremorVorbisDecoder::OpenStream(std::shared_ptr<IStream> input,
uint32_t offset)
-> cpp::result<OutputFormat, Error> {
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<IStream> 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<sample::Sample> output)
};
}
auto TremorVorbisDecoder::SeekTo(size_t target) -> cpp::result<void, Error> {
if (ov_pcm_seek(vorbis_.get(), target) != 0) {
return cpp::fail(Error::kInternalError);
}
return {};
}
} // namespace codecs

@ -248,10 +248,6 @@ auto WavDecoder::DecodeTo(cpp::span<sample::Sample> output)
.is_stream_finished = samples_written == 0 && is_eof};
}
auto WavDecoder::SeekTo(size_t target) -> cpp::result<void, Error> {
return {};
}
auto codecs::WavDecoder::GetFormat() const -> uint16_t {
if (wave_format_ == kWaveFormatExtensible) {
return subformat_;

Loading…
Cancel
Save