如何将文本字符串转换为语音声音

52

我正在寻找一种将C#中的英文文本(字符串)转换为语音(声音)的方法。是否有人知道可以帮助我完成这个任务的方法或开源库?


3
为什么选择开源?.Net 的答案如此明显,以至于你确实应该说明为什么不考虑它。 - flup
.NET选项对我来说可以。 - user2110292
6个回答

64
你可以使用 .NET 库 (System.Speech.Synthesis)。
根据 Microsoft 的说法:
“System.Speech.Synthesis 命名空间包含一些类,允许你初始化和配置语音合成引擎、创建提示、生成语音、响应事件和修改声音特性。语音合成通常被称为文本到语音或 TTS。”
语音合成器将文本作为输入并产生一个音频流作为输出。语音合成也被称为文本到语音(TTS)。
合成器必须执行大量的分析和处理工作,才能准确地将一串字符转换成听起来像单词被讲出来的音频流。最简单的想象方式是将这个过程看作是两个部分系统的前端和后端。
文本分析
前端专门使用自然语言规则分析文本。它分析一串字符以确定单词的位置 (在英语中很容易做到,但在诸如中文和日语之类的语言中不太容易)。这个前端还找出了语法细节,如功能和词性。例如,哪些单词是专有名词、数字等;句子从哪里开始和结束;一个短语是一个问题还是一个陈述句;以及陈述句是过去、现在还是将来时。
所有这些元素对于选择单词、短语和句子的适当发音和语调都至关重要。考虑到在英语中,问题通常以上升的音调结束,或者“read”这个单词根据其时态的不同而发音非常不同。显然,理解单词或短语的用法是将文本转换为声音的关键方面之一。为了进一步复杂化事情,每种语言的规则略有不同。因此,如你所想象的那样,前端必须进行一些非常复杂的分析。
声音生成
后端任务完全不同。它接收前端完成的分析,并通过自己的一些非平凡的分析,为输入文本生成适当的声音。老的合成器 (以及具有最小脚印的今天的合成器) 通过算法生成单个音频,导致非常机械化的声音。现代合成器,如 Windows Vista 和 Windows 7 中的合成器,使用由数小时的录音构建的声音片段数据库。后端的效果取决于它在为任何给定的输入选择适当的声音片段并将它们平稳地拼接在一起方面有多好。
准备使用
上述文本到语音功能内置于 Windows Vista 和 Windows 7 操作系统中,允许应用程序轻松使用此技术。这消除了创建自己的语音引擎的需要。你可以通过调用一个函数来调用所有这些处理。请参阅 Speak the Contents of a String。
尝试以下代码:
using System.Speech.Synthesis;

namespace ConsoleApplication5
{
    class Program
    {

        static void Main(string[] args)
        {
            SpeechSynthesizer synthesizer = new SpeechSynthesizer();
            synthesizer.Volume = 100;  // 0...100
            synthesizer.Rate = -2;     // -10...10

            // Synchronous
            synthesizer.Speak("Hello World");

            // Asynchronous
            synthesizer.SpeakAsync("Hello World");



        }

    }
}

1
四分之一个世纪前,我使用了一个程序,它使用数字来表示重音,以表达语音(因此,“What is that?”可以是[IIRC]“WHUH1T IH2IH4IH4ZAE1T。”或“WHUH3T IH1Z DHAE3T。”取决于重音所在的位置)。要获得自然流畅的韵律通常需要进行大量调整,但调整可以提供非常详细的控制水平。如果目标是通过组合各种文本字符串来生成语音,则是否有任何好的方法将数据作为包括重音和韵律标记的语音字符串提交到语音API? - supercat
有趣的 Bug:只有在我重新启动 Visual Studio 后它才会说话。 - Loren Pechtel
1
@supercat,不确定您是否正在寻找SSML支持?语音合成器具有SpeakSsml方法。SSML似乎支持prosody。附注:我不知道所有这些意味着什么。 :) - publicgk
@publicgk:看起来很有前途;似乎可以使用PromptBuilder对象将文本字符串转换为SSML。该页面指出,prosody元素目前不支持“轮廓”,但可能可以连接具有不同prosody元素的元素以实现正确的重音。总的来说,prosody是指节奏和抑扬顿挫的变化,这些变化会导致单词在不同的语境下发音不同。 - supercat
我无法将System.Speech.Synthesis安装到我的VS 2019的.Net Framework 4.7.1中。Install-Package: 无法安装包'System.Speech.dll 1.0.4'。您正在尝试将此软件包安装到针对'.NETFramework,Version=v4.7.1'的项目中,但该软件包不包含与该框架兼容的任何程序集引用或内容文件。 - Jeremy Parker

23

该功能在System.Speech命名空间的主类库中存在。具体来说,请查看System.Speech.Synthesis

请注意,您可能需要添加对 System.Speech.dll 的引用。

SpeechSynthesizer类提供对安装在主机计算机上的语音合成引擎的功能访问。已安装的语音合成引擎由一个语音表示,例如Microsoft Anna。 SpeechSynthesizer实例初始化为默认语音。要配置SpeechSynthesizer实例以使用其他已安装的语音之一,请调用SelectVoice或SelectVoiceByHints方法。要获取有关已安装语音的信息,请使用GetInstalledVoices方法。

与所有MSDN文档一样,都有可供使用的代码示例。以下是来自System.Speech.Synthesis.SpeechSynthesizer类的示例。

using System;
using System.Speech.Synthesis;

namespace SampleSynthesis
{
  class Program
  {
    static void Main(string[] args)
    {

      // Initialize a new instance of the SpeechSynthesizer.
      SpeechSynthesizer synth = new SpeechSynthesizer();

      // Configure the audio output. 
      synth.SetOutputToDefaultAudioDevice();

      // Speak a string.
      synth.Speak("This example demonstrates a basic use of Speech Synthesizer");

      Console.WriteLine();
      Console.WriteLine("Press any key to exit...");
      Console.ReadKey();
    }
  }
}

7
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Speech.Synthesis; // first import this package

    namespace textToSpeech
    {
        public partial class home : Form
        {
            public string s = "pran"; // storing string (pran) to s

            private void home_Load(object sender, EventArgs e)
                {
                    speech(s); // calling the function with a string argument
                }

            private void speech(string args) // defining the function which will accept a string parameter
                {
                    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
                    synthesizer.SelectVoiceByHints(VoiceGender.Male , VoiceAge.Adult); // to change VoiceGender and VoiceAge check out those links below
                    synthesizer.Volume = 100;  // (0 - 100)
                    synthesizer.Rate = 0;     // (-10 - 10)
                    // Synchronous
                    synthesizer.Speak("Now I'm speaking, no other function'll work");
                    // Asynchronous
                    synthesizer.SpeakAsync("Welcome" + args); // here args = pran
                }       
         }
    }
  • 使用"SpeakAsync"会更好,因为当"Speak"函数执行时,除非它完成工作,否则其他任何函数都不起作用(个人推荐)

更改VoiceGender
更改VoiceAge


2
你可以通过 System.Speech.Synthesis 命名空间来实现这一点。为此,您需要首先添加对 System.speech.dll 的引用。
尝试这样做:
using System.Speech.Synthesis;

namespace TextToSpeech
{
   public partial class Form1 : Form
   {
     SpeechSynthesizer speak;
     public Form1()
     {
        InitializeComponent();
        speak = new SpeechSynthesizer();
     }

     private void button1_Click(object sender, EventArgs e)
     {
        string text="Speak this";
        speak.SpeakAsync(text);
     }
  }
}

1

最近,谷歌发布了Google Cloud Text To Speech

可以在此处找到 Google.Cloud.TextToSpeech 的 .NET 客户端版本: https://github.com/jhabjan/Google.Cloud.TextToSpeech.V1

Nuget: Install-Package JH.Google.Cloud.TextToSpeech.V1

以下是如何使用客户端的简短示例:

GoogleCredential credentials =
    GoogleCredential.FromFile(Path.Combine(Program.AppPath, "jhabjan-test-47a56894d458.json"));

TextToSpeechClient client = TextToSpeechClient.Create(credentials);

SynthesizeSpeechResponse response = client.SynthesizeSpeech(
    new SynthesisInput()
    {
        Text = "Google Cloud Text-to-Speech enables developers to synthesize natural-sounding speech with 32 voices"
    },
    new VoiceSelectionParams()
    {
        LanguageCode = "en-US",
        Name = "en-US-Wavenet-C"
    },
    new AudioConfig()
    {
        AudioEncoding = AudioEncoding.Mp3
    }
);

string speechFile = Path.Combine(Directory.GetCurrentDirectory(), "sample.mp3");

File.WriteAllBytes(speechFile, response.AudioContent);

找不到“TextToSpeechClient”的引用。API命名空间已更改为Google.Apis.TextToSpeech.v1。你能帮我解决一下吗? - Faisal Rashid

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接