如何从原始字节重建 PCM 样本?

Posted

技术标签:

【中文标题】如何从原始字节重建 PCM 样本?【英文标题】:How to reconstruct PCM samples from raw bytes? 【发布时间】:2021-10-18 16:24:07 【问题描述】:

我正在使用 react-native-audio-record 包录制音频。我想使用临时数据来可视化东西。如example (function AudioRecord.on) 这里:

const options = 
  sampleRate: 16000,
  channels: 1,
  bitsPerSample: 16,
  wavFile: 'test.wav'
;

AudioRecord.init(options);

AudioRecord.on('data', data => 
  const chunk = Buffer.from(data, 'base64');
  console.log('chunk size', chunk.byteLength);
  // do something with audio chunk
); 

如何将变量块解码为 PCM?据另一个论坛所述,此块不包括 .wav 文件的 headerBytes。

【问题讨论】:

这可以分为多个步骤,你问如何将base64转换为字节数组***.com/questions/21797299/…,然后如何将数组缓冲区转换为音频缓冲区***.com/questions/50512436/… 感谢您的回复:我刚刚编辑了问题。我相信,我已经通过 Buffer.from(data,"base64") 获得了数组缓冲区。当我使用 react-native 时,我不能使用 BaseAudioContext。有解决办法吗? 您的选择是包装原生音频 API(乏味)或在纯 javascript 中执行此操作(也很乏味)。这些问题仍然有多个部分。第一个是改变字节为PCM,第二个是how to DFT / FFT in JavaScript fft 部分应该很清楚 - 再次编辑问题。我不知道怎么去 PCM。 那么你的问题是:如何从原始字节重构 PCM 样本? 【参考方案1】:

如 cmets 中所述,用纯 JavaScript 重构 PCM 很繁琐。因此,我使用了节点包 node-wav (仅在包含标头时才有效)如下:

存储特定 wav 选项的标题:

const header = Buffer.from([82, 73, 70, 70, 248, 167, ... ])

并按如下方式连接数据:

import wav from 'node-wav';
    
    AudioRecord.on('data', data => 
          const chunks = [header] 
          const chunk = Buffer.from(data, 'base64');
          chunks.push(chunk)
          const pcm = wav.decode(Buffer.concat(chunks)).channelData
        );

此方法仅在您可以重建标头时才有效。另一方面,包 node-wave 表示为 high performance WAV decoder and encoder 。

【讨论】:

以上是关于如何从原始字节重建 PCM 样本?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 PCM 音频样本流转换为音量?

如何使用 fread 和 fwrite 从文件中读取 pcm 样本?

从线性 PCM 中提取音频通道

如何使用 C++ 从 PCM 样本中过滤出超出听力范围的数据?

拼接子图像重建原始图像

如何从原始 16 位、44100 赫兹、立体声 PCM 获得正确的声音(立体声)