This repository has been archived by the owner on Aug 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 78
/
player.js
104 lines (88 loc) · 3.32 KB
/
player.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
/* -*- mode: javascript; tab-width: 2; indent-tabs-mode: nil; -*-
*
* Copyright (c) 2011-2013 Marcus Geelnard
*
* This file is part of SoundBox.
*
* SoundBox is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SoundBox is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SoundBox. If not, see <http://www.gnu.org/licenses/>.
*
*/
"use strict";
var CPlayer = function () {
//--------------------------------------------------------------------------
// Private members
//--------------------------------------------------------------------------
var mProgressCallback;
var mGeneratedBuffer;
var mWorker = new Worker("player-worker.js");
mWorker.onmessage = function (event) {
if (event.data.cmd === "progress") {
mGeneratedBuffer = event.data.buffer;
if (mProgressCallback) {
mProgressCallback(event.data.progress);
}
}
};
//--------------------------------------------------------------------------
// Public methods
//--------------------------------------------------------------------------
// Generate the audio data (done in worker).
this.generate = function (song, opts, progressCallback) {
mProgressCallback = progressCallback;
mWorker.postMessage({
cmd: "generate",
song: song,
opts: opts
});
};
// Create a WAVE formatted Uint8Array from the generated audio data.
this.createWave = function() {
// Turn critical object properties into local variables (performance)
var mixBuf = mGeneratedBuffer,
waveWords = mixBuf.length;
// Create WAVE header
var headerLen = 44;
var l1 = headerLen + waveWords * 2 - 8;
var l2 = l1 - 36;
var wave = new Uint8Array(headerLen + waveWords * 2);
wave.set(
[82,73,70,70,
l1 & 255,(l1 >> 8) & 255,(l1 >> 16) & 255,(l1 >> 24) & 255,
87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,
68,172,0,0,16,177,2,0,4,0,16,0,100,97,116,97,
l2 & 255,(l2 >> 8) & 255,(l2 >> 16) & 255,(l2 >> 24) & 255]
);
// Append actual wave data
for (var i = 0, idx = headerLen; i < waveWords; ++i) {
// Note: We clamp here
var y = mixBuf[i];
y = y < -32767 ? -32767 : (y > 32767 ? 32767 : y);
wave[idx++] = y & 255;
wave[idx++] = (y >> 8) & 255;
}
// Return the WAVE formatted typed array
return wave;
};
// Get n samples of wave data at time t [s]. Wave data in range [-2,2].
this.getData = function(t, n) {
var i = 2 * Math.floor(t * 44100);
var d = new Array(n);
var b = mGeneratedBuffer;
for (var j = 0; j < 2*n; j += 1) {
var k = i + j;
d[j] = t > 0 && k < b.length ? b[k] / 32768 : 0;
}
return d;
};
};