输出到文件和流时,Microsoft SpeechSynthesizer Crackles Crackles



我正在编写一种使用SpeechSynthesizer根据请求生成波浪文件的东西,但是我在cracking噪声方面遇到问题。很奇怪的是,直接输出到声卡就可以了。

这个简短的PowerShell脚本演示了这个问题,尽管我正在用C#写下我的程序。

Add-Type -AssemblyName System.Speech
$speech = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speech.Speak('Guybrush Threepwood, mighty pirate!')
$speech.SetOutputToWaveFile("${PSScriptRoot}foo.wav")
$speech.Speak('Guybrush Threepwood, mighty pirate!')

应该做的是输出到扬声器,然后保存与脚本旁边的" foo.wav"的声音。

它的作用是向扬声器输出,然后保存一个crack啪作响的旧唱片播放器,将其声音作为波浪文件。我已经在三台不同的机器上测试过,尽管默认情况下它们选择了不同的声音(所有Microsoft提供了默认的声音),但它们听起来都像是垃圾在Wave File中掉下楼梯。

为什么?

编辑:我正在Windows 10 Pro上测试此信息,其中最新更新添加了Taskbar上的令人讨厌的"人"按钮。

编辑2:以上脚本生成的示例声音的链接。请注意crack啪作响的声音,当脚本直接输出扬声器时,这不在那儿。

编辑3:女性语音更加明显

编辑4:与上面相同的语音,保存到Textaloud 3-没有破裂,没有垂直尖峰。

我很难相信这是一个豪华的问题。这不是在串行磁盘上进行编码的豪华。它是正在使用的API/类。

'msdn.microsoft.com/en-us/library/system.speech.synthesis.speechsynthesizer(v = vs.110).aspx'

根据MSDN,没有选择控制编码,比特率等。

.wav从来都不是总部的东西。因此,我想知道您是否将其通过转换器乘以.mp3或mp4,是否可以纠正您的质量问题。但这也意味着将转换器在用户系统上获取。

其次,由于Win8,默认播放器甚至无法正确播放.WAV或根本没有播放。当然,您仍然可以将.wav的默认播放设置为Windows Media Player或通过VLC调用文件,但它仍然是.WAV文件。但是,这也意味着您必须在每个目标系统上设置媒体播放器分配。

这是Speechsynthesizer API的问题,它只是提供了不良质量,crack缩的音频,如上面的样本所示。解决方案是执行TextAloud的操作,即直接使用Segendlib com对象。

这是通过将com引用添加到" Microsoft语音对象库(5.4)"来完成的。这是我最终得到的代码的片段,它产生的音频剪辑与Textaloud相同:

public new static byte[] GetSound(Order o)
{
    const SpeechVoiceSpeakFlags speechFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
    var synth = new SpVoice();
    var wave = new SpMemoryStream();
    var voices = synth.GetVoices();
    try
    {
        // synth setup
        synth.Volume = Math.Max(1, Math.Min(100, o.Volume ?? 100));
        synth.Rate = Math.Max(-10, Math.Min(10, o.Rate ?? 0));
        foreach (SpObjectToken voice in voices)
        {
            if (voice.GetAttribute("Name") == o.Voice.Name)
            {
                synth.Voice = voice;
            }
        }
        wave.Format.Type = SpeechAudioFormatType.SAFT22kHz16BitMono;
        synth.AudioOutputStream = wave;
        synth.Speak(o.Text, speechFlags);
        synth.WaitUntilDone(Timeout.Infinite);
        var waveFormat = new WaveFormat(22050, 16, 1);
        using (var ms = new MemoryStream((byte[])wave.GetData()))
        using (var reader = new RawSourceWaveStream(ms, waveFormat))
        using (var outStream = new MemoryStream())
        using (var writer = new WaveFileWriter(outStream, waveFormat))
        {
            reader.CopyTo(writer);
            return o.Mp3 ? ConvertToMp3(outStream) : outStream.GetBuffer();
        }
    }
    finally
    {
        Marshal.ReleaseComObject(voices);
        Marshal.ReleaseComObject(wave);
        Marshal.ReleaseComObject(synth);
    }
}

这是将波浪文件转换为mp3的代码。它使用nuget的naudio.lame。

internal static byte[] ConvertToMp3(Stream wave)
{
    wave.Position = 0;
    using (var mp3 = new MemoryStream())
    using (var reader = new WaveFileReader(wave))
    using (var writer = new LameMP3FileWriter(mp3, reader.WaveFormat, 128))
    {
        reader.CopyTo(writer);
        mp3.Position = 0;
        return mp3.ToArray();
    }
}

相关内容

  • 没有找到相关文章

最新更新