Core SDK

C/C++

Access the Typecast API with our official C/C++ SDK.

The official C/C++ library for the Typecast API. Convert text to lifelike speech using AI-powered voices.

Compatible with C11 and later versions. Works with CMake, manual compilation, and supports cross-platform development including Windows, Linux, macOS, and embedded systems.

Requirements

  • CMake 3.14+
  • libcurl (with SSL support)
  • C11 compatible compiler
sudo apt-get install build-essential cmake libcurl4-openssl-dev

Installation

Clone the repository and build with CMake:

git clone https://github.com/neosapience/typecast-sdk.git
cd typecast-sdk/typecast-c
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .

Build Options

OptionDefaultDescription
TYPECAST_BUILD_SHAREDONBuild shared library (.dll/.so/.dylib)
TYPECAST_BUILD_STATICOFFBuild static library
TYPECAST_BUILD_EXAMPLESONBuild example programs
TYPECAST_BUILD_TESTSONBuild test programs

Quick Start

#include "typecast.h"
#include <stdio.h>

int main() {
    // Initialize client
    TypecastClient* client = typecast_client_create("YOUR_API_KEY");
    if (!client) return 1;

    // Convert text to speech
    TypecastTTSRequest request = {0};
    request.text = "Hello there! I'm your friendly text-to-speech agent.";
    request.voice_id = "tc_672c5f5ce59fac2a48faeaee"; /* Find voice IDs at https://studio.typecast.ai/developers/api/voices */
    request.model = TYPECAST_MODEL_SSFM_V30;
    request.language = "eng";

    TypecastTTSResponse* response = typecast_text_to_speech(client, &request);
    if (response) {
        // Save audio file
        FILE* fp = fopen("output.wav", "wb");
        fwrite(response->audio_data, 1, response->audio_size, fp);
        fclose(fp);

        printf("Audio saved! Duration: %.2fs, Size: %zu bytes\n", 
               response->duration, response->audio_size);

        typecast_tts_response_free(response);
    }

    // Clean up
    typecast_client_destroy(client);
    return 0;
}

Features

The Typecast C/C++ SDK provides powerful features for text-to-speech conversion:

  • C and C++ Support: Pure C API with optional C++ wrapper for convenience
  • Multiple Voice Models: Support for ssfm-v30 (latest) and ssfm-v21 AI voice models
  • Multi-language Support: 37 languages including English, Korean, Spanish, Japanese, Chinese, and more
  • Emotion Control: Preset emotions (normal, happy, sad, angry, whisper, toneup, tonedown) or smart context-aware inference
  • Audio Customization: Control loudness (LUFS -70 to 0), pitch (-12 to +12 semitones), tempo (0.5x to 2.0x), and format (WAV/MP3)
  • Voice Discovery: V2 Voices API with filtering by model, gender, age, and use cases
  • Instant Voice Cloning: Upload a WAV/MP3 sample and create a custom voice ID
  • Cross-Platform: Windows, Linux, macOS, ARM (32/64-bit) support
  • Embedded Ready: Optimized for minimal footprint, cross-compilation support
  • Timestamp TTS: Word- and character-level alignment data for subtitles, karaoke, and lip-sync
  • Unreal Engine Ready: Designed for easy integration with game engines
  • Streaming: Real-time chunked audio delivery for low-latency playback

Voice Recommendations

Use typecast_recommend_voices when you know the desired style but not the exact voice_id.

TypecastRecommendedVoicesResponse* voices = typecast_recommend_voices(
    client,
    "warm female voice for a product tutorial",
    3
);

if (voices) {
    for (int i = 0; i < voices->count; i++) {
        printf("%s %s %.3f\n",
            voices->voices[i].voice_id,
            voices->voices[i].voice_name,
            voices->voices[i].score);
    }
    typecast_recommended_voices_response_free(voices);
}

Recommendation results contain only voice_id, voice_name, and score. Use typecast_get_voice or typecast_get_voices when you need detailed metadata such as supported models, emotions, gender, age, or use cases.

Configuration

Set your API key via environment variable or constructor:

#include <stdlib.h>

// Using environment variable
// export TYPECAST_API_KEY="your-api-key-here"
const char* api_key = getenv("TYPECAST_API_KEY");
TypecastClient* client = typecast_client_create(api_key);

// Or pass directly
TypecastClient* client = typecast_client_create("your-api-key-here");

// Or with custom base URL
TypecastClient* client = typecast_client_create_with_host(
    "your-api-key-here", 
    "https://custom-api.example.com"
);
TypecastClient* client = typecast_client_create_with_host(
    NULL,
    "https://your-proxy.example.com"
);

Advanced Usage

Emotion Control (ssfm-v30)

ssfm-v30 offers two emotion control modes: Preset and Smart.

Let the AI infer emotion from context:

TypecastTTSRequest request = {0};
request.text = "Everything is going to be okay.";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
request.model = TYPECAST_MODEL_SSFM_V30;
request.language = "eng";

// Smart emotion with context
TypecastPrompt prompt = {0};
prompt.emotion_type = TYPECAST_EMOTION_TYPE_SMART;
prompt.previous_text = "I just got the best news!";   // Optional context
prompt.next_text = "I can't wait to celebrate!";      // Optional context
request.prompt = &prompt;

TypecastTTSResponse* response = typecast_text_to_speech(client, &request);

Audio Customization

Control loudness, pitch, tempo, and output format:

TypecastTTSRequest request = {0};
request.text = "Customized audio output!";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
request.model = TYPECAST_MODEL_SSFM_V30;
request.language = "eng";

// Configure output settings
TypecastOutput output = TYPECAST_OUTPUT_DEFAULT();
output.use_target_lufs = 1;
output.target_lufs = -14.0f;                    // Range: -70 to 0 (LUFS)
output.audio_pitch = 2;                        // Range: -12 to +12 semitones
output.audio_tempo = 1.2f;                     // Range: 0.5x to 2.0x
output.audio_format = TYPECAST_AUDIO_FORMAT_MP3;  // Options: WAV, MP3
request.output = &output;

request.seed = 42;  // Unsigned seed for reproducible results

TypecastTTSResponse* response = typecast_text_to_speech(client, &request);
if (response) {
    const char* ext = (response->format == TYPECAST_AUDIO_FORMAT_MP3) ? "mp3" : "wav";
    char filename[64];
    snprintf(filename, sizeof(filename), "output.%s", ext);
    
    FILE* fp = fopen(filename, "wb");
    fwrite(response->audio_data, 1, response->audio_size, fp);
    fclose(fp);
    
    printf("Duration: %.2fs, Format: %s\n", response->duration, ext);
    typecast_tts_response_free(response);
}

Generate audio to a file

Use typecast_generate_to_file when you want the SDK to synthesize speech and write the audio bytes directly to a local file. The model defaults to ssfm-v30, and .mp3 / .wav extensions infer the output format when no output format is set. Browse available voice IDs on the Voices page.

TypecastGenerateToFileRequest request = {0};
request.text = "Hello from Typecast.";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee"; /* Find voice IDs at https://studio.typecast.ai/developers/api/voices */

TypecastErrorCode code = typecast_generate_to_file(client, "output.mp3", &request);
if (code != TYPECAST_SUCCESS) {
    fprintf(stderr, "Failed to generate audio: %s\n", typecast_error_string(code));
}

For C++ wrapper users:

typecast::GenerateToFileRequest request;
request.text = "Hello from Typecast.";
request.voiceId = "tc_672c5f5ce59fac2a48faeaee"; // Find voice IDs at https://studio.typecast.ai/developers/api/voices

auto response = client.generateToFile("output.mp3", request);

Text pauses

Use text pause markup when you only need silent gaps inside one composed text segment. Put <|5s|>, <|1s|>, <|0.3s|>, or <|0.34413s|> directly in the text. The value is interpreted as seconds and must end with s. This keeps the pause expression visible in plain text without adding separate pause calls.

TypecastSpeechComposer* composer = typecast_speech_composer_create(client);
TypecastComposerSettings defaults = {0};
defaults.voice_id = "tc_672c5f5ce59fac2a48faeaee";
defaults.model = TYPECAST_MODEL_SSFM_V30;
typecast_speech_composer_defaults(composer, &defaults);

typecast_speech_composer_say(
    composer,
    "Hello<|5s|>Nice to meet you<|1s|>Today<|2s|>how does the weather feel?",
    NULL
);

TypecastTTSResponse* audio = typecast_speech_composer_generate(composer, TYPECAST_AUDIO_FORMAT_WAV);
typecast_tts_response_free(audio);
typecast_speech_composer_destroy(composer);

Multi-speaker composition

Use the composer chaining API when one output file needs different voices or per-segment options such as pitch, tempo, prompt, or seed. The composer generates each segment as WAV, trims leading/trailing silent PCM samples, and concatenates the result. If you need MP3, generate WAV first and convert it in your app or server pipeline.

TypecastSpeechComposer* composer = typecast_speech_composer_create(client);
TypecastComposerSettings defaults = {0};
defaults.voice_id = "tc_672c5f5ce59fac2a48faeaee";
defaults.model = TYPECAST_MODEL_SSFM_V30;
typecast_speech_composer_defaults(composer, &defaults);

typecast_speech_composer_say(composer, "Hello there", NULL);
typecast_speech_composer_pause(composer, 5.0f);

TypecastComposerSettings second = {0};
second.voice_id = "tc_60e5426de8b95f1d3000d7b5";
second.output.audio_pitch = 2;
typecast_speech_composer_say(composer, "Nice to meet you", &second);
typecast_speech_composer_pause(composer, 2.0f);
typecast_speech_composer_say(composer, "How does the weather feel?", NULL);

TypecastTTSResponse* audio = typecast_speech_composer_generate(composer, TYPECAST_AUDIO_FORMAT_WAV);
/* write audio->audio_data / audio->audio_len to conversation.wav */
typecast_tts_response_free(audio);
typecast_speech_composer_destroy(composer);

Voice Discovery (V2 API)

List and filter available voices with enhanced metadata:

// Get all voices
TypecastVoicesResponse* voices = typecast_get_voices(client, NULL);

// Or filter by criteria
TypecastModel model = TYPECAST_MODEL_SSFM_V30;
TypecastGender gender = TYPECAST_GENDER_FEMALE;
TypecastAge age = TYPECAST_AGE_YOUNG_ADULT;

TypecastVoicesFilter filter = {0};
filter.model = &model;
filter.gender = &gender;
filter.age = &age;

TypecastVoicesResponse* filtered = typecast_get_voices(client, &filter);

// Display voice info
if (voices) {
    for (size_t i = 0; i < voices->count; i++) {
        TypecastVoice* v = &voices->voices[i];
        printf("ID: %s, Name: %s\n", v->voice_id, v->voice_name);
        printf("Gender: %d, Age: %d\n", v->gender, v->age);
        
        for (size_t j = 0; j < v->models_count; j++) {
            printf("Model: %s, Emotions: ", 
                   typecast_model_to_string(v->models[j].version));
            for (size_t k = 0; k < v->models[j].emotions_count; k++) {
                printf("%s ", v->models[j].emotions[k]);
            }
            printf("\n");
        }
        
        if (v->use_cases) {
            printf("Use cases: ");
            for (size_t k = 0; k < v->use_cases_count; k++) {
                printf("%s ", v->use_cases[k]);
            }
            printf("\n");
        }
    }
    typecast_voices_response_free(voices);
}

Multilingual Content

The SDK supports 37 languages with automatic language detection:

// Auto-detect language (recommended - omit language field)
TypecastTTSRequest request = {0};
request.text = "こんにちは。お元気ですか。";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
request.model = TYPECAST_MODEL_SSFM_V30;
// language is NULL, so it will be auto-detected

TypecastTTSResponse* response = typecast_text_to_speech(client, &request);

// Or specify language explicitly using ISO 639-3 code
TypecastTTSRequest korean_request = {0};
korean_request.text = "안녕하세요. 반갑습니다.";
korean_request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
korean_request.model = TYPECAST_MODEL_SSFM_V30;
korean_request.language = "kor";  // ISO 639-3 language code

TypecastTTSResponse* korean_response = typecast_text_to_speech(client, &korean_request);

Streaming

Stream audio chunks in real-time for low-latency playback:

// Extract raw PCM for real-time playback (skip 44-byte WAV header)
static int g_first = 1;

static int on_chunk(const uint8_t *data, size_t len, void *user_data) {
    const uint8_t *pcm = data;
    size_t pcm_len = len;

    if (g_first) {
        pcm += 44;       // Skip WAV header
        pcm_len -= 44;
        g_first = 0;
    }
    // pcm is raw 16-bit mono PCM at 32000 Hz
    // Feed to your audio output (e.g. PortAudio, ALSA)
    play_audio(pcm, pcm_len);  // your playback function
    return 0;
}

Timestamp TTS

typecast_text_to_speech_with_timestamps() wraps POST /v1/text-to-speech/with-timestamps and returns the audio together with per-word and per-character alignment data - useful for karaoke highlights, subtitle generation, and lip-sync applications.

Basic Usage

#include "typecast.h"
#include <stdio.h>
#include <stdlib.h>

int main() {
    TypecastClient* client = typecast_client_create("YOUR_API_KEY");
    if (!client) return 1;

    TypecastTTSWithTimestampsRequest request = {0};
    request.text     = "Hello. How are you?";
    request.voice_id = "tc_60e5426de8b95f1d3000d7b5";
    request.model    = TYPECAST_MODEL_SSFM_V30;

    TypecastTTSWithTimestampsResponse* result =
        typecast_text_to_speech_with_timestamps(client, &request);

    if (result) {
        FILE* fp = fopen("output.wav", "wb");
        fwrite(result->audio_data, 1, result->audio_size, fp);
        fclose(fp);

        printf("Duration: %.3fs\n", result->audio_duration);

        for (size_t i = 0; i < result->word_count; i++) {
            printf("  [%.3fs – %.3fs] %s\n",
                result->words[i].start_time,
                result->words[i].end_time,
                result->words[i].text);
        }

        typecast_tts_with_timestamps_response_free(result);
    }

    typecast_client_destroy(client);
    return 0;
}

Granularity

Set request.granularity = TYPECAST_GRANULARITY_WORD (default) or TYPECAST_GRANULARITY_CHAR to control the alignment unit.

request.granularity = TYPECAST_GRANULARITY_CHAR;  /* required for jpn / zho */

Subtitle Export

// Export SRT (caller must free the returned string)
char* srt = typecast_tts_with_timestamps_to_srt(result);
FILE* fp = fopen("output.srt", "w");
fputs(srt, fp);
fclose(fp);
free(srt);

// Export WebVTT
char* vtt = typecast_tts_with_timestamps_to_vtt(result);
// ... same pattern as above
free(vtt);

Instant Voice Cloning

Clone a custom voice from a short audio sample, then pass the returned uc_ voice ID directly to TTS.

TypecastCustomVoice voice;
TypecastErrorCode rc = typecast_clone_voice(
    client,
    audio_bytes,
    audio_len,
    "sample.wav",
    "My Voice",
    "ssfm-v30",
    &voice
);

if (rc == TYPECAST_OK) {
    TypecastTTSRequest request = {0};
    request.voice_id = voice.voice_id;
    request.text = "Hello from my cloned voice!";
    request.model = TYPECAST_MODEL_SSFM_V30;

    TypecastTTSResponse* response = typecast_text_to_speech(client, &request);
    if (response) {
        typecast_tts_response_free(response);
    }

    typecast_delete_voice(client, voice.voice_id);
}

Supported Languages

The SDK supports 37 languages with automatic language detection:

CodeLanguageCodeLanguageCodeLanguage
engEnglishjpnJapaneseukrUkrainian
korKoreanellGreekindIndonesian
spaSpanishtamTamildanDanish
deuGermantglTagalogsweSwedish
fraFrenchfinFinnishmsaMalay
itaItalianzhoChinesecesCzech
polPolishslkSlovakporPortuguese
nldDutcharaArabicbulBulgarian
rusRussianhrvCroatianronRomanian
benBengalihinHindihunHungarian
nanHokkiennorNorwegianpanPunjabi
thaThaiturTurkishvieVietnamese
yueCantonese

Error Handling

The SDK provides specific error codes for handling API errors:

#include "typecast.h"

TypecastTTSResponse* response = typecast_text_to_speech(client, &request);

if (!response) {
    const TypecastError* err = typecast_client_get_error(client);
    
    switch (err->code) {
        case TYPECAST_ERROR_UNAUTHORIZED:
            // 401: Invalid API key
            fprintf(stderr, "Invalid API key: %s\n", err->message);
            break;
        case TYPECAST_ERROR_PAYMENT_REQUIRED:
            // 402: Insufficient credits
            fprintf(stderr, "Insufficient credits: %s\n", err->message);
            break;
        case TYPECAST_ERROR_NOT_FOUND:
            // 404: Resource not found
            fprintf(stderr, "Voice not found: %s\n", err->message);
            break;
        case TYPECAST_ERROR_UNPROCESSABLE_ENTITY:
            // 422: Validation error
            fprintf(stderr, "Validation error: %s\n", err->message);
            break;
        case TYPECAST_ERROR_RATE_LIMIT:
            // 429: Rate limit exceeded
            fprintf(stderr, "Rate limit exceeded - please retry later\n");
            break;
        case TYPECAST_ERROR_INTERNAL_SERVER:
            // 500: Server error
            fprintf(stderr, "Server error: %s\n", err->message);
            break;
        default:
            fprintf(stderr, "API error (%d): %s\n", err->code, err->message);
            break;
    }
}

Error Codes

Error CodeValueDescription
TYPECAST_OK0Success
TYPECAST_ERROR_INVALID_PARAM-1Invalid request parameters
TYPECAST_ERROR_OUT_OF_MEMORY-2Memory allocation failed
TYPECAST_ERROR_CURL_INIT-3Failed to initialize libcurl
TYPECAST_ERROR_NETWORK-4Network error
TYPECAST_ERROR_JSON_PARSE-5JSON parsing error
TYPECAST_ERROR_BAD_REQUEST400Invalid request
TYPECAST_ERROR_UNAUTHORIZED401Invalid or missing API key
TYPECAST_ERROR_PAYMENT_REQUIRED402Insufficient credits
TYPECAST_ERROR_NOT_FOUND404Resource not found
TYPECAST_ERROR_UNPROCESSABLE_ENTITY422Validation error
TYPECAST_ERROR_RATE_LIMIT429Rate limit exceeded
TYPECAST_ERROR_INTERNAL_SERVER500Server error

C++ Wrapper

For C++ projects, enable the optional C++ wrapper for a more idiomatic interface:

#define TYPECAST_CPP_WRAPPER
#include "typecast.h"

#include <fstream>
#include <iostream>

int main() {
    try {
        // Initialize client
        typecast::Client client("YOUR_API_KEY");

        // Convert text to speech
        typecast::TTSRequest request;
        request.text = "Hello there! I'm your friendly text-to-speech agent.";
        request.voiceId = "tc_672c5f5ce59fac2a48faeaee";
        request.model = typecast::Model::SSFM_V30;
        request.language = "eng";

        auto response = client.textToSpeech(request);

        // Save audio file
        std::ofstream file("output.wav", std::ios::binary);
        file.write(reinterpret_cast<const char*>(response.audioData.data()), 
                   response.audioData.size());

        std::cout << "Audio saved! Duration: " << response.duration << "s\n";

    } catch (const typecast::TypecastException& e) {
        std::cerr << "Error (" << e.code << "): " << e.what() << "\n";
        return 1;
    }

    return 0;
}

Platform Support

The SDK has been verified through automated E2E testing on the following platforms:

PlatformArchitectureglibcC StandardStatus
CentOS 6.9x86_642.12C99Verified
CentOS 7x86_642.17C11Verified
Amazon Linux 2x86_642.26C11Verified
Ubuntu 20.04 LTSx86_642.31C11Verified
Debian Bullseyex86_642.31C11Verified
Windowsx64N/AC11Verified
macOSx86_64 / arm64N/AC11Verified

Embedded Systems

This SDK can be integrated into embedded systems with network connectivity.

Cross-Compilation

mkdir build-arm && cd build-arm
cmake .. \
    -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-gnueabihf.cmake \
    -DTYPECAST_BUILD_STATIC=ON \
    -DTYPECAST_BUILD_SHARED=OFF \
    -DCMAKE_BUILD_TYPE=MinSizeRel
cmake --build .

Memory Requirements

ComponentApproximate Size
Static library (MinSizeRel)~50 KB
Runtime heap per client~8 KB
TTS response bufferVariable (audio size)
JSON parsing buffer~4 KB

Unreal Engine Integration

This SDK is designed for seamless integration with Unreal Engine 4.27+ and Unreal Engine 5.x.

  1. Build the SDK

    Build as a static library:

    mkdir build && cd build
    cmake .. -DTYPECAST_BUILD_STATIC=ON -DTYPECAST_BUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release
    cmake --build . --config Release
    
  2. Create Plugin Structure

    Create a plugin in your Unreal project:

    Plugins/
    └── TypecastTTS/
        ├── Source/TypecastTTS/
        │   ├── Private/
        │   ├── Public/
        │   └── ThirdParty/Typecast/
        │       ├── include/typecast.h
        │       └── lib/Win64/typecast_static.lib
        ├── TypecastTTS.uplugin
        └── TypecastTTS.Build.cs
    
  3. Configure Build.cs

    Add library linking to your Build.cs:

    // Add include path
    PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "include"));
    PublicDefinitions.Add("TYPECAST_STATIC");
    
    // Link static library (platform-specific)
    if (Target.Platform == UnrealTargetPlatform.Win64)
    {
        PublicAdditionalLibraries.Add(
            Path.Combine(LibPath, "Win64", "typecast_static.lib"));
        AddEngineThirdPartyPrivateStaticDependencies(Target, "libcurl");
    }
    

API Reference

Client Functions

FunctionDescription
typecast_client_create(api_key)Create client with API key
typecast_client_create_with_host(api_key, host)Create client with custom host
typecast_client_destroy(client)Destroy client and free resources
typecast_client_get_error(client)Get last error information

Text-to-Speech Functions

FunctionDescription
typecast_text_to_speech(client, request)Convert text to speech audio
typecast_generate_to_file(client, path, request)Generate speech and save it directly to a local file
typecast_tts_response_free(response)Free TTS response memory

Voice Functions

FunctionDescription
typecast_get_voices(client, filter)Get available voices (optionally filtered)
typecast_get_voice(client, voice_id)Get a specific voice by ID
typecast_clone_voice(client, audio, audio_len, filename, name, model, out)Create a custom voice via instant cloning
typecast_delete_voice(client, voice_id)Delete a custom cloned voice
typecast_voices_response_free(response)Free voices response memory
typecast_voice_free(voice)Free single voice memory

Utility Functions

FunctionDescription
typecast_version()Get library version string
typecast_model_to_string(model)Convert model enum to string
typecast_emotion_to_string(emotion)Convert emotion enum to string
typecast_audio_format_to_string(format)Convert format enum to string
typecast_error_message(code)Get error message for error code

TypecastTTSRequest Fields

FieldTypeRequiredDescription
textconst char*Text to synthesize (max 2000 chars)
voice_idconst char*Voice ID (format: tc_* or uc_*)
modelTypecastModelTTS model (SSFM_V21 or SSFM_V30)
languageconst char*ISO 639-3 code (auto-detected if NULL)
promptTypecastPrompt*Emotion settings
outputTypecastOutput*Audio output settings
seedunsigned intUnsigned integer seed for reproducibility (≥ 0)

TypecastTTSResponse Fields

FieldTypeDescription
audio_datauint8_t*Generated audio data
audio_sizesize_tSize of audio data in bytes
durationfloatAudio duration in seconds
formatTypecastAudioFormatAudio format (wav or mp3)
⌘I