Моя цель заключается в следующем: позволить пользователям моей программы .NET выбирать свои собственные файлы .wav для звуковых эффектов. Эти эффекты могут быть воспроизведены одновременно. NAudio показался мне лучшим выбором.
Я решил использовать WaveMixerStream32. Одна из первых проблем заключалась в том, что у моих пользователей были файлы .wav разных форматов, поэтому, чтобы иметь возможность смешивать их вместе с WaveMixerStream32, мне нужно было «нормализовать» их в общем формате. Мне не удалось найти хороший пример для подражания, поэтому я подозреваю, что моя проблема - результат неправильного выполнения этой части.
Моя проблема в том, что когда воспроизводятся некоторые звуки, на их конце появляются очень заметные звуки "щелчка". Я могу воспроизвести это сам.
Кроме того, мои пользователи жаловались на то, что иногда звуки вообще не воспроизводятся или являются "скрипучими" на всем протяжении. Я не смог воспроизвести это в процессе разработки, но я слышал это для себя в нашей производственной среде.
Я сам воспроизводил wav-файлы пользователя с помощью Windows Media и VLC, поэтому я знаю, что файлы не повреждены. Должно быть проблема в том, как я их использую с 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, я обнаружил, что качество звука было ужасным, с слышимыми «тиками», возникающими несколько раз в секунду.
Чтобы инициализировать звуковой файл, я сделал это:
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, мой код устанавливает его «Положение» в 0. Этот код, который делает это, направляется в поток пользовательского интерфейса.
Это почти прекрасно работает. Я могу играть несколько звуков одновременно. К сожалению, качество звука плохое, как описано выше. Может кто-нибудь помочь мне понять, почему?