Punctuation and casing
The problem. Raw speech recognition gives a flat stream of words: “hello id like to change my address is that possible”. Punctuation and casing turn it into sentences people can read, and that downstream tools (summaries, search, LLMs) understand better.
Where it works. Every model, every language. On by default: nothing to do.
{ "text": "Hello, I'd like to change my address. Is that possible?" }Turning it off
Section titled “Turning it off”To feed your own text processing with the words only, set punctuation: false.
# pip install gladiaio-sdk requestsimport osimport sysimport threadingimport wave
import requestsfrom gladiaio_sdk import GladiaClient, LiveV2ConnectSessionOptions
API_URL = os.environ.get("GLADIA_API_URL", "https://eu1.api.gladia.io")API_KEY = os.environ["GLADIA_API_KEY"]
with wave.open(sys.argv[1]) as wav: # a 16-bit PCM WAV file rate, channels = wav.getframerate(), wav.getnchannels() audio = wav.readframes(wav.getnframes())
config = { "encoding": "wav/pcm", "sample_rate": rate, "bit_depth": 16, "channels": channels, "model": "trantoria-1", "language_config": { "languages": [ "en" ] }, "punctuation": False}
client = GladiaClient(api_key=API_KEY, api_url=API_URL)# `punctuation` is a Gladia Enterprise option the Python SDK does not send yet# (gladiaio/sdk#61): create the session over HTTP, then let the SDK stream it.created = requests.post(f"{API_URL}/v2/live", headers={"x-gladia-key": API_KEY}, json=config, timeout=10)created.raise_for_status()info = created.json()session = client.live_v2().connect_session(LiveV2ConnectSessionOptions(id=info["id"], url=info["url"]))ended, errors = threading.Event(), []
@session.on("message")def on_message(message): if message.type == "transcript" and message.data.is_final: print(message.data.utterance.text)
session.on("error", errors.append)session.once("ended", lambda _: ended.set())
step = rate * channels * 2 // 10 # 100 ms of audio per chunkfor start in range(0, len(audio), step): session.send_audio(audio[start : start + step]) # live audio: send each chunk as it is capturedsession.stop_recording()
ended.wait(timeout=60)sys.exit(1 if errors or not ended.is_set() else 0)// npm install @gladiaio/sdkimport { readFileSync } from "node:fs";import { GladiaClient } from "@gladiaio/sdk";
const { sampleRate, channels, pcm } = readWav(process.argv[2]); // a 16-bit PCM WAV file
const config = { encoding: "wav/pcm", sample_rate: sampleRate, bit_depth: 16, channels, model: "trantoria-1", language_config: { languages: [ "en" ] }, punctuation: false};
const client = new GladiaClient({ apiKey: process.env.GLADIA_API_KEY, apiUrl: process.env.GLADIA_API_URL ?? "https://eu1.api.gladia.io",});// `punctuation` is a Gladia Enterprise option not in the SDK's types yet: the SDK sends it as is.const session = client.liveV2().startSession(config);
session.on("message", (message) => { if (message.type === "transcript" && message.data.is_final) console.log(message.data.utterance.text);});session.on("error", (error) => { console.error(error); process.exitCode = 1;});session.once("ended", () => process.exit());
const step = (sampleRate * channels * 2) / 10; // 100 ms of audio per chunkfor (let start = 0; start < pcm.length; start += step) { session.sendAudio(pcm.subarray(start, start + step)); // live audio: send each chunk as it is captured}session.stopRecording();
function readWav(path) { const file = readFileSync(path); let fmt, pcm; for (let pos = 12; pos < file.length; ) { const id = file.toString("ascii", pos, pos + 4); const size = file.readUInt32LE(pos + 4); if (id === "fmt ") fmt = { channels: file.readUInt16LE(pos + 10), sampleRate: file.readUInt32LE(pos + 12) }; if (id === "data") pcm = file.subarray(pos + 8, pos + 8 + size); pos += 8 + size + (size % 2); } return { ...fmt, pcm };}Create the session, then stream its audio to the returned url (Live WebSocket):
curl -X POST https://eu1.api.gladia.io/v2/live \ -H "x-gladia-key: $GLADIA_API_KEY" \ -H "content-type: application/json" \ -d '{ "encoding": "wav/pcm", "sample_rate": 16000, "bit_depth": 16, "channels": 1, "model": "trantoria-1", "language_config": { "languages": [ "en" ] }, "punctuation": false }'Limits and gotchas
Section titled “Limits and gotchas”- Finals only. Punctuation and casing are applied to final transcripts. Partials show the text as the model writes it: their punctuation may differ, then settle in the final. Compare finals with finals.
- Off means off. With
punctuation: false, the casing goes too: do not expect sentences. - A Gladia Enterprise option. Gladia’s cloud API does not know
punctuation: do not send it there.