2

私の目的はこれです: 私の .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 スレッドにマーシャリングされます。

これはほとんどうまくいきます。複数の音を同時に鳴らすことができます。残念ながら音質は上記の通り悪いです。誰でも理由を理解するのを手伝ってもらえますか?

4

1 に答える 1

4

あなたの質問に答えるいくつかのポイント:

  • はい、ミキサーにフィードする前に、すべての入力を同じサンプルレートにする必要があります。これは単にデジタルオーディオがどのように機能するかです。WaveFormatConversionストリームによって提供されるACMサンプルレート変換は優れていません(エイリアシング保護はありません)。入力ファイルの通常のサンプルレートはどれくらいですか?
  • すべての入力を2つのWaveFormatConversionStreamsに渡します。どうしても必要な場合にのみこれを行ってください。
  • NAudioのデフォルトであるNumberOfBuffers=2で音が悪くなっていることに驚いています。バッファがドロップされる可能性があるバグがあったため、一時停止して再開しましたか(最新で修正され、NAudio 1.4ファイナルで修正される予定です)
  • ファイルの最後をクリックすると、サンプルがゼロで終了しないことを意味します。これを排除するには、フェードアウトを追加する必要があります(多くのメディアプレーヤーはこれを自動的に行います)
  • 悪い音の問題をトラブルシューティングするときはいつでも、WaveFileWriterを使用してWaveStreamをWAVファイルに変換することをお勧めします(終わりのないファイルを生成しないように注意してください!)。これにより、別のメディアプレーヤーで聞くことができます。これにより、問題の原因がオーディオ処理なのか、再生自体なのかをすばやく判断できます。
于 2011-06-01T06:45:05.207 に答える