SeasonTTS 1.0.0
See the version list below for details.
dotnet add package SeasonTTS --version 1.0.0
NuGet\Install-Package SeasonTTS -Version 1.0.0
<PackageReference Include="SeasonTTS" Version="1.0.0" />
<PackageVersion Include="SeasonTTS" Version="1.0.0" />
<PackageReference Include="SeasonTTS" />
paket add SeasonTTS --version 1.0.0
#r "nuget: SeasonTTS, 1.0.0"
#:package SeasonTTS@1.0.0
#addin nuget:?package=SeasonTTS&version=1.0.0
#tool nuget:?package=SeasonTTS&version=1.0.0
SeasonTTS
SeasonTTS is a .NET text-to-speech library for Qwen3-TTS ONNX bundles.
The initial public release focuses on a simple application-facing API:
- instance-based preset voice generation through
new CustomVoice(model)andGenerate(...) - instance-based voice cloning through
new CloneVoice(model)andClone(...) - explicit initialization through
Initialize()so model loading stays outside the hot inference path - standard WAV byte output suitable for saving directly as
.wav - local model directory loading without requiring a Python runtime
The current implementation targets the pre-exported Qwen3-TTS ONNX bundles published by elbruno on Hugging Face. SeasonTTS is an independent project and is not affiliated with Qwen, Alibaba, or ElBruno.QwenTTS.
Naming
- Package name:
SeasonTTS - Main runtime APIs:
SeasonTTS.CustomVoice,SeasonTTS.CloneVoice - Repository: SeasonRealms/SeasonTTS
Origin
- SeasonTTS is built from a simplified and performance-tuned codebase derived in part from ElBruno.QwenTTS.
- Source files copied or adapted from
ElBruno.QwenTTSretain their original attribution headers where applicable. - SeasonTTS restructures the public API around two direct entry points:
CustomVoiceandCloneVoice. - The current release also separates initialization from inference so repeated synthesis avoids repeated model loading.
Features
- Qwen3-TTS CustomVoice inference from .NET
- Qwen3-TTS Base voice cloning inference from .NET
- Explicit
Initialize()step for model/session setup - Returns standard RIFF/WAVE bytes instead of binding to a specific playback stack
- Supports local ONNX model directories
- Supports preset speaker selection via
QwenVoicePreset - Supports
instructstyle control on compatible 1.7B CustomVoice models - Supports reference-audio cloning, with optional
referenceTextfor ICL mode when the Base bundle includestokenizer12hz_encode.onnx
Current 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);
}
Install
NuGet packaging is planned, but the first public release is source-first.
For now, either:
- reference the
SeasonTTSproject directly - copy the published source into your solution
- wait for the upcoming NuGet package
Supported Models
SeasonTTS currently targets these three ONNX model repositories:
| 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:
- elbruno/Qwen3-TTS-12Hz-0.6B-CustomVoice-ONNX
- elbruno/Qwen3-TTS-12Hz-1.7B-CustomVoice-ONNX
- elbruno/Qwen3-TTS-12Hz-0.6B-Base-ONNX
These repositories are public. In normal direct-download usage, HF_TOKEN is usually not required.
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-customvoiceqwen3-tts-12hz-1.7b-customvoiceqwen3-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_TOKENas an optional repository secret can improve reliability
2. Download directly from Hugging Face
You can manually download the same ONNX bundles from:
- elbruno/Qwen3-TTS-12Hz-0.6B-CustomVoice-ONNX
- elbruno/Qwen3-TTS-12Hz-1.7B-CustomVoice-ONNX
- elbruno/Qwen3-TTS-12Hz-0.6B-Base-ONNX
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/
Quick Start
CustomVoice
This example matches the current sample app usage:
using SeasonTTS;
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;
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
This example also follows the current samples/Sample/App.cs pattern:
using SeasonTTS;
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:
using SeasonTTS;
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,
referenceText: "The transcript of the reference audio.");
File.WriteAllBytes("clonevoice-icl.wav", wavBytes);
Why This API
This initial API is intentionally simple:
- the caller creates either
CustomVoiceorCloneVoice Initialize()performs the expensive model and embedding setup ahead of inferenceGenerate(...)andClone(...)return ready-to-save WAV bytes- the host application remains free to choose its own recording, playback, storage, or transport flow
This shape matches the current sample integration style and keeps app-side code small.
Initialization Notes
The current public API expects the caller to initialize the instance explicitly before synthesis:
var customVoice = new CustomVoice(modelDir);
await customVoice.Initialize();
var cloneVoice = new CloneVoice(modelDir);
await cloneVoice.Initialize();
This avoids paying model-loading cost inside every inference call.
Result Format
Generate(...) and Clone(...) both 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(...)
Copyright And Attribution
SeasonTTS contains code derived in part from ElBruno.QwenTTS.
- SeasonTTS repository code is released under the MIT License
- portions derived from
ElBruno.QwenTTSremain subject to the upstream MIT License and attribution requirements - the upstream project and license text are listed in
THIRD-PARTY-NOTICES.md - copied or adapted files should retain their attribution headers
Project relationship:
- Upstream inspiration and source base: elbruno/ElBruno.QwenTTS
- This project simplifies the public API, restructures initialization, and continues development independently
License Split
- This repository code is released under the MIT License
- Pre-exported ONNX model bundles are not covered by this repository MIT license
- Model weights, tokenizer assets, and converted ONNX bundles remain governed by their own upstream terms and repository metadata
Recommended references:
Disclaimer
SeasonTTS is an independent open source project. It is not affiliated with, endorsed by, or distributed by Qwen, Alibaba, or the ElBruno.QwenTTS project.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.ML.OnnxRuntime (>= 1.26.0)
- Microsoft.ML.Tokenizers (>= 2.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.