.NET SpeechSynthesizer のウェーブ出力を取得して、音声をロボットっぽい音にしようとしています。
いくつかの調査の結果、リングモジュレーションが必要な効果を得るのに適したオプションであることがわかりました。式は基本的に であることがわかりResult(t) = Voice(t) * SineWave(t)
ました。
ただし、Wave Stream からこの効果を適用する方法はわかりませんが、次のようなライブラリはありますか?
- 正弦波を生成し、ウェーブ ストリームに処理します。
- 結果を得るために両方のストリームを乗算します
そうでない場合、他のオプションを知っていますか? Voice Wave Stream の各サンプルを正弦波の各サンプルで乗算できますか?
C#/.net フレームワークを使用しています。
ありがとうございました !
編集:さて、数時間失敗した試みの後、私は最終的に良い結果と思われるものを思いつきました. 唯一の問題は、出力に多くのパチパチ音がすることです。私が見つけた唯一の修正は、ローパス フィルターを適用することです。
私がこれまでに得たものは次のとおりです(クイックで汚いコードでコメントなしですが、自明のはずです):
class Mixer
{
public static Stream RingModulation(Stream voiceStream, TimeSpan duration, SpeechAudioFormatInfo format)
{
var sineWave = SineOscillator.GenerateWave(duration, 80, 1, format);
var numSamples = Convert.ToInt32(duration.TotalSeconds * format.SamplesPerSecond);
var dataStream = new MemoryStream();
sineWave.Position = 0;
voiceStream.Position = 0;
var buf1 = new byte[2];
var buf2 = new byte[2];
for (var i = 0; i < numSamples; i++)
{
voiceStream.Read(buf1, 0, 2);
sineWave.Read(buf2, 0, 2);
var data = BitConverter.GetBytes(Convert.ToInt16(BitConverter.ToInt16(buf1, 0) * BitConverter.ToInt16(buf2, 0)));
dataStream.Write(data, 0, data.Length);
}
return dataStream;
}
}
class SineOscillator
{
public static Stream GenerateWave(TimeSpan duration, double frequency, int amplitude, SpeechAudioFormatInfo format)
{
var numSamples = Convert.ToInt32(duration.TotalSeconds * format.SamplesPerSecond);
var dataStream = new MemoryStream();
var angle = (Math.PI * 2 * frequency) / (format.SamplesPerSecond * format.ChannelCount);
for (var i = 0; i < numSamples; i++)
{
var data = BitConverter.GetBytes(Convert.ToInt16(amplitude * Math.Sin(angle*i)));
// Generate a sine wave in both channels.
dataStream.Write(data, 0, data.Length);
}
return dataStream;
}
}
ローパスフィルターはまだ適用されていませんが、誰かが提供する良い答えやより良い方法を提供する場合に備えて、質問はまだ開いています:)