Git Product home page Git Product logo

Comments (2)

baadc0de avatar baadc0de commented on August 23, 2024 1

Thank you so much for taking the time. I'll be implementing the General Solution in my project, it sounds like exactly what I want to do.

from claxon.

ruuda avatar ruuda commented on August 23, 2024

Excellent library!

Thanks!

Would returning io::ErrorKind::WouldBlock from io::Read make the reads for samples retryable?

Maybe in a few lucky cases that would work, but in general it will not. A flac stream consists of frames, and each frame needs to be decoded in one go. Decoding of a frame cannot be suspended or resumed, because all of the state required for it lives on the call stack, in local variables. When the decoder returns the IO error, the call stack is lost. The lucky case is when the io::ErrorKind::WouldBlock happens exactly at the start of a frame, then you could retry decoding that frame.

What would be the best way to use the library in an environment where future bytes may not exist yet?

I can think of a few ways to go about this, ranging from easy but not guaranteed to work, to complicated but general.

Easy but cheating solution

I think the easiest way to do this right now, is to run the decoder on a separate thread, with a blocking reader, possibly backed by std::sync::mpsc::channel::<Box<[u8]>>. The promise could then send the bytes to the channel. This does require a new thread though, which as far as I am aware is not currently possible in WASM.

Easy but not general solution

The streaminfo metadata block may contain information about the maximum frame size in max_frame_size. If you know that your input can supply at least max_frame_size bytes, then it should be safe to decode one frame with FrameReader::read_next_or_eof. You would need some out of band way to know when you are done decoding, for example by checking whether the underlying input encountered EOF, or by comparing the number of samples decoded against the number of samples in the streaminfo, if that is present.

General solution

A more involved solution would be to implement a buffer that keeps consumed bytes around for a while. On top of this, you can decode frame by frame with FrameReader::read_next_or_eof. That would work roughly like this:

  • Before reading the frame, record the current offset in the buffer.
  • Try to decode the frame.
  • If it succeeds, the buffer until the current offset can safely be dropped.
  • If it fails due to WouldBlock, rewind to the start of the frame, and try to decode it again at a later time, when more data is available.

You could use input::BufferedReader as a starting point, it already has everything you need, only it drops the old contents of the buffer when it needs to be replenished. A rewindable buffered reader would instead append new contents, until an explicit clear after decoding a block.

from claxon.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.