Qwen-Audio-TTS/CosyVoice Speech Synthesis iOS SDK

更新时间:
复制 MD 格式

Use the Qwen-Audio-TTS/CosyVoice iOS SDK to turn text into high-quality, expressive speech in your iOS apps.

User guide: For model overviews and how to choose a model, see Speech synthesis.

NeoNui

Architecture highlights:

  • Singleton pattern: get the global instance through NeoNui.sharedInstance().

  • Callback-driven: receive events and audio data through the StreamInputTtsDelegate protocol.

  • JSON configuration: pass parameters as JSON strings.

Call flows

Qwen-Audio-TTS/CosyVoice supports two invocation modes: one-shot input and streaming input.

One-shot input: best for short-text synthesis or when you need SSML markup.

  1. startStreamInputTts() — Initialize the SDK and set the callback delegate and connection parameters.

  2. playStreamInputTts() or asyncPlayStreamInputTts() — Send the text and start synthesis.

  3. onStreamInputTtsDataCallback() — Receive audio data.

  4. TTS_EVENT_SYNTHESIS_COMPLETE — Synthesis complete.

Streaming input: best for real-time conversations or long-form "speak-while-synthesizing" scenarios. This mode does not support SSML markup.

  1. startStreamInputTts() — Initialize the SDK and set the callback delegate and connection parameters.

  2. sendStreamInputTts() — Continuously send text fragments to be synthesized.

  3. onStreamInputTtsDataCallback() — Receive audio data.

  4. stopStreamInputTts() or asyncStopStreamInputTts() — Stop sending text and wait for synthesis to complete.

  5. TTS_EVENT_SYNTHESIS_COMPLETE — Synthesis complete.

startStreamInputTts

Starts a streaming speech synthesis task and opens a connection to the server.

  • Method signature

    - (int) startStreamInputTts:(const char *)ticket parameters:(const char *)parameters sessionId:(const char *)sessionId logLevel:(NuiSdkLogLevel)logLevel saveLog:(BOOL)saveLog;
  • Parameters

    Parameter

    Type

    Description

    ticket

    char*

    JSON string that holds authentication, connection, and debugging settings.

    parameters

    char*

    JSON string that holds the speech synthesis effect settings.

    sessionId

    char*

    Client-specified session ID. If omitted, the server generates one.

    logLevel

    NuiSdkLogLevel

    Print level for the SDK's internal logs.

    saveLog

    BOOL

    Whether to save logs locally. When set to YES, you must specify a path with debug_path and can cap the file size with max_log_file_size.

  • Return value

    Returns an error code.

  • ticket JSON example: The following example does not list every field. Add the others as your code requires:

    {
        "url": "wss://dashscope.aliyuncs.com/api-ws/v1/inference",
        "apikey": "st-****",
        "device_id": "my_device_id"
    }
  • ticket fields

    Field

    Type

    Required

    Description

    url

    string

    Yes

    Service URL. Set to wss://dashscope.aliyuncs.com/api-ws/v1/inference.

    apikey

    string

    Yes

    API key. To limit exposure if a long-lived key leaks, use a short-lived API key instead.

    device_id

    string

    Yes

    Unique identifier for the end user. Set this to the in-app user ID or a client-generated device identifier. The ID is used for log tracing and troubleshooting.

    complete_waiting_ms

    int

    No

    Timeout, in milliseconds, for waiting on the synthesis-complete event (TTS_EVENT_SYNTHESIS_COMPLETE) after you call stopStreamInputTts.

    Default: 10000.

    debug_path

    string

    No

    Local path where log files are stored.

    This field takes effect only when saveLog is set to YES in startStreamInputTts, playStreamInputTts, or asyncPlayStreamInputTts. In that case, you must set this path; otherwise, an error is returned.

    At most two log files are kept locally.

    max_log_file_size

    int

    No

    Maximum size of a log file, in bytes.

    This field takes effect only when saveLog is set to YES in startStreamInputTts, playStreamInputTts, or asyncPlayStreamInputTts.

    Default: 104857600 (100 × 1024 × 1024 bytes, that is, 100 MiB).

    log_track_level

    int

    No

    Filter level for logs delivered through the log callback (onStreamInputTtsLogTrackCallback).

    Default: 2.

    Valid values:

    • 0: LOG_LEVEL_VERBOSE

    • 1: LOG_LEVEL_DEBUG

    • 2: LOG_LEVEL_INFO

    • 3: LOG_LEVEL_WARNING

    • 4: LOG_LEVEL_ERROR

    • 5: LOG_LEVEL_NONE (disables the callback)

    Note: log_track_level and logLevel (set through startStreamInputTts, playStreamInputTts, or asyncPlayStreamInputTts) together determine which logs reach the callback. A log fires the callback only when its level is at or above both thresholds. For example, if log_track_level is 2 (INFO) and logLevel is 3 (WARNING), only logs at WARNING or higher (level >= 3) are delivered.

  • parameters JSON example: The following example does not list every field. Add the others as your code requires:

    {
        "model": "qwen-audio-3.0-tts-flash",
        "voice": "longanlingxi",
        "format": "mp3",
        "sample_rate": 24000,
        "volume": 50,
        "rate": 1,
        "pitch": 1,
        "language_hints": ["zh"],
        "enable_ssml": false
    }
  • parameters fields

    Field

    Type

    Required

    Description

    model

    string

    Yes

    The model name.

    voice

    string

    Yes

    The voice used for speech synthesis.

    • System voices: See CosyVoice Voice list

    • Cloned voices: Custom voices created through voice cloning

    • Custom voices: Custom voices created through voice design

    format

    string

    No

    The audio encoding format.

    Valid values:

    • pcm

    • wav

    • mp3 (default)

    • opus

    Important

    cosyvoice-v1 doesn't support the opus format.

    volume

    int

    No

    The volume level.

    Default value: 50.

    Valid values: [0, 100].

    sample_rate

    int

    No

    The audio sample rate in Hz.

    Valid values: 8000, 16000, 22050 (default), 24000, 44100, 48000.

    rate

    float

    No

    The speech rate.

    Default value: 1.0.

    Valid values: [0.5, 2.0].

    pitch

    float

    No

    The pitch.

    Default value: 1.0.

    Valid values: [0.5, 2.0].

    bit_rate

    int

    No

    The audio bit rate in kbps. When the audio format is opus, use bit_rate to adjust the bit rate.

    Default value: 32.

    Valid values: [6, 510].

    cosyvoice-v1 doesn't support this parameter.

    enable_ssml

    boolean

    No

    Whether to enable SSML.

    Default: false.

    • true: enabled.

    • false: disabled.

    For the SSML usage restrictions (supported models, voices, and APIs), see Limitations.

    word_timestamp_enabled

    boolean

    No

    Specifies whether to enable word-level timestamps.

    Default value: false.

    Available only in streaming output mode. Supported voices: cloned voices of cosyvoice-v3.5-plus, cosyvoice-v3.5-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2, and system voices marked as supported in CosyVoice Voice list. qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, and cloned voices of other models do not support this feature.

    Timestamps are returned in all_response of onStreamInputTtsEventCallback.

    seed

    int

    No

    A random seed for controlling variation in the synthesis output. When the model version, text, voice, and other parameters are unchanged, using the same seed produces identical results.

    Default value: 0.

    Valid values: [0, 65535].

    cosyvoice-v1 doesn't support this parameter.

    language_hints

    array[string]

    No

    Important
    • This parameter is an array, but the current version only processes the first element. Pass a single value.

    • This parameter specifies the target language for speech synthesis. It's unrelated to the language of the audio sample used in voice cloning. To set the source language for a cloning task, see the voice cloning API reference.

    Specifies the target language for speech synthesis to improve output quality. cosyvoice-v1 doesn't support this feature.

    When digit pronunciation, abbreviation expansion, symbol reading, or minority-language synthesis doesn't meet expectations, use this parameter. For example:

    • Unexpected digit pronunciation: "hello, this is 110" is read as "hello, this is one zero" instead of the expected Chinese pronunciation

    • Inaccurate symbol pronunciation: "@" is read as the Chinese equivalent instead of "at"

    • Poor minor language synthesis quality with unnatural results

    Valid values:

    • zh: Chinese

    • en: English

    • fr: French

    • de: German

    • ja: Japanese

    • ko: Korean

    • ru: Russian

    • pt: Portuguese

    • th: Thai

    • id: Indonesian

    • vi: Vietnamese

    • it: Italian

    • ms: Malay

    instruction

    string

    No

    Controls synthesis characteristics such as dialect, emotion, or speaking style.

    For usage details, see Instruction-based control.

    enable_aigc_tag

    boolean

    No

    Specifies whether to embed an AIGC watermark in the generated audio. When set to true, the watermark is embedded in audio files of supported formats (wav/mp3/opus).

    Default value: false.

    Only qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.

    aigc_propagator

    string

    No

    Sets the ContentPropagator field in the AIGC watermark, identifying the content propagator. Takes effect only when enable_aigc_tag is true.

    Default value: Alibaba Cloud UID.

    Only qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.

    aigc_propagate_id

    string

    No

    Sets the PropagateID field in the AIGC watermark, uniquely identifying a specific propagation action. Takes effect only when enable_aigc_tag is true.

    Default value: The request ID of the current speech synthesis request.

    Only qwen-audio-3.0-tts-plus, qwen-audio-3.0-tts-flash, cosyvoice-v3-flash, cosyvoice-v3-plus, and cosyvoice-v2 support this feature.

sendStreamInputTts

Sends text to be synthesized. Use this method together with startStreamInputTts.

After you call startStreamInputTts, use this method to push text continuously.

After all text is sent, call stopStreamInputTts or asyncStopStreamInputTts to signal end of input.

  • Method signature

    - (int) sendStreamInputTts:(const char *)text;
  • Parameters

    Parameter

    Type

    Description

    text

    char*

    Text to synthesize. SSML is not supported. SSML tags in the input are read as plain text rather than parsed.

  • Return value

    Returns an error code.

stopStreamInputTts

Synchronous method. Notifies the server that all text has been sent, then blocks until every audio chunk is synthesized and TTS_EVENT_SYNTHESIS_COMPLETE is received.

The block timeout is controlled by complete_waiting_ms.

  • Method signature

    - (int) stopStreamInputTts;
  • Return value

    Returns an error code.

asyncStopStreamInputTts

Asynchronous method. Notifies the server that all text has been sent and returns immediately. Synthesis continues in the background.

Use TTS_EVENT_SYNTHESIS_COMPLETE to detect when synthesis finishes.

  • Method signature

    - (int) asyncStopStreamInputTts;
  • Return value

    Returns an error code.

cancelStreamInputTts

Immediately drops the connection to the server and terminates the current synthesis task. After this method is called, no further audio data callbacks fire.

  • Method signature

    - (int) cancelStreamInputTts;
  • Return value

    Returns an error code.

playStreamInputTts

Asynchronous one-shot synthesis method. Returns immediately and runs synthesis in the background; results are delivered through callbacks. You do not need to call stopStreamInputTts afterward.

This method enables SSML by default. To disable SSML, set the enable_ssml field in parameters to false.

  • Method signature

    - (int) playStreamInputTts:(const char *)ticket parameters:(const char *)parameters text:(const char *)text sessionId:(const char *)sessionId logLevel:(NuiSdkLogLevel)logLevel saveLog:(BOOL)saveLog;
  • Parameters

    The ticket, parameters, and other shared parameters use the same definitions as startStreamInputTts.

    Parameter

    Type

    Description

    text

    char*

    Text to synthesize. Supports SSML.

  • Return value

    Returns an error code.

asyncPlayStreamInputTts

This method sends all text for synthesis asynchronously. It returns immediately without waiting for audio data. You do not need to call stopStreamInputTts afterward.

This method enables SSML by default. To disable SSML, set the enable_ssml field in parameters to false.

  • Method signature

    - (int) asyncPlayStreamInputTts:(const char *)ticket parameters:(const char *)parameters text:(const char *)text sessionId:(const char *)sessionId logLevel:(NuiSdkLogLevel)logLevel saveLog:(BOOL)saveLog;
  • Parameters

    The ticket, parameters, and other shared parameters use the same definitions as startStreamInputTts.

    Parameter

    Type

    Description

    text

    char*

    Text to synthesize. Supports SSML.

  • Return value

    Returns an error code.

StreamInputTtsDelegate

Callback protocol for Qwen-Audio-TTS/CosyVoice streaming speech synthesis. Implement this protocol to receive synthesis events, audio data, and logs.

onStreamInputTtsEventCallback: listen for events

  • Method signature

    - (void)onStreamInputTtsEventCallback:(StreamInputTtsCallbackEvent)event taskId:(char*)taskid sessionId:(char*)sessionId ret_code:(int)ret_code error_msg:(char*)error_msg timestamp:(char*)timestamp all_response:(char*)all_response;
  • Parameters

    Parameter

    Type

    Description

    event

    StreamInputTtsCallbackEvent

    Callback event.

    taskid

    char*

    Speech synthesis task ID.

    sessionId

    char*

    Session ID. The client-supplied value is returned as-is. If none was supplied, the server generates one.

    ret_code

    int

    Error code. Valid only for the TTS_EVENT_TASK_FAILED event. See error codes.

    error_msg

    char*

    Error message. Valid only for the TTS_EVENT_TASK_FAILED event.

    timestamp

    char*

    Timestamp information for the synthesis result.

    all_response

    char*

    Full JSON response. Parse this string to extract the fields you need.

onStreamInputTtsDataCallback: listen for audio data

The SDK fires this callback repeatedly during synthesis. Read the audio data from the callback.

  • Method signature

    - (void)onStreamInputTtsDataCallback:(char*)buffer len:(int)len;
  • Parameters

    Parameter

    Type

    Description

    buffer

    char*

    Audio data for the current segment. Use this data to:

    • Assemble a complete audio file and play it.

    • Stream the data to a player that supports streaming playback.

    Note:

    • For the compressed mp3 and opus formats, use a streaming player. Playing segments frame by frame can cause decoding failures.

    • When assembling a complete file, append each segment to the same file.

    • For the wav and mp3 formats, only the first onStreamInputTtsDataCallback invocation includes the file header; later invocations return raw audio data. Concatenate all buffer values in order. For the opus format, each frame is a self-contained Ogg page that you can concatenate directly.

    len

    int

    Length of the audio data, in bytes.

onStreamInputTtsLogTrackCallback: listen for trace logs

This callback delivers detailed SDK-internal logs to help with troubleshooting and debugging.

  • Method signature

    - (void)onStreamInputTtsLogTrackCallback:(NuiSdkLogLevel)level
                                  logMessage:(const char *)log;
  • Parameters

    Parameter

    Type

    Description

    level

    NuiSdkLogLevel

    Log level.

    log

    char*

    Log content.

StreamInputTtsCallbackEvent

Event-type enum for Qwen-Audio-TTS/CosyVoice streaming speech synthesis.

Event

Description

TTS_EVENT_SYNTHESIS_STARTED

The server accepted the request and started processing. onStreamInputTtsDataCallback typically delivers the first audio segment shortly after this event.

TTS_EVENT_SENTENCE_SYNTHESIS

Progress information emitted during synthesis, including billing data.

TTS_EVENT_SYNTHESIS_COMPLETE

The server has finished sending all audio data. onStreamInputTtsDataCallback is not called again. This event is the definitive end-of-stream signal.

TTS_EVENT_TASK_FAILED

The task failed. Read task_id, error_code, and error_message from all_response in onStreamInputTtsEventCallback to diagnose the failure.

{
          "header": {
              "task_id": "2bf83b9a-baeb-4fda-8d9a-xxxxxxxxxxxx",
              "event": "task-failed",
              "error_code": "InvalidParameter",
              "error_message": "[tts:]Engine return error code: 418",
              "attributes": {}
          },
          "payload": {}
      }

NuiSdkLogLevel

SDK log-level enum that controls log output.

Level

Description

0: LOG_LEVEL_VERBOSE

Most detailed log level. Includes all debug information.

1: LOG_LEVEL_DEBUG

Debug-level logs.

2: LOG_LEVEL_INFO

General informational logs (default).

3: LOG_LEVEL_WARNING

Warning-level logs.

4: LOG_LEVEL_ERROR

Error-level logs.

5: LOG_LEVEL_NONE

Disables log output.

Sample code

  1. Get your API key: Obtain an API key.

    Note

    For third-party apps or end users that need temporary access, or when you want tight control over sensitive operations such as data access and deletion, use a temporary API key instead. A temporary API key is valid for a fixed 60 seconds and must be regenerated after it expires.

  2. Download the SDK and run the sample code:

    • Download the latest SDK bundle.

    • Extract the ZIP archive and add nuisdk.framework to your Xcode project.

    • In Build Phases > Link Binary With Libraries, add nuisdk.framework.

    • In General > Frameworks, Libraries, and Embedded Content, set nuisdk.framework to Embed & Sign.

    • Open the sample project in Xcode. The sample code is in DashQwen-Audio-TTS/CosyVoiceStreamInputTTSViewController.m. Replace the placeholder API key with your own and run the app to try it out.

Call modes

Call mode

Description

One-shot input

Steps:

  1. Initialize the SDK and the player component.

  2. Configure the parameters for your scenario.

  3. Call playStreamInputTts or asyncPlayStreamInputTts to send the text and start synthesis.

  4. Wait for the TTS_EVENT_SYNTHESIS_COMPLETE callback, which signals that synthesis is finished.

Use cases:

  • Short-text synthesis.

  • Scenarios that require SSML markup.

Streaming input

Steps:

  1. Initialize the SDK and the player component.

  2. Configure the parameters for your scenario.

  3. Call startStreamInputTts to start streaming synthesis.

  4. Call sendStreamInputTts repeatedly to send text in chunks.

  5. Read the binary audio data from onStreamInputTtsDataCallback.

  6. Call stopStreamInputTts or asyncStopStreamInputTts to stop sending text and wait for synthesis to finish.

  7. Wait for the TTS_EVENT_SYNTHESIS_COMPLETE callback, which signals that synthesis is finished.

Use cases:

  • Real-time conversation or long-form "speak as you synthesize" scenarios.

  • This mode does not support SSML markup.

Advanced features

SSML markup

Purpose: Embed XML tags in the input text to precisely control pronunciation, speech rate, pauses, and other prosody details.

Limitations: SSML is supported only with One-shot input (the playStreamInputTts and asyncPlayStreamInputTts methods). It is not supported with Streaming input (the sendStreamInputTts method).

How to use: When you call playStreamInputTts or asyncPlayStreamInputTts, the SDK enables SSML automatically. Pass text that contains SSML tags directly in the text parameter.

For more details, see SSML.

Math expressions

Purpose: Make the model read common math formulas and expressions correctly.

How to use: Pass text that contains math expressions in LaTeX format directly in the text parameter. For more details, see Convert LaTeX formulas to speech (Chinese language only).