如何解释 MP3 文件中的原始 pcm 数据

Posted

技术标签:

【中文标题】如何解释 MP3 文件中的原始 pcm 数据【英文标题】:How to interpret raw pcm data from an MP3 file 【发布时间】:2015-03-11 21:42:06 【问题描述】:

我正在使用 NAudio 从 MP3 文件中检索原始 pcm 数据。然后我需要以设定的时间间隔(基于时间)读取这些数据。

但是,我很难理解如何解释这些数据。例如,如果 MP3 是立体声 vs 单声道 vs 其他任何东西,我应该如何读取数据?我如何检查 MP3 是立体声还是单声道?还有哪些其他因素会改变我需要读取数据的方式?

我希望这里有示例代码,但感谢任何帮助。

NAudio.Wave.WaveStream pcm = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(mp3FilePath));
int someInterval = 88200;//~1 second depending on the file specs
byte[] buffer = new byte[someInterval];
int current = 0;
int ret = 0;
do

     ret = pcm.Read(buffer, current, someInterval);

     //do something

     current += someInterval;
 while (ret != -1);

上一个问题的上下文:(How to relate audio data to time)

If you have a raw audio file (no headers or anything) with a single channel (mono, not stereo) sampled at 44.1kHz 16 bit, then you would read 88,200 bytes per second of data [to read 1 second of audio data].

如何检测频道?那么如何读取pcm数据来匹配呢?

【问题讨论】:

NAudio 的 .net api 是否有任何支持文档? 我找不到与此相关的东西。似乎 NAudio 更专注于播放。我会继续寻找。 (请注意,如果我确实看到了一些有用的东西,我可能不会知道。当谈到音频时,我真的不知道我在说什么。) 【参考方案1】:

您可以从pcm.WaveFormat 获取格式,从中可以找到通道数、通道数、每秒平均字节数等...

NAudio.Wave.WaveStream pcm = NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(mp3FilePath));
int someInterval = pcm.WaveFormat.Channels * pcm.WaveFormat.SampleRate * pcm.WaveFormat.BitsPerSample/8;

从那里您需要将字节解码为整数或浮点数。 SO解决这个问题有很多答案。

【讨论】:

太棒了。那么“someInterval”在这里仍然是一个时间单位吗?如果是这样,它是什么(每毫秒,每秒等)?如果没有,那么我如何确定如何准确读取 1 秒的数据(或任意间隔)? 是的,这是 1 秒的字节数。样本/秒 * 字节/样本 = 字节/秒。将粗通道数乘以标量。您可以将最终答案乘以秒作为双精度并截断。所以一半的结果除以 2。

以上是关于如何解释 MP3 文件中的原始 pcm 数据的主要内容,如果未能解决你的问题,请参考以下文章

LAME -- 解码和编码音频文件

使用 Android SDK 从原始 PCM 数据创建 WAV 文件

从 MP3 中提取原始音频/波形

使用 GStreamer 播放保存在数组中的原始 PCM

Android 音频采集——MediaRecord(编码后录影文件) AudioRecord(PCM原始数据)

如何在 Android 设备上将 WAV 编码为 mp3