質問

使ってます System.speech.synthesis.speechsynthesizer テキストをスピーチに変換します。そして、Microsoftの貧血文書のために(私のリンクを参照してください、発言やコードの例はありません)、2つの方法の違いの頭や尾を作るのに苦労しています。

SetOutputToAudioStreamおよびSetOutputTowesteam。

これが私が推測したものです:

SetOutputToAudioStreamは、Waveファイル(1秒あたりのサンプル、1秒あたりのビット、オーディオチャネルなど)の形式を定義し、テキストをストリームに書き込むストリームとSpeechAudioFormatinfoインスタンスを取ります。

SetOutputTowaveStreamは、ストリームだけを取り、16ビット、モノ、22kHz、PCMウェーブファイルをストリームに書き込みます。 SpeechAudioFormatinfoで合格する方法はありません。

私の問題は、SetOutputToAudioStreamがStreamに有効なWaveファイルを書き込まないことです。たとえば、System.media.soundPlayerにストリームを渡すときに、InvalidOperationException(「Wave Headerが破損しています」)が取得されます。ストリームをディスクに書いてWMPで再生しようとすると、「Windowsメディアプレーヤーがファイルを再生できません...」エラーを取得しますが、SettutTowavestreamによって書かれたストリームは両方で適切に再生されます。私の理論では、SetOutputToAudioStreamは(有効な)ヘッダーを書いていないということです。

奇妙なことに、SetOutputto* blah*の命名規則は一貫していません。 SetOutputTowaveFileはSpeechAudiOforMatinfoを取りますが、SetOutputTowavestreamはそうではありません。

8kHz、16ビット、モノウェーブファイルをストリームに書くことができる必要があります。誰かがSpeechSynthesizerとこれら2つの方法についての洞察を持っていますか?

参照のために、ここにいくつかのコードがあります:

Stream ret = new MemoryStream();
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
  synth.SelectVoice(voiceName);
  synth.SetOutputToWaveStream(ret);
  //synth.SetOutputToAudioStream(ret, new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono));
  synth.Speak(textToSpeak);
}

解決:

@Hans Passantに感謝します。これが私が今使用しているものの要点です:

Stream ret = new MemoryStream();
using (SpeechSynthesizer synth = new SpeechSynthesizer())
{
  var mi = synth.GetType().GetMethod("SetOutputStream", BindingFlags.Instance | BindingFlags.NonPublic);
  var fmt = new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Sixteen, AudioChannel.Mono);
  mi.Invoke(synth, new object[] { ret, fmt, true, true });
  synth.SelectVoice(voiceName);
  synth.Speak(textToSpeak);
}
return ret;

大まかなテストではうまく機能しますが、リフレクションを使用することは少し厄介です。ファイルをディスクに書き込み、ストリームを開くよりも優れています。

役に立ちましたか?

解決

あなたのコードスニペットはボルキングされています、あなたは使用しています シンセ 処分された後。しかし、それは私が確信している本当の問題ではありません。 SetOutputToAudioStreamは、RAW PCMオーディオ「番号」を生成します。コンテナファイル形式(ヘッダー)がありません。はい、それは通常のメディアプログラムで再生することはできません。

SpeechUaudioformatinfoを採用するSetOutputTowavestreamの過負荷が不足しているのは奇妙です。 .NETフレームワークでは非常にまれですが、それは本当に私にとって監視のように見えます。それが機能するべきではない理由はありません。基礎となるSAPIインターフェイスはそれをサポートしています。プライベートSettputStreamメソッドを呼び出すために、反射でハッキングできます。これは私がそれをテストしたときに正常に機能しましたが、私はそれを保証することはできません:

using System.Reflection;
...
            using (Stream ret = new MemoryStream())
            using (SpeechSynthesizer synth = new SpeechSynthesizer()) {
                var mi = synth.GetType().GetMethod("SetOutputStream", BindingFlags.Instance | BindingFlags.NonPublic);
                var fmt = new SpeechAudioFormatInfo(8000, AudioBitsPerSample.Eight, AudioChannel.Mono);
                mi.Invoke(synth, new object[] { ret, fmt, true, true });
                synth.Speak("Greetings from stack overflow");
                // Testing code:
                using (var fs = new FileStream(@"c:\temp\test.wav", FileMode.Create, FileAccess.Write, FileShare.None)) {
                    ret.Position = 0;
                    byte[] buffer = new byte[4096];
                    for (;;) {
                        int len = ret.Read(buffer, 0, buffer.Length);
                        if (len == 0) break;
                        fs.Write(buffer, 0, len);
                    }
                }
            }

ハックに不快な場合は、path.getTempfileName()を使用してファイルに一時的にストリーミングすることは確かに機能します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top