#ifndef DECODER_H #define DECODER_H /** * @todo write docs */ #include #include #include "mad.h" #define GLUE_LENGTH 6000 class Decoder { public: Decoder(); ~Decoder(); void addFragment(const emscripten::val& array); emscripten::val decode(uint32_t count = UINT32_MAX); bool hasMore() const; uint32_t framesLeft(uint32_t max = UINT32_MAX); private: enum State { empty, onBufferHalf, onBufferFull, onGlueHalf, onGlueFull }; struct RawBuffer { uint8_t* ptr; uint32_t length; }; State state; uint32_t sampleRate; uint8_t channels; uint32_t cachedLength; uint16_t samplesPerFrame; uint8_t* glue; uint8_t const* cachedNext; uint8_t const* cachedThis; mad_error cachedError; bool cached; mad_synth* synth; mad_stream* stream; mad_frame* frame; emscripten::val context; std::deque pending; private: void pullBuffer(); void changeBuffer(); void prepareNextBuffer(); void initializeProbe(mad_stream& probe); void switchToGlue(); void switchBuffer(uint8_t* bufferPtr, uint32_t length); }; #endif // DECODER_H