From 67cc09416fd63b3942bd9e61a719c7c428e19381 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 23 Aug 2014 13:52:51 +0200 Subject: [PATCH] decoder/dsf: implement seeking --- NEWS | 1 + src/decoder/plugins/DsfDecoderPlugin.cxx | 26 +++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 350206b1b..26dbce533 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,7 @@ ver 0.19 (not yet released) - audiofile: support scanning remote files - audiofile: log libaudiofile errors - dsdiff, dsf: report bit rate + - dsf: implement seeking - dsf: support DSD512 - dsf: support multi-channel files - dsf: fix big-endian bugs diff --git a/src/decoder/plugins/DsfDecoderPlugin.cxx b/src/decoder/plugins/DsfDecoderPlugin.cxx index 2e8bc4f2a..b85f7ce4f 100644 --- a/src/decoder/plugins/DsfDecoderPlugin.cxx +++ b/src/decoder/plugins/DsfDecoderPlugin.cxx @@ -243,6 +243,12 @@ InterleaveDsfBlock(uint8_t *gcc_restrict dest, const uint8_t *gcc_restrict src, InterleaveDsfBlockGeneric(dest, src, channels); } +static offset_type +TimeToBlock(double t, unsigned sample_rate) +{ + return offset_type(t * sample_rate / DSF_BLOCK_BITS); +} + /** * Decode one complete DSF 'data' chunk i.e. a complete song */ @@ -253,9 +259,27 @@ dsf_decode_chunk(Decoder &decoder, InputStream &is, bool bitreverse) { const size_t block_size = channels * DSF_BLOCK_SIZE; + const offset_type start_offset = is.GetOffset(); auto cmd = decoder_get_command(decoder); for (offset_type i = 0; i < n_blocks && cmd != DecoderCommand::STOP;) { + if (cmd == DecoderCommand::SEEK) { + double t = decoder_seek_where(decoder); + offset_type block = TimeToBlock(t, sample_rate); + if (block >= n_blocks) { + decoder_command_finished(decoder); + break; + } + + offset_type offset = + start_offset + block * block_size; + if (dsdlib_skip_to(&decoder, is, offset)) { + decoder_command_finished(decoder); + i = block; + } else + decoder_seek_error(decoder); + } + /* worst-case buffer size */ uint8_t buffer[MAX_CHANNELS * DSF_BLOCK_SIZE]; if (!decoder_read_full(&decoder, is, buffer, block_size)) @@ -298,7 +322,7 @@ dsf_stream_decode(Decoder &decoder, InputStream &is) (float) metadata.sample_rate; /* success: file was recognized */ - decoder_initialized(decoder, audio_format, false, songtime); + decoder_initialized(decoder, audio_format, is.IsSeekable(), songtime); dsf_decode_chunk(decoder, is, metadata.channels, metadata.sample_rate,