Skip to content

Commit

Permalink
Merge pull request #17 from eshaz/fix-samplerate
Browse files Browse the repository at this point in the history
Fix Samplerate
  • Loading branch information
eshaz authored Nov 25, 2021
2 parents 0a0b0b1 + d7b7d07 commit a2a37df
Show file tree
Hide file tree
Showing 37 changed files with 765 additions and 773 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ define MPG123_EMCC_OPTS
, '_mpeg_frame_decoder_create' \
, '_mpeg_frame_decoder_destroy' \
, '_mpeg_decode_interleaved' \
, '_mpeg_get_sample_rate' \
]" \
--pre-js 'src/mpg123-decoder/src/emscripten-pre.js' \
--post-js 'src/mpg123-decoder/src/emscripten-post.js' \
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@ Pre-built minified JS files are available from NPM and in each decoder's `dist`

### [`mpg123-decoder`](https://github.com/eshaz/wasm-audio-decoders/tree/master/src/mpg123-decoder)
Decodes MPEG Layer I/II/III into PCM
* 85.7 KiB minified bundle size
* 85.5 KiB minified bundle size
* Browser and NodeJS support
* Built in Web Worker support
* Based on [`mpg123`](https://www.mpg123.de/)
* Install using [NPM](https://www.npmjs.com/package/mpg123-decoder)

### [`ogg-opus-decoder`](https://github.com/eshaz/wasm-audio-decoders/tree/master/src/ogg-opus-decoder)
Decodes Ogg Opus data into PCM
* 115.3 KiB minified bundle size
* 115.1 KiB minified bundle size
* Browser and NodeJS support
* Built in Web Worker support
* Based on [`libopusfile`](https://github.com/xiph/opusfile)
* Install using [NPM](https://www.npmjs.com/package/ogg-opus-decoder)

### [`opus-decoder`](https://github.com/eshaz/wasm-audio-decoders/tree/master/src/opus-decoder)
Decodes raw Opus audio frames into PCM
* 87.4 KiB minified bundle size
* 87.2 KiB minified bundle size
* Browser and NodeJS support
* Built in Web Worker support
* Based on [`libopus`](https://github.com/xiph/opus)
Expand Down
191 changes: 95 additions & 96 deletions demo/mpg123-decoder.js

Large diffs are not rendered by default.

146 changes: 74 additions & 72 deletions demo/ogg-opus-decoder.js

Large diffs are not rendered by default.

159 changes: 79 additions & 80 deletions demo/opus-decoder.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/mpg123-decoder/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# `mpg123-decoder`

`mpg123-decoder` is a Web Assembly MPEG Layer (I/II/II) audio decoder.
* 85.7 KiB minified bundle size
* 85.5 KiB minified bundle size
* Browser and NodeJS support
* Built in Web Worker support
* Based on [`mpg123`](https://www.mpg123.de/)
Expand Down
191 changes: 95 additions & 96 deletions src/mpg123-decoder/dist/mpg123-decoder.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/mpg123-decoder/dist/mpg123-decoder.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/mpg123-decoder/dist/mpg123-decoder.min.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/mpg123-decoder/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/mpg123-decoder/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mpg123-decoder",
"version": "0.3.2",
"version": "0.3.3",
"description": "Web Assembly streaming MPEG Layer I/II/III decoder",
"main": "dist/mpg123-decoder.min.js",
"module": "index.js",
Expand Down
19 changes: 5 additions & 14 deletions src/mpg123-decoder/src/EmscriptenWasm.js

Large diffs are not rendered by default.

52 changes: 31 additions & 21 deletions src/mpg123-decoder/src/MPEGDecoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ export default class MPEGDecoder {
return ret;
}

_createOutputArray(length) {
const pointer = this._api._malloc(Float32Array.BYTES_PER_ELEMENT * length);
const array = new Float32Array(this._api.HEAPF32.buffer, pointer, length);
_allocateTypedArray(length, TypedArray) {
const pointer = this._api._malloc(TypedArray.BYTES_PER_ELEMENT * length);
const array = new TypedArray(this._api.HEAP, pointer, length);
return [pointer, array];
}

Expand Down Expand Up @@ -55,25 +55,34 @@ export default class MPEGDecoder {

this._sampleRate = 0;

// input buffer
this._inDataPtrSize = 2 ** 18;
[this._inDataPtr, this._inData] = this._allocateTypedArray(
this._inDataPtrSize,
Uint8Array
);

// output buffer
this._outputLength = 1152 * 512;
[this._leftPtr, this._leftArr] = this._createOutputArray(
this._outputLength
[this._leftPtr, this._leftArr] = this._allocateTypedArray(
this._outputLength,
Float32Array
);
[this._rightPtr, this._rightArr] = this._createOutputArray(
this._outputLength
[this._rightPtr, this._rightArr] = this._allocateTypedArray(
this._outputLength,
Float32Array
);

// input buffer
this._inDataPtrSize = 2 ** 18;
this._inDataPtr = this._api._malloc(this._inDataPtrSize);

// input decoded bytes pointer
this._decodedBytesPtr = this._api._malloc(Uint32Array.BYTES_PER_ELEMENT);
this._decodedBytes = new Uint32Array(
this._api.HEAPU32.buffer,
this._decodedBytesPtr,
1
[this._decodedBytesPtr, this._decodedBytes] = this._allocateTypedArray(
1,
Uint32Array
);

// sample rate
[this._sampleRateBytePtr, this._sampleRateByte] = this._allocateTypedArray(
1,
Uint32Array
);

this._decoder = this._api._mpeg_frame_decoder_create();
Expand All @@ -91,10 +100,12 @@ export default class MPEGDecoder {
free() {
this._api._mpeg_frame_decoder_destroy(this._decoder);

this._api._free(this._decoder);
this._api._free(this._inDataPtr);
this._api._free(this._decodedBytesPtr);
this._api._free(this._leftPtr);
this._api._free(this._rightPtr);
this._api._free(this._sampleRateBytePtr);
}

_decode(data, decodeInterval) {
Expand All @@ -103,8 +114,7 @@ export default class MPEGDecoder {
`Data to decode must be Uint8Array. Instead got ${typeof data}`
);

this._api.HEAPU8.set(data, this._inDataPtr);

this._inData.set(data);
this._decodedBytes[0] = 0;

const samplesDecoded = this._api._mpeg_decode_interleaved(
Expand All @@ -115,11 +125,11 @@ export default class MPEGDecoder {
decodeInterval,
this._leftPtr,
this._rightPtr,
this._outputLength
this._outputLength,
this._sampleRateBytePtr
);

if (!this._sampleRate)
this._sampleRate = this._api._mpeg_get_sample_rate(this._decoder);
this._sampleRate = this._sampleRateByte[0];

return new this._MPEGDecodedAudio(
[
Expand Down
112 changes: 57 additions & 55 deletions src/mpg123-decoder/src/MPEGDecoderWebWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,66 +8,68 @@ let sourceURL;

export default class MPEGDecoderWebWorker extends Worker {
constructor() {
const webworkerSourceCode =
"'use strict';" +
// dependencies need to be manually resolved when stringifying this function
`(${((_MPEGDecoder, _MPEGDecodedAudio, _EmscriptenWASM) => {
// We're in a Web Worker
const decoder = new _MPEGDecoder(_MPEGDecodedAudio, _EmscriptenWASM);
const detachBuffers = (buffer) =>
Array.isArray(buffer)
? buffer.map((buffer) => new Uint8Array(buffer))
: new Uint8Array(buffer);
self.onmessage = ({ data: { id, command, mpegData } }) => {
switch (command) {
case "ready":
decoder.ready.then(() => {
self.postMessage({
id,
if (!sourceURL) {
const webworkerSourceCode =
"'use strict';" +
// dependencies need to be manually resolved when stringifying this function
`(${((_MPEGDecoder, _MPEGDecodedAudio, _EmscriptenWASM) => {
// We're in a Web Worker
const decoder = new _MPEGDecoder(_MPEGDecodedAudio, _EmscriptenWASM);
const detachBuffers = (buffer) =>
Array.isArray(buffer)
? buffer.map((buffer) => new Uint8Array(buffer))
: new Uint8Array(buffer);
self.onmessage = ({ data: { id, command, mpegData } }) => {
switch (command) {
case "ready":
decoder.ready.then(() => {
self.postMessage({
id,
});
});
});
break;
case "free":
decoder.free();
self.postMessage({
id,
});
break;
case "reset":
decoder.reset().then(() => {
break;
case "free":
decoder.free();
self.postMessage({
id,
});
});
break;
case "decode":
case "decodeFrame":
case "decodeFrames":
const { channelData, samplesDecoded, sampleRate } = decoder[
command
](detachBuffers(mpegData));
self.postMessage(
{
id,
channelData,
samplesDecoded,
sampleRate,
},
// The "transferList" parameter transfers ownership of channel data to main thread,
// which avoids copying memory.
channelData.map((channel) => channel.buffer)
);
break;
default:
this.console.error("Unknown command sent to worker: " + command);
}
};
}).toString()})(${MPEGDecoder}, ${MPEGDecodedAudio}, ${EmscriptenWASM})`;
break;
case "reset":
decoder.reset().then(() => {
self.postMessage({
id,
});
});
break;
case "decode":
case "decodeFrame":
case "decodeFrames":
const { channelData, samplesDecoded, sampleRate } = decoder[
command
](detachBuffers(mpegData));
self.postMessage(
{
id,
channelData,
samplesDecoded,
sampleRate,
},
// The "transferList" parameter transfers ownership of channel data to main thread,
// which avoids copying memory.
channelData.map((channel) => channel.buffer)
);
break;
default:
this.console.error(
"Unknown command sent to worker: " + command
);
}
};
}).toString()})(${MPEGDecoder}, ${MPEGDecodedAudio}, ${EmscriptenWASM})`;

if (!sourceURL) {
const type = "text/javascript";
try {
// browser
Expand Down
10 changes: 1 addition & 9 deletions src/mpg123-decoder/src/emscripten-post.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
this.ready = new Promise((resolve) => {
ready = resolve;
}).then(() => {
this.HEAP8 = HEAP8;
this.HEAP16 = HEAP16;
this.HEAP32 = HEAP32;
this.HEAPU8 = HEAPU8;
this.HEAPU16 = HEAPU16;
this.HEAPU32 = HEAPU32;
this.HEAPF32 = HEAPF32;
this.HEAPF64 = HEAPF64;
this.HEAP = buffer;
this._malloc = _malloc;
this._free = _free;
this._mpeg_frame_decoder_create = _mpeg_frame_decoder_create;
this._mpeg_decode_interleaved = _mpeg_decode_interleaved;
this._mpeg_get_sample_rate = _mpeg_get_sample_rate;
this._mpeg_frame_decoder_destroy = _mpeg_frame_decoder_destroy;
});
12 changes: 5 additions & 7 deletions src/mpg123-decoder/src/mpeg_frame_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ int mpeg_decode_interleaved(
size_t in_read_chunk_size, // interval of bytes to read from input data
float *left, // pointer to save the left output audio
float *right, // pointer to save the right output audio
size_t decode_buffer_size // output audio buffer size
size_t decode_buffer_size, // output audio buffer size
unsigned int *sample_rate // pointer to save the sample rate
) {
in_read_chunk_size = in_size > in_read_chunk_size ? in_read_chunk_size : in_size;
int samples_decoded = 0;
Expand Down Expand Up @@ -65,13 +66,10 @@ int mpeg_decode_interleaved(
// printf("in_read_pos %u, in_size %zu, total_bytes_decoded %u, decode_buffer_size %zu\n",
// *in_read_pos, in_size, samples_decoded * 8, decode_buffer_size * 8);

return samples_decoded;
}

long mpeg_get_sample_rate(MPEGFrameDecoder *decoder) {
mpg123_info(decoder->mh, &decoder->fr);

return decoder->fr.rate;
*sample_rate = (int) decoder->fr.rate;

return samples_decoded;
}

void mpeg_frame_decoder_destroy(MPEGFrameDecoder *decoder) {
Expand Down
3 changes: 2 additions & 1 deletion src/mpg123-decoder/src/mpeg_frame_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ int mpeg_decode_interleaved(
size_t in_read_chunk_size, // interval of bytes to read from input data
float *left, // left output audio
float *right, // right output audio
size_t out_size // output audio buffer size
size_t out_size, // output audio buffer size
unsigned int *sample_rate // pointer to save the sample rate
);

void mpeg_frame_decoder_destroy(MPEGFrameDecoder *st);
2 changes: 1 addition & 1 deletion src/ogg-opus-decoder/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# `ogg-opus-decoder`

`ogg-opus-decoder` is a Web Assembly Ogg Opus audio decoder.
* 115.3 KiB minified bundle size
* 115.1 KiB minified bundle size
* Browser and NodeJS support
* Built in Web Worker support
* Based on [`libopusfile`](https://github.com/xiph/opusfile)
Expand Down
146 changes: 74 additions & 72 deletions src/ogg-opus-decoder/dist/ogg-opus-decoder.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/ogg-opus-decoder/dist/ogg-opus-decoder.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit a2a37df

Please sign in to comment.