-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathAudioSampleLoader.js
145 lines (129 loc) · 4.11 KB
/
AudioSampleLoader.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* AudioSampleLoader loads and decodes audio samples with audioCtx. It can be
* provided a single URL as a string or a list of URL strings. It is designed to
* function very similar to XMLHttpRequest Level 2.
* <p>
* Sample Usage:<br>
* var loader = new AudioSampleLoader();<br>
* loader.ctx = yourWebAudioContext;<br>
* loader.src = yourPathOrListOfPathsToAudioFiles;<br>
* loader.onload = yourCallbackFunction;<br>
* loader.onerror = yourOptionalErrorCallback;<br>
* loader.send();<br>
* <p>
* When your callback is called, you can view your decoded buffers at:<br>
* loader.response;<br>
* ... which will be an AudioBuffer (or a list of AudioBuffers in the order that
* you provided). Your response will NOT be an argument in the callback. The
* callback only gives you a trigger for completion time (just like XHR).
* <p>
* Basically, imagine it like XMLHttpRequest for loading WebAudio samples.
*
* @author Scott Michaud
* @version 0.2
*/
//Forward-declare AudioContext for Safari and older Google Chrome.
window.AudioContext = window.AudioContext || window.webkitAudioContext;
function AudioSampleLoader() {
"use strict";
this.loaded = 0;
}
AudioSampleLoader.prototype.send = function () {
"use strict";
var console = window.console,
i;
if (!this.hasOwnProperty('ctx')) {
this.ctx = new window.AudioContext();
} else if (!(this.ctx instanceof window.AudioContext)) {
//TODO: Post an error, but do not overwrite the variable with a valid context.
console.error('AudioSampleLoader: ctx not an instance of AudioContext');
return;
}
if (!this.hasOwnProperty('onload')) {
console.error('AudioSampleLoader: Callback onload does not exist');
return;
} else if (typeof this.onload !== 'function') {
console.error('AudioSampleLoader: Callback onload not a function');
return;
}
if (!this.hasOwnProperty('onerror') || typeof this.onerror !== 'function') {
this.onerror = function () {};
}
if (Array.isArray(this.src)) {
for (i = 0; i < this.src.length; i += 1) {
if (typeof this.src[i] !== 'string') {
console.error('AudioSampleLoader: src[' + i + '] is not a string');
this.onerror();
return;
}
}
//If src is a valid list of strings.
this.response = new Array(this.src.length);
for (i = 0; i < this.src.length; i += 1) {
this.loadOneOfBuffers(this.src[i], i);
}
} else if (typeof this.src === 'string') {
//If src is just a single string.
this.loadOneBuffer(this.src);
} else {
console.error('AudioSampleLoader: src not string or list of strings');
this.onerror();
return;
}
};
AudioSampleLoader.prototype.loadOneBuffer = function (url) {
"use strict";
var console = window.console,
loader = this,
XHR = new XMLHttpRequest();
XHR.open('GET', url, true);
XHR.responseType = 'arraybuffer';
XHR.onload = function () {
loader.ctx.decodeAudioData(
XHR.response,
function (buffer) {
loader.response = buffer;
loader.onload();
},
function () {
console.error('AudioSampleLoader: ctx.decodeAudioData() called onerror');
loader.onerror();
}
);
};
XHR.onerror = function () {
console.error('AudioSampleLoader: XMLHttpRequest called onerror');
loader.onerror();
};
XHR.send();
};
AudioSampleLoader.prototype.loadOneOfBuffers = function (url, index) {
"use strict";
var console = window.console,
loader = this,
XHR = new XMLHttpRequest();
XHR.open('GET', url, true);
XHR.responseType = 'arraybuffer';
XHR.onload = function () {
loader.ctx.decodeAudioData(
XHR.response,
function (buffer) {
loader.response[index] = buffer;
loader.loaded += 1;
if (loader.loaded === loader.src.length) {
loader.loaded = 0;
loader.onload();
}
},
function () {
console.error('AudioSampleLoader: ctx.decodeAudioData() called onerror');
loader.onerror();
}
);
};
XHR.onerror = function () {
console.error('AudioSampleLoader: XMLHttpRequest called onerror');
loader.onerror();
};
XHR.send();
};