radio/lorgar/lib/em/decoder.h

80 lines
1.6 KiB
C++

#ifndef DECODER_H
#define DECODER_H
/**
* @todo write docs
*/
#include <deque>
#include <emscripten/val.h>
#include <emscripten/bind.h>
#include "mad.h"
#define GLUE_LENGTH 6000
#define DEBUGGING false
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<RawBuffer> pending;
private:
void pullBuffer();
void changeBuffer();
void prepareNextBuffer();
void initializeProbe(mad_stream& probe);
void switchToGlue();
void switchBuffer(uint8_t* bufferPtr, uint32_t length);
};
EMSCRIPTEN_BINDINGS(jsmad) {
emscripten::class_<Decoder>("Decoder")
.constructor<>()
.function("addFragment", &Decoder::addFragment)
.function("hasMore", &Decoder::hasMore)
.function("framesLeft", &Decoder::framesLeft)
.function("decode", &Decoder::decode);
}
#endif // DECODER_H