async function ttsWebsocketLowLatency(client: Cartesia): Promise<void> {
const sampleRate = 44100;
const audioCtx = new AudioContext({ sampleRate });
let nextStartTime = audioCtx.currentTime;
const ws = await client.tts.websocket();
ws.on('error', (err) => console.error(err.message));
try {
const ctx = ws.context({
model_id: 'sonic-latest',
voice: { mode: 'id', id: '6ccbfb76-1fc6-48f7-b71d-91ac6298247b' },
output_format: { container: 'raw', encoding: 'pcm_f32le', sample_rate: sampleRate },
language: 'en',
});
await ctx.push({
transcript: 'Low latency streaming. Each chunk plays as soon as it arrives.',
});
await ctx.no_more_inputs();
for await (const event of ctx.receive()) {
if (event.type === 'chunk' && event.audio) {
const floats = new Float32Array(
event.audio.buffer,
event.audio.byteOffset,
event.audio.byteLength / 4,
);
const audioBuffer = audioCtx.createBuffer(1, floats.length, sampleRate);
audioBuffer.getChannelData(0).set(floats);
const source = audioCtx.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioCtx.destination);
// Schedule this chunk right after the previous one
const startTime = Math.max(nextStartTime, audioCtx.currentTime);
source.start(startTime);
nextStartTime = startTime + audioBuffer.duration;
} else if (event.type === 'error') {
console.error(event.title, event.message);
}
}
} finally {
ws.close();
}
}
Browser
WebSocket Low-Latency Playback
Play audio chunks as they arrive for lowest latency.