Signatur
Beschreibung
GainNode ist ein AudioNode mit genau einem Eingang und einem Ausgang, der jedes Sample des Eingangssignals mit dem Wert seines gain-Parameters multipliziert. Damit ist er der Standard-Baustein für Lautstärkeregler, Stummschaltung, Ein- und Ausblenden (Fades), Crossfades zwischen Quellen sowie für Hüllkurven (ADSR) bei Synthesizern.
Erzeugt wird ein Knoten entweder über die Fabrikmethode audioContext.createGain() oder über den Konstruktor new GainNode(context, options). Die einzige eigene Eigenschaft ist gain, ein a-rate-AudioParam mit dem Standardwert 1 (unverändert). Werte zwischen 0 und 1 schwächen ab, Werte über 1 verstärken, negative Werte kehren zusätzlich die Phase um.
Weil gain ein AudioParam ist, lässt er sich sample-genau automatisieren – etwa mit setValueAtTime(), linearRampToValueAtTime(), exponentialRampToValueAtTime() oder setTargetAtTime(). So vermeidet man hörbare Knackser, die beim abrupten Setzen von gain.value entstehen können. Außerdem kann ein anderer Audio-Knoten (z. B. ein OscillatorNode als LFO) direkt mit gain verbunden werden, um Tremolo-Effekte zu erzeugen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $context Pflicht | BaseAudioContext | Der AudioContext oder OfflineAudioContext, zu dem der Knoten gehört (nur beim Konstruktor). |
|
| $options | { gain?: number, channelCount?: number, channelCountMode?: string, channelInterpretation?: string } | { gain: 1 } | Optionale Startwerte. gain legt die anfängliche Verstärkung fest; die übrigen Felder sind die üblichen AudioNodeOptions. |
Rückgabewert
GainNode, dessen Eigenschaft gain (AudioParam, Standard 1, a-rate) die Verstärkung steuert.Beispiele
Lautstärkeregler für einen Oszillator
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { frequency: 440 });
const volume = ctx.createGain();
// Kette: Oszillator -> Gain -> Lautsprecher
osc.connect(volume).connect(ctx.destination);
volume.gain.value = 0.2; // 20 % Lautstärke
document.querySelector('#play').addEventListener('click', async () => {
await ctx.resume(); // Autoplay-Sperre aufheben
osc.start();
});
document.querySelector('#volume').addEventListener('input', (e) => {
// Sanft nachführen statt hart setzen -> keine Knackser
volume.gain.setTargetAtTime(Number(e.target.value), ctx.currentTime, 0.02);
});
console.log(volume.gain.defaultValue);
Konstruktor mit Optionen und Fade-out
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { type: 'sawtooth', frequency: 220 });
const fader = new GainNode(ctx, { gain: 0.5 });
osc.connect(fader).connect(ctx.destination);
const now = ctx.currentTime;
osc.start(now);
// Ausgangswert festhalten, dann in 2 s auf nahezu 0 ausblenden
fader.gain.setValueAtTime(0.5, now);
fader.gain.exponentialRampToValueAtTime(0.0001, now + 2);
osc.stop(now + 2.1);
console.log(fader.gain.value);
ADSR-Hüllkurve für einen Synthesizer-Ton
const ctx = new AudioContext();
const playNote = (freq, duration = 1) => {
const osc = new OscillatorNode(ctx, { frequency: freq });
const env = new GainNode(ctx, { gain: 0 });
osc.connect(env).connect(ctx.destination);
const t = ctx.currentTime;
env.gain.setValueAtTime(0, t);
env.gain.linearRampToValueAtTime(0.8, t + 0.02); // Attack
env.gain.linearRampToValueAtTime(0.5, t + 0.2); // Decay -> Sustain
env.gain.setValueAtTime(0.5, t + duration);
env.gain.linearRampToValueAtTime(0, t + duration + 0.3); // Release
osc.start(t);
osc.stop(t + duration + 0.35);
};
document.querySelector('#note').addEventListener('click', () => playNote(261.63));
Tremolo: LFO moduliert den gain-Parameter
const ctx = new AudioContext();
const carrier = new OscillatorNode(ctx, { frequency: 330 });
const amp = new GainNode(ctx, { gain: 0.5 });
const lfo = new OscillatorNode(ctx, { frequency: 5 }); // 5 Hz
const depth = new GainNode(ctx, { gain: 0.3 }); // Modulationstiefe
// LFO-Signal wird zum Grundwert 0.5 addiert: 0.2 … 0.8
lfo.connect(depth).connect(amp.gain);
carrier.connect(amp).connect(ctx.destination);
carrier.start();
lfo.start();
// Wichtig · Fallstricke
- Knackser vermeiden: Das direkte Setzen von
gain.valuewährend der Wiedergabe erzeugt Sprünge im Signal. BessersetTargetAtTime()oder Rampen verwenden. exponentialRampToValueAtTime()darf nicht auf0zielen oder von0starten (RangeError) – stattdessen einen sehr kleinen Wert wie0.0001nehmen.- Rampen beginnen beim zuletzt geplanten Ereignis. Vor einer Rampe daher mit
setValueAtTime()(bzw.cancelScheduledValues()) einen definierten Startpunkt setzen. - Werte über
1können zu Übersteuerung (Clipping) am Ausgang führen; bei mehreren summierten Quellen ggf. einen Master-Gain unter1oder einenDynamicsCompressorNodeeinsetzen. - Die Wahrnehmung von Lautstärke ist logarithmisch: Für natürliche Regler Dezibel umrechnen, z. B.
gain = 10 ** (dB / 20). - Kompatibilität: In allen modernen Browsern verfügbar; der Konstruktor
new GainNode()fehlt nur in sehr alten Versionen (dortcreateGain()nutzen, historisch in WebKitcreateGainNode()). EinAudioContextstartet wegen Autoplay-Richtlinien oft im Zustandsuspendedund muss nach einer Nutzerinteraktion mitresume()aktiviert werden.