私の目的はこれです: 私の .NET プログラムのユーザーが効果音用に独自の .wav ファイルを選択できるようにすることです。これらの効果は同時に再生される場合があります。NAudio は私の最善の策のように思えました。
WaveMixerStream32 を使用することにしました。初期の課題の 1 つは、ユーザーがさまざまな形式の .wav ファイルを持っていたため、それらを WaveMixerStream32 と一緒にミックスできるようにするために、それらを共通の形式に「正規化」する必要があったことでした。従うべき良い例を見つけることができなかったので、私の問題は、この部分を間違って実行した結果であると思われます。
私の問題は、一部のサウンドが再生されると、最後に非常に目立つ「クリック」音が発生することです。私はこれを自分で再現できます。
また、私のユーザーは、サウンドがまったく再生されない、または最後まで「スクラッチ」することがあると不満を漏らしています。開発ではこれを再現できませんでしたが、実稼働環境ではこれを自分で聞いたことがあります。
Windows Media と VLC を使用してユーザーの wav ファイルを自分で再生したので、ファイルが破損していないことはわかっています。NAudioでそれらをどのように使用しているかに問題があるに違いありません。
私の NAudio のバージョンは v1.4.0.0 です。
これが私が使用したコードです。ミキサーをセットアップするには:
_mixer = new WaveMixerStream32 { AutoStop = false, };
_waveOutDevice = new WaveOut(WaveCallbackInfo.NewWindow())
{
DeviceNumber = -1,
DesiredLatency = 300,
NumberOfBuffers = 3,
};
_waveOutDevice.Init(_mixer);
_waveOutDevice.Play();
驚いたことに、ここで "NumberOfBuffers" を 2 に設定すると、1 秒に数回 "カチカチ" という音が聞こえ、音質がひどいことがわかりました。
サウンド ファイルを初期化するには、次のようにしました。
var sample = new AudioSample(fileName);
sample.Position = sample.Length; // To prevent the sample from playing right away
_mixer.AddInputStream(sample);
AudioSample は私のクラスです。そのコンストラクターは、wav ファイル形式の「正規化」を担当します。次のようになります。
private class AudioSample : WaveStream
{
private readonly WaveChannel32 _channelStream;
public AudioSample(string fileName)
{
MemoryStream memStream;
using (var fileStream = File.OpenRead(fileName))
{
memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
}
WaveStream originalStream = new WaveFileReader(memStream);
var pcmStream = WaveFormatConversionStream.CreatePcmStream(originalStream);
var blockAlignReductionStream = new BlockAlignReductionStream(pcmStream);
var waveFormatConversionStream = new WaveFormatConversionStream(
new WaveFormat(44100, blockAlignReductionStream.WaveFormat.BitsPerSample, 2), blockAlignReductionStream);
var waveOffsetStream = new WaveOffsetStream(waveFormatConversionStream);
_channelStream = new WaveChannel32(waveOffsetStream);
}
基本的に、AudioSample はその _channelStream オブジェクトに委譲します。AudioSample を再生するには、コードで「Position」を 0 に設定します。これを行うこのコードは、UI スレッドにマーシャリングされます。
これはほとんどうまくいきます。複数の音を同時に鳴らすことができます。残念ながら音質は上記の通り悪いです。誰でも理由を理解するのを手伝ってもらえますか?