代码之家  ›  专栏  ›  技术社区  ›  Mauro Bilotti

如何从声波值创建.pcm文件?

  •  1
  • Mauro Bilotti  · 技术社区  · 7 年前

    可能我有点迷路了,所以我想暴露我的问题,我真的很感谢任何能帮助我的人。

    我正在做一个在Arduino使用麦克风的项目,我可以得到声音的波形,它对我的声音或任何其他声音的响应都是正常的。 麦克风是一个名为lm393的通用麦克风(我找不到任何数据表来指定这个设备的采样率频率),原理图是这样的(唯一的区别是我将输出连接到模拟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转换成一个pcm文件,或者更好的.wav文件 ?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Scott Stensland    7 年前

    音频只是一条曲线,但上面的绘图不是音频曲线…沉默只是一条平的线,更大的音量自然会让你随着高度的增加而摇摆…为了准确捕获音频,您必须对音频信号进行采样,采样频率至少为您希望捕获的最高频率的两倍…例如,要捕获1千赫兹的信号,采样率必须至少为2千赫兹…典型的CD音质音频使用的采样率为44100赫兹,允许捕获高达22050赫兹的输入音频信号。你没有提到采样率-更新你的问题告诉我们你在使用什么

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

    • 采样率
    • 钻头深度
    • 频道数

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

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

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

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

    我的建议是生成一个位深为16位的PCM输出文件,在该文件中,您将每个输入10位数据点分布在两个字节之间…所以下一步是把每个10位整数转换成一对2字节…注意词尾的概念(小词尾或大词尾)。正常的pcm或wav使用小endian…此转换将需要执行移位操作…在较高的级别上,输出的第一个字节将只是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…文件->导入->原始数据…用于编码的值取决于如何处理音频曲线…通常,沉默值为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.pdf 如中所述 https://forum.arduino.cc/index.php?topic=292533.0

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

    让我们知道你是怎么上的…这是非常可行的