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

> 공식 C/C++ SDK로 타입캐스트 API를 사용하세요.

[타입캐스트 API](https://typecast.ai)용 공식 C/C++ 라이브러리입니다. AI 기반 음성을 사용하여 텍스트를 자연스러운 음성으로 변환하세요.

C11 이상 버전과 호환됩니다. CMake, 수동 컴파일을 지원하며 Windows, Linux, macOS 및 임베디드 시스템을 포함한 크로스 플랫폼 개발이 가능합니다.

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

  <Card title="API 문서" icon="book" href="https://docs.typecast.ai">
    타입캐스트 API 문서
  </Card>
</CardGroup>

## 요구 사항

* CMake 3.14+
* libcurl (SSL 지원 필요)
* C11 호환 컴파일러

<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은 Xcode에 포함되어 있습니다
    xcode-select --install
    brew install cmake
    ```
  </Tab>

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

## 설치

<Tabs>
  <Tab title="CMake (권장)">
    저장소를 복제하고 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="수동 설치">
    GCC 또는 Clang으로 직접 컴파일합니다:

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

    # 소스 파일 컴파일
    gcc -c src/typecast.c src/cJSON.c -I include -I src -O2

    # 정적 라이브러리 생성
    ar rcs libtypecast.a typecast.o cJSON.o

    # 또는 애플리케이션 직접 컴파일
    gcc -o myapp myapp.c src/typecast.c src/cJSON.c \
        -I include -I src -lcurl -O2
    ```
  </Tab>

  <Tab title="FetchContent (CMake)">
    `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>최신 등록 버전은 SDK Git 태그 기준 **v1.2.7**입니다.</Note>

### 빌드 옵션

| 옵션                        | 기본값 | 설명                            |
| ------------------------- | --- | ----------------------------- |
| `TYPECAST_BUILD_SHARED`   | ON  | 공유 라이브러리 빌드 (.dll/.so/.dylib) |
| `TYPECAST_BUILD_STATIC`   | OFF | 정적 라이브러리 빌드                   |
| `TYPECAST_BUILD_EXAMPLES` | ON  | 예제 프로그램 빌드                    |
| `TYPECAST_BUILD_TESTS`    | ON  | 테스트 프로그램 빌드                   |

## 빠른 시작

```c theme={null}
#include "typecast.h"
#include <stdio.h>

int main() {
    // 클라이언트 초기화
    TypecastClient* client = typecast_client_create("YOUR_API_KEY");
    if (!client) return 1;

    // 텍스트를 음성으로 변환
    TypecastTTSRequest request = {0};
    request.text = "안녕하세요! 저는 친절한 텍스트-투-스피치 에이전트입니다.";
    request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
    request.model = TYPECAST_MODEL_SSFM_V30;
    request.language = "kor";

    TypecastTTSResponse* response = typecast_text_to_speech(client, &request);
    if (response) {
        // 오디오 파일 저장
        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);
    }

    // 정리
    typecast_client_destroy(client);
    return 0;
}
```

## 기능

Typecast C/C++ SDK는 텍스트-투-스피치 변환을 위한 강력한 기능을 제공합니다:

* **C 및 C++ 지원**: 순수 C API와 편의를 위한 선택적 C++ 래퍼 제공
* **다중 음성 모델**: `ssfm-v30` (최신) 및 `ssfm-v21` AI 음성 모델 지원
* **다국어 지원**: 영어, 한국어, 스페인어, 일본어, 중국어 등 37개 언어 지원
* **감정 제어**: 이모션 프리셋 (normal, happy, sad, angry, whisper, toneup, tonedown) 또는 스마트 문맥 인식 추론
* **오디오 커스터마이징**: 라우드니스 (LUFS -70 to 0), 피치 (-12 to +12 반음), 템포 (0.5x to 2.0x), 포맷 (WAV/MP3) 제어
* **음성 검색**: 모델, 성별, 나이, 사용 사례별 필터링이 가능한 V2 Voices API
* **크로스 플랫폼**: Windows, Linux, macOS, ARM (32/64비트) 지원
* **타임스탬프 TTS**: 자막, 가라오케, 립싱크를 위한 단어·문자 단위 정렬 데이터
* **스트리밍**: 저지연 재생을 위한 실시간 청크 오디오 전송
* **임베디드 지원**: 최소 용량 최적화, 크로스 컴파일 지원
* **언리얼 엔진 지원**: 게임 엔진과의 쉬운 통합을 위해 설계됨

## 보이스 추천

원하는 스타일은 알지만 정확한 `voice_id`를 모를 때 `typecast_recommend_voices`를 사용합니다.

```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);
}
```

추천 결과에는 `voice_id`, `voice_name`, `score`만 포함됩니다. 지원 모델, 감정, 성별, 연령대, 사용 사례 같은 상세 메타데이터가 필요하면 `typecast_get_voice` 또는 `typecast_get_voices`로 추가 조회하세요.

## 설정

환경 변수 또는 생성자를 통해 API 키를 설정합니다:

```c theme={null}
#include <stdlib.h>

// 환경 변수 사용
// export TYPECAST_API_KEY="your-api-key-here"
const char* api_key = getenv("TYPECAST_API_KEY");
TypecastClient* client = typecast_client_create(api_key);

// 또는 직접 전달
TypecastClient* client = typecast_client_create("your-api-key-here");

// 또는 커스텀 베이스 URL과 함께
TypecastClient* client = typecast_client_create_with_host(
    "your-api-key-here", 
    "https://custom-api.example.com"
);
```

<Info>
  자체 프록시를 통해 요청하는 경우 프록시 호스트를 전달하고 API 키는 `NULL` 또는 빈 문자열로 생략할 수 있습니다. API 키가 비어 있거나 없으면 SDK는 `X-API-KEY` 헤더를 보내지 않습니다. 기본 Typecast 호스트로 요청할 때는 API 키가 계속 필요합니다.
</Info>

```c API 키 없는 프록시 theme={null}
TypecastClient* client = typecast_client_create_with_host(
    NULL,
    "https://your-proxy.example.com"
);
```

## 고급 사용법

### 감정 제어 (ssfm-v30)

ssfm-v30은 두 가지 감정 제어 모드를 제공합니다: **프리셋** 및 **스마트**.

<Tabs>
  <Tab title="스마트 모드">
    AI가 문맥에서 감정을 추론하도록 합니다:

    ```c theme={null}
    TypecastTTSRequest request = {0};
    request.text = "모든 것이 잘 될 거예요.";
    request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
    request.model = TYPECAST_MODEL_SSFM_V30;
    request.language = "kor";

    // 문맥을 활용한 스마트 이모션
    TypecastPrompt prompt = {0};
    prompt.emotion_type = TYPECAST_EMOTION_TYPE_SMART;
    prompt.previous_text = "방금 최고의 소식을 들었어요!";   // 선택적 문맥
    prompt.next_text = "축하하고 싶어서 기다릴 수가 없어요!";  // 선택적 문맥
    request.prompt = &prompt;

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

  <Tab title="프리셋 모드">
    프리셋 값으로 감정을 명시적으로 설정합니다:

    ```c theme={null}
    TypecastTTSRequest request = {0};
    request.text = "이 기능들을 보여드리게 되어 정말 기뻐요!";
    request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
    request.model = TYPECAST_MODEL_SSFM_V30;
    request.language = "kor";

    // 이모션 프리셋
    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;                 // 범위: 0.0 ~ 2.0
    request.prompt = &prompt;

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

### 오디오 커스터마이징

라우드니스, 피치, 템포 및 출력 포맷을 제어합니다:

```c theme={null}
TypecastTTSRequest request = {0};
request.text = "커스터마이징된 오디오 출력입니다!";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
request.model = TYPECAST_MODEL_SSFM_V30;
request.language = "kor";

// 출력 설정 구성
TypecastOutput output = TYPECAST_OUTPUT_DEFAULT();
output.use_target_lufs = 1;
output.target_lufs = -14.0f;                    // 범위: -70 ~ 0 (LUFS)
output.audio_pitch = 2;                        // 범위: -12 to +12 반음
output.audio_tempo = 1.2f;                     // 범위: 0.5x to 2.0x
output.audio_format = TYPECAST_AUDIO_FORMAT_MP3;  // 옵션: WAV, MP3
request.output = &output;

request.seed = 42;  // 부호 없는 정수 시드 (재현 가능한 결과)

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);
}
```

### 파일로 바로 생성하기

`typecast_generate_to_file`은 음성 합성과 파일 저장을 한 번에 처리합니다. `model`은 기본값으로 `ssfm-v30`을 사용하고, `.mp3` 또는 `.wav` 확장자로 출력 형식을 결정합니다.

```c theme={null}
int result = typecast_generate_to_file(
    client,
    "hello.mp3",
    "안녕하세요, 타입캐스트입니다.",
    "tc_672c5f5ce59fac2a48faeaee", /* voice_id는 https://typecast.ai/developers/api/voices 에서 확인하세요. */
    NULL
);
```

### 텍스트만으로 쉼 표현

한 voice로 읽는 문장 안에 쉼만 넣고 싶다면 텍스트에 pause markup을 직접 작성합니다. `<|5s|>`, `<|1s|>`, `<|0.3s|>`, `<|0.34413s|>`처럼 쓰며 값은 초 단위이고 반드시 `s`로 끝납니다. 별도 pause 함수를 호출하지 않아도 텍스트만 보고 쉼 위치를 확인할 수 있습니다.

```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,
    "안녕하세요<|5s|>반갑습니다<|1s|>오늘<|2s|>날씨는 어떤 것 같으세요?",
    NULL
);

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

### 다중 화자 합성

한 파일 안에서 서로 다른 voice나 구간별 pitch, tempo, prompt, seed 같은 옵션을 조합해야 할 때 사용합니다. composer는 각 구간을 WAV로 생성하고 앞뒤 무음 PCM 샘플을 trim한 뒤 합성합니다. MP3가 필요하면 먼저 WAV를 생성한 다음 앱 또는 서버 파이프라인에서 변환하세요.

```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);
```

### 음성 검색 (V2 API)

향상된 메타데이터로 사용 가능한 음성을 나열하고 필터링합니다:

```c theme={null}
// 모든 음성 가져오기
TypecastVoicesResponse* voices = typecast_get_voices(client, NULL);

// 또는 조건으로 필터링
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);

// 음성 정보 표시
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");
        }
    }
    typecast_voices_response_free(voices);
}
```

### 다국어 콘텐츠

SDK는 자동 언어 감지와 함께 37개 언어를 지원합니다:

```c theme={null}
// 자동 언어 감지 (권장 - language 필드 생략)
TypecastTTSRequest request = {0};
request.text = "こんにちは。お元気ですか。";
request.voice_id = "tc_672c5f5ce59fac2a48faeaee";
request.model = TYPECAST_MODEL_SSFM_V30;
// language가 NULL이면 자동으로 감지됩니다

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

// 또는 ISO 639-3 코드로 언어를 명시적으로 지정
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 언어 코드

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

### 스트리밍

저지연 재생을 위한 실시간 오디오 청크 스트리밍:

```c theme={null}
// 실시간 재생을 위한 원시 PCM 추출 (44바이트 WAV 헤더 건너뛰기)
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;       // WAV 헤더 건너뛰기
        pcm_len -= 44;
        g_first = 0;
    }
    // pcm은 32000 Hz 16비트 모노 원시 PCM
    // 오디오 출력으로 전달 (예: PortAudio, ALSA)
    play_audio(pcm, pcm_len);  // 재생 함수
    return 0;
}
```

<Note>
  **WAV 스트리밍 형식:** 32000 Hz, 16비트, 모노 PCM. 첫 번째 청크에 44바이트 WAV 헤더(size = `0xFFFFFFFF`)가 포함되며, 이후 청크는 원시 PCM 데이터만 포함합니다. MP3 형식: 320 kbps, 44100 Hz, 각 청크는 독립적으로 디코딩 가능합니다. 안전한 기본값으로 출력 설정을 초기화하려면 `TYPECAST_OUTPUT_STREAM_DEFAULT()`를 사용하세요.
</Note>

## 타임스탬프 TTS

`typecast_text_to_speech_with_timestamps()`는 `POST /v1/text-to-speech/with-timestamps`를 래핑하며, 오디오와 함께 단어·문자 단위 정렬 데이터를 반환합니다. 가라오케 하이라이트, 자막 생성, 립싱크 애플리케이션에 활용할 수 있습니다.

### 기본 사용법

```c theme={null}
#include "typecast.h"
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    TypecastClient *client = typecast_client_new("YOUR_API_KEY");

    TypecastTTSRequestWithTimestamps req = {
        .voice_id    = "tc_60e5426de8b95f1d3000d7b5",
        .text        = "Hello. How are you?",
        .model       = "ssfm-v30",
        .granularity = TYPECAST_GRANULARITY_WORD,
    };

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

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

    printf("재생 시간: %.3f초\n", result->audio_duration);
    for (size_t i = 0; i < result->words_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_free(client);
    return 0;
}
```

### 정밀도(Granularity) 설정

`TYPECAST_GRANULARITY_WORD`(기본값) 또는 `TYPECAST_GRANULARITY_CHAR`를 설정해 정렬 단위를 제어합니다.

```c theme={null}
// 문자 단위 정렬 — 일본어·중국어에 필수
TypecastTTSRequestWithTimestamps req = {
    .voice_id    = "tc_60e5426de8b95f1d3000d7b5",
    .text        = "Hello. How are you?",
    .model       = "ssfm-v30",
    .granularity = TYPECAST_GRANULARITY_CHAR,
};
```

### 자막 내보내기

```c theme={null}
char *srt = typecast_tts_with_timestamps_to_srt(result);
FILE *fs = fopen("output.srt", "w");
fputs(srt, fs);
fclose(fs);
free(srt);

char *vtt = typecast_tts_with_timestamps_to_vtt(result);
FILE *fv = fopen("output.vtt", "w");
fputs(vtt, fv);
fclose(fv);
free(vtt);
```

<Note>
  **일본어·중국어:** 공백 구분자가 없는 언어(jpn, zho)는 단어 단위 세그먼트가 의미를 갖지 않습니다. 해당 언어에는 `TYPECAST_GRANULARITY_CHAR`를 사용해 문자 단위 정렬 데이터를 얻으세요.
</Note>

## 지원 언어

SDK는 자동 언어 감지와 함께 37개 언어를 지원합니다:

| 코드    | 언어    | 코드    | 언어     | 코드    | 언어     |
| ----- | ----- | ----- | ------ | ----- | ------ |
| `eng` | 영어    | `jpn` | 일본어    | `ukr` | 우크라이나어 |
| `kor` | 한국어   | `ell` | 그리스어   | `ind` | 인도네시아어 |
| `spa` | 스페인어  | `tam` | 타밀어    | `dan` | 덴마크어   |
| `deu` | 독일어   | `tgl` | 타갈로그어  | `swe` | 스웨덴어   |
| `fra` | 프랑스어  | `fin` | 핀란드어   | `msa` | 말레이어   |
| `ita` | 이탈리아어 | `zho` | 중국어    | `ces` | 체코어    |
| `pol` | 폴란드어  | `slk` | 슬로바키아어 | `por` | 포르투갈어  |
| `nld` | 네덜란드어 | `ara` | 아랍어    | `bul` | 불가리아어  |
| `rus` | 러시아어  | `hrv` | 크로아티아어 | `ron` | 루마니아어  |
| `ben` | 벵골어   | `hin` | 힌디어    | `hun` | 헝가리어   |
| `nan` | 민난어   | `nor` | 노르웨이어  | `pan` | 펀자브어   |
| `tha` | 태국어   | `tur` | 터키어    | `vie` | 베트남어   |
| `yue` | 광동어   |       |        |       |        |

<Info>
  지정하지 않으면 입력 텍스트에서 언어가 자동으로 감지됩니다.
</Info>

## 오류 처리

SDK는 API 오류 처리를 위한 특정 오류 코드를 제공합니다:

```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: 유효하지 않은 API 키
            fprintf(stderr, "Invalid API key: %s\n", err->message);
            break;
        case TYPECAST_ERROR_PAYMENT_REQUIRED:
            // 402: 크레딧 부족
            fprintf(stderr, "Insufficient credits: %s\n", err->message);
            break;
        case TYPECAST_ERROR_NOT_FOUND:
            // 404: 리소스를 찾을 수 없음
            fprintf(stderr, "Voice not found: %s\n", err->message);
            break;
        case TYPECAST_ERROR_UNPROCESSABLE_ENTITY:
            // 422: 유효성 검사 오류
            fprintf(stderr, "Validation error: %s\n", err->message);
            break;
        case TYPECAST_ERROR_RATE_LIMIT:
            // 429: 요청 제한 초과
            fprintf(stderr, "Rate limit exceeded - please try again later\n");
            break;
        case TYPECAST_ERROR_INTERNAL_SERVER:
            // 500: 서버 오류
            fprintf(stderr, "Server error: %s\n", err->message);
            break;
        default:
            fprintf(stderr, "API error (%d): %s\n", err->code, err->message);
            break;
    }
}
```

### 오류 코드

| 오류 코드                                 | 값   | 설명                 |
| ------------------------------------- | --- | ------------------ |
| `TYPECAST_OK`                         | 0   | 성공                 |
| `TYPECAST_ERROR_INVALID_PARAM`        | -1  | 유효하지 않은 요청 매개변수    |
| `TYPECAST_ERROR_OUT_OF_MEMORY`        | -2  | 메모리 할당 실패          |
| `TYPECAST_ERROR_CURL_INIT`            | -3  | libcurl 초기화 실패     |
| `TYPECAST_ERROR_NETWORK`              | -4  | 네트워크 오류            |
| `TYPECAST_ERROR_JSON_PARSE`           | -5  | JSON 파싱 오류         |
| `TYPECAST_ERROR_BAD_REQUEST`          | 400 | 잘못된 요청             |
| `TYPECAST_ERROR_UNAUTHORIZED`         | 401 | 유효하지 않거나 누락된 API 키 |
| `TYPECAST_ERROR_PAYMENT_REQUIRED`     | 402 | 크레딧 부족             |
| `TYPECAST_ERROR_NOT_FOUND`            | 404 | 리소스를 찾을 수 없음       |
| `TYPECAST_ERROR_UNPROCESSABLE_ENTITY` | 422 | 유효성 검사 오류          |
| `TYPECAST_ERROR_RATE_LIMIT`           | 429 | 요청 제한 초과           |
| `TYPECAST_ERROR_INTERNAL_SERVER`      | 500 | 서버 오류              |

## C++ 래퍼

C++ 프로젝트의 경우, 더 관용적인 인터페이스를 위한 선택적 C++ 래퍼를 활성화할 수 있습니다:

```cpp theme={null}
#define TYPECAST_CPP_WRAPPER
#include "typecast.h"

#include <fstream>
#include <iostream>

int main() {
    try {
        // 클라이언트 초기화
        typecast::Client client("YOUR_API_KEY");

        // 텍스트를 음성으로 변환
        typecast::TTSRequest request;
        request.text = "안녕하세요! 저는 친절한 텍스트-투-스피치 에이전트입니다.";
        request.voiceId = "tc_672c5f5ce59fac2a48faeaee";
        request.model = typecast::Model::SSFM_V30;
        request.language = "kor";

        auto response = client.textToSpeech(request);

        // 오디오 파일 저장
        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;
}
```

## 플랫폼 지원

SDK는 다음 플랫폼에서 자동화된 E2E 테스트를 통해 검증되었습니다:

| 플랫폼                  | 아키텍처            | glibc | C 표준 | 상태  |
| -------------------- | --------------- | ----- | ---- | --- |
| **CentOS 6.9**       | x86\_64         | 2.12  | C99  | 검증됨 |
| **CentOS 7**         | x86\_64         | 2.17  | C11  | 검증됨 |
| **Amazon Linux 2**   | x86\_64         | 2.26  | C11  | 검증됨 |
| **Ubuntu 20.04 LTS** | x86\_64         | 2.31  | C11  | 검증됨 |
| **Debian Bullseye**  | x86\_64         | 2.31  | C11  | 검증됨 |
| **Windows**          | x64             | N/A   | C11  | 검증됨 |
| **macOS**            | x86\_64 / arm64 | N/A   | C11  | 검증됨 |

## 임베디드 시스템

이 SDK는 네트워크 연결이 가능한 임베디드 시스템에 통합할 수 있습니다.

### 크로스 컴파일

<Tabs>
  <Tab title="ARM Linux (32비트)">
    ```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>

### 메모리 요구 사항

| 구성 요소                 | 대략적인 크기     |
| --------------------- | ----------- |
| 정적 라이브러리 (MinSizeRel) | \~50 KB     |
| 클라이언트당 런타임 힙          | \~8 KB      |
| TTS 응답 버퍼             | 가변 (오디오 크기) |
| JSON 파싱 버퍼            | \~4 KB      |

## 언리얼 엔진 통합

이 SDK는 Unreal Engine 4.27+ 및 Unreal Engine 5.x와의 원활한 통합을 위해 설계되었습니다.

<Steps>
  <Step title="SDK 빌드">
    정적 라이브러리로 빌드합니다:

    ```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="플러그인 구조 생성">
    언리얼 프로젝트에 플러그인을 생성합니다:

    ```
    Plugins/
    └── TypecastTTS/
        ├── Source/TypecastTTS/
        │   ├── Private/
        │   ├── Public/
        │   └── ThirdParty/Typecast/
        │       ├── include/typecast.h
        │       └── lib/Win64/typecast_static.lib
        ├── TypecastTTS.uplugin
        └── TypecastTTS.Build.cs
    ```
  </Step>

  <Step title="Build.cs 구성">
    `Build.cs`에 라이브러리 링킹을 추가합니다:

    ```csharp theme={null}
    // 인클루드 경로 추가
    PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "include"));
    PublicDefinitions.Add("TYPECAST_STATIC");

    // 정적 라이브러리 링크 (플랫폼별)
    if (Target.Platform == UnrealTargetPlatform.Win64)
    {
        PublicAdditionalLibraries.Add(
            Path.Combine(LibPath, "Win64", "typecast_static.lib"));
        AddEngineThirdPartyPrivateStaticDependencies(Target, "libcurl");
    }
    ```
  </Step>
</Steps>

<Info>
  블루프린트 지원 및 오디오 재생을 포함한 전체 언리얼 엔진 통합 가이드는 SDK 저장소의 [README](https://github.com/neosapience/typecast-sdk/tree/main/typecast-c)를 참조하세요.
</Info>

## API 레퍼런스

### 클라이언트 함수

| 함수                                                | 설명                |
| ------------------------------------------------- | ----------------- |
| `typecast_client_create(api_key)`                 | API 키로 클라이언트 생성   |
| `typecast_client_create_with_host(api_key, host)` | 커스텀 호스트로 클라이언트 생성 |
| `typecast_client_destroy(client)`                 | 클라이언트 삭제 및 리소스 해제 |
| `typecast_client_get_error(client)`               | 마지막 오류 정보 가져오기    |

### 텍스트-투-스피치 함수

| 함수                                                 | 설명                    |
| -------------------------------------------------- | --------------------- |
| `typecast_text_to_speech(client, request)`         | 텍스트를 음성 오디오로 변환       |
| `typecast_generate_to_file(client, path, request)` | 음성을 생성하고 로컬 파일로 바로 저장 |
| `typecast_tts_response_free(response)`             | TTS 응답 메모리 해제         |

### 음성 함수

| 함수                                        | 설명                       |
| ----------------------------------------- | ------------------------ |
| `typecast_get_voices(client, filter)`     | 사용 가능한 음성 가져오기 (선택적 필터링) |
| `typecast_get_voice(client, voice_id)`    | ID로 특정 음성 가져오기           |
| `typecast_voices_response_free(response)` | 음성 응답 메모리 해제             |
| `typecast_voice_free(voice)`              | 단일 음성 메모리 해제             |

### 유틸리티 함수

| 함수                                        | 설명                    |
| ----------------------------------------- | --------------------- |
| `typecast_version()`                      | 라이브러리 버전 문자열 가져오기     |
| `typecast_model_to_string(model)`         | 모델 열거형을 문자열로 변환       |
| `typecast_emotion_to_string(emotion)`     | 감정 열거형을 문자열로 변환       |
| `typecast_audio_format_to_string(format)` | 포맷 열거형을 문자열로 변환       |
| `typecast_error_message(code)`            | 오류 코드에 대한 오류 메시지 가져오기 |

### TypecastTTSRequest 필드

| 필드         | 타입                | 필수 | 설명                                |
| ---------- | ----------------- | -- | --------------------------------- |
| `text`     | `const char*`     | ✓  | 합성할 텍스트 (최대 2000자)                |
| `voice_id` | `const char*`     | ✓  | 음성 ID (형식: `tc_*` 또는 `uc_*`)      |
| `model`    | `TypecastModel`   | ✓  | TTS 모델 (`SSFM_V21` 또는 `SSFM_V30`) |
| `language` | `const char*`     |    | ISO 639-3 코드 (NULL이면 자동 감지)       |
| `prompt`   | `TypecastPrompt*` |    | 감정 설정                             |
| `output`   | `TypecastOutput*` |    | 오디오 출력 설정                         |
| `seed`     | `unsigned int`    |    | 재현성을 위한 부호 없는 정수 시드 (≥ 0)         |

### TypecastTTSResponse 필드

| 필드           | 타입                    | 설명                  |
| ------------ | --------------------- | ------------------- |
| `audio_data` | `uint8_t*`            | 생성된 오디오 데이터         |
| `audio_size` | `size_t`              | 오디오 데이터 크기 (바이트)    |
| `duration`   | `float`               | 오디오 길이 (초)          |
| `format`     | `TypecastAudioFormat` | 오디오 포맷 (wav 또는 mp3) |
