Signatur
Beschreibung
Die Eigenschaft frequency eines OscillatorNode gibt ein AudioParam-Objekt zurück, das die Grundfrequenz des erzeugten Tons in Hertz festlegt. Der Standardwert ist 440, also der Kammerton a'. Die Eigenschaft selbst ist schreibgeschützt: Du weist nicht osc.frequency = 880 zu, sondern änderst den Wert über osc.frequency.value oder mit den Automatisierungsmethoden des AudioParam.
Weil es sich um einen a-rate-Parameter handelt, wird der Wert für jedes einzelne Sample neu berechnet. Deshalb eignet er sich für sample-genaue Automatisierung wie Glissandi, Sirenen oder Pitch-Envelopes, zum Beispiel mit setValueAtTime(), linearRampToValueAtTime(), exponentialRampToValueAtTime() oder setTargetAtTime().
Außerdem lässt sich ein anderer Audioknoten direkt mit dem Parameter verbinden, etwa ein zweiter Oszillator als LFO über einen GainNode. So entstehen Vibrato oder Frequenzmodulation (FM-Synthese). Das eingehende Signal wird dabei zum Grundwert value addiert. Die tatsächlich wirksame Frequenz ergibt sich zusammen mit detune (in Cent) nach der Formel frequency · 2^(detune/1200).
Rückgabewert
AudioParam mit defaultValue 440, minValue −Nyquist-Frequenz und maxValue +Nyquist-Frequenz (sampleRate / 2, z. B. 24000 bei 48 kHz).Beispiele
Ton mit fester Frequenz abspielen
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx, { type: 'sine', frequency: 261.63 }); // c'
osc.connect(ctx.destination);
console.log(osc.frequency.value, osc.frequency.defaultValue);
osc.start();
osc.stop(ctx.currentTime + 1); // eine Sekunde lang
Sirene: Frequenz automatisiert hoch- und runterfahren
const ctx = new AudioContext();
const osc = ctx.createOscillator();
osc.type = 'sawtooth';
osc.connect(ctx.destination);
const t = ctx.currentTime;
const f = osc.frequency;
f.setValueAtTime(400, t);
for (let i = 0; i < 4; i++) {
f.exponentialRampToValueAtTime(900, t + i + 0.5);
f.exponentialRampToValueAtTime(400, t + i + 1);
}
osc.start(t);
osc.stop(t + 4);
Vibrato per LFO an frequency anschließen
const ctx = new AudioContext();
const carrier = new OscillatorNode(ctx, { frequency: 440 });
const lfo = new OscillatorNode(ctx, { frequency: 5 }); // 5 Hz Vibrato
const depth = new GainNode(ctx, { gain: 10 }); // ±10 Hz
lfo.connect(depth).connect(carrier.frequency); // Signal wird zu value addiert
carrier.connect(ctx.destination);
lfo.start();
carrier.start();
setTimeout(() => { carrier.stop(); lfo.stop(); }, 3000);
Frequenz per Schieberegler ohne Knacken ändern
const ctx = new AudioContext();
const osc = new OscillatorNode(ctx);
osc.connect(ctx.destination);
document.querySelector('#start').addEventListener('click', async () => {
await ctx.resume();
osc.start();
}, { once: true });
document.querySelector('#freq').addEventListener('input', (e) => {
const hz = Number(e.target.value);
// weiches Nachführen statt harter Sprünge
osc.frequency.setTargetAtTime(hz, ctx.currentTime, 0.02);
});
// Wichtig · Fallstricke
- Schreibgeschützt:
osc.frequency = 880hat keine Wirkung (im Strict Mode gibt es einenTypeError). Richtig istosc.frequency.value = 880oder eine Automatisierungsmethode. - value vs. Automatisierung: Sobald Ereignisse eingeplant sind, können direkte Zuweisungen an
valueignoriert oder überschrieben werden. Bestehende Planungen löschst du vorher mitcancelScheduledValues(). exponentialRampToValueAtTime()bricht bei Ziel- oder Startwert0mit einemRangeErrorab. Außerdem braucht die Rampe einen vorherigen Ankerpunkt, zum Beispiel übersetValueAtTime().- Werte außerhalb von ±Nyquist werden begrenzt. Frequenzen nahe der Nyquist-Grenze verursachen bei den Wellenformen
square,sawtoothundtrianglehörbares Aliasing. - Abrupte Wertsprünge können Knackser verursachen. Für flüssige Übergänge besser
setTargetAtTime()oder Rampen verwenden. - Browser starten einen
AudioContextwegen der Autoplay-Richtlinien oft im Zustandsuspended. Rufectx.resume()daher in einer Benutzeraktion auf. - Kompatibilität: Die Eigenschaft wird in allen modernen Browsern unterstützt. Alte Safari-Versionen brauchen noch
webkitAudioContext, und der Konstruktornew OscillatorNode()fehlt dort teilweise. In dem Fall hilftctx.createOscillator().