> ## Documentation Index
> Fetch the complete documentation index at: https://typecast.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# C/C++

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

The official C/C++ library for the [Typecast API](https://typecast.ai). 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.

<CardGroup cols={2}>
  <Card title="Source Code" icon="github" href="https://github.com/neosapience/typecast-sdk/tree/main/typecast-c">
    Typecast C SDK Source Code
  </Card>

  <Card title="API Documentation" icon="book" href="https://docs.typecast.ai">
    Typecast API Documentation
  </Card>
</CardGroup>

## Requirements

* CMake 3.14+
* libcurl (with SSL support)
* C11 compatible compiler

<Tabs>
  <Tab title="Linux (Ubuntu/Debian)">
    ```bash theme={null}
    sudo apt-get install build-essential cmake libcurl4-openssl-dev
    ```
  </Tab>

  <Tab title="macOS">
    ```bash theme={null}
    # libcurl is included with Xcode
    xcode-select --install
    brew install cmake
    ```
  </Tab>

  <Tab title="Windows (MSVC)">
    ```powershell theme={null}
    vcpkg install curl:x64-windows
    ```
  </Tab>
</Tabs>

## Installation

<Tabs>
  <Tab title="CMake (Recommended)">
    Clone the repository and build with CMake:

    ```bash theme={null}
    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 .
    ```
  </Tab>

  <Tab title="Manual">
    Compile directly with GCC or Clang:

    ```bash theme={null}
    git clone https://github.com/neosapience/typecast-sdk.git
    cd typecast-sdk/typecast-c

    # Compile source files
    gcc -c src/typecast.c src/cJSON.c -I include -I src -O2

    # Create static library
    ar rcs libtypecast.a typecast.o cJSON.o

    # Or compile your application directly
    gcc -o myapp myapp.c src/typecast.c src/cJSON.c \
        -I include -I src -lcurl -O2
    ```
  </Tab>

  <Tab title="FetchContent (CMake)">
    Add to your `CMakeLists.txt`:

    ```cmake theme={null}
    include(FetchContent)
    FetchContent_Declare(
        typecast
        GIT_REPOSITORY https://github.com/neosapience/typecast-sdk.git
        SOURCE_SUBDIR typecast-c
        GIT_TAG v1.2.7
    )
    FetchContent_MakeAvailable(typecast)

    target_link_libraries(your_target PRIVATE typecast)
    ```
  </Tab>
</Tabs>

<Note>Latest registered version: **v1.2.7** in the SDK Git tags.</Note>

### Build Options

| Option                    | Default | Description                            |
| ------------------------- | ------- | -------------------------------------- |
| `TYPECAST_BUILD_SHARED`   | ON      | Build shared library (.dll/.so/.dylib) |
| `TYPECAST_BUILD_STATIC`   | OFF     | Build static library                   |
| `TYPECAST_BUILD_EXAMPLES` | ON      | Build example programs                 |
| `TYPECAST_BUILD_TESTS`    | ON      | Build test programs                    |

## Quick Start

```c theme={null}
#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://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`.

```c theme={null}
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:

```c theme={null}
#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"
);
```

<Info>
  When requests go through your own proxy, pass the proxy host and omit the API key by passing `NULL` or an empty string. The SDK will not send the `X-API-KEY` header for empty or missing keys. Requests to the default Typecast host still require an API key.
</Info>

```c Proxy without API key theme={null}
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**.

<Tabs>
  <Tab title="Smart Mode">
    Let the AI infer emotion from context:

    ```c theme={null}
    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);
    ```
  </Tab>

  <Tab title="Preset Mode">
    Explicitly set emotion with preset values:

    ```c theme={null}
    TypecastTTSRequest request = {0};
    request.text = "I am so excited to show you these features!";
    request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
    request.model = TYPECAST_MODEL_SSFM_V30;
    request.language = "eng";

    // Preset emotion
    TypecastPrompt prompt = TYPECAST_PROMPT_DEFAULT();
    prompt.emotion_type = TYPECAST_EMOTION_TYPE_PRESET;
    prompt.emotion_preset = TYPECAST_EMOTION_HAPPY;  // normal, happy, sad, angry, whisper, toneup, tonedown
    prompt.emotion_intensity = 1.5f;                 // Range: 0.0 to 2.0
    request.prompt = &prompt;

    TypecastTTSResponse* response = typecast_text_to_speech(client, &request);
    ```
  </Tab>
</Tabs>

### Audio Customization

Control loudness, pitch, tempo, and output format:

```c theme={null}
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](https://typecast.ai/developers/api/voices) page.

```c theme={null}
TypecastGenerateToFileRequest request = {0};
request.text = "Hello from Typecast.";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee"; /* Find voice IDs at https://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:

```cpp theme={null}
typecast::GenerateToFileRequest request;
request.text = "Hello from Typecast.";
request.voiceId = "tc_672c5f5ce59fac2a48faeaee"; // Find voice IDs at https://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.

```c theme={null}
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.

```c theme={null}
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:

```c theme={null}
// 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:

```c theme={null}
// 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:

```c theme={null}
// 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;
}
```

<Note>
  **WAV streaming format:** 32000 Hz, 16-bit, mono PCM. The first chunk includes a 44-byte WAV header (size = `0xFFFFFFFF`); subsequent chunks are raw PCM only. For MP3: 320 kbps, 44100 Hz, each chunk is independently decodable. Use `TYPECAST_OUTPUT_STREAM_DEFAULT()` for safe output defaults.
</Note>

## 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

```c theme={null}
#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.

```c theme={null}
request.granularity = TYPECAST_GRANULARITY_CHAR;  /* required for jpn / zho */
```

### Subtitle Export

```c theme={null}
// 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);
```

<Note>
  **Japanese / Chinese:** Word-level segmentation is not meaningful for languages without whitespace delimiters (jpn, zho). Use `TYPECAST_GRANULARITY_CHAR` for these languages to get character-level alignment.
</Note>

## Instant Voice Cloning

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

```c theme={null}
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);
}
```

<Warning>
  Voice cloning audio must be **25 MB or smaller**, the audio duration must be **5-150 seconds**, and the custom voice name must be **1-30 characters**.
</Warning>

## Supported Languages

The SDK supports 37 languages with automatic language detection:

| Code  | Language  | Code  | Language  | Code  | Language   |
| ----- | --------- | ----- | --------- | ----- | ---------- |
| `eng` | English   | `jpn` | Japanese  | `ukr` | Ukrainian  |
| `kor` | Korean    | `ell` | Greek     | `ind` | Indonesian |
| `spa` | Spanish   | `tam` | Tamil     | `dan` | Danish     |
| `deu` | German    | `tgl` | Tagalog   | `swe` | Swedish    |
| `fra` | French    | `fin` | Finnish   | `msa` | Malay      |
| `ita` | Italian   | `zho` | Chinese   | `ces` | Czech      |
| `pol` | Polish    | `slk` | Slovak    | `por` | Portuguese |
| `nld` | Dutch     | `ara` | Arabic    | `bul` | Bulgarian  |
| `rus` | Russian   | `hrv` | Croatian  | `ron` | Romanian   |
| `ben` | Bengali   | `hin` | Hindi     | `hun` | Hungarian  |
| `nan` | Hokkien   | `nor` | Norwegian | `pan` | Punjabi    |
| `tha` | Thai      | `tur` | Turkish   | `vie` | Vietnamese |
| `yue` | Cantonese |       |           |       |            |

<Info>
  If not specified, the language will be automatically detected from the input text.
</Info>

## Error Handling

The SDK provides specific error codes for handling API errors:

```c theme={null}
#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 Code                            | Value | Description                  |
| ------------------------------------- | ----- | ---------------------------- |
| `TYPECAST_OK`                         | 0     | Success                      |
| `TYPECAST_ERROR_INVALID_PARAM`        | -1    | Invalid request parameters   |
| `TYPECAST_ERROR_OUT_OF_MEMORY`        | -2    | Memory allocation failed     |
| `TYPECAST_ERROR_CURL_INIT`            | -3    | Failed to initialize libcurl |
| `TYPECAST_ERROR_NETWORK`              | -4    | Network error                |
| `TYPECAST_ERROR_JSON_PARSE`           | -5    | JSON parsing error           |
| `TYPECAST_ERROR_BAD_REQUEST`          | 400   | Invalid request              |
| `TYPECAST_ERROR_UNAUTHORIZED`         | 401   | Invalid or missing API key   |
| `TYPECAST_ERROR_PAYMENT_REQUIRED`     | 402   | Insufficient credits         |
| `TYPECAST_ERROR_NOT_FOUND`            | 404   | Resource not found           |
| `TYPECAST_ERROR_UNPROCESSABLE_ENTITY` | 422   | Validation error             |
| `TYPECAST_ERROR_RATE_LIMIT`           | 429   | Rate limit exceeded          |
| `TYPECAST_ERROR_INTERNAL_SERVER`      | 500   | Server error                 |

## C++ Wrapper

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

```cpp theme={null}
#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:

| Platform             | Architecture    | glibc | C Standard | Status   |
| -------------------- | --------------- | ----- | ---------- | -------- |
| **CentOS 6.9**       | x86\_64         | 2.12  | C99        | Verified |
| **CentOS 7**         | x86\_64         | 2.17  | C11        | Verified |
| **Amazon Linux 2**   | x86\_64         | 2.26  | C11        | Verified |
| **Ubuntu 20.04 LTS** | x86\_64         | 2.31  | C11        | Verified |
| **Debian Bullseye**  | x86\_64         | 2.31  | C11        | Verified |
| **Windows**          | x64             | N/A   | C11        | Verified |
| **macOS**            | x86\_64 / arm64 | N/A   | C11        | Verified |

## Embedded Systems

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

### Cross-Compilation

<Tabs>
  <Tab title="ARM Linux (32-bit)">
    ```bash theme={null}
    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 .
    ```
  </Tab>

  <Tab title="ARM64 Linux">
    ```bash theme={null}
    mkdir build-arm64 && cd build-arm64
    cmake .. \
        -DCMAKE_SYSTEM_NAME=Linux \
        -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
        -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \
        -DTYPECAST_BUILD_STATIC=ON \
        -DTYPECAST_BUILD_SHARED=OFF \
        -DCMAKE_BUILD_TYPE=MinSizeRel
    cmake --build .
    ```
  </Tab>
</Tabs>

### Memory Requirements

| Component                   | Approximate Size      |
| --------------------------- | --------------------- |
| Static library (MinSizeRel) | \~50 KB               |
| Runtime heap per client     | \~8 KB                |
| TTS response buffer         | Variable (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.

<Steps>
  <Step title="Build the SDK">
    Build as a static library:

    ```bash theme={null}
    mkdir build && cd build
    cmake .. -DTYPECAST_BUILD_STATIC=ON -DTYPECAST_BUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release
    cmake --build . --config Release
    ```
  </Step>

  <Step title="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
    ```
  </Step>

  <Step title="Configure Build.cs">
    Add library linking to your `Build.cs`:

    ```csharp theme={null}
    // 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");
    }
    ```
  </Step>
</Steps>

<Info>
  For complete Unreal Engine integration guide including Blueprint support and audio playback, see the [README](https://github.com/neosapience/typecast-sdk/tree/main/typecast-c) in the SDK repository.
</Info>

## API Reference

### Client Functions

| Function                                          | Description                       |
| ------------------------------------------------- | --------------------------------- |
| `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

| Function                                           | Description                                          |
| -------------------------------------------------- | ---------------------------------------------------- |
| `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

| Function                                                                     | Description                                |
| ---------------------------------------------------------------------------- | ------------------------------------------ |
| `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

| Function                                  | Description                      |
| ----------------------------------------- | -------------------------------- |
| `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

| Field      | Type              | Required | Description                                     |
| ---------- | ----------------- | -------- | ----------------------------------------------- |
| `text`     | `const char*`     | ✓        | Text to synthesize (max 2000 chars)             |
| `voice_id` | `const char*`     | ✓        | Voice ID (format: `tc_*` or `uc_*`)             |
| `model`    | `TypecastModel`   | ✓        | TTS model (`SSFM_V21` or `SSFM_V30`)            |
| `language` | `const char*`     |          | ISO 639-3 code (auto-detected if NULL)          |
| `prompt`   | `TypecastPrompt*` |          | Emotion settings                                |
| `output`   | `TypecastOutput*` |          | Audio output settings                           |
| `seed`     | `unsigned int`    |          | Unsigned integer seed for reproducibility (≥ 0) |

### TypecastTTSResponse Fields

| Field        | Type                  | Description                 |
| ------------ | --------------------- | --------------------------- |
| `audio_data` | `uint8_t*`            | Generated audio data        |
| `audio_size` | `size_t`              | Size of audio data in bytes |
| `duration`   | `float`               | Audio duration in seconds   |
| `format`     | `TypecastAudioFormat` | Audio format (wav or mp3)   |
