@@ -7,13 +7,19 @@ import { pcmS16le } from '../daemon/voice-adapters.js';
|
||||
import { WakeEngine } from '../daemon/wake-engine.js';
|
||||
import { VadSegmenter } from '../daemon/vad.js';
|
||||
import { PipeWireCapture, pcmRms } from '../daemon/audio-pipewire.js';
|
||||
import { SentenceBuffer, isMeaningfulTranscript, isSpeakable } from '../daemon/transcript.js';
|
||||
import { SentenceBuffer, isMeaningfulTranscript, isSpeakable, speakableForTts } from '../daemon/transcript.js';
|
||||
|
||||
test('Phase 4 transcript filtering and sentence buffering are deterministic', () => {
|
||||
assert.equal(isMeaningfulTranscript('[BLANK_AUDIO]'), false);
|
||||
assert.equal(isMeaningfulTranscript('hi'), false);
|
||||
assert.equal(isSpeakable('OK.'), true);
|
||||
assert.equal(isSpeakable('[object Object]'), false);
|
||||
assert.equal(speakableForTts('Using `run_terminal_cmd`'), "Using 'run terminal cmd'");
|
||||
assert.equal(speakableForTts('Your IP is 192.168.0.1'), 'Your I P is 192 168 0 1');
|
||||
assert.equal(
|
||||
speakableForTts('QVAC fetched https://example.com/ip'),
|
||||
'Quantum Verse Automatic Computer fetched example dot com slash I P'
|
||||
);
|
||||
assert.equal(isMeaningfulTranscript('what time is it'), true);
|
||||
const out = []; const buffer = new SentenceBuffer({ onSentence: (s) => out.push(s) });
|
||||
buffer.push('First sentence. Second'); buffer.push(' sentence!'); buffer.flush();
|
||||
@@ -71,6 +77,33 @@ test('empty TTS still leaves the daemon listening', async () => {
|
||||
assert.equal(daemon.finished, true);
|
||||
});
|
||||
|
||||
test('multi-sentence speech returns to listening once', async () => {
|
||||
const daemon = new EventEmitter();
|
||||
const states = [];
|
||||
daemon.state = 'SPEAKING';
|
||||
daemon.voice = {
|
||||
finishSpeaking() {
|
||||
daemon.finished = (daemon.finished || 0) + 1;
|
||||
},
|
||||
};
|
||||
daemon.setState = (state) => { daemon.state = state; states.push(state); };
|
||||
const capture = new EventEmitter(); capture.start = () => {}; capture.stop = () => {};
|
||||
const wake = new WakeEngine({ detect: () => null });
|
||||
const loop = new VoiceLoop({
|
||||
daemon,
|
||||
capture,
|
||||
wake,
|
||||
vad: new VadSegmenter(),
|
||||
tts: { speak: async () => ({ samples: new Int16Array(2) }) },
|
||||
playback: { play: async () => {}, stop() {} },
|
||||
});
|
||||
loop.status.tts = true;
|
||||
await loop.speak('Hello there. How are you today?');
|
||||
assert.equal(daemon.state, 'LISTENING');
|
||||
assert.equal(daemon.finished, 1);
|
||||
assert.deepEqual(states, ['LISTENING']);
|
||||
});
|
||||
|
||||
test('PCM packing uses even s16le sample pairs', () => {
|
||||
const buf = Buffer.alloc(4);
|
||||
buf.writeInt16LE(256, 0);
|
||||
|
||||
Reference in New Issue
Block a user