diff --git a/NEWS b/NEWS index 198ada6a9..1deecbe56 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ ver 0.18.12 (not yet released) - audiofile: improve responsiveness - audiofile: fix WAV stream playback - dsdiff, dsf: fix stream playback + - sndfile: improve responsiveness * randomize next song when enabling "random" mode while not playing * randomize next song when adding to single-song queue diff --git a/src/decoder/SndfileDecoderPlugin.cxx b/src/decoder/SndfileDecoderPlugin.cxx index 4082f3e0f..5b2913c13 100644 --- a/src/decoder/SndfileDecoderPlugin.cxx +++ b/src/decoder/SndfileDecoderPlugin.cxx @@ -31,10 +31,20 @@ static constexpr Domain sndfile_domain("sndfile"); +struct SndfileInputStream { + Decoder *const decoder; + InputStream &is; + + size_t Read(void *buffer, size_t size) { + return decoder_read(decoder, is, buffer, size); + } +}; + static sf_count_t sndfile_vio_get_filelen(void *user_data) { - const InputStream &is = *(const InputStream *)user_data; + SndfileInputStream &sis = *(SndfileInputStream *)user_data; + const InputStream &is = sis.is; return is.GetSize(); } @@ -42,7 +52,8 @@ sndfile_vio_get_filelen(void *user_data) static sf_count_t sndfile_vio_seek(sf_count_t offset, int whence, void *user_data) { - InputStream &is = *(InputStream *)user_data; + SndfileInputStream &sis = *(SndfileInputStream *)user_data; + InputStream &is = sis.is; Error error; if (!is.LockSeek(offset, whence, error)) { @@ -56,25 +67,18 @@ sndfile_vio_seek(sf_count_t offset, int whence, void *user_data) static sf_count_t sndfile_vio_read(void *ptr, sf_count_t count, void *user_data) { - InputStream &is = *(InputStream *)user_data; + SndfileInputStream &sis = *(SndfileInputStream *)user_data; sf_count_t total_bytes = 0; - Error error; /* this loop is necessary because libsndfile chokes on partial reads */ do { - size_t nbytes = is.LockRead((char *)ptr + total_bytes, - count - total_bytes, error); - if (nbytes == 0) { - if (error.IsDefined()) { - LogError(error); - return -1; - } - - break; - } + size_t nbytes = sis.Read((char *)ptr + total_bytes, + count - total_bytes); + if (nbytes == 0) + return -1; total_bytes += nbytes; } while (total_bytes < count); @@ -94,7 +98,8 @@ sndfile_vio_write(gcc_unused const void *ptr, static sf_count_t sndfile_vio_tell(void *user_data) { - const InputStream &is = *(const InputStream *)user_data; + SndfileInputStream &sis = *(SndfileInputStream *)user_data; + const InputStream &is = sis.is; return is.GetOffset(); } @@ -140,7 +145,8 @@ sndfile_stream_decode(Decoder &decoder, InputStream &is) info.format = 0; - sf = sf_open_virtual(&vio, SFM_READ, &info, &is); + SndfileInputStream sis{&decoder, is}; + sf = sf_open_virtual(&vio, SFM_READ, &info, &sis); if (sf == nullptr) { LogWarning(sndfile_domain, "sf_open_virtual() failed"); return;