fix: support Int16Array depuis LiveKit Node SDK

LiveKit renvoie Int16Array directement au lieu de Buffer.
Ajout détection Int16Array dans _bufferToFloat32 avec conversion directe.

Ajout logs RMS/dBFS pour diagnostiquer niveau audio.
This commit is contained in:
2026-05-28 15:31:41 +02:00
parent 5534a43b0a
commit 05e7f69ffb
2 changed files with 101 additions and 82 deletions
+31 -8
View File
@@ -374,12 +374,21 @@ export class AudioBridge extends EventEmitter {
client.on('audioData', ({ participantName, pcmData, sampleRate, channels }) => { client.on('audioData', ({ participantName, pcmData, sampleRate, channels }) => {
// Log premier frame pour diagnostic // Log premier frame pour diagnostic
if (!this._firstFrameLogged) { if (!this._firstFrameLogged) {
// Calculer RMS pour détecter silence
let sumSquares = 0;
for (let i = 0; i < Math.min(240, pcmData.length); i++) {
sumSquares += pcmData[i] * pcmData[i];
}
const rms = Math.sqrt(sumSquares / Math.min(240, pcmData.length));
const dbFS = 20 * Math.log10(rms / 32768.0);
console.log(`🔍 Diagnostic audio LiveKit: console.log(`🔍 Diagnostic audio LiveKit:
sampleRate: ${sampleRate} sampleRate: ${sampleRate}
channels: ${channels} channels: ${channels || 1} (défaut: 1 si undefined)
buffer size: ${pcmData.length} bytes buffer size: ${pcmData.length} samples (${pcmData.length * 2} bytes)
buffer type: ${pcmData.constructor.name} buffer type: ${pcmData.constructor.name}
first 10 bytes: [${Array.from(pcmData.slice(0, 10)).join(', ')}]`); first 10 samples: [${Array.from(pcmData.slice(0, 10)).join(', ')}]
RMS level: ${rms.toFixed(0)} (${dbFS.toFixed(1)} dBFS)`);
this._firstFrameLogged = true; this._firstFrameLogged = true;
} }
@@ -596,19 +605,33 @@ export class AudioBridge extends EventEmitter {
} }
/** /**
* Convertit Buffer PCM 16-bit → Float32Array [-1.0, 1.0] * Convertit Buffer/Int16Array PCM 16-bit → Float32Array [-1.0, 1.0]
* @param {Buffer} buffer - Buffer PCM 16-bit signed * @param {Buffer|Int16Array|Uint8Array} buffer - Buffer PCM 16-bit signed
* @returns {Float32Array} * @returns {Float32Array}
* @private * @private
*/ */
_bufferToFloat32(buffer) { _bufferToFloat32(buffer) {
// Convertir en Buffer Node.js si c'est un Uint8Array ou ArrayBuffer let samples;
let float32;
// Cas 1 : Int16Array (LiveKit Node SDK format)
if (buffer instanceof Int16Array) {
samples = buffer.length;
float32 = this._acquireFloat32Buffer(samples);
for (let i = 0; i < samples; i++) {
float32[i] = buffer[i] / 32768.0;
}
return float32;
}
// Cas 2 : Buffer/Uint8Array (format classique)
if (!(buffer instanceof Buffer)) { if (!(buffer instanceof Buffer)) {
buffer = Buffer.from(buffer); buffer = Buffer.from(buffer);
} }
const samples = buffer.length / 2; // 2 bytes per sample (16-bit) samples = buffer.length / 2; // 2 bytes per sample (16-bit)
const float32 = this._acquireFloat32Buffer(samples); float32 = this._acquireFloat32Buffer(samples);
for (let i = 0; i < samples; i++) { for (let i = 0; i < samples; i++) {
// Lire 16-bit signed little-endian // Lire 16-bit signed little-endian
File diff suppressed because one or more lines are too long