80 lines
1.6 KiB
C
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
|