pipedog is an unofficial community port of Pipecat, not affiliated with Daily.
pipedog
Text-to-speech

Camb.ai

Text-to-speech with Camb.ai's MARS models: CambTTSService streams PCM audio over HTTP.

Overview

CambTTSService posts each sentence to Camb.ai's tts-stream endpoint and pushes the streamed 16-bit PCM, kept aligned to whole samples. Models: mars-flash (fast, 22.05 kHz, the default), mars-pro (high quality, 48 kHz) and mars-instruct (22.05 kHz, takes instructions for tone and style).

Installation

bun add @pipedog/camb
import { CambTTSService } from "@pipedog/camb/tts";

Prerequisites

  • A Camb.ai account and an API key.
  • Pass the key as apiKey. The examples read it from CAMB_API_KEY.

Configuration

Prop

Type

Settings

Runtime-updatable settings, passed as settings: new CambTTSService.Settings({...}) (CambTTSSettings). Any setting you leave out keeps the default below.

SettingTypeDefaultDescription
modelstring"mars-flash"mars-flash, mars-pro or mars-instruct.
voicenumber147320Voice id. Camb.ai uses integer ids.
languageLanguage | string"en-us"Language, as a lowercase BCP-47 tag.
userInstructionsstring | nullnullInstructions for mars-instruct only, up to 1000 characters. Ignored by the other models.

Usage

tts.ts
import { CambTTSService } from "@pipedog/camb/tts";
import { TTSUpdateSettingsFrame } from "@pipedog/core/frames/frames";

// mars-flash (22.05 kHz) is the default; mars-pro renders at 48 kHz.
const tts = new CambTTSService({
  apiKey: process.env.CAMB_API_KEY ?? "",
  settings: new CambTTSService.Settings({ model: "mars-pro", voice: 147320 }),
});

Change settings mid-call with a TTSUpdateSettingsFrame:

// Queue it on the worker, or push it from a processor upstream of the service.
const update = new TTSUpdateSettingsFrame({
  delta: new CambTTSService.Settings({ voice: 12345 }),
});

Notes

  • Without a sampleRate, the service uses the model's: 22050 Hz for mars-flash and mars-instruct, 48000 Hz for mars-pro. A sampleRate that differs from the model's logs a warning.
  • Text over 3000 characters is truncated.
  • timeout (60 seconds by default, the minimum Camb.ai recommends) limits the wait for the response and the wait for each chunk of audio.

Runtime notes

  • Upstream uses Camb's Python SDK. That SDK is a thin client over one endpoint, so this port sends the same request (POST /tts-stream with an x-api-key header) with the global fetch, which works on Bun, Node, Deno and Cloudflare Workers. baseUrl and fetch are not upstream options.
  • The deprecated params (InputParams), voiceId and model options are not ported. Use settings.
  • Upstream has no Camb.ai tests. Ours run against a local fake server, not against Camb.ai itself.
RuntimeWorksWhat it needs
Bun✅ yesNothing.
Node.js✅ yesNothing.
Deno✅ yesNothing.
Cloudflare Workers✅ yesNothing.

Generated from pipecat.runtimes and pipecat.compat in packages/camb/package.json: ✅ means the compat smoke test passes on that runtime.

pipedog is an unofficial community TypeScript port of Pipecat. It is not affiliated with or endorsed by Daily or the Pipecat project.

Portions adapted from the Pipecat documentation, Copyright (c) 2024–2025 Daily, BSD-2-Clause (see apps/docs/LICENSE-pipecat-docs).

On this page