1
- // import processor name via preval.require so that it's available as a value at compile time
1
+ // import dependencies via preval.require so that they're available as values at compile time
2
2
const processorNames = preval . require ( './processorNames' ) ;
3
+ const RingBuffer = preval . require ( './ringBuffer' ) . default ;
3
4
4
5
class AmplitudeProcessor extends AudioWorkletProcessor {
5
6
constructor ( options ) {
6
7
super ( ) ;
7
8
8
9
const processorOptions = options . processorOptions || { } ;
9
- this . smoothing = processorOptions . smoothing || 0 ;
10
+ this . numOutputChannels = options . outputChannelCount || 1 ;
11
+ this . numInputChannels = processorOptions . numInputChannels || 2 ;
10
12
this . normalize = processorOptions . normalize || false ;
13
+ this . smoothing = processorOptions . smoothing || 0 ;
14
+ this . bufferSize = processorOptions . bufferSize || 2048 ;
15
+
16
+ this . inputRingBuffer = new RingBuffer ( this . bufferSize , this . numInputChannels ) ;
17
+ this . outputRingBuffer = new RingBuffer ( this . bufferSize , this . numOutputChannels ) ;
18
+ this . inputRingBufferArraySequence = new Array ( this . numInputChannels ) . fill ( null ) . map ( ( ) => new Float32Array ( this . bufferSize ) ) ;
11
19
12
20
this . stereoVol = [ 0 , 0 ] ;
13
21
this . stereoVolNorm = [ 0 , 0 ] ;
@@ -30,53 +38,61 @@ class AmplitudeProcessor extends AudioWorkletProcessor {
30
38
const output = outputs [ 0 ] ;
31
39
const smoothing = this . smoothing ;
32
40
33
- for ( let channel = 0 ; channel < input . length ; ++ channel ) {
34
- const inputBuffer = input [ channel ] ;
35
- const bufLength = inputBuffer . length ;
36
-
37
- let sum = 0 ;
38
- for ( var i = 0 ; i < bufLength ; i ++ ) {
39
- const x = inputBuffer [ i ] ;
40
- if ( this . normalize ) {
41
- sum += Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) * Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) ;
42
- } else {
43
- sum += x * x ;
41
+ this . inputRingBuffer . push ( input ) ;
42
+
43
+ if ( this . inputRingBuffer . framesAvailable >= this . bufferSize ) {
44
+ this . inputRingBuffer . pull ( this . inputRingBufferArraySequence ) ;
45
+
46
+ for ( let channel = 0 ; channel < this . numInputChannels ; ++ channel ) {
47
+ const inputBuffer = this . inputRingBufferArraySequence [ channel ] ;
48
+ const bufLength = inputBuffer . length ;
49
+
50
+ let sum = 0 ;
51
+ for ( var i = 0 ; i < bufLength ; i ++ ) {
52
+ const x = inputBuffer [ i ] ;
53
+ if ( this . normalize ) {
54
+ sum += Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) * Math . max ( Math . min ( x / this . volMax , 1 ) , - 1 ) ;
55
+ } else {
56
+ sum += x * x ;
57
+ }
44
58
}
45
- }
46
59
47
- // ... then take the square root of the sum.
48
- const rms = Math . sqrt ( sum / bufLength ) ;
60
+ // ... then take the square root of the sum.
61
+ const rms = Math . sqrt ( sum / bufLength ) ;
49
62
50
- this . stereoVol [ channel ] = Math . max ( rms , this . stereoVol [ channel ] * smoothing ) ;
51
- this . volMax = Math . max ( this . stereoVol [ channel ] , this . volMax ) ;
52
- }
63
+ this . stereoVol [ channel ] = Math . max ( rms , this . stereoVol [ channel ] * smoothing ) ;
64
+ this . volMax = Math . max ( this . stereoVol [ channel ] , this . volMax ) ;
65
+ }
53
66
54
- // calculate stero normalized volume and add volume from all channels together
55
- let volSum = 0 ;
56
- for ( let index = 0 ; index < this . stereoVol . length ; index ++ ) {
57
- this . stereoVolNorm [ index ] = Math . max ( Math . min ( this . stereoVol [ index ] / this . volMax , 1 ) , 0 ) ;
58
- volSum += this . stereoVol [ index ] ;
59
- }
67
+ // calculate stero normalized volume and add volume from all channels together
68
+ let volSum = 0 ;
69
+ for ( let index = 0 ; index < this . stereoVol . length ; index ++ ) {
70
+ this . stereoVolNorm [ index ] = Math . max ( Math . min ( this . stereoVol [ index ] / this . volMax , 1 ) , 0 ) ;
71
+ volSum += this . stereoVol [ index ] ;
72
+ }
60
73
61
- // volume is average of channels
62
- const volume = volSum / this . stereoVol . length ;
74
+ // volume is average of channels
75
+ const volume = volSum / this . stereoVol . length ;
63
76
64
- // normalized value
65
- const volNorm = Math . max ( Math . min ( volume / this . volMax , 1 ) , 0 ) ;
77
+ // normalized value
78
+ const volNorm = Math . max ( Math . min ( volume / this . volMax , 1 ) , 0 ) ;
66
79
67
- this . port . postMessage ( {
68
- name : 'amplitude' ,
69
- volume : volume ,
70
- volNorm : volNorm ,
71
- stereoVol : this . stereoVol ,
72
- stereoVolNorm : this . stereoVolNorm
73
- } ) ;
80
+ this . port . postMessage ( {
81
+ name : 'amplitude' ,
82
+ volume : volume ,
83
+ volNorm : volNorm ,
84
+ stereoVol : this . stereoVol ,
85
+ stereoVolNorm : this . stereoVolNorm
86
+ } ) ;
74
87
75
- // pass input through to output
76
- for ( let channel = 0 ; channel < output . length ; ++ channel ) {
77
- output [ channel ] . set ( input [ channel ] ) ;
88
+ // pass input through to output
89
+ this . outputRingBuffer . push ( this . inputRingBufferArraySequence ) ;
78
90
}
79
91
92
+ // pull 128 frames out of the ring buffer
93
+ // if the ring buffer does not have enough frames, the output will be silent
94
+ this . outputRingBuffer . pull ( output ) ;
95
+
80
96
return true ;
81
97
}
82
98
}
0 commit comments