Start · Sprachen · JavaScript · Referenz · AudioBuffer.copyToChannel()

AudioBuffer.copyToChannel()

Methode

Kopiert Samples aus einem <code>Float32Array</code> in einen bestimmten Kanal eines <code>AudioBuffer</code>, optional ab einer Startposition.

seit JavaScript Baseline: alle modernen Browser (Web Audio API) Kategorie: webapi

Signatur

AudioBuffer.prototype.copyToChannel(source, channelNumber, bufferOffset)

Beschreibung

copyToChannel() schreibt Audio-Samples aus einem Float32Array in einen Kanal eines AudioBuffer. Damit kann man Pufferinhalte gezielt überschreiben, etwa um synthetisch erzeugte Wellenformen, bearbeitete Samples oder dekodierte Rohdaten in einen Puffer zu übertragen, der danach über einen AudioBufferSourceNode abgespielt wird.

Die Methode ist das Gegenstück zu copyFromChannel(). Anders als getChannelData(), das eine direkte Ansicht auf die internen Daten liefert, arbeitet copyToChannel() immer mit einer Kopie. Der Browser kann den Puffer so intern optimieren, und du musst dich nicht um Sperren kümmern, während der Puffer gerade abgespielt wird.

Über bufferOffset legst du fest, ab welchem Sample im Zielkanal geschrieben wird. Ist das Quellarray länger als der verbleibende Platz im Kanal, werden nur so viele Samples kopiert, wie hineinpassen. Der Rest wird stillschweigend verworfen.

Parameter

Name Typ Default Beschreibung
$source Pflicht Float32Array Das Array mit den Samples, die kopiert werden sollen. Übliche Werte liegen zwischen -1.0 und 1.0.
$channelNumber Pflicht number Index des Zielkanals, beginnend bei 0. Der Wert muss kleiner als buffer.numberOfChannels sein.
$bufferOffset number 0 Sample-Position im Zielkanal, ab der geschrieben wird. Ist der Wert größer als buffer.length, wird nichts kopiert.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Der Inhalt des Puffers wird direkt verändert.

Beispiele

Sinuston erzeugen und abspielen

const ctx = new AudioContext();
const sampleRate = ctx.sampleRate;
const dauer = 1; // Sekunden
const buffer = ctx.createBuffer(1, sampleRate * dauer, sampleRate);

// 440-Hz-Sinus berechnen
const samples = new Float32Array(buffer.length);
for (let i = 0; i < samples.length; i++) {
  samples[i] = Math.sin(2 * Math.PI * 440 * i / sampleRate) * 0.3;
}

buffer.copyToChannel(samples, 0);

const quelle = ctx.createBufferSource();
quelle.buffer = buffer;
quelle.connect(ctx.destination);
quelle.start();

Linken Kanal in den rechten kopieren (Mono → Stereo)

const ctx = new AudioContext();
const buffer = ctx.createBuffer(2, 4, ctx.sampleRate);

buffer.copyToChannel(new Float32Array([0.1, 0.2, 0.3, 0.4]), 0);

// Linken Kanal auslesen und rechts einfügen
const links = new Float32Array(buffer.length);
buffer.copyFromChannel(links, 0);
buffer.copyToChannel(links, 1);

console.log(Array.from(buffer.getChannelData(1)));
[0.10000000149011612, 0.20000000298023224, 0.30000001192092896, 0.4000000059604645]

Mit Offset einfügen und Kürzung am Pufferende

const ctx = new OfflineAudioContext(1, 6, 44100);
const buffer = ctx.createBuffer(1, 6, 44100);

// 4 Samples ab Position 4: nur 2 passen hinein
buffer.copyToChannel(new Float32Array([1, 1, 1, 1]), 0, 4);

console.log(Array.from(buffer.getChannelData(0)));
[0, 0, 0, 0, 1, 1]

// Wichtig · Fallstricke

  • Ist channelNumber größer oder gleich numberOfChannels, wird ein IndexSizeError (DOMException) ausgelöst.
  • Ist source kein Float32Array, wird ein TypeError ausgelöst. Normale Arrays musst du vorher mit new Float32Array(arr) umwandeln.
  • Wenn das Quellarray nicht in den Kanal passt, wird es ohne Warnung gekürzt. Prüfe bei Bedarf vorher buffer.length - bufferOffset.
  • Änderungen, die du über eine früher mit getChannelData() geholte Ansicht vornimmst, können mit copyToChannel() kollidieren. Verwende beim Schreiben am besten nur einen der beiden Wege.
  • Das source-Array darf nicht auf einem SharedArrayBuffer beruhen. Sonst gibt es einen TypeError.
  • Browser-Kompatibilität: Chrome, Firefox, Edge und Safari (ab Version 14.1) unterstützen die Methode. Sehr alte Safari-Versionen kennen nur webkitAudioContext und kein copyToChannel(). Dort bleibt als Ausweg nur getChannelData().set().