Signatur
Beschreibung
Der Konstruktor DynamicsCompressorNode() erzeugt einen Dynamikkompressor für einen Audiograph der Web Audio API. Ein Kompressor senkt den Pegel ab, sobald das Signal einen Schwellwert (threshold) überschreitet. Das Verhältnis (ratio) legt fest, wie stark abgesenkt wird. Dadurch wird der Dynamikumfang kleiner, und leise wie laute Passagen liegen näher beieinander. Das ist besonders nützlich, wenn mehrere Quellen gleichzeitig spielen und die Summe sonst übersteuern würde (Clipping).
Im Unterschied zur älteren Fabrikmethode BaseAudioContext.createDynamicsCompressor() kannst du beim Konstruktor alle Parameter direkt über das options-Objekt setzen. Das funktioniert auch mit einem OfflineAudioContext, z. B. um Audio außerhalb der Echtzeit zu rendern.
Die Parameter threshold, knee, ratio, attack und release stehen danach als AudioParam-Eigenschaften zur Verfügung. Du kannst sie also mit Methoden wie setValueAtTime() oder linearRampToValueAtTime() zeitgenau automatisieren. Die schreibgeschützte Eigenschaft reduction zeigt die aktuelle Pegelabsenkung in dB an. Mit ihr lässt sich z. B. eine Anzeige für die Gain Reduction bauen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $context Pflicht | BaseAudioContext | Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehören soll. |
|
| $options | DynamicsCompressorOptions | {} | Optionales Objekt mit Anfangswerten. Nicht angegebene Felder bekommen ihren Standardwert. |
| $options.threshold | number | -24 | Schwellwert in dB, ab dem komprimiert wird. Bereich: -100 bis 0. |
| $options.knee | number | 30 | Breite des weichen Übergangs oberhalb des Schwellwerts in dB. Bereich: 0 bis 40. |
| $options.ratio | number | 12 | Kompressionsverhältnis: Um wie viele dB muss der Eingang steigen, damit der Ausgang um 1 dB steigt? Bereich: 1 bis 20. |
| $options.attack | number | 0.003 | Ansprechzeit in Sekunden, bis die Pegelabsenkung um 10 dB erreicht ist. Bereich: 0 bis 1. |
| $options.release | number | 0.25 | Rückstellzeit in Sekunden, bis die Absenkung um 10 dB wieder aufgehoben ist. Bereich: 0 bis 1. |
| $options.channelCount | number | 2 | Anzahl der Kanäle. Nur 1 oder 2 sind erlaubt, sonst wird ein NotSupportedError ausgelöst. |
| $options.channelCountMode | "clamped-max" | "explicit" | "clamped-max" | Legt fest, wie die Kanalzahl bestimmt wird. "max" ist nicht erlaubt und löst einen NotSupportedError aus. |
| $options.channelInterpretation | "speakers" | "discrete" | "speakers" | Legt fest, wie Kanäle beim Hoch- oder Heruntermischen verteilt werden. |
Rückgabewert
DynamicsCompressorNode mit einem Eingang und einem Ausgang.Beispiele
Kompressor mit eigenen Einstellungen erzeugen und einbinden
const ctx = new AudioContext();
const audioEl = document.querySelector('audio');
const source = ctx.createMediaElementSource(audioEl);
const compressor = new DynamicsCompressorNode(ctx, {
threshold: -50,
knee: 40,
ratio: 12,
attack: 0,
release: 0.25
});
// Quelle -> Kompressor -> Lautsprecher
source.connect(compressor).connect(ctx.destination);
document.querySelector('#play').addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Richtlinie: erst nach Nutzeraktion
audioEl.play();
console.log(compressor.threshold.value, compressor.ratio.value);
});
Standardwerte prüfen
const ctx = new AudioContext();
const comp = new DynamicsCompressorNode(ctx);
console.log({
threshold: comp.threshold.value,
knee: comp.knee.value,
ratio: comp.ratio.value,
attack: comp.attack.value.toFixed(3),
release: comp.release.value
});
Kompressor ein- und ausschalten und Pegelabsenkung anzeigen
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { type: 'sawtooth', frequency: 220 });
const gain = new GainNode(ctx, { gain: 2 }); // absichtlich zu laut
const comp = new DynamicsCompressorNode(ctx, { threshold: -30, ratio: 8 });
osc.connect(gain).connect(comp).connect(ctx.destination);
osc.start();
let active = true;
const toggle = () => {
gain.disconnect();
comp.disconnect();
if (active) {
gain.connect(ctx.destination); // Umgehung (Bypass)
} else {
gain.connect(comp).connect(ctx.destination);
}
active = !active;
};
const meter = () => {
console.log(`Reduktion: ${comp.reduction.toFixed(1)} dB`);
requestAnimationFrame(meter);
};
meter();
Offline rendern mit Kompressor
const offline = new OfflineAudioContext(2, 44100 * 2, 44100);
const osc = new OscillatorNode(offline, { frequency: 440 });
const comp = new DynamicsCompressorNode(offline, { threshold: -20, ratio: 4 });
osc.connect(comp).connect(offline.destination);
osc.start();
const buffer = await offline.startRendering();
console.log(buffer.duration);
// Wichtig · Fallstricke
- Kanalbeschränkung: Wenn
channelCountgrößer als 2 ist oderchannelCountModeden Wert\"max\"hat, löst der Konstruktor einenNotSupportedErroraus. - Wertebereiche: Werte außerhalb der Bereiche werden auf den gültigen Bereich begrenzt (geclampt). Dabei wird kein Fehler ausgelöst. Nicht-endliche Werte wie
NaNlösen dagegen einenTypeErroraus. - Automatisierung:
threshold,knee,ratio,attackundreleasesindk-rate-Parameter. Sie werden also nur einmal pro Render-Block (128 Samples) ausgewertet und nicht sampelgenau. - Kein Limiter: Ein Kompressor mit Standardwerten verhindert Clipping nicht vollständig. Für harte Begrenzung brauchst du ein hohes
ratio(20),attacknahe 0 und eventuell zusätzlich einenGainNodedahinter. - Latenz/Lookahead: Browser arbeiten intern mit einem kurzen Lookahead. Das kann eine kleine Verzögerung verursachen.
- Kompatibilität: Der Konstruktor wird von allen aktuellen Browsern unterstützt. In sehr alten Browsern (älteres Safari,
webkitAudioContext) gibt es nurcreateDynamicsCompressor(). Wenn du diese Browser unterstützen musst, nimm die Fabrikmethode als Ausweichlösung. - Ein
AudioContextstartet wegen der Autoplay-Richtlinien oft im Zustand\"suspended\". Du musst ihn nach einer Nutzeraktion mitresume()starten.