使用 NAudio 重新采样原始音频

Posted

技术标签:

【中文标题】使用 NAudio 重新采样原始音频【英文标题】:Resampling raw audio with NAudio 【发布时间】:2013-04-14 23:25:24 【问题描述】:

我想重新采样音频:将其采样率从 44k 更改为 11k。我得到的输入是以字节为单位的原始音频。它确实是原始的,它没有标题 - 如果我尝试将其加载到 WaveFileReader 中,我会收到一个异常消息“不是 WAVE 文件 - 没有 RIFF 标题”。

我目前正在尝试实现它的方式是这样的(只是一段非常简化的代码):

WaveFormat ResampleInputFormat = new WaveFormat(44100, 1);
WaveFormat ResampleOutputFormat = new WaveFormat(11025, 1);

MemoryStream ResampleInputMemoryStream = new MemoryStream();

foreach (var b in InputListOfBytes)

    ResampleInputMemoryStream.Write(new byte[]b, 0, 1);


RawSourceWaveStream ResampleInputWaveStream =
  new RawSourceWaveStream(ResampleInputMemoryStream, ResampleInputFormat);
WaveFormatConversionStream ResampleOutputStream =
  new WaveFormatConversionStream(ResampleOutputFormat, ResampleInputWaveStream);

byte[] bytes = new byte[2];
while (ResampleOutputStream.Read(bytes, 0, 2) > 0)

    OutputListOfBytes.Add(bytes[0]);
    OutputListOfBytes.Add(bytes[1]);

我的问题是:最后一个循环是一个无限循环。 Read() 始终获得相同的值,并且永远不会在 Stream 中前进。我什至在每个Read() 之后尝试Seek()-ing 到正确的位置,但这似乎也不起作用,我仍然总是得到相同的值。

我做错了什么?这甚至是重新采样原始音频的正确方法吗?提前致谢!

【问题讨论】:

【参考方案1】:

首先,您需要将 ResampleInputMemoryStream 的位置重置为开始。实际上,基于数组创建内存流可能更容易:

new MemoryStream(InputListOfBytes)

其次,在读取重采样器时,您需要一次读取大于两个字节的块。尝试至少一秒钟的音频(使用ResampleOutputStream.WaveFormat.AverageBytesPerSecond)。

【讨论】:

1) 好吧,我可能把我的代码简化了一点,因为我去掉了一些我认为不必要的细节——事实上,我最初拥有的是一个 List,所以不幸的是,我无法制作它的流。 2) NAudio.Wave.WaveFormatConversionStream 没有AverageBytesPerSecond 属性。有没有其他方法可以获得这个价值?感谢您的回答! 抱歉,它是您输出流上 WaveFormat 属性的一个属性。我会修改我的答案 谢谢,它正在工作。现在我遇到了另一个问题,但我会将这个问题标记为已回答,因为这是另一个问题。

以上是关于使用 NAudio 重新采样原始音频的主要内容,如果未能解决你的问题,请参考以下文章

[C#] 使用 NAudio 实现音频可视化

即时将原始音频字节从 NAudio 转换为 wav 字节

NAudio 流采样 8 位数据

在 NAudio 中添加 WAV 标头

音频重采样实现原理

NAudio:在保持声卡打开的同时播放许多音频文件