arkennemasis fal · MiniMax Preview Speech 2.5 Turbo · $0.06/1k chars
6 Cents per 1,000 Characters, Persian and Tagalog Included
- audio
- audio_path
- duration_ms
- info
The cheapest way to get speech out of the 2.5 preview family: $0.06 per 1,000 characters. Same voice list, same language picker, same inputs as the HD node one rung up. If you're producing narration in bulk - a series, a course, a pile of shorts - this is the one that keeps the budget boring.
What it is
A wrapper around fal's minimax/preview/speech-2.5-turbo endpoint, one node in the pack's 36-model fal audio catalogue. Turbo sits inside MiniMax's voice family, the line they benchmark against ElevenLabs - which is the whole reason to reach for a hosted TTS instead of hanging Chatterbox off your own GPU. Local TTS does generic English narration extremely well now; it gets shakier across many languages, and this node's language_boost picker is unusually broad for a cheap tier, including Persian, Filipino and Tamil alongside the usual Chinese/English/Japanese/Korean/European set.
How it works
FAL_KEY comes from the .env beside your ComfyUI launcher. The node validates the text, estimates the cost from its character count, submits one billed request to fal, polls with a live status on the node, and downloads into output/fal/fal-ai_minimax_preview_speech-2.5-turbo/. Nothing is uploaded on a TTS run, so every failure before the submit is free.
Inputs
text- namedtext, notprompt; max 5000 characters. Cost maths: about 180 words per 1,000 characters, so a two-minute script is roughly 2,000 characters - a hair over 12 cents.voice_setting_voice_id- free-text box, defaultWise_Woman. Paste a MiniMax predefined voice ID; leaving it empty hands the choice to the model.voice_setting_emotion-(not set)or one ofhappy,sad,angry,fearful,disgusted,surprised,neutral.(not set)is usually right.language_boost- pick the language. Leaving it at(not set)with non-English text is the single most common cause of a "bad" result.voice_setting_speed- 0.5 to 2.0. Withvoice_setting_pitch(−12 to 12),voice_setting_vol(0.01–10) andvoice_setting_english_normalization(off by default; on for number-heavy scripts).- Output settings -
audio_setting_format(mp3,pcm,flac),audio_setting_bitrate(32k–256k),audio_setting_sample_rate(8k–44.1k),audio_setting_channel(1 = mono, 2 = stereo),pronunciation_dict(JSON text replacements),output_format(urlorhex, non-streaming only; leave the default alone).
Optional: max_cost_usd (default $20 - the node stops before sending anything if the estimate is above it, 0 turns the cap off; at 6 cents per 1,000 characters you'd need a very long script to hit it), max_concurrent (default 1, one paid fal call at a time across a run), reuse_identical_run (default on), extra_json.
Outputs: audio (waveform + sample rate, playable on the node), audio_path, duration_ms (real measured length in milliseconds - feed it to Narration Length or Word Timings so cuts and captions follow the voice), and info.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
pip install httpx
Or Install via Git URL in ComfyUI Manager. Then beside run_nvidia_gpu.bat:
FAL_KEY=your-key-from-fal.ai/dashboard/keys
Restart - it's under arkennemasis/fal/Audio/MiniMax, titled with its rate.
Practical notes
There are no pause markers on this generation. The <#x#> syntax arrives with the 2.6 and 2.8 nodes; here you get punctuation and line breaks, nothing else. If your read needs a dramatic beat, write two sentences and cut the silence in afterwards.
Two pack behaviours worth knowing before you conclude something's broken. reuse_identical_run returns the existing file when text and settings are unchanged - free, and correct, but it looks like nothing happened. And if you're rendering a batch of voice-overs through several fal nodes at once, leave max_concurrent at 1 unless you enjoy rate-limit errors; the default exists because ComfyUI runs nodes side by side.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Text to convert to speech (max 5000 characters, minimum 1 non-whitespace character) | |
| voice_setting_speed | FLOAT | 1.000.5–2 | Speech speed (0.5-2.0) |
| voice_setting_vol | FLOAT | 1.000.01–10 | Volume (0-10) |
| voice_setting_english_normalization | BOOLEAN | false | Enables English text normalization to improve number reading performance, with a slight increase in latency |
| voice_setting_pitch | INT | 0-12–12 | Voice pitch (-12 to 12) |
| voice_setting_emotion | COMBO | (not set) | Emotion of the generated speech '(not set)' leaves it to the model. |
| voice_setting_voice_id | STRING | Wise_Woman | Predefined voice ID to use for synthesis Empty leaves it out. |
| audio_setting_format | COMBO | mp3 | Audio format |
| audio_setting_bitrate | COMBO | 128000 | Bitrate of generated audio |
| audio_setting_sample_rate | COMBO | 32000 | Sample rate of generated audio |
| audio_setting_channel | COMBO | 1 | Number of audio channels (1=mono, 2=stereo) |
| language_boost | COMBO | (not set) | Enhance recognition of specified languages and dialects '(not set)' leaves it to the model. |
| output_format | COMBO | hex | Format of the output content (non-streaming only) |
| pronunciation_dict | STRING | Custom pronunciation dictionary for text replacement JSON. Empty leaves it out. | |
| max_cost_usdopt | FLOAT | 20.00–100000 | Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap. |
| reuse_identical_runopt | BOOLEAN | true | If these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings. |
| extra_jsonopt | STRING | Advanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally. | |
| max_concurrentopt | INT | 11–32 | How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| audio_path | STRING | — |
| duration_ms | INT | — |
| info | STRING | JSON: request id, cost estimate, saved files and fal's full answer. |