15

我正在执行一些文本到语音转换,我想在词典文件中指定一些特殊的发音。我已经逐字运行了MSDN 的 AddLexicon 示例,它说出了这个句子,但它没有使用给定的词典,似乎有些东西被破坏了。

这是提供的示例:

using System;
using Microsoft.Speech.Synthesis;

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

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

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

        PromptBuilder builder = new PromptBuilder();
        builder.AppendText("Gimme the whatchamacallit.");

        // Append the lexicon file.
        synth.AddLexicon(new Uri("c:\\test\\whatchamacallit.pls"), "application/pls+xml");

        // Speak the prompt and play back the output file.
        synth.Speak(builder);
      }

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

和词典文件:

<lexicon version="1.0" 
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.w3.org/2005/01/pronunciation-lexicon 
        http://www.w3.org/TR/2007/CR-pronunciation-lexicon-20071212/pls.xsd"
      alphabet="x-microsoft-ups" xml:lang="en-US">


  <lexeme>
    <grapheme> whatchamacallit </grapheme>
    <phoneme> W S1 AX T CH AX M AX K S2 AA L IH T </phoneme>
  </lexeme>

</lexicon>

控制台打开,说出文本,但不使用新的发音。我当然已经将文件保存到c:\test\whatchamacallit.pls指定的位置。

我尝试了 Uri 和文件位置(例如@"C:\Temp\whatchamacallit.pls", @"file:///c:\test\whatchamacallit.pls")、绝对路径和相对路径、将其复制到构建文件夹等的变体。

我运行了Process Monitor并且没有访问该文件。如果是目录/文件权限问题(不是),我仍然会看到拒绝访问消息,但是除了偶尔来自我的文本编辑器的参考之外,我根本没有记录任何参考。我在尝试时确实看到了访问的文件File.OpenRead

不幸的是,使用垃圾 Uri 时没有错误消息。

经过进一步调查,我意识到这个例子来自Microsoft.Speech.Synthesis,而我在这里使用System.Speech.Synthesis。但是据我所知,除了一些额外的信息和示例之外,它们是相同的,并且都指向相同的规范。这仍然是问题吗?

我确认该项目已设置为使用正确的 .NET Framework 4。

我将 MSDN 中的示例与引用规范中的示例进行了比较,并直接尝试了这些示例,但没有帮助。考虑到该文件似乎没有被访问,我并不感到惊讶。

(我可以PromptBuilder.AppendTextWithPronunciation很好地使用,但对于我的用例来说这是一个糟糕的选择。)

MSDN上的例子坏了吗?如何在 SpeechSynthesizer 中使用词典?

4

3 回答 3

10

经过大量的研究和陷阱,我可以向你保证,你的假设是完全错误的。出于某种原因System.Speech.Synthesis.SpeechSynthesizer.AddLexicon(),将词典添加到内部列表中,但根本不使用它。似乎以前没有人尝试过使用它并且这个错误没有被注意到。

Microsoft.Speech.Synthesis.SpeechSynthesizer.AddLexicon()另一方面(属于 Microsoft Speech SDK)按预期工作(它将词典传递给 COM 对象,COM 对象将其解释为广告)。

有关如何安装 SDK,请参阅本指南:http: //msdn.microsoft.com/en-us/library/hh362873%28v=office.14%29.aspx

笔记:

  • 人们报告了 64 位版本导致 COM 异常(因为库没有正确安装),我在 64 位 Windows 7 机器上确认了这一点
    • 使用x86版本规避问题
  • 务必在 SDK 之前安装运行时
  • 确保还安装运行时语言(如链接页面上的建议),因为 SDK 不使用默认系统语音引擎
于 2012-11-22T00:21:28.020 回答
2

您可以使用System.Speech.Synthesis.SpeechSynthesizer.SpeakSsml()而不是词典。

此代码将“blue”的发音改为“yellow”,将“dog”的发音改为“fish”。

SpeechSynthesizer synth = new SpeechSynthesizer();
string text = "This is a blue dog";
Dictionary<string, string> phonemeDictionary = new Dictionary<string, string> { { "blue", "jelow" }, { "dog", "fyʃ" } };
foreach (var element in phonemeDictionary)
{
   text = text.Replace(element.Key, "<phoneme ph=\"" + element.Value + "\">" + element.Key + "</phoneme>");
}
text = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\">" + text + "</speak>";
synth.SpeakSsml(text);

于 2019-11-25T15:58:47.347 回答
1

我最近在 Windows 10 上一直在研究这个问题。

我发现了两件事System.Speech.Synthesis

您使用的任何语音都必须与 Lexicon 文件中的语言相匹配。在词典中,您有以下语言:

<lexicon version="1.0"
      xmlns="http://www.w3.org/2005/01/pronunciation-lexicon"
      alphabet="x-microsoft-ups" xml:lang="en-US">

我发现我可以将我的词典命名为“blue.en-US.pls”并使用“blue.en-GB.pls”进行复制。里面会有 xml:lang="en-GB"

在您将使用的代码中:

string langFile = Path.Combine(_appPath, $"blue.{synth.Voice.Culture.IetfLanguageTag}.pls");
synth.AddLexicon(new Uri(langFile), "application/pls+xml");

我发现的另一件事是,它根本不适用于“Microsoft Zira Desktop - 英语(美国)”。我不知道为什么。这似乎是 Windows 10 上的默认语音。

在此处访问和更改您的默认语音:%windir%\system32\speech\SpeechUX\SAPI.cpl

否则你应该可以通过代码设置它:

var voices = synth.GetInstalledVoices();
// US: David, Zira. UK: Hazel.
var voice = voices.First(v => v.VoiceInfo.Name.Contains("David"));
synth.SelectVoice(voice.VoiceInfo.Name);

我有 David(美国)和 Hazel(英国),它们中的任何一个都可以正常工作。这似乎与注册表中的语音令牌是否具有SpLexicon键值直接相关。Microsoft Zira Desktop 语音没有此注册表值。虽然 Microsoft David Desktop 语音具有以下特性: Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_EN-US_DAVID_11.0\Attributes\SpLexicon={0655E396-25D0-11D3-9C26-00C04F8EF87C}

于 2019-03-25T04:50:48.840 回答