2
2
3
3
define ( function ( require ) {
4
4
var p5sound = require ( 'master' ) ;
5
+ var processorNames = require ( './audioWorklet/processorNames' ) ;
5
6
6
7
/**
7
8
* Amplitude measures volume between 0.0 and 1.0.
@@ -50,38 +51,42 @@ define(function (require) {
50
51
51
52
// set audio context
52
53
this . audiocontext = p5sound . audiocontext ;
53
- this . processor = this . audiocontext . createScriptProcessor ( this . bufferSize , 2 , 1 ) ;
54
+ this . _workletNode = new AudioWorkletNode ( this . audiocontext , processorNames . amplitudeProcessor , {
55
+ outputChannelCount : [ 1 ] ,
56
+ parameterData : { smoothing : smoothing || 0 } ,
57
+ processorOptions : { normalize : false }
58
+ } ) ;
59
+
60
+ this . _workletNode . port . onmessage = function ( event ) {
61
+ if ( event . data . name === 'amplitude' ) {
62
+ this . volume = event . data . volume ;
63
+ this . volNorm = event . data . volNorm ;
64
+ this . stereoVol = event . data . stereoVol ;
65
+ this . stereoVolNorm = event . data . stereoVolNorm ;
66
+ }
67
+ } . bind ( this ) ;
54
68
55
69
// for connections
56
- this . input = this . processor ;
70
+ this . input = this . _workletNode ;
57
71
58
72
this . output = this . audiocontext . createGain ( ) ;
59
- // smoothing defaults to 0
60
- this . smoothing = smoothing || 0 ;
61
-
62
73
63
74
// the variables to return
64
75
this . volume = 0 ;
65
- this . average = 0 ;
66
-
76
+ this . volNorm = 0 ;
67
77
this . stereoVol = [ 0 , 0 ] ;
68
- this . stereoAvg = [ 0 , 0 ] ;
69
78
this . stereoVolNorm = [ 0 , 0 ] ;
70
79
71
- this . volMax = 0.001 ;
72
80
this . normalize = false ;
73
81
74
- this . processor . onaudioprocess = this . _audioProcess . bind ( this ) ;
75
-
76
-
77
- this . processor . connect ( this . output ) ;
82
+ this . _workletNode . connect ( this . output ) ;
78
83
this . output . gain . value = 0 ;
79
84
80
85
// this may only be necessary because of a Chrome bug
81
86
this . output . connect ( this . audiocontext . destination ) ;
82
87
83
88
// connect to p5sound master output by default, unless set by input()
84
- p5sound . meter . connect ( this . processor ) ;
89
+ p5sound . meter . connect ( this . _workletNode ) ;
85
90
86
91
// add this p5.SoundFile to the soundArray
87
92
p5sound . soundArray . push ( this ) ;
@@ -128,29 +133,29 @@ define(function (require) {
128
133
p5sound . meter . disconnect ( ) ;
129
134
130
135
if ( smoothing ) {
131
- this . smoothing = smoothing ;
136
+ this . _workletNode . parameters . get ( ' smoothing' ) . value = smoothing ;
132
137
}
133
138
134
139
// connect to the master out of p5s instance if no snd is provided
135
140
if ( source == null ) {
136
141
console . log ( 'Amplitude input source is not ready! Connecting to master output instead' ) ;
137
- p5sound . meter . connect ( this . processor ) ;
142
+ p5sound . meter . connect ( this . _workletNode ) ;
138
143
}
139
144
140
145
// if it is a p5.Signal
141
146
else if ( source instanceof p5 . Signal ) {
142
- source . output . connect ( this . processor ) ;
147
+ source . output . connect ( this . _workletNode ) ;
143
148
}
144
149
// connect to the sound if it is available
145
150
else if ( source ) {
146
- source . connect ( this . processor ) ;
147
- this . processor . disconnect ( ) ;
148
- this . processor . connect ( this . output ) ;
151
+ source . connect ( this . _workletNode ) ;
152
+ this . _workletNode . disconnect ( ) ;
153
+ this . _workletNode . connect ( this . output ) ;
149
154
}
150
155
151
156
// otherwise, connect to the master out of p5s instance (default)
152
157
else {
153
- p5sound . meter . connect ( this . processor ) ;
158
+ p5sound . meter . connect ( this . _workletNode ) ;
154
159
}
155
160
} ;
156
161
@@ -172,56 +177,6 @@ define(function (require) {
172
177
}
173
178
} ;
174
179
175
- // TO DO make this stereo / dependent on # of audio channels
176
- p5 . Amplitude . prototype . _audioProcess = function ( event ) {
177
-
178
- for ( var channel = 0 ; channel < event . inputBuffer . numberOfChannels ; channel ++ ) {
179
- var inputBuffer = event . inputBuffer . getChannelData ( channel ) ;
180
- var bufLength = inputBuffer . length ;
181
-
182
- var total = 0 ;
183
- var sum = 0 ;
184
- var x ;
185
-
186
- for ( var i = 0 ; i < bufLength ; i ++ ) {
187
- x = inputBuffer [ i ] ;
188
- if ( this . normalize ) {
189
- total += Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) ;
190
- sum += Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) * Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) ;
191
- }
192
- else {
193
- total += x ;
194
- sum += x * x ;
195
- }
196
- }
197
- var average = total / bufLength ;
198
-
199
- // ... then take the square root of the sum.
200
- var rms = Math . sqrt ( sum / bufLength ) ;
201
-
202
- this . stereoVol [ channel ] = Math . max ( rms , this . stereoVol [ channel ] * this . smoothing ) ;
203
- this . stereoAvg [ channel ] = Math . max ( average , this . stereoVol [ channel ] * this . smoothing ) ;
204
- this . volMax = Math . max ( this . stereoVol [ channel ] , this . volMax ) ;
205
- }
206
-
207
- // add volume from all channels together
208
- var self = this ;
209
- var volSum = this . stereoVol . reduce ( function ( previousValue , currentValue , index ) {
210
- self . stereoVolNorm [ index - 1 ] = Math . max ( Math . min ( self . stereoVol [ index - 1 ] / self . volMax , 1 ) , 0 ) ;
211
- self . stereoVolNorm [ index ] = Math . max ( Math . min ( self . stereoVol [ index ] / self . volMax , 1 ) , 0 ) ;
212
-
213
- return previousValue + currentValue ;
214
- } ) ;
215
-
216
- // volume is average of channels
217
- this . volume = volSum / this . stereoVol . length ;
218
-
219
- // normalized value
220
- this . volNorm = Math . max ( Math . min ( this . volume / this . volMax , 1 ) , 0 ) ;
221
-
222
-
223
- } ;
224
-
225
180
/**
226
181
* Returns a single Amplitude reading at the moment it is called.
227
182
* For continuous readings, run in the draw loop.
@@ -288,6 +243,7 @@ define(function (require) {
288
243
else {
289
244
this . normalize = ! this . normalize ;
290
245
}
246
+ this . _workletNode . port . postMessage ( { name : 'toggleNormalize' , normalize : this . normalize } ) ;
291
247
} ;
292
248
293
249
/**
@@ -300,7 +256,7 @@ define(function (require) {
300
256
*/
301
257
p5 . Amplitude . prototype . smooth = function ( s ) {
302
258
if ( s >= 0 && s < 1 ) {
303
- this . smoothing = s ;
259
+ this . _workletNode . parameters . get ( ' smoothing' ) . value = s ;
304
260
} else {
305
261
console . log ( 'Error: smoothing must be between 0 and 1' ) ;
306
262
}
@@ -320,7 +276,8 @@ define(function (require) {
320
276
delete this . output ;
321
277
}
322
278
323
- delete this . processor ;
279
+ this . _workletNode . disconnect ( ) ;
280
+ delete this . _workletNode ;
324
281
} ;
325
282
326
283
} ) ;
0 commit comments