【发布时间】:2021-12-20 20:30:17
【问题描述】:
我正在研究一种重新采样 wav 文件的方法,方法如下:
internal byte[] ResampleWav(byte[] rawPcmData, int frequency, int bits, int channels, int newFrequency)
{
byte[] pcmData;
using (MemoryStream AudioSample = new MemoryStream(rawPcmData))
{
RawSourceWaveStream Original = new RawSourceWaveStream(AudioSample, new WaveFormat(frequency, bits, channels));
using (MediaFoundationResampler conversionStream = new MediaFoundationResampler(Original, new WaveFormat(newFrequency, bits, channels)))
{
//Here should go the code to get the array of bytes with the resampled PCM data
}
}
return pcmData;
}
这里的问题是 MediaFoundationResampler 中没有任何属性可以返回缓冲区的大小。该方法应返回一个仅包含重新采样的 PCM 数据的字节数组。
提前致谢!
--编辑
经过一段时间的工作,我可以得到这个:
internal byte[] WavChangeFrequency(byte[] rawPcmData, int frequency, int bits, int channels, int newFrequency)
{
byte[] pcmData;
using (MemoryStream AudioSample = new MemoryStream(rawPcmData))
{
RawSourceWaveStream Original = new RawSourceWaveStream(AudioSample, new WaveFormat(frequency, bits, channels));
using (MediaFoundationResampler conversionStream = new MediaFoundationResampler(Original, newFrequency))
{
//Start reading PCM data
using (MemoryStream wavData = new MemoryStream())
{
byte[] readBuffer = new byte[1024];
while ((conversionStream.Read(readBuffer, 0, readBuffer.Length)) != 0)
{
wavData.Write(readBuffer, 0, readBuffer.Length);
}
pcmData = wavData.ToArray();
}
}
}
return pcmData;
}
“似乎”工作正常,但还有另一个问题,似乎 PCM 数据字节数组大于预期。这是我用该方法测试过的测试之一:
输入设置:
44100Hz
16 Bits
01 Channel
1846324 Bytes of PCM data
预期(当我使用 Audition、Audacity 和 WaveFormatConversionStream 重新采样相同的 wav 文件时,我得到了这个):
22050Hz
16 Bits
01 Channel
923162 Bytes
MediaFoundationResampler 结果:
22050Hz
16 Bits
01 Channel
923648 Bytes
如果我改变 readBuffer 数组的大小,大小会发生巨大变化。
主要问题是 MediaFoundationResampler 没有属性 Lenght 来了解重新采样的 PCM 数据缓冲区的实际大小。使用 WaveFormatConversionStream 代码是这样的,但是质量不是很好:
internal byte[] WavChangeFrequency(byte[] rawPcmData, int frequency, int bits, int channels, int newFrequency)
{
byte[] pcmData;
using (MemoryStream AudioSample = new MemoryStream(rawPcmData))
{
RawSourceWaveStream Original = new RawSourceWaveStream(AudioSample, new WaveFormat(frequency, bits, channels));
using (WaveFormatConversionStream wavResampler = new WaveFormatConversionStream(new WaveFormat(newFrequency, bits, channels), Original))
{
pcmData = new byte[wavResampler.Length];
wavResampler.Read(pcmData, 0, pcmData.Length);
}
}
return pcmData;
}
我应该怎么做才能使用 MediaFoundationResampler 获得预期的 PCM 数据数组?
【问题讨论】:
-
您确定不能使用您方法的参数 frequency 和 newFrequency 计算新长度吗?
-
嗯,可能是的,但我不确定该怎么做。公式是什么?
-
如果唯一的变化是采样频率,类似: var NewLength = rawPcmData.Length * (newFrequency / frequency);很可能会有一些长度舍入问题。我不知道这个库,所以这可能是解决您问题的不好方法。
-
已测试,但不起作用,不知道为什么但给出了零。无论如何,谢谢!
-
奇怪,我做了一个快速测试,它似乎工作。今晚有时间我会再试一次。