This commit is contained in:
Blue 2019-01-18 04:50:48 +03:00
parent db0b829fbd
commit df77690724
3 changed files with 54 additions and 51 deletions

View File

@ -12,9 +12,9 @@ cachedNext(NULL),
cachedThis(NULL), cachedThis(NULL),
cachedError(MAD_ERROR_NONE), cachedError(MAD_ERROR_NONE),
cached(false), cached(false),
synth(), synth(new mad_synth()),
stream(), stream(new mad_stream()),
frame(), frame(new mad_frame()),
context(0), context(0),
pending() pending()
{ {
@ -22,9 +22,9 @@ pending()
glue[i] = 0; glue[i] = 0;
} }
mad_frame_init(&frame); mad_frame_init(frame);
mad_stream_init(&stream); mad_stream_init(stream);
mad_synth_init(&synth); mad_synth_init(synth);
emscripten::val AudioContext = emscripten::val::global("AudioContext"); emscripten::val AudioContext = emscripten::val::global("AudioContext");
if (!AudioContext.as<bool>()) { if (!AudioContext.as<bool>()) {
@ -38,9 +38,13 @@ Decoder::~Decoder()
{ {
context.call<void>("close"); context.call<void>("close");
mad_synth_finish(&synth); mad_synth_finish(synth);
mad_stream_finish(&stream); mad_stream_finish(stream);
mad_frame_finish(&frame); mad_frame_finish(frame);
delete synth;
delete stream;
delete frame;
delete[] glue; delete[] glue;
} }
@ -56,10 +60,9 @@ void Decoder::addFragment(intptr_t bufferPtr, uint32_t length)
RawBuffer rb = {buffer, length, 0, 0}; RawBuffer rb = {buffer, length, 0, 0};
pending.push_back(rb); pending.push_back(rb);
std::cout << "The state now is " << state << std::endl;
switch (state) { switch (state) {
case empty: case empty:
mad_stream_buffer(&stream, buffer, length); mad_stream_buffer(stream, buffer, length);
for (int i = 0; i < GLUE_LENGTH/2; ++i) { for (int i = 0; i < GLUE_LENGTH/2; ++i) {
glue[i] = buffer[length - GLUE_LENGTH/2 + i]; glue[i] = buffer[length - GLUE_LENGTH/2 + i];
@ -106,32 +109,32 @@ emscripten::val Decoder::decode(uint32_t count)
} }
for (int i = 0; success < available; ++i) { for (int i = 0; success < available; ++i) {
int res = mad_frame_decode(&frame, &stream); int res = mad_frame_decode(frame, stream);
if (res == 0) { if (res == 0) {
++success; ++success;
} else { } else {
if (MAD_RECOVERABLE(stream.error)) { if (MAD_RECOVERABLE(stream->error)) {
std::cout << "Unexpected error during the decoding process: " << mad_stream_errorstr(&stream) << std::endl; std::cout << "Unexpected error during the decoding process: " << mad_stream_errorstr(stream) << std::endl;
continue; continue;
} else { } else {
break; break;
} }
} }
mad_synth_frame(&synth, &frame); mad_synth_frame(synth, frame);
for (int j = 0; j < samplesPerFrame; ++j) { for (int j = 0; j < samplesPerFrame; ++j) {
for (int k = 0; k < channels; ++k) { for (int k = 0; k < channels; ++k) {
float value = mad_f_todouble(synth.pcm.samples[k][j]); float value = mad_f_todouble(synth->pcm.samples[k][j]);
chans[k].set(std::to_string(success * samplesPerFrame + j), emscripten::val(value)); chans[k].set(std::to_string(success * samplesPerFrame + j), emscripten::val(value));
} }
} }
} }
cachedLength -= available; cachedLength -= available;
std::cout << "Processed " << available << " frames, " << success << " successfully, last error " << mad_stream_errorstr(&stream) << std::endl; std::cout << "Processed " << available << " frames, " << success << " successfully, last error " << mad_stream_errorstr(stream) << std::endl;
if (cachedLength == 0) { if (cachedLength == 0) {
cached = false; cached = false;
@ -145,7 +148,7 @@ emscripten::val Decoder::decode(uint32_t count)
bool Decoder::hasMore() const bool Decoder::hasMore() const
{ {
if (pending.size() == 1) { if (pending.size() == 1) {
return stream.error != MAD_ERROR_BUFLEN; return stream->error != MAD_ERROR_BUFLEN;
} else { } else {
return true; return true;
} }
@ -202,14 +205,13 @@ void Decoder::pullBuffer()
if (cached == false) { if (cached == false) {
std::cout << "Error in pullBuffer method!" << std::endl; std::cout << "Error in pullBuffer method!" << std::endl;
} }
stream.this_frame = cachedThis; stream->this_frame = cachedThis;
stream.next_frame = cachedNext; stream->next_frame = cachedNext;
stream.error = cachedError; stream->error = cachedError;
} }
void Decoder::changeBuffer() void Decoder::changeBuffer()
{ {
uint32_t left;
switch (state) { switch (state) {
case empty: case empty:
std::cout << "Wrong state on switchBuffer method - empty, aborting" << std::endl; std::cout << "Wrong state on switchBuffer method - empty, aborting" << std::endl;
@ -265,32 +267,30 @@ void Decoder::initializeProbe(mad_stream& probe)
{ {
mad_stream_init(&probe); mad_stream_init(&probe);
probe.buffer = stream.buffer; probe.buffer = stream->buffer;
probe.bufend = stream.bufend; probe.bufend = stream->bufend;
probe.skiplen = stream.skiplen; //probe.skiplen = stream->skiplen;
probe.sync = stream.sync; //probe.sync = stream->sync;
probe.freerate = stream.freerate; //probe.freerate = stream->freerate;
probe.this_frame = stream.this_frame; //probe.this_frame = stream->this_frame;
probe.next_frame = stream.next_frame; probe.next_frame = stream->next_frame;
probe.ptr.byte = stream.ptr.byte; //probe.ptr.byte = stream->ptr.byte;
probe.ptr.cache = stream.ptr.cache; //probe.ptr.cache = stream->ptr.cache;
probe.ptr.cache = stream.ptr.cache; //probe.ptr.cache = stream->ptr.cache;
probe.anc_ptr.byte = stream.anc_ptr.byte; //probe.anc_ptr.byte = stream->anc_ptr.byte;
probe.anc_ptr.cache = stream.anc_ptr.cache; //probe.anc_ptr.cache = stream->anc_ptr.cache;
probe.anc_ptr.cache = stream.anc_ptr.cache; //probe.anc_ptr.cache = stream->anc_ptr.cache;
probe.anc_bitlen = stream.anc_bitlen; //probe.anc_bitlen = stream->anc_bitlen;
//probe.main_data = stream.main_data; //probe.main_data = stream.main_data;
//probe.md_len = stream.md_len; //probe.md_len = stream.md_len;
probe.options = stream.options; //probe.options = stream->options;
probe.error = stream.error; //probe.error = stream->error;
} }
void Decoder::switchToGlue() void Decoder::switchToGlue()
{ {
std::cout << "Switching to glue" << std::endl; std::cout << "Switching to glue" << std::endl;
switchBuffer(glue, GLUE_LENGTH); switchBuffer(glue, GLUE_LENGTH);
stream.error = MAD_ERROR_NONE;
std::cout << "Freeing the drained fragment" << std::endl; std::cout << "Freeing the drained fragment" << std::endl;
free(pending[0].ptr); free(pending[0].ptr);
@ -300,11 +300,12 @@ void Decoder::switchToGlue()
void Decoder::switchBuffer(uint8_t* bufferPtr, uint32_t length) void Decoder::switchBuffer(uint8_t* bufferPtr, uint32_t length)
{ {
uint32_t left; uint32_t left;
if (stream.error != MAD_ERROR_BUFLEN) {
std::cout << "WARNING: Switching buffers while the previous one is not drained, error: " << mad_stream_errorstr(&stream) << std::endl; if (stream->error != MAD_ERROR_BUFLEN) {
std::cout << "WARNING: Switching buffers while the previous one is not drained, error: " << mad_stream_errorstr(stream) << std::endl;
} }
if (stream.next_frame != NULL) { if (stream->next_frame != NULL) {
left = stream.bufend - stream.next_frame; left = stream->bufend - stream->next_frame;
} else { } else {
std::cout << "WARNING: not supposed to happen" << std::endl; std::cout << "WARNING: not supposed to happen" << std::endl;
} }
@ -313,7 +314,9 @@ void Decoder::switchBuffer(uint8_t* bufferPtr, uint32_t length)
std::cout << "Error: bytes to read in the buffer are more then glue buffer can fit (" << left << ")" << std::endl; std::cout << "Error: bytes to read in the buffer are more then glue buffer can fit (" << left << ")" << std::endl;
throw 1; throw 1;
} }
mad_stream_buffer(&stream, bufferPtr + GLUE_LENGTH / 2 - left, length - (GLUE_LENGTH / 2 - left));
stream.error = MAD_ERROR_NONE; mad_stream_buffer(stream, bufferPtr + GLUE_LENGTH / 2 - left, length - (GLUE_LENGTH / 2 - left));
stream->error = MAD_ERROR_NONE;
while (mad_header_decode(&frame->header, stream) != 0 && stream->error != MAD_ERROR_BUFLEN) {}
} }

View File

@ -9,7 +9,7 @@
#include <emscripten/val.h> #include <emscripten/val.h>
#include "mad.h" #include "mad.h"
#define GLUE_LENGTH 10240 #define GLUE_LENGTH 6000
class Decoder { class Decoder {
public: public:
@ -50,9 +50,9 @@ private:
mad_error cachedError; mad_error cachedError;
bool cached; bool cached;
mad_synth synth; mad_synth* synth;
mad_stream stream; mad_stream* stream;
mad_frame frame; mad_frame* frame;
emscripten::val context; emscripten::val context;
std::deque<RawBuffer> pending; std::deque<RawBuffer> pending;

View File

@ -31,7 +31,7 @@
scheduleData(); scheduleData();
setTimeout(.bind(ctx), 1000); setTimeout(ctx.resume.bind(ctx), 1000);
} }
reader.readAsArrayBuffer(file); reader.readAsArrayBuffer(file);