Skip to content

Generate speech

Use generateSpeech when a provider exposes text-to-speech.

For incremental text input and audio output, see Stream speech.

Examples/Sources/GenerateSpeech/main.swift
import Foundation
import SwiftAISDK
@main
struct GenerateSpeechExample {
static func main() async throws {
let provider = try AIProviders.openAI()
let model = try provider.speechModel("gpt-4o-mini-tts")
let result = try await model.generateSpeech(
"Welcome to the SwiftAISDK demo.",
voice: "alloy",
format: "mp3",
speed: 1.0
)
try result.audio.write(to: URL(fileURLWithPath: "welcome.mp3"))
}
}

The protocol method is named speak(_:) for low-level model implementations. Application code should usually prefer the facade spelling generateSpeech.

let result = try await AI.generateSpeech(
"Read this in a calm tone.",
using: model,
instructions: "Calm, precise, and friendly."
)

Azure mai-voice-2, mai-voice-2-flash, mai-voice-2.1, and mai-voice-2.1-flash use the Azure Speech endpoint. Text is XML-escaped for SSML; speed becomes prosody, and providerOptions.azure.style / styleDegree control speaking style. voice overrides the locale selected by language. mp3, opus, pcm, wav, and native Azure output format names are accepted. Other Azure speech model IDs continue to use the OpenAI audio route.

let azure = try AIProviders.azure(resourceName: "my-resource")
let model = try azure.speechModel("mai-voice-2.1")
let result = try await AI.generateSpeech(
model: model,
request: SpeechRequest(
text: "Hello!",
language: "en",
providerOptions: ["azure": ["style": "cheerful"]]
)
)

Separate Speech host overrides use AzureOpenAIAudioSettings.speechBaseURL. API keys use Ocp-Apim-Subscription-Key; Entra token providers also apply to the Speech route. Protocol-reset 502 responses produce an actionable, non-retryable error while retaining the raw response for diagnostics.

  • voice selects a provider voice.
  • format requests an output audio format.
  • speed adjusts playback speed when supported.
  • language hints the spoken language.
  • instructions gives delivery or style guidance.
  • providerOptions carries provider-specific controls.
  • extraBody, headers, abortSignal, retryPolicy, and telemetry follow the shared facade behavior.

SpeechResult contains the generated bytes and metadata:

Its optional usage is native provider JSON, such as Deepgram character counts or Gateway usage. Speech telemetry records the byte length and content type without recording generated audio bytes or the raw audio response body.

  • audio
  • contentType
  • warnings
  • providerMetadata
  • requestMetadata
  • responseMetadata

The facade resolves contentType from detected bytes first, then the response header, requested format, and provider metadata. Headerless raw requests with those requested formats now retain canonical audio/l16, audio/mulaw, or audio/alaw types instead of falling through to the generic MP3 default.