Agash.TTSTextNormalization 0.0.0-alpha.0.2

This is a prerelease version of Agash.TTSTextNormalization.
There is a newer version of this package available.
See the version list below for details.
dotnet add package Agash.TTSTextNormalization --version 0.0.0-alpha.0.2
                    
NuGet\Install-Package Agash.TTSTextNormalization -Version 0.0.0-alpha.0.2
                    
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="Agash.TTSTextNormalization" Version="0.0.0-alpha.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Agash.TTSTextNormalization" Version="0.0.0-alpha.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Agash.TTSTextNormalization" />
                    
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 Agash.TTSTextNormalization --version 0.0.0-alpha.0.2
                    
#r "nuget: Agash.TTSTextNormalization, 0.0.0-alpha.0.2"
                    
#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 Agash.TTSTextNormalization@0.0.0-alpha.0.2
                    
#: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=Agash.TTSTextNormalization&version=0.0.0-alpha.0.2&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Agash.TTSTextNormalization&version=0.0.0-alpha.0.2&prerelease
                    
Install as a Cake Tool

TTSTextNormalization - Normalize Text for TTS

NuGet Version Build Status

A .NET 9 / C# 13 class library designed to normalize text containing emojis, currency symbols, numbers, abbreviations, and other non-standard elements, making it suitable for consistent and natural-sounding Text-to-Speech (TTS) synthesis across different engines (e.g., System.Speech, KokoroSharp). Specifically tailored for scenarios involving user-generated content like Twitch/YouTube chat and donations.

Problem Solved

TTS engines often struggle with or produce inconsistent results when encountering:

  • Emojis (e.g., ✨, πŸ‘, πŸ‡¬πŸ‡§)
  • Currency symbols and codes from various locales (e.g., $, Β£, €, USD, JPY, BRL)
  • Different number formats (cardinals, ordinals, decimals, version numbers)
  • Common chat/gaming abbreviations and slang (e.g., lol, brb, gg, afk)
  • Excessive punctuation or letter repetitions (e.g., !!!, ???, sooooo)
  • URLs or non-standard characters

This library preprocesses input text using a configurable pipeline of rules to replace or adjust these elements before sending the text to the TTS engine, leading to a more predictable, consistent, and pleasant listening experience.

Features

  • Emoji Normalization: Replaces Unicode emojis (including flags, ZWJ sequences) with descriptive text (e.g., ✨ β†’ sparkles, πŸ‘ β†’ thumbs up, πŸ‡¬πŸ‡§ β†’ flag United Kingdom) using an up-to-date emoji dataset processed by a source generator.
  • Currency Normalization: Detects currency symbols and ISO codes known to the .NET runtime. Replaces amounts with spoken text using locale-aware mappings (e.g., $10.50 β†’ ten dollars fifty cents, €100 β†’ one hundred euros, 500 JPY β†’ five hundred yen). Uses Humanizer for number-to-word conversion. Requires manual mapping for TTS spoken names per ISO code.
  • Number Normalization: Handles standalone cardinals ("123" β†’ one hundred and twenty-three), ordinals ("1st" β†’ first), decimals ("1.5" β†’ one point five), and basic version-like numbers ("1.2.3" β†’ one point two point three) using Humanizer and custom Regex.
  • Abbreviation/Acronym Expansion: Expands a comprehensive list of common chat, gaming, and streaming abbreviations (e.g., lol β†’ laughing out loud, gg β†’ good game, afk β†’ away from keyboard). Case-insensitive and whole-word matching.
  • Basic Text Sanitization: Normalizes line breaks, removes common problematic control/formatting characters, and replaces non-standard "fancy" punctuation (smart quotes, dashes, ellipsis) with ASCII equivalents.
  • Chat Text Cleanup:
    • Reduces sequences of excessive punctuation (!!! β†’ !, ... β†’ ., ??? β†’ ?).
    • Reduces excessive letter repetitions (soooo β†’ soo).
  • Whitespace Normalization: Trims leading/trailing whitespace, collapses multiple internal whitespace characters to a single space, and normalizes spacing around common punctuation (removes space before, ensures space after).
  • Extensibility: Designed around a pipeline of ITextNormalizationRule instances, easily configurable via Dependency Injection. Custom rules can be created by implementing the interface.
  • Performance: Optimized using modern .NET features like source generators (Regex, Emoji data), FrozenDictionary for lookups, and efficient string handling where possible.

Technology

  • C# 13 / .NET 9 (Preview): Leverages the latest language and runtime features.
  • Source Generators: Used for generating optimized Regex patterns and embedding up-to-date Emoji data at compile time.
  • Humanizer: Used for robust number-to-words and ordinal conversion.
  • Core .NET Libraries: System.Text.RegularExpressions, System.Globalization, System.Collections.Frozen, System.Text.Json (in generator).
  • Dependency Injection: Designed for easy integration using Microsoft.Extensions.DependencyInjection.

Getting Started

Installation

dotnet add package Agash.TTSTextNormalization

Or install Agash.TTSTextNormalization via the NuGet Package Manager in Visual Studio.

  1. Configure Services (e.g., in Program.cs or Startup.cs):

    using Microsoft.Extensions.DependencyInjection;
    using TTSTextNormalization.Abstractions; // For ITextNormalizer
    using TTSTextNormalization.DependencyInjection; // For extension methods
    
    // ... other using statements
    
    var services = new ServiceCollection();
    
    // Configure the normalization pipeline with desired rules
    services.AddTextNormalization(builder =>
    {
        // Add rules - order is managed internally by the 'Order' property of each rule (currently not yet configurable, opinionated)
        builder.AddBasicSanitizationRule();       // Runs first (Order 10)
        builder.AddEmojiRule();                   // Order 100
        builder.AddCurrencyRule();                // Order 200
        builder.AddAbbreviationNormalizationRule(); // Order 300
        builder.AddNumberNormalizationRule();       // Order 400
        builder.AddExcessivePunctuationRule();    // Order 500
        builder.AddLetterRepetitionRule();        // Order 510
        // Add custom rules here if needed: builder.AddRule<MyCustomRule>();
        builder.AddWhitespaceNormalizationRule(); // Runs last (Order 9000)
    });
    
    // Register other services...
    
    // Build the provider
    var serviceProvider = services.BuildServiceProvider();
    
  2. Use the Normalizer:

    // Get the normalizer instance from DI
    var normalizer = serviceProvider.GetRequiredService<ITextNormalizer>();
    
    // Example inputs
    string input1 = "  OMG!!! That stream was πŸ”₯πŸ”₯πŸ”₯!! Costs $10... BRB. 1st place!! ";
    string input2 = "He said β€œhello” β€Ήyouβ€Ί sooo many times... 1.2.3 check";
    
    // Normalize
    string normalized1 = normalizer.Normalize(input1);
    string normalized2 = normalizer.Normalize(input2);
    
    // Output (approximate, based on current rules)
    Console.WriteLine(normalized1);
    // Output: oh my god! That stream was fire fire fire! Costs ten dollars. be right back. first place!
    
    Console.WriteLine(normalized2);
    // Output: He said "hello" 'you' soo many times. one point two point three check
    
    // Pass the normalized text to your TTS engine
    // MyTTSEngine.Speak(normalized1);
    // MyTTSEngine.Speak(normalized2);
    

Building

Ensure you have the .NET 9 SDK (Preview) installed.

  1. Clone the repository:
    git clone https://github.com/Agash/TTSTextNormalization.git
    cd TTSTextNormalization
    
  2. Build the solution:
    dotnet build -c Release
    

Contributing

Contributions are welcome! Please open an issue first to discuss potential changes or bug fixes. If submitting a pull request, ensure tests pass and new features include corresponding tests.

License

This project is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
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
0.2.1 164 4/18/2025
0.1.1 164 4/18/2025
0.1.0 191 4/17/2025
0.0.0-alpha.0.2 155 4/17/2025