Signatur
Beschreibung
parameterDescriptors ist keine Eigenschaft, die der Browser vorgibt. Du definierst sie selbst als statischen Getter in deiner Klasse, die von AudioWorkletProcessor erbt. Wenn du die Klasse mit registerProcessor() anmeldest, liest der Browser den Getter einmal aus. Aus jedem Deskriptor entsteht ein AudioParam, der im Haupt-Thread über AudioWorkletNode.parameters erreichbar ist.
Jedes Objekt im Iterable folgt dem Aufbau von AudioParamDescriptor:
name(Pflicht): eindeutiger Name des ParametersdefaultValue: Startwert, Standard0minValue: kleinster Wert, Standard-3.4028235e38maxValue: größter Wert, Standard3.4028235e38automationRate:"a-rate"(ein Wert pro Sample) oder"k-rate"(ein Wert pro Block mit 128 Frames), Standard"a-rate"
In process(inputs, outputs, parameters) kommen die aktuellen Werte als Float32Array unter dem jeweiligen Namen an. Das Array hat entweder 128 Einträge (der Wert wird im Block automatisiert) oder genau 1 Eintrag (der Wert bleibt im ganzen Block gleich). Dein Code muss beide Fälle abdecken.
Die Eigenschaft brauchst du immer dann, wenn ein eigener Audio-Prozessor Parameter haben soll, die sich sample-genau steuern lassen: etwa Lautstärke, Frequenz oder Mischverhältnis. Diese Parameter unterstützen dann setValueAtTime(), linearRampToValueAtTime() und Co. und lassen sich mit anderen Knoten verbinden.
Rückgabewert
AudioParam beschreiben: name, optional defaultValue, minValue, maxValue und automationRate.Beispiele
Gain-Prozessor mit einem Parameter (gain-processor.js)
// Datei: gain-processor.js – läuft im AudioWorkletGlobalScope
class GainProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
return [
{
name: 'gain',
defaultValue: 1,
minValue: 0,
maxValue: 1,
automationRate: 'a-rate'
}
];
}
process(inputs, outputs, parameters) {
const input = inputs[0];
const output = outputs[0];
const gain = parameters.gain; // Float32Array mit Länge 1 oder 128
for (let ch = 0; ch < output.length; ch++) {
const inCh = input[ch];
const outCh = output[ch];
if (!inCh) continue;
for (let i = 0; i < outCh.length; i++) {
// Konstanter Wert (Länge 1) oder automatisierter Wert pro Sample
outCh[i] = inCh[i] * (gain.length > 1 ? gain[i] : gain[0]);
}
}
return true; // Prozessor weiterlaufen lassen
}
}
registerProcessor('gain-processor', GainProcessor);
Parameter im Haupt-Thread nutzen und automatisieren
const ctx = new AudioContext();
await ctx.audioWorklet.addModule('gain-processor.js');
const osc = new OscillatorNode(ctx, { frequency: 440 });
const gainNode = new AudioWorkletNode(ctx, 'gain-processor', {
parameterData: { gain: 0.5 } // überschreibt defaultValue
});
osc.connect(gainNode).connect(ctx.destination);
// Aus dem Deskriptor entstandener AudioParam
const gainParam = gainNode.parameters.get('gain');
console.log(gainParam.defaultValue, gainParam.minValue, gainParam.maxValue);
// Fade-out über 2 Sekunden
gainParam.setValueAtTime(0.5, ctx.currentTime);
gainParam.linearRampToValueAtTime(0, ctx.currentTime + 2);
osc.start();
Mehrere Parameter, k-rate und Aufzählung
// Im Worklet-Modul
class FilterProcessor extends AudioWorkletProcessor {
static get parameterDescriptors() {
return [
{ name: 'cutoff', defaultValue: 1000, minValue: 20, maxValue: 20000, automationRate: 'k-rate' },
{ name: 'mix', defaultValue: 1, minValue: 0, maxValue: 1 }
];
}
process(inputs, outputs, parameters) {
const cutoff = parameters.cutoff[0]; // k-rate: immer genau 1 Wert pro Block
// ... Filterberechnung ...
return true;
}
}
registerProcessor('filter-processor', FilterProcessor);
// Im Haupt-Thread: alle Parameter auflisten
// const node = new AudioWorkletNode(ctx, 'filter-processor');
// for (const [name, param] of node.parameters) {
// console.log(name, param.value, param.automationRate);
// }
// Wichtig · Fallstricke
- Nur beim Registrieren gelesen: Der Getter wird bei
registerProcessor()ausgewertet. Wenn du ihn danach änderst, hat das keine Wirkung. Parameter lassen sich also nicht dynamisch hinzufügen. - Muss
staticsein: Ein normaler Getter oder eine Instanz-Eigenschaft wird ignoriert. Liefert der Getter kein Iterable, wirftregisterProcessor()einenTypeError. - Fehler bei der Registrierung: Doppelte Namen oder ein
defaultValueaußerhalb vonminValue/maxValueführen zu einerNotSupportedError-DOMException. Dasselbe gilt fürminValue > maxValue. - Länge des Arrays prüfen: Das
Float32Arrayinprocess()hat entweder 1 oder 128 Einträge. Wer blind aufparam[i]zugreift, liest bei konstanten Wertenundefinedund erzeugtNaN-Audio. - Werte außerhalb von
minValue/maxValuewerden automatisch auf den Bereich begrenzt. - Kompatibilität: AudioWorklet gibt es in Chrome 66+, Firefox 76+ und Safari 14.1+. Es braucht einen sicheren Kontext (HTTPS oder localhost).