-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexport.es6
97 lines (91 loc) · 2.91 KB
/
export.es6
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
//Code borrowed from RecorderJS
class Export {
constructor(audioBuffer) {
console.log(audioBuffer);
this.audioBuffer = audioBuffer;
this.sampleRate = audioBuffer.sampleRate;
this.numChannels = audioBuffer.numberOfChannels;
this.recBuffers = [];
this.recLength = audioBuffer.length;
this.recBuffers.push(this.audioBuffer.getChannelData(0));
}
export() {
var buffers = [];
for (var channel = 0; channel < this.numChannels; channel++){
buffers.push(this.mergeBuffers(this.recBuffers, this.recLength));
}
if (this.numChannels === 2){
var interleaved = this.interleave(buffers[0], buffers[1]);
} else {
var interleaved = buffers[0];
}
var dataview = this.encodeWAV(interleaved);
var audioBlob = new Blob([dataview], { type: 'audio/wav' });
return audioBlob;
}
interleave(inputL, inputR) {
var length = inputL.length + inputR.length;
var result = new Float32Array(length);
var index = 0,
inputIndex = 0;
while (index < length){
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return result;
}
mergeBuffers(recBuffers, recLength){
console.log(recBuffers);
var result = new Float32Array(recLength);
var offset = 0;
for (var i = 0; i < recBuffers.length; i++){
result.set(recBuffers[i], offset);
offset += recBuffers[i].length;
}
return result;
}
writeString(view, offset, string){
for (var i = 0; i < string.length; i++){
view.setUint8(offset + i, string.charCodeAt(i));
}
}
encodeWAV(samples){
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
/* RIFF identifier */
this.writeString(view, 0, 'RIFF');
/* RIFF chunk length */
view.setUint32(4, 36 + samples.length * 2, true);
/* RIFF type */
this.writeString(view, 8, 'WAVE');
/* format chunk identifier */
this.writeString(view, 12, 'fmt ');
/* format chunk length */
view.setUint32(16, 16, true);
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
view.setUint16(22, this.numChannels, true);
/* sample rate */
view.setUint32(24, this.sampleRate, true);
/* byte rate (sample rate * block align) */
view.setUint32(28, this.sampleRate * 4, true);
/* block align (channel count * bytes per sample) */
view.setUint16(32, this.numChannels * 2, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
this.writeString(view, 36, 'data');
/* data chunk length */
view.setUint32(40, samples.length * 2, true);
this.floatTo16BitPCM(view, 44, samples);
return view;
}
floatTo16BitPCM(output, offset, input){
for (var i = 0; i < input.length; i++, offset+=2){
var s = Math.max(-1, Math.min(1, input[i]));
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
}
}
}