如何根据声波值创建.PCM文件?

时间:2018-05-22 22:22:45

标签: arduino wav pcm

可能我有点失落,所以我想揭露我的问题,我真的很感激能帮助我的人。

我正在开发一个在Arduino中使用麦克风的项目,我能够获得声音的波动,并且它能够响应我的声音或任何其他声音。 麦克风是一个名为LM393的通用麦克风(我无法找到指定此设备采样率的任何数据表),原理图就是这样(唯一不同的是我将OUT连接到模拟A0): enter image description here

enter image description here

这个简单的代码是我在Arduino中使用的代码:

#include <SoftwareSerial.h>

SoftwareSerial connection(10,11);
int microphonePin = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(microphonePin, INPUT);
  connection.begin(9600);
  Serial.begin(115200); 
}

void loop() {
  // put your main code here, to run repeatedly: 
  int response = analogRead(microphonePin);  
  Serial.println(response);
  connection.print(String(response) + " ");
  delay(1);  
}

一些评论: 模拟A0响应0到1023之间的值(每个样本的位数是10?)

正如您所看到的,我通过蓝牙(通过使用HC-05模块)发送从麦克风获得的每个值,并且我在.NET Winforms应用程序上接收这些值。

这些值在我的.NET端看起来像这样:

168 4 0 271 0 297 0 9 611 0 124 0 0 331 0 637 0 231 0 2 53 0 139 0 611 38 63 23 38 1 20 68 0 3 1 375 4 04 374 574 69 

我搜索了所有的网络,试图查找和示例如何呈现数据,我无法弄明白。考虑到每个样本的是10(0..1023),我应该将这些int转换为二进制吗?

我的主要目标是记录我的声音。 所以我的问题是,如何将这些int转换为PCM文件或更好的.wav文件

1 个答案:

答案 0 :(得分:1)

音频只是一条曲线,但上图不是音频曲线...静音只是一条平线,更大的音量自然会让你的高度增加摆动......为了准确捕捉音频你必须采样音频信号至少是您希望捕获的最高频率的两倍...例如,为了捕获1kHz信号,您的采样率必须至少为2kHz ...典型的CD质量音频使用的采样率为44,100 Hz,允许捕获输入音频信号高达22,050赫兹给予或接受......你没有提及采样率 - 更新你的问题告诉我们你在使用什么

三个因素决定了捕获音频所需的存储空间

  • SAMPLE_RATE
  • bit_depth
  • number_of_channels

例如,让我们使用位为10位的单声道(1声道)(写入输出文件为16位的两个字节)和44.1 kHz的采样率......然后一秒钟的捕获音频给我们1 * 2 * 44100字节的数据...如果您知道捕获数据的文件大小而不知道说采样率,您可以使用上述关系计算它

...也许你正在绘制必须首先以某种方式转换的数据...或者你可能以比输入音频信号的频率更慢的采样率捕获音频强度值

假设您显示的数据点是您的10位音频样本,其中一个字节是8位,因此10位信号每个数据点必须存储两个字节...例如

637 shown above taken from a 10 bit signal which can vary from 0 to 1024

我的建议是生成一个比特深度为16位的PCM输出文件,在这个PCM文件中将每个输入10位数据点扩展到两个字节...所以下一步是转换每个10位整数一对两个字节...注意字节序的概念(小端或大端)...正常的PCM或WAV使用小端...这种转换需要执行一个移位操作......在高水平输出的第一个字节只是10位整数的低8位...然后在该10位整数上向右移位,然后成为写入PCM文件的输出的第二个字节

这是一个10位数字(以二进制显示)

0101011100   all 10 bits shown 
01  01011100 same data separated into two byte

most significant byte  01   least significant byte  01011100

将该数字存储在两个字节中,然后通过消耗最低有效8位来填充第一个字节,如

01011100   

然后将相同的原始数字0101011100右移8个位置(8位),这将成为

01

并将其存储到第二个字节......上面是概念上你需要做的事情然而在代码中用c语言说它可以在几行代码中完成

Audacity可以渲染PCM音频,文件后缀没有任何影响可以是任何东西.PCM ...文件 - &gt;导入 - &gt;原始数据...用于编码的值取决于您对音频曲线的处理方式...通常静音为0,然后曲线从正值到负值摆动...如果您的数据从0到1024变化是未签名的你可能想要标准化它所以它从-1到+1变化所以它被认为是签名...各种这样的格式将起作用

您有两个挑战:(1)验证您的音频捕获和(2)使用原始音频正确剪切二进制文件...我强烈建议您编写循环以将sin曲线写入PCM文件以修复在进行捕获验证之前的那个过程

更新这里有一些文档http://www.mpja.com/download/31072mp.pdf

和规格表http://www.ti.com/lit/ds/symlink/lm393-n.pdfhttps://forum.arduino.cc/index.php?topic=292533.0

中所述

看起来你正在使用数字输出这是一个声音指示器(比较器),根据麦克风音量是否超过电位器控制的阈值,它可以提供高1024或低0 ...电路板可能有一个模拟输出应该给你音频曲线,但是你必须把它送入ADC(模拟数字转换器)以馈送整数流

让我们知道你是如何继续...这是非常可行的