-
Notifications
You must be signed in to change notification settings - Fork 0
/
audioequalizer.js
155 lines (114 loc) · 3.69 KB
/
audioequalizer.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
146
147
148
149
150
151
152
153
154
155
/********************* EQUALIZER *******************************/
// Based on great tutorial found from:
// https://dzone.com/articles/exploring-html5-web-audio
/**
* Class for generating audio spectrum.
*/
var Equalizer = new Function();
/**
* Variables.
*/
Equalizer.prototype.context = new AudioContext();
Equalizer.prototype.audioBuffer = [];
Equalizer.prototype.sourceNode = {};
Equalizer.prototype.analyser = {};
Equalizer.prototype.javascriptNode = {};
Equalizer.prototype.audioData = [];
Equalizer.prototype.fftSize = 512;
/**
* Load audio file and start playing it.
*/
Equalizer.prototype.play = function(url, loadCallback) {
var self = this;
// If AudioContext is not set (which is most probably the case)
// try to use webkit specific context.
if (! window.AudioContext) {
if (! window.webkitAudioContext) {
alert('no audiocontext found');
}
window.AudioContext = window.webkitAudioContext;
}
// Create a javascriptnode that is called whenever
// the 2048 frames have been sampled.
this.javascriptNode = this.context.createScriptProcessor(2048, 1, 1);
// Connect to destination.
this.javascriptNode.connect(this.context.destination);
// Bind audio processor.
this.javascriptNode.onaudioprocess = function() {
self.processAudio();
};
// Setup an analyzer.
this.analyser = this.context.createAnalyser();
this.analyser.smoothingTimeConstant = 0.2;
// The fftSize determine how many buckets we get containing
// frequency information. If we have a fftSize of 1024 we get 512 buckets.
this.analyser.fftSize = this.fftSize;
// Create a buffer source node and connect analyzer to it.
this.sourceNode = this.context.createBufferSource();
this.sourceNode.connect(this.analyser);
// Connect analyser to javascriptNode.
this.analyser.connect(this.javascriptNode);
// Aaaaand connect sourceNode to destination.
this.sourceNode.connect(this.context.destination);
// Then start loading the sound file.
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// On load callback.
request.onload = function() {
// Decode the data.
self.context.decodeAudioData(request.response, function(buffer) {
// Play sound when it's completely decoded.
self.playSound(buffer);
if (typeof(loadCallback) !== "unefined") {
loadCallback();
}
}, self.onLoadError);
}
// Fire request.
request.send();
}
/**
* Start playing sound.
*/
Equalizer.prototype.playSound = function(buffer) {
this.sourceNode.buffer = buffer;
this.sourceNode.start(0);
}
/**
* Audio file couldn't load.
*/
Equalizer.prototype.onLoadError = function(e) {
console.log(e);
}
/**
* Process audio samples and save values to an array.
*/
Equalizer.prototype.processAudio = function() {
// Get the average for the first channel.
this.audioData = new Uint8Array(this.analyser.frequencyBinCount);
this.analyser.getByteFrequencyData(this.audioData);
}
/**
* Return the current spectrum.
*/
Equalizer.prototype.getSpectrum = function() {
return this.audioData;
}
/**
* Return the current spectrum at given bucket.
*/
Equalizer.prototype.getSpectrumAt = function(i) {
return typeof(this.audioData[i]) !== "undefined" ? this.audioData[i] : 0;
}
/**
* Get bucket value by giving "frequency percentage" or something.
* I'm too tired to truly explain what the fuck this method does...
* just read the source and cry.
*
* @param {Number} p Float between 0-1.
*/
Equalizer.prototype.getSpectrumByPercentage = function(p) {
var i = Math.floor(p * this.audioData.length);
return typeof(this.audioData[i]) !== "undefined" ? this.audioData[i] : 0;
}