Signatur
Beschreibung
copyFromChannel() liest die PCM-Samples eines bestimmten Kanals aus einem AudioBuffer und schreibt sie in ein Float32Array, das du selbst anlegst. Die Werte liegen normalerweise im Bereich −1.0 bis +1.0. Kopiert wird ab dem Index bufferOffset im Quellkanal, und zwar so viele Samples, wie in das Ziel-Array passen oder im Kanal noch übrig sind (je nachdem, was kleiner ist).
Im Unterschied zu getChannelData(), das eine direkte Referenz auf die internen Kanaldaten zurückgibt, entsteht hier eine unabhängige Kopie. Wenn du das Ziel-Array später änderst, bleibt der Buffer unverändert. Außerdem kannst du ein vorhandenes Array immer wieder befüllen, also etwa blockweise durch einen langen Buffer gehen, ohne jedes Mal neuen Speicher anzulegen.
Typische Einsatzfälle sind Wellenform-Darstellungen, Pegel- und Spitzenwertanalyse, das Ausschneiden von Abschnitten, das Kopieren zwischen Buffern (zusammen mit copyToChannel()) und die Übergabe von Audiodaten an Worker oder Encoder.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $destination Pflicht | Float32Array | Ziel-Array, in das die Samples geschrieben werden. Seine Länge bestimmt, wie viele Samples höchstens kopiert werden. | |
| $channelNumber Pflicht | number | Index des Quellkanals, bei 0 beginnend (bei Stereo: 0 = links, 1 = rechts). Muss kleiner als numberOfChannels sein. |
|
| $bufferOffset | number | 0 | Sample-Index im Quellkanal, ab dem kopiert wird. Nützlich, um Abschnitte oder Blöcke auszulesen. |
Rückgabewert
undefined). Das Ergebnis steht im übergebenen destination-Array.Beispiele
Einen Kanal vollständig kopieren
const ctx = new AudioContext();
const buffer = new AudioBuffer({ numberOfChannels: 2, length: 4, sampleRate: ctx.sampleRate });
// Linken Kanal mit Testdaten füllen
buffer.copyToChannel(new Float32Array([0.1, 0.5, -0.5, 1]), 0);
const links = new Float32Array(buffer.length);
buffer.copyFromChannel(links, 0);
links[0] = 0.9; // ändert NICHT den Buffer
console.log(Array.from(links));
console.log(buffer.getChannelData(0)[0]);
Einen Ausschnitt ab einer Zeitposition auslesen
const sekundeAusschneiden = (buffer, startSekunden, kanal = 0) => {
const start = Math.floor(startSekunden * buffer.sampleRate);
const ziel = new Float32Array(buffer.sampleRate); // 1 Sekunde
buffer.copyFromChannel(ziel, kanal, start);
return ziel;
};
const response = await fetch('/audio/song.mp3');
const ctx = new AudioContext();
const buffer = await ctx.decodeAudioData(await response.arrayBuffer());
const ausschnitt = sekundeAusschneiden(buffer, 10);
console.log(ausschnitt.length === buffer.sampleRate);
Spitzenwerte für eine Wellenform-Anzeige blockweise berechnen
const berechnePeaks = (buffer, anzahlBalken, kanal = 0) => {
const blockGroesse = Math.floor(buffer.length / anzahlBalken);
const block = new Float32Array(blockGroesse); // wird wiederverwendet
const peaks = [];
for (let i = 0; i < anzahlBalken; i++) {
buffer.copyFromChannel(block, kanal, i * blockGroesse);
let max = 0;
for (const s of block) max = Math.max(max, Math.abs(s));
peaks.push(Number(max.toFixed(3)));
}
return peaks;
};
const ctx = new OfflineAudioContext(1, 44100, 44100);
const buffer = ctx.createBuffer(1, 44100, 44100);
const daten = buffer.getChannelData(0);
for (let i = 0; i < daten.length; i++) daten[i] = Math.sin(i / 20) * (i / daten.length);
console.log(berechnePeaks(buffer, 4));
Kanal zwischen zwei Buffern kopieren (Mono zu Stereo)
const monoZuStereo = (ctx, mono) => {
const stereo = ctx.createBuffer(2, mono.length, mono.sampleRate);
const tmp = new Float32Array(mono.length);
mono.copyFromChannel(tmp, 0);
stereo.copyToChannel(tmp, 0);
stereo.copyToChannel(tmp, 1);
return stereo;
};
const ctx = new AudioContext();
const mono = ctx.createBuffer(1, 1000, ctx.sampleRate);
const stereo = monoZuStereo(ctx, mono);
console.log(stereo.numberOfChannels);
// Wichtig · Fallstricke
- Ungültiger Kanal: Ist
channelNumbergrößer oder gleichnumberOfChannels, wird eineIndexSizeError-DOMExceptiongeworfen. Prüfe daher vorherbuffer.numberOfChannels. - Falscher Zieltyp:
destinationmuss einFloat32Arraysein. Normale Arrays oderFloat64Arrayführen zu einemTypeError. - Keine Fehlermeldung bei zu kurzem Rest: Wenn ab
bufferOffsetweniger Samples übrig sind, als das Ziel aufnehmen kann, werden nur die vorhandenen kopiert. Der Rest des Ziel-Arrays bleibt, wie er war, also nicht automatisch 0. Beim Wiederverwenden eines Arrays solltest du es vorher mitfill(0)leeren. Ältere Browser warfen bei einem Offset außerhalb des Buffers teils eineIndexSizeError. - Kopie oder Referenz:
getChannelData()gibt die internen Daten ohne Kopie zurück und ist für reine Lesezugriffe oft schneller.copyFromChannel()nimmst du, wenn du die Daten unabhängig vom Buffer brauchst. - Kompatibilität: In Chrome, Firefox und Edge seit Langem verfügbar, in Safari erst ab Version 14.1. Für sehr alte Safari-Versionen kannst du auf
getChannelData(n).slice()ausweichen.