import { QvacVoiceAdapter } from '../daemon/voice-adapters.js'; import { PipeWirePlayback } from '../daemon/audio-playback.js'; import { closeQvac } from '../daemon/qvac-master.js'; const tts = new QvacVoiceAdapter({ role: 'tts' }); const asr = new QvacVoiceAdapter({ role: 'asr' }); try { await tts.start(); const audio = await tts.speak('The voice system is ready.'); if (!audio.samples.length || !audio.samples.some((sample) => sample !== 0)) throw new Error('TTS returned empty or silent audio'); if (process.argv.includes('--play')) await new PipeWirePlayback().play(audio.samples); console.log(`TTS generated ${audio.samples.length} samples at ${audio.sampleRate} Hz`); await asr.start(); // Convert 44.1 kHz synthesis to the capture contract (16 kHz mono PCM). const resampled = new Int16Array(Math.floor(audio.samples.length * 16000 / audio.sampleRate)); for (let i = 0; i < resampled.length; i++) resampled[i] = audio.samples[Math.floor(i * audio.sampleRate / 16000)]; const text = await asr.transcribeAudio(Buffer.from(resampled.buffer)); if (!/voice|system|ready/i.test(text)) throw new Error(`ASR roundtrip failed: ${text}`); console.log(`ASR recognized: ${text}`); } finally { await asr.stop(); await tts.stop(); await closeQvac(); }