-
-
Notifications
You must be signed in to change notification settings - Fork 682
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace ScriptProcessorNode with AudioWorkletNode in p5.SoundFile and p5.Amplitude #373
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// import processor name via preval.require so that it's available as a value at compile time | ||
const processorNames = preval.require('./processorNames'); | ||
|
||
class AmplitudeProcessor extends AudioWorkletProcessor { | ||
static get parameterDescriptors() { | ||
return [ | ||
{ | ||
name: 'smoothing', | ||
defaultValue: 0, | ||
minValue: 0, | ||
maxValue: 1, | ||
automationRate: 'k-rate' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inspecting this in Chrome 75.0.3770.100, somehow it has become There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @oshoham seems like this is related to a bug in the polyfill: In Firefox and Safari (using the ScriptProcessorNode fallback) the smoothing param is being passed to the I think the best way around this for now is to make Smoothing one of the processorOptions that updates on a message, like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I see the bug, it looks like the polyfill is assuming that all worklet parameters are I think your suggested approach makes sense - another possible solution is to treat the smoothing parameter as |
||
} | ||
]; | ||
} | ||
|
||
constructor(options) { | ||
super(); | ||
|
||
const processorOptions = options.processorOptions || {}; | ||
this.normalize = processorOptions.normalize || false; | ||
|
||
this.stereoVol = [0, 0]; | ||
this.stereoVolNorm = [0, 0]; | ||
|
||
this.volMax = 0.001; | ||
|
||
this.port.onmessage = (event) => { | ||
const data = event.data; | ||
if (data.name === 'toggleNormalize') { | ||
this.normalize = data.normalize; | ||
} | ||
}; | ||
} | ||
|
||
// TO DO make this stereo / dependent on # of audio channels | ||
process(inputs, outputs, parameters) { | ||
const input = inputs[0]; | ||
const output = outputs[0]; | ||
const smoothing = parameters.smoothing; | ||
|
||
for (let channel = 0; channel < input.length; ++channel) { | ||
const inputBuffer = input[channel]; | ||
const bufLength = inputBuffer.length; | ||
|
||
let sum = 0; | ||
for (var i = 0; i < bufLength; i++) { | ||
const x = inputBuffer[i]; | ||
if (this.normalize) { | ||
sum += Math.max(Math.min(x / this.volMax, 1), -1) * Math.max(Math.min(x / this.volMax, 1), -1); | ||
} else { | ||
sum += x * x; | ||
} | ||
} | ||
|
||
// ... then take the square root of the sum. | ||
const rms = Math.sqrt(sum / bufLength); | ||
|
||
this.stereoVol[channel] = Math.max(rms, this.stereoVol[channel] * smoothing); | ||
this.volMax = Math.max(this.stereoVol[channel], this.volMax); | ||
} | ||
|
||
// calculate stero normalized volume and add volume from all channels together | ||
let volSum = 0; | ||
for (let index = 0; index < this.stereoVol.length; index++) { | ||
this.stereoVolNorm[index] = Math.max(Math.min(this.stereoVol[index] / this.volMax, 1), 0); | ||
volSum += this.stereoVol[index]; | ||
} | ||
|
||
// volume is average of channels | ||
const volume = volSum / this.stereoVol.length; | ||
|
||
// normalized value | ||
const volNorm = Math.max(Math.min(volume / this.volMax, 1), 0); | ||
|
||
this.port.postMessage({ | ||
name: 'amplitude', | ||
volume: volume, | ||
volNorm: volNorm, | ||
stereoVol: this.stereoVol, | ||
stereoVolNorm: this.stereoVolNorm | ||
}); | ||
|
||
// pass input through to output | ||
for (let channel = 0; channel < output.length; ++channel) { | ||
output[channel].set(input[channel]); | ||
} | ||
|
||
return true; | ||
} | ||
} | ||
|
||
registerProcessor(processorNames.amplitudeProcessor, AmplitudeProcessor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a potential improvement, we could check the range here, as in the
smooth
method. But we could also just let the parameterDescriptors handle enforcing (and choosing whether to notify the user) about the range.