重用带有 NAudio 的混合通道
Reusing a mixed Channel with NAudio
我当然缺少 NAudio 的基础知识。我正在尝试 播放相同的声音两次 但不能。怎么回事?
var path = @"\Rim Shot 2.wav";
var path2 = @"\Rim Shot 4.wav";
var mStream1 = new MemoryStream(File.ReadAllBytes(path));
var mStream2 = new MemoryStream(File.ReadAllBytes(path2));
var stream1 = (new WaveFileReader(mStream1)).ToStandardWaveStream();
var stream2 = (new WaveFileReader(mStream2)).ToStandardWaveStream();
stream1.WaveFormat.Dump();
stream2.WaveFormat.Dump();
var channel1 = new SampleChannel(stream1);
var channel2 = new SampleChannel(stream2);
var format = stream1.WaveFormat;
format = WaveFormat.CreateIeeeFloatWaveFormat(format.SampleRate, format.Channels);
var mixer = new MixingSampleProvider(format);
mixer.ReadFully = true;
try
{
output.Init(mixer);
output.Play();
mixer.AddMixerInput(channel1);
Task.Delay(10).Wait();
mixer.AddMixerInput(channel2);
Task.Delay(10).Wait();
mixer.AddMixerInput(channel1);
Task.Delay(2000).Wait();
}
catch(Exception ex)
{
ex.Dump();
}
finally
{
if(mStream1 != null) mStream1.Dispose();
if(mStream2 != null) mStream2.Dispose();
if(stream1 != null) stream1.Dispose();
if(stream2 != null) stream2.Dispose();
}
其中 ToStandardWaveStream()
是我的扩展方法:
public static WaveStream ToStandardWaveStream(this WaveStream stream)
{
if(stream == null) throw new ArgumentNullException("The expected Wave Stream is not here.");
var encoding = stream.WaveFormat.Encoding;
var isNotPcmFormat = (encoding != WaveFormatEncoding.Pcm);
var isNotIeeeFloatFormat = (encoding != WaveFormatEncoding.IeeeFloat);
Func<WaveStream> convert = () =>
{
stream = WaveFormatConversionStream.CreatePcmStream(stream);
stream = new BlockAlignReductionStream(stream);
return stream;
};
return (isNotPcmFormat && isNotIeeeFloatFormat) ? convert() : stream;
}
您不能将同一个流作为输入添加到混音器两次。您需要从同一个 WAV 文件中创建第二个全新的流读取以添加。第二个流将在开头。为了提高效率,在鼓机中,我会缓存声音数据(就像你所做的那样),但你仍然需要创建新的 WaveFileReader(或 RawSourceStreams),所以它们从头开始
有关此操作的示例,请查看 WPF Drum machine demo 的 NAudio 源代码。
我当然缺少 NAudio 的基础知识。我正在尝试 播放相同的声音两次 但不能。怎么回事?
var path = @"\Rim Shot 2.wav";
var path2 = @"\Rim Shot 4.wav";
var mStream1 = new MemoryStream(File.ReadAllBytes(path));
var mStream2 = new MemoryStream(File.ReadAllBytes(path2));
var stream1 = (new WaveFileReader(mStream1)).ToStandardWaveStream();
var stream2 = (new WaveFileReader(mStream2)).ToStandardWaveStream();
stream1.WaveFormat.Dump();
stream2.WaveFormat.Dump();
var channel1 = new SampleChannel(stream1);
var channel2 = new SampleChannel(stream2);
var format = stream1.WaveFormat;
format = WaveFormat.CreateIeeeFloatWaveFormat(format.SampleRate, format.Channels);
var mixer = new MixingSampleProvider(format);
mixer.ReadFully = true;
try
{
output.Init(mixer);
output.Play();
mixer.AddMixerInput(channel1);
Task.Delay(10).Wait();
mixer.AddMixerInput(channel2);
Task.Delay(10).Wait();
mixer.AddMixerInput(channel1);
Task.Delay(2000).Wait();
}
catch(Exception ex)
{
ex.Dump();
}
finally
{
if(mStream1 != null) mStream1.Dispose();
if(mStream2 != null) mStream2.Dispose();
if(stream1 != null) stream1.Dispose();
if(stream2 != null) stream2.Dispose();
}
其中 ToStandardWaveStream()
是我的扩展方法:
public static WaveStream ToStandardWaveStream(this WaveStream stream)
{
if(stream == null) throw new ArgumentNullException("The expected Wave Stream is not here.");
var encoding = stream.WaveFormat.Encoding;
var isNotPcmFormat = (encoding != WaveFormatEncoding.Pcm);
var isNotIeeeFloatFormat = (encoding != WaveFormatEncoding.IeeeFloat);
Func<WaveStream> convert = () =>
{
stream = WaveFormatConversionStream.CreatePcmStream(stream);
stream = new BlockAlignReductionStream(stream);
return stream;
};
return (isNotPcmFormat && isNotIeeeFloatFormat) ? convert() : stream;
}
您不能将同一个流作为输入添加到混音器两次。您需要从同一个 WAV 文件中创建第二个全新的流读取以添加。第二个流将在开头。为了提高效率,在鼓机中,我会缓存声音数据(就像你所做的那样),但你仍然需要创建新的 WaveFileReader(或 RawSourceStreams),所以它们从头开始
有关此操作的示例,请查看 WPF Drum machine demo 的 NAudio 源代码。