Flow

Vocalization

Flow can synthesize singing and speech via formant synthesis and an optional text-to-speech hook. These live in @audio and produce ordinary Buffer values you can mix, effect, and export.

sing

Synthesize a vowel or consonant-vowel syllable at a given pitch and duration:

use "@std"
use "@audio"

Buffer vowel = (sing "ah" C4 0.5)
(play vowel)
Open in playground

Signature: (sing String phoneme, Note pitch, Double duration) -> Buffer. The duration also accepts a Second or Millisecond literal, so (sing "ah" C4 0.5), (sing "ah" C4 0.5s), and (sing "ah" C4 200ms) all work.

sing is tuning-aware — under enable justIntonation; + key Cmajor, an E4 vocalization renders at the 5/4 ratio rather than 12-TET. Same for enable pythagorean;, enable equalTemperament;, and tuning t { } blocks.

Honest scope. sing is a single Tenor formant voice with no vibrato. It supports the five vowels below plus the three consonant onsets s / t / n — nothing else. It is not a vocaloid-style engine (that is a planned goal, not a shipped feature). For anything richer, layer multiple sing buffers or process them with the effects chain.

Vowels

The five core vowels are supported:

SyllableIPAExample
"ah"/a/“father”
"ee"/i/“see”
"eh"/e/“bed”
"oh"/o/“go”
"oo"/u/“moon”
use "@audio"

Buffer a  = (sing "ah" A4 0.3)
Buffer e  = (sing "ee" A4 0.3)
Buffer i  = (sing "eh" A4 0.3)
Buffer o  = (sing "oh" A4 0.3)
Buffer u  = (sing "oo" A4 0.3)

Buffer phrase = a -> appendBuffers e -> appendBuffers i -> appendBuffers o -> appendBuffers u
(writeWav "vowels.wav" phrase)
Open in playground

Consonant-Vowel Syllables

Prefix a vowel with one of three supported consonants — s (sibilant fricative, filtered noise), t (plosive), or n (nasal) — to get a syllable. The synthesizer renders the consonant onset, then crossfades into the vowel formants:

use "@audio"

Buffer na = (sing "na" C4 0.5)
Buffer ta = (sing "ta" E4 0.3)
Buffer sa = (sing "sa" G4 0.3)
Buffer noo = (sing "noo" C5 0.5)
Open in playground

Other consonants are not yet supported — passing an unsupported phoneme (e.g. "la") raises a runtime error: Unknown vowel phoneme: 'la'. Valid: ah, ee, eh, oh, oo.

Mixing Vocals with Instruments

Since sing returns a normal Buffer, you can mix and process it like any other source:

use "@std"
use "@audio"

Buffer vocal  = (sing "ah" C4 1.0)
Buffer tone   = (createSineTone 440Hz 1.0 0.5)
Buffer mixed  = (mix vocal tone)

Buffer wet = mixed -> reverb 0.4 -> gain 0dB
(writeWav "vocal_mix.wav" wet)
Open in playground

Different Pitches

Formant synthesis preserves vowel character across the usable vocal range:

use "@audio"

Buffer low  = (sing "oh" C3 0.5)
Buffer mid  = (sing "oh" C4 0.5)
Buffer high = (sing "oh" C5 0.5)
Open in playground

Very low or very high pitches may become less intelligible, as with real voices.

Text-to-Speech Hook

Flow can delegate a string to an external TTS engine and return the generated audio as a buffer. The default command is espeak-ng --stdout — install espeak-ng (or any TTS that writes WAV to stdout) and tts works without further setup.

Desktop-only. tts shells out to an external process, so it requires espeak-ng (or your configured engine) to be installed on the machine, and it does not work in the browser playground — the sandbox has no TTS binary. Formant sing, which is pure synthesis, does work in the browser.

Setting a Custom TTS Command

use "@audio"

Note: The first token is the executable; remaining tokens are base args.
Note: The text to speak is appended as a quoted last argument, so the command
Note: must write WAV data to stdout (espeak-ng's --stdout does exactly this).
(setTtsCommand "espeak-ng -v en --stdout")
Open in playground

Running TTS

use "@audio"

Buffer greeting = (tts "Hello from Flow")
(play greeting)
Open in playground

If the TTS executable can’t be found, tts raises an error pointing at setTtsCommand to change engines. The process is killed if it doesn’t return within 30 seconds.

Exporting TTS Audio

Since the result is a standard buffer, it can be processed and exported:

use "@audio"

Buffer words = (tts "welcome to the piece")
Buffer wet   = words -> reverb 0.5 -> fadeOut 0.5s
(writeWav "intro_voice.wav" wet)
Open in playground

Use Cases

  • Singing synthesis: layer vocal buffers over instrumental parts to add a human timbre
  • Spoken intros/outros: use TTS for ambient narration or spoken-word pieces
  • Ear training / demos: name scale degrees or chords out loud inside longer renders
  • Phoneme play: sequence sing calls to build nonsense syllable patterns over a groove

Function Reference

FunctionSignatureDescription
sing(String, Note, Double) -> BufferFormant-synthesized vowel or syllable (tuning-aware)
tts(String) -> BufferExternal TTS -> buffer (defaults to espeak-ng --stdout)
setTtsCommand(String) -> VoidConfigure the TTS command template

See Also