Signatur
Beschreibung
exponentialRampToValueAtTime() plant auf der Zeitachse eines AudioParam einen exponentiellen Verlauf. Er beginnt beim Wert und Zeitpunkt des vorherigen geplanten Ereignisses und endet beim Zielwert value zum Zeitpunkt endTime, gemessen in der Zeitbasis von AudioContext.currentTime.
Exponentielle Rampen klingen für das menschliche Ohr natürlicher als lineare, denn Tonhöhe und Lautstärke nehmen wir logarithmisch wahr. Deshalb eignen sie sich besonders für Frequenz-Sweeps (z. B. OscillatorNode.frequency oder Filter-Grenzfrequenzen) und für das Ein- und Ausblenden von GainNode.gain. Beim Übergang von 100 Hz auf 200 Hz dauert der Weg genauso lange wie von 200 Hz auf 400 Hz.
Wichtig: Die Rampe braucht einen definierten Startpunkt. Setze vorher mit setValueAtTime() einen Ausgangswert fest. Ohne ein vorheriges Ereignis springen manche Browser sofort oder beginnen die Rampe an einer unerwarteten Stelle. Start- und Zielwert müssen dasselbe Vorzeichen haben und dürfen nicht 0 sein, denn eine Exponentialkurve kann 0 nie erreichen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | number | Zielwert, den der Parameter bei endTime erreicht. Darf nicht 0 sein und muss dasselbe Vorzeichen haben wie der Startwert. Ist er 0, wird ein RangeError geworfen. |
|
| $endTime Pflicht | number | Zeitpunkt in Sekunden (Zeitbasis AudioContext.currentTime), an dem die Rampe endet. Muss ≥ 0 und endlich sein, sonst wird ein RangeError bzw. TypeError geworfen. Liegt der Zeitpunkt in der Vergangenheit, wird der Zielwert sofort gesetzt. |
Rückgabewert
AudioParam-Objekt. Dadurch lassen sich mehrere Aufrufe verketten. In älteren Firefox-Versionen ist der Rückgabewert undefined.Beispiele
Frequenz-Sweep eines Oszillators
const ctx = new AudioContext();
const osc = ctx.createOscillator();
osc.connect(ctx.destination);
const now = ctx.currentTime;
// Startpunkt festlegen, dann exponentiell von 110 Hz auf 880 Hz in 2 Sekunden
osc.frequency.setValueAtTime(110, now);
osc.frequency.exponentialRampToValueAtTime(880, now + 2);
osc.start(now);
osc.stop(now + 2);
Weiches Ausblenden (Fade-out) ohne Knacken
const ctx = new AudioContext();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain).connect(ctx.destination);
const now = ctx.currentTime;
gain.gain.setValueAtTime(1, now);
// 0 ist nicht erlaubt – daher auf einen sehr kleinen Wert blenden
gain.gain.exponentialRampToValueAtTime(0.0001, now + 1.5);
// Danach hart auf 0 setzen
gain.gain.setValueAtTime(0, now + 1.5);
osc.start(now);
osc.stop(now + 1.6);
ADSR-Hüllkurve per Button-Klick
const ctx = new AudioContext();
const playNote = (freq = 440) => {
const osc = ctx.createOscillator();
const env = ctx.createGain();
osc.frequency.value = freq;
osc.connect(env).connect(ctx.destination);
const t = ctx.currentTime;
env.gain
.setValueAtTime(0.0001, t) // Start
.exponentialRampToValueAtTime(0.8, t + 0.02) // Attack
.exponentialRampToValueAtTime(0.3, t + 0.2) // Decay
.setValueAtTime(0.3, t + 0.6) // Sustain
.exponentialRampToValueAtTime(0.0001, t + 1.2); // Release
osc.start(t);
osc.stop(t + 1.25);
};
document.querySelector('#play').addEventListener('click', async () => {
if (ctx.state === 'suspended') await ctx.resume();
playNote(523.25);
});
Fehler bei Zielwert 0 abfangen
const ctx = new AudioContext();
const gain = ctx.createGain();
try {
gain.gain.exponentialRampToValueAtTime(0, ctx.currentTime + 1);
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Kein Zielwert 0:
value = 0löst einenRangeErroraus. Blende stattdessen auf z. B.0.0001und setze danach mitsetValueAtTime(0, …)auf 0. Alternativ kannst dusetTargetAtTime()verwenden. - Vorzeichenwechsel: Haben Start- und Zielwert unterschiedliche Vorzeichen oder ist der Startwert 0, bleibt der Wert bis
endTimekonstant und springt dann auf den Zielwert. - Startpunkt setzen: Rufe immer zuerst
setValueAtTime()auf. Das Setzen vonparam.valueallein legt kein verlässliches Zeitachsen-Ereignis an. Ohne Startpunkt beginnt die Rampe beim letzten Ereignis, im Zweifel bei Zeitpunkt 0. - Rampen unterbrechen: Mit
cancelScheduledValues()bzw.cancelAndHoldAtTime()brichst du geplante Rampen ab, etwa wenn eine Taste vorzeitig losgelassen wird.cancelAndHoldAtTime()wird von Firefox bisher nicht unterstützt. - Autoplay-Richtlinie: Ein
AudioContextstartet oft im Zustandsuspended. Rufectx.resume()daher nach einer Nutzerinteraktion auf. - Verkettung: Sehr alte Firefox-Versionen geben
undefinedstatt desAudioParamzurück. Für maximale Kompatibilität verzichtest du deshalb auf Verkettung.