SeasonTTS 1.0.1

dotnet add package SeasonTTS --version 1.0.1
                    
NuGet\Install-Package SeasonTTS -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SeasonTTS" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SeasonTTS" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="SeasonTTS" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SeasonTTS --version 1.0.1
                    
#r "nuget: SeasonTTS, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SeasonTTS@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SeasonTTS&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=SeasonTTS&version=1.0.1
                    
Install as a Cake Tool

SeasonTTS

SeasonTTS is a cross-platform .NET text-to-speech library for Qwen3-TTS, offering two runtime backends:

  • ONNX mode — direct ONNX Runtime inference against pre-exported ONNX model bundles, with a simple CustomVoice / CloneVoice API
  • GGML mode — P/Invoke wrapper around qwentts.cpp (Qwen3-TTS GGML), supporting base synthesis, CustomVoice, VoiceDesign, and voice cloning

Supports Windows, Linux, macOS, Android, iOS, and MacCatalyst. SeasonTTS is an independent project and is not affiliated with Qwen, Alibaba, or the upstream projects whose code it derives from.

Naming

  • Package name: SeasonTTS
  • ONNX namespace: SeasonTTS.ONNX (classes: CustomVoice, CloneVoice)
  • GGML namespace: SeasonTTS.GGML (class: QwenEngine)
  • Repository: SeasonRealms/SeasonTTS

Origin

SeasonTTS combines and restructures code derived from two upstream projects:

Backend Upstream License What was adapted
ONNX ElBruno.QwenTTS MIT ONNX inference pipeline, tokenizer, vocoder, embedding store — restructured into CustomVoice / CloneVoice with explicit Initialize() separation
GGML ServeurpersoCom/qwentts.cpp MIT Native C library wrapped via P/Invoke; managed bindings under SeasonTTS.GGML with QwenEngine high-level API, backend auto-selection, streaming, and cancellation

Source files copied or adapted from upstream retain their original attribution headers where applicable.

Modes at a Glance

Capability ONNX (SeasonTTS.ONNX) GGML (SeasonTTS.GGML)
Base (plain) synthesis engine.Synthesize(text)
CustomVoice (named speakers) new CustomVoice(model).Generate(text, voice) engine.Synthesize(text, speaker: "vivian")
VoiceDesign (attribute instruction) engine.Synthesize(text, instruct: "...")
Voice cloning (reference audio) new CloneVoice(model).Clone(text, stream) engine.Synthesize(text, refAudio24k: wav)
GPU acceleration via ONNX Runtime EP selection CUDA / Vulkan / Metal auto-select
Cross-platform .NET 10 targets Windows, Linux, macOS, Android, iOS, MacCatalyst
Streaming output engine.SynthesizeStreaming(callback, ...)
Cancellation CancellationToken CancellationToken

Features

  • Qwen3-TTS CustomVoice inference with 9 preset speakers
  • Qwen3-TTS Base voice cloning from reference audio
  • VoiceDesign attribute instruction control (GGML, 1.7B)
  • Explicit Initialize() step for ONNX model/session setup
  • Standard RIFF/WAVE bytes (ONNX) or float PCM samples (GGML)
  • Local model directory loading (ONNX) or GGUF files (GGML)
  • GPU auto-detection: CUDA / Vulkan / Metal with CPU fallback (GGML)
  • Streaming audio chunks with rolling overlap (GGML)
  • Cancellation support with step-level granularity (GGML)

ONNX Mode

The ONNX backend targets pre-exported Qwen3-TTS ONNX bundles published by elbruno on Hugging Face. It uses Microsoft.ML.OnnxRuntime for inference.

ONNX API

public class CustomVoice : IDisposable
{
    public CustomVoice(
        string model,
        Func<SessionOptions>? sessionOptionsFactory = null,
        Func<SessionOptions>? vocoderSessionOptionsFactory = null);

    public Task Initialize(CancellationToken cancellationToken = default);

    public Task<byte[]> Generate(
        string text,
        QwenVoicePreset voice = QwenVoicePreset.Ryan,
        string language = "auto",
        string? instruct = null,
        CancellationToken cancellationToken = default);
}

public class CloneVoice : IDisposable
{
    public CloneVoice(
        string model,
        Func<SessionOptions>? sessionOptionsFactory = null);

    public Task Initialize(CancellationToken cancellationToken = default);

    public Task<byte[]> Clone(
        string text,
        Stream referenceAudioStream,
        string? referenceText = null,
        string language = "auto",
        CancellationToken cancellationToken = default);
}

Supported ONNX Models

Model family Hugging Face repo Typical use
CustomVoice 0.6B elbruno/Qwen3-TTS-12Hz-0.6B-CustomVoice-ONNX preset voices, smaller footprint
CustomVoice 1.7B elbruno/Qwen3-TTS-12Hz-1.7B-CustomVoice-ONNX preset voices plus instruct style control
Base 0.6B elbruno/Qwen3-TTS-12Hz-0.6B-Base-ONNX voice cloning from reference audio

Direct model pages:

ONNX Quick Start

CustomVoice:

using SeasonTTS.ONNX;

var model = @"../../../../../../Models/qwen3-tts-12hz-0.6b-customvoice-onnx";
var customVoice = new CustomVoice(model);

await customVoice.Initialize();

byte[] wavBytes = await customVoice.Generate(
    "Hello from SeasonTTS.",
    QwenVoicePreset.Vivian);

File.WriteAllBytes("customvoice.wav", wavBytes);

Example with 1.7B instruct control:

using SeasonTTS.ONNX;

var model = @"../../../../../../Models/qwen3-tts-12hz-1.7b-customvoice-onnx";
var customVoice = new CustomVoice(model);

await customVoice.Initialize();

byte[] wavBytes = await customVoice.Generate(
    "Welcome to SeasonTTS.",
    QwenVoicePreset.Ryan,
    instruct: "Speak warmly and slowly with a clear presentation style.");

File.WriteAllBytes("customvoice-17b.wav", wavBytes);

CloneVoice:

using SeasonTTS.ONNX;

var model = @"../../../../../../Models/qwen3-tts-12hz-0.6b-base-onnx";
var cloneVoice = new CloneVoice(model);

await cloneVoice.Initialize();

using var referenceStream = File.OpenRead("reference.wav");

byte[] wavBytes = await cloneVoice.Clone(
    "This sentence uses the cloned voice.",
    referenceStream);

File.WriteAllBytes("clonevoice.wav", wavBytes);

Optional ICL mode with reference transcript:

byte[] wavBytes = await cloneVoice.Clone(
    "This sentence uses the cloned voice.",
    referenceStream,
    referenceText: "The transcript of the reference audio.");

GGML Mode

The GGML backend wraps qwentts.cpp via P/Invoke. It loads GGUF model files and uses GGML's hardware-accelerated backends for inference. The managed API lives in SeasonTTS.GGML.

GGML API

public sealed class QwenEngine : IDisposable
{
    public QwenEngine(
        string talkerGgufPath,
        string codecGgufPath,
        bool useFA = true,
        bool clampFp16 = false,
        string? backend = null);

    // Base / CustomVoice / VoiceDesign / Clone — mode auto-detected from GGUF
    public float[] Synthesize(
        string text,
        string lang = "English",
        string? speaker = null,
        string? instruct = null,
        float[]? refAudio24k = null,
        string? refText = null,
        long? seed = null,
        CancellationToken cancellationToken = default);

    // Streaming variant
    public void SynthesizeStreaming(
        AudioChunkCallback onChunk,
        string text,
        string lang = "English",
        ...);

    // Queries
    public string[] GetAvailableSpeakers();
    public QtBackendInfo[] EnumerateBackends();
}

The engine auto-detects the synthesis mode from the talker GGUF:

Talker GGUF Mode Speaker Instruct
*-base-*.gguf Base + Clone
*-customvoice-*.gguf CustomVoice speaker: "vivian"
*-voicedesign-*.gguf VoiceDesign instruct: "male, young..."

Platform Support & GPU Backends

Platform RID GPU backend CPU fallback
Windows x64 win-x64 CUDA / Vulkan Yes
Linux x64 linux-x64 CUDA / Vulkan Yes
macOS ARM64 osx-arm64 Metal Yes
MacCatalyst ARM64 maccatalyst-arm64 Metal Yes
iOS ARM64 ios-arm64 Metal Yes
Android ARM64 android-arm64-v8a Vulkan Yes

At runtime the GGML backend auto-selects the best available GPU. Set GGML_BACKEND=CUDA0|Vulkan0|CPU to force a specific device.

Supported GGUF Models

Pre-converted GGUFs are available on Hugging Face:

Two GGUFs are required per pipeline instance:

  • Talker: qwen-talker-{size}-{mode}-{quant}.gguf
    • sizes: 0.6b (all modes), 1.7b (all modes; VoiceDesign is 1.7B only)
    • modes: base, customvoice, voicedesign
    • quants: F32, BF16, Q8_0, Q4_K_M
  • Codec: qwen-tokenizer-12hz-{quant}.gguf (shared across all modes)

GGML Quick Start

using SeasonTTS.GGML;

// 1. Create engine (loads models once)
using var engine = new QwenEngine(
    "Models/qwen-talker-0.6b-base-Q8_0.gguf",
    "Models/qwen-tokenizer-12hz-Q8_0.gguf");

// 2. Base synthesis
float[] audio = engine.Synthesize("Hello world.", lang: "English");
// audio is mono float PCM at 24 kHz

// 3. CustomVoice — named speaker
float[] customAudio = engine.Synthesize(
    "Hello from Vivian.", lang: "English", speaker: "vivian");
// Requires a customvoice talker GGUF; engine auto-validates mode.

// 4. VoiceDesign — attribute instruction (1.7B only)
float[] designAudio = engine.Synthesize(
    "A designed voice.", lang: "English",
    instruct: "male, young adult, moderate pitch");

// 5. Clone — reference audio (base model)
float[] refWav = LoadWav24k("reference.wav"); // your own loader
float[] cloneAudio = engine.Synthesize(
    "Cloned voice speaking.", lang: "English",
    refAudio24k: refWav, refText: "The transcript of the reference.");

Streaming

engine.SynthesizeStreaming(
    (chunk, n) => { /* process n samples of float PCM */ },
    "A longer text for streaming synthesis.",
    lang: "English");

Chunks are emitted every codecChunkSec (default 24 s) of decoded audio with a codecLeftContextSec (default 2 s) rolling overlap to avoid edge artifacts.

Cancellation

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
float[] audio = engine.Synthesize("...", cancellationToken: cts.Token);

The native loop polls the token at the top of every autoregressive step (~83 ms granularity).

Runtime Backend Selection

Set the environment variable before creating the engine:

GGML_BACKEND=CUDA0     # force CUDA GPU 0
GGML_BACKEND=Vulkan0   # force Vulkan GPU 0
GGML_BACKEND=CPU       # force CPU only

Build Native Libraries (GGML)

Native libraries for the GGML backend are built via the GitHub Actions workflow:

.github/workflows/build-qwentts.yml

Trigger it manually (workflow_dispatch) with the desired qwentts.cpp ref and CUDA version. Artifacts are produced for all six RIDs.

For local builds, clone qwentts.cpp with submodules and use one of:

./buildcuda.sh      # NVIDIA GPU
./buildvulkan.sh    # AMD / Intel GPU (Vulkan)
./buildcpu.sh       # CPU only
./buildall.sh       # all backends, runtime DL

The shared library target (-DQWEN_SHARED=ON) exports only the qt_* symbols described in the public ABI header (qwen.h).

ONNX Model Download

You have two practical options:

1. Download via GitHub Actions

The repository includes .github/workflows/download-qwen-tts-onnx.yml. This workflow supports three choices:

  • qwen3-tts-12hz-0.6b-customvoice
  • qwen3-tts-12hz-1.7b-customvoice
  • qwen3-tts-12hz-0.6b-base

It downloads the full selected Hugging Face repository snapshot and uploads it as a workflow artifact.

Notes:

  • direct downloads from these public repositories usually work without HF_TOKEN
  • if GitHub-hosted runners hit Hugging Face rate limits, setting HF_TOKEN as an optional repository secret can improve reliability

2. Download directly from Hugging Face

You can manually download the same ONNX bundles from the Hugging Face model pages listed above.

Typical local layout:

Models/
  qwen3-tts-12hz-0.6b-customvoice-onnx/
  qwen3-tts-12hz-1.7b-customvoice-onnx/
  qwen3-tts-12hz-0.6b-base-onnx/

Install

NuGet packaging is planned, but the first public release is source-first.

For now, either:

  • reference the SeasonTTS project directly
  • copy the published source into your solution
  • wait for the upcoming NuGet package

Result Format

ONNX modeGenerate(...) and Clone(...) return a byte[] containing a standard .wav file:

  • sample format: 16-bit PCM WAV
  • sample rate: 24000
  • output is ready to save with File.WriteAllBytes(...)

GGML modeSynthesize(...) returns float[] mono PCM:

  • sample format: 32-bit float PCM
  • sample rate: 24000
  • convert to WAV or play directly with your preferred audio stack

SeasonTTS contains code derived in part from two upstream projects:

ElBruno.QwenTTS (ONNX backend)

  • Repository: elbruno/ElBruno.QwenTTS
  • License: MIT
  • Copyright: Bruno Capuano
  • Portions adapted for the ONNX inference pipeline, restructured into CustomVoice and CloneVoice with explicit initialization separation

qwentts.cpp (GGML backend)

Copied or adapted files retain their attribution headers where applicable. Full upstream license texts are listed in THIRD-PARTY-NOTICES.md.

License

  • This repository code is released under the MIT License (see LICENSE)
  • Pre-exported ONNX model bundles and GGUF files are not covered by this repository's MIT license
  • Model weights, tokenizer assets, and converted bundles remain governed by their own upstream terms:
    • Qwen3-TTS models by Alibaba / Qwen team — Apache 2.0
    • ONNX bundles by elbruno — see individual Hugging Face repos
    • GGUF bundles by Serveurperso — see Serveurperso/Qwen3-TTS-GGUF

Recommended references:

Disclaimer

SeasonTTS is an independent open source project. It is not affiliated with, endorsed by, or distributed by Qwen, Alibaba, the ElBruno.QwenTTS project, or the qwentts.cpp project.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-browser1.0 is compatible.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-maccatalyst26.0 is compatible.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed.  net10.0-windows10.0.19041 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 115 6/20/2026
1.0.0 118 6/5/2026