forked from phoboslab/jsmpeg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mp2-wasm.js
124 lines (94 loc) · 3.19 KB
/
mp2-wasm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
JSMpeg.Decoder.MP2AudioWASM = (function(){ "use strict";
// Based on kjmp2 by Martin J. Fiedler
// http://keyj.emphy.de/kjmp2/
var MP2WASM = function(options) {
JSMpeg.Decoder.Base.call(this, options);
this.onDecodeCallback = options.onAudioDecode;
this.module = options.wasmModule;
this.bufferSize = options.audioBufferSize || 128*1024;
this.bufferMode = options.streaming
? JSMpeg.BitBuffer.MODE.EVICT
: JSMpeg.BitBuffer.MODE.EXPAND;
this.sampleRate = 0;
};
MP2WASM.prototype = Object.create(JSMpeg.Decoder.Base.prototype);
MP2WASM.prototype.constructor = MP2WASM;
MP2WASM.prototype.initializeWasmDecoder = function() {
if (!this.module.instance) {
console.warn('JSMpeg: WASM module not compiled yet');
return;
}
this.instance = this.module.instance;
this.functions = this.module.instance.exports;
this.decoder = this.functions._mp2_decoder_create(this.bufferSize, this.bufferMode);
};
MP2WASM.prototype.destroy = function() {
if (!this.decoder) {
return;
}
this.functions._mp2_decoder_destroy(this.decoder);
};
MP2WASM.prototype.bufferGetIndex = function() {
if (!this.decoder) {
return;
}
return this.functions._mp2_decoder_get_index(this.decoder);
};
MP2WASM.prototype.bufferSetIndex = function(index) {
if (!this.decoder) {
return;
}
this.functions._mp2_decoder_set_index(this.decoder, index);
};
MP2WASM.prototype.bufferWrite = function(buffers) {
if (!this.decoder) {
this.initializeWasmDecoder();
}
var totalLength = 0;
for (var i = 0; i < buffers.length; i++) {
totalLength += buffers[i].length;
}
var ptr = this.functions._mp2_decoder_get_write_ptr(this.decoder, totalLength);
for (var i = 0; i < buffers.length; i++) {
this.instance.heapU8.set(buffers[i], ptr);
ptr += buffers[i].length;
}
this.functions._mp2_decoder_did_write(this.decoder, totalLength);
return totalLength;
};
MP2WASM.prototype.decode = function() {
var startTime = JSMpeg.Now();
if (!this.decoder) {
return false;
}
var decodedBytes = this.functions._mp2_decoder_decode(this.decoder);
if (decodedBytes === 0) {
return false;
}
if (!this.sampleRate) {
this.sampleRate = this.functions._mp2_decoder_get_sample_rate(this.decoder);
}
if (this.destination) {
// Create a Float32 View into the modules output channel data
var leftPtr = this.functions._mp2_decoder_get_left_channel_ptr(this.decoder),
rightPtr = this.functions._mp2_decoder_get_right_channel_ptr(this.decoder);
var leftOffset = leftPtr / Float32Array.BYTES_PER_ELEMENT,
rightOffset = rightPtr / Float32Array.BYTES_PER_ELEMENT;
var left = this.instance.heapF32.subarray(leftOffset, leftOffset + MP2WASM.SAMPLES_PER_FRAME),
right = this.instance.heapF32.subarray(rightOffset, rightOffset + MP2WASM.SAMPLES_PER_FRAME);
this.destination.play(this.sampleRate, left, right);
}
this.advanceDecodedTime(MP2WASM.SAMPLES_PER_FRAME / this.sampleRate);
var elapsedTime = JSMpeg.Now() - startTime;
if (this.onDecodeCallback) {
this.onDecodeCallback(this, elapsedTime);
}
return true;
};
MP2WASM.prototype.getCurrentTime = function() {
var enqueuedTime = this.destination ? this.destination.enqueuedTime : 0;
return this.decodedTime - enqueuedTime;
};
MP2WASM.SAMPLES_PER_FRAME = 1152;
return MP2WASM;
})();