summaryrefslogtreecommitdiff
path: root/src/codecs/miniflac.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codecs/miniflac.cpp')
-rw-r--r--src/codecs/miniflac.cpp130
1 files changed, 129 insertions, 1 deletions
diff --git a/src/codecs/miniflac.cpp b/src/codecs/miniflac.cpp
index d0b40f96..8ec12df5 100644
--- a/src/codecs/miniflac.cpp
+++ b/src/codecs/miniflac.cpp
@@ -111,6 +111,131 @@ auto MiniFlacDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
return cpp::fail(Error::kMalformedData);
}
+ // Seeking
+ offset = 50;
+ if (offset) {
+ // TODO: This assumes a constant sample_rate
+ uint64_t target_sample = sample_rate * offset;
+ uint32_t num_seekpoints;
+ read_until_result([&](cpp::span<std::byte> buf) -> size_t {
+ uint32_t bytes_used = 0;
+ res = miniflac_seektable_seekpoints(
+ flac_.get(), reinterpret_cast<const uint8_t*>(buf.data()),
+ buf.size_bytes(), &bytes_used, &num_seekpoints);
+ return bytes_used;
+ });
+ if (res != MINIFLAC_OK) {
+ // TODO: Not having a seektable is not malformed
+ // but currently seeking will not work without it.
+ return cpp::fail(Error::kMalformedData);
+ }
+ // Loop over the seek table
+ ESP_LOGI(kTag, "Found seektable with %lu points", num_seekpoints);
+ uint64_t sample_number;
+ uint64_t sample_offset_bytes;
+ uint16_t num_samples_in_target;
+ for (uint32_t i = 0; i < num_seekpoints; i++) {
+ // Get sample number
+ read_until_result([&](cpp::span<std::byte> buf) -> size_t {
+ uint32_t bytes_used = 0;
+ res = miniflac_seektable_sample_number(
+ flac_.get(), reinterpret_cast<const uint8_t*>(buf.data()),
+ buf.size_bytes(), &bytes_used, &sample_number);
+ return bytes_used;
+ });
+ if (res != MINIFLAC_OK) {
+ return cpp::fail(Error::kMalformedData);
+ }
+ read_until_result([&](cpp::span<std::byte> buf) -> size_t {
+ uint32_t bytes_used = 0;
+ res = miniflac_seektable_sample_offset(
+ flac_.get(), reinterpret_cast<const uint8_t*>(buf.data()),
+ buf.size_bytes(), &bytes_used, &sample_offset_bytes);
+ return bytes_used;
+ });
+ if (res != MINIFLAC_OK) {
+ return cpp::fail(Error::kMalformedData);
+ }
+ read_until_result([&](cpp::span<std::byte> buf) -> size_t {
+ uint32_t bytes_used = 0;
+ res = miniflac_seektable_samples(
+ flac_.get(), reinterpret_cast<const uint8_t*>(buf.data()),
+ buf.size_bytes(), &bytes_used, &num_samples_in_target);
+ return bytes_used;
+ });
+ if (res != MINIFLAC_OK) {
+ return cpp::fail(Error::kMalformedData);
+ }
+
+ ESP_LOGI(kTag, "Seektable entry %lu", i);
+
+ // Check if we want to seek to this seektable position?
+ if (sample_number + num_samples_in_target >= target_sample) {
+ ESP_LOGI(kTag, "Break on Seektable entry %lu", i);
+ break;
+ }
+ }
+
+ // Seek forward to target_sample
+ if (sample_number > 0) {
+ ESP_LOGI(kTag, "total samples: %llu", total_samples);
+ ESP_LOGI(kTag, "TARGET SAMPLE: %llu", target_sample);
+ ESP_LOGI(kTag, "SAMPLE NUMBER: %llu", sample_number);
+ }
+ uint64_t byte_offset = sample_offset_bytes;
+ ESP_LOGI(kTag, "Byte offset is forward %llu bytes", byte_offset);
+ ESP_LOGI(kTag, "Decoder state pre: %d", flac_->state);
+ 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, "Decoder error 1 %d", res);
+ }
+ }
+ ESP_LOGI(kTag, "Decoder state post: %d", flac_->state);
+
+
+ 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);
+ ESP_LOGI(kTag, "Skipped %llu bytes", byte_offset);
+ }
+
+
+ ESP_LOGI(kTag, "Pre-refill");
+ buffer_.Refill(input_.get());
+ ESP_LOGI(kTag, "Post-refill");
+
+
+ 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, "Decoder error 1 %d", res);
+ }
+ ESP_LOGI(kTag, "JOB'S DONE");
+ }
+
+ 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),
@@ -128,6 +253,7 @@ auto MiniFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
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.
@@ -147,7 +273,8 @@ auto MiniFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
.is_stream_finished = true,
};
} else {
- return cpp::fail(Error::kMalformedData);
+ ESP_LOGI(kTag, "Failed: decoder result: %d", res);
+ // return cpp::fail(Error::kMalformedData);
}
}
@@ -170,6 +297,7 @@ auto MiniFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
}
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};
}