fix: application du buffer d'accumulation aux backends Linux (PipeWire/JACK)
- Ajout buffer d'accumulation dans PipeWireBackend (même pattern que CoreAudio) - Ajout buffer d'accumulation dans JACKBackend - pw-cat et jack_rec émettent aussi des chunks de taille variable - Garantit frames fixes (960 samples) sur tous les backends - Prévient audio haché/robotique sous Linux
This commit is contained in:
@@ -30,6 +30,12 @@ export class JACKBackend extends EventEmitter {
|
||||
this.jackProcess = null;
|
||||
this.isCapturing = false;
|
||||
this.isPlaying = false;
|
||||
this.shuttingDown = false;
|
||||
|
||||
// Buffer d'accumulation pour la capture (JACK peut envoyer des chunks de taille variable)
|
||||
this.captureAccumulator = Buffer.alloc(0);
|
||||
this.targetCaptureBytes = this.options.framesPerBuffer * 2 * this.options.channels; // 2 bytes per sample
|
||||
|
||||
this.playbackBuffer = [];
|
||||
this.maxBufferSize = 10;
|
||||
|
||||
@@ -213,8 +219,17 @@ export class JACKBackend extends EventEmitter {
|
||||
]);
|
||||
|
||||
this.jackProcess.stdout.on('data', (audioData) => {
|
||||
// Émet les données audio capturées (Buffer PCM 16-bit)
|
||||
this.emit('audioData', audioData);
|
||||
// Accumuler les données jusqu'à avoir un frame complet
|
||||
this.captureAccumulator = Buffer.concat([this.captureAccumulator, audioData]);
|
||||
|
||||
// Émettre des frames de taille fixe
|
||||
while (this.captureAccumulator.length >= this.targetCaptureBytes) {
|
||||
const frame = this.captureAccumulator.subarray(0, this.targetCaptureBytes);
|
||||
this.emit('audioData', Buffer.from(frame)); // Copier pour éviter les références
|
||||
|
||||
// Garder le reste pour la prochaine frame
|
||||
this.captureAccumulator = this.captureAccumulator.subarray(this.targetCaptureBytes);
|
||||
}
|
||||
});
|
||||
|
||||
this.jackProcess.stderr.on('data', (data) => {
|
||||
@@ -248,6 +263,7 @@ export class JACKBackend extends EventEmitter {
|
||||
this.jackProcess.kill('SIGTERM');
|
||||
this.jackProcess = null;
|
||||
this.isCapturing = false;
|
||||
this.captureAccumulator = Buffer.alloc(0); // Reset accumulator
|
||||
console.log('✓ Capture JACK arrêtée');
|
||||
}
|
||||
}
|
||||
@@ -359,6 +375,7 @@ export class JACKBackend extends EventEmitter {
|
||||
* Arrête tous les streams
|
||||
*/
|
||||
destroy() {
|
||||
this.shuttingDown = true;
|
||||
this.stopCapture();
|
||||
this.stopPlayback();
|
||||
this.removeAllListeners();
|
||||
|
||||
@@ -33,6 +33,12 @@ export class PipeWireBackend extends EventEmitter {
|
||||
this.playbackProcess = null;
|
||||
this.isCapturing = false;
|
||||
this.isPlaying = false;
|
||||
this.shuttingDown = false;
|
||||
|
||||
// Buffer d'accumulation pour la capture (pw-cat envoie des chunks de taille variable)
|
||||
this.captureAccumulator = Buffer.alloc(0);
|
||||
this.targetCaptureBytes = this.options.framesPerBuffer * 2 * this.options.channels; // 2 bytes per sample
|
||||
|
||||
this.playbackBuffer = [];
|
||||
this.maxBufferSize = 10;
|
||||
}
|
||||
@@ -194,7 +200,17 @@ export class PipeWireBackend extends EventEmitter {
|
||||
this.captureProcess = spawn('pw-cat', args);
|
||||
|
||||
this.captureProcess.stdout.on('data', (audioData) => {
|
||||
this.emit('audioData', audioData);
|
||||
// Accumuler les données jusqu'à avoir un frame complet
|
||||
this.captureAccumulator = Buffer.concat([this.captureAccumulator, audioData]);
|
||||
|
||||
// Émettre des frames de taille fixe
|
||||
while (this.captureAccumulator.length >= this.targetCaptureBytes) {
|
||||
const frame = this.captureAccumulator.subarray(0, this.targetCaptureBytes);
|
||||
this.emit('audioData', Buffer.from(frame)); // Copier pour éviter les références
|
||||
|
||||
// Garder le reste pour la prochaine frame
|
||||
this.captureAccumulator = this.captureAccumulator.subarray(this.targetCaptureBytes);
|
||||
}
|
||||
});
|
||||
|
||||
this.captureProcess.stderr.on('data', (data) => {
|
||||
@@ -231,6 +247,7 @@ export class PipeWireBackend extends EventEmitter {
|
||||
this.captureProcess.kill('SIGTERM');
|
||||
this.captureProcess = null;
|
||||
this.isCapturing = false;
|
||||
this.captureAccumulator = Buffer.alloc(0); // Reset accumulator
|
||||
console.log('✓ Capture PipeWire arrêtée');
|
||||
}
|
||||
}
|
||||
@@ -360,6 +377,7 @@ export class PipeWireBackend extends EventEmitter {
|
||||
* Arrête tous les streams
|
||||
*/
|
||||
destroy() {
|
||||
this.shuttingDown = true;
|
||||
this.stopCapture();
|
||||
this.stopPlayback();
|
||||
this.removeAllListeners();
|
||||
|
||||
Reference in New Issue
Block a user