如何从声波值创建 .PCM 文件?
How to create a .PCM file from sound wave values?
可能我有点迷茫,所以我想揭露我的问题,我真的很感谢任何能帮助我的人。
我正在做一个在 Arduino 中使用麦克风的项目,我能够得到声音的波浪,它对我的声音或任何其他声音的响应都很好。
麦克风是一个名为 LM393 的通用麦克风(我找不到任何指定该设备采样率频率的数据表),原理图看起来是这样的(唯一的区别是我将 OUT 连接到模拟 A0):
这个简单的代码就是我在 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),我是否应该将这些整数转换为二进制?
我在这里的主要目的是记录我的声音。
所以我的问题是,如何将这些整数转换为 PCM 文件或更好的 .wav 文件?
音频只是一条曲线,但上面的图不是音频曲线...静音只是一条平线,音量越大自然会让您随着高度的增加而摇摆...为了准确捕捉音频,您必须对音频信号至少是您希望捕获的最高频率速率的两倍……例如,要捕获 1kHz 信号,您的采样率必须至少为 2kHz……典型的 CD 质量音频使用 44,100 Hz 的采样率,这允许捕获高达 22,050 Hz 的输入音频信号的输入或接收...您没有提及采样率 - 更新您的问题,告诉我们您正在使用什么
三个因素决定了捕获音频所需的存储空间
- 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 输出文件,您将每个输入的 10 位数据点分布在该 PCM 文件中的两个字节中...所以下一步是转换每个 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 ...文件 -> 导入 -> 原始数据 ...您用于编码的值取决于您如何处理音频曲线...通常静音是值 0 然后随着曲线摆动它从正值到负值...如果您的数据从 0 到 1024 变化,这是无符号的,您可能想要对其进行归一化,因此它从 -1 到 + 变化1 所以它被认为是签名的......各种这样的格式都可以工作
您有两个挑战:(1) 验证您的音频捕获和 (2) 使用原始音频正确剪切二进制文件...我强烈建议您编写一个循环以将 sin 曲线写入 PCM 文件在进行捕获验证战斗之前确定该过程
更新 这是一些文档 http://www.mpja.com/download/31072mp.pdf
和规格 sheet http://www.ti.com/lit/ds/symlink/lm393-n.pdf
如https://forum.arduino.cc/index.php?topic=292533.0
所述
看起来你正在使用数字输出,它是一个声音指示器(比较器),根据麦克风音量是否超过电位器控制的阈值,它会给出高 1024 或低 0 ......板可能有一个模拟应该为您提供音频曲线的输出,但是您必须将其输入 ADC(模拟数字转换器)以输入整数流
让我们知道您的进展情况...这是非常可行的
可能我有点迷茫,所以我想揭露我的问题,我真的很感谢任何能帮助我的人。
我正在做一个在 Arduino 中使用麦克风的项目,我能够得到声音的波浪,它对我的声音或任何其他声音的响应都很好。
麦克风是一个名为 LM393 的通用麦克风(我找不到任何指定该设备采样率频率的数据表),原理图看起来是这样的(唯一的区别是我将 OUT 连接到模拟 A0):
这个简单的代码就是我在 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),我是否应该将这些整数转换为二进制?
我在这里的主要目的是记录我的声音。 所以我的问题是,如何将这些整数转换为 PCM 文件或更好的 .wav 文件?
音频只是一条曲线,但上面的图不是音频曲线...静音只是一条平线,音量越大自然会让您随着高度的增加而摇摆...为了准确捕捉音频,您必须对音频信号至少是您希望捕获的最高频率速率的两倍……例如,要捕获 1kHz 信号,您的采样率必须至少为 2kHz……典型的 CD 质量音频使用 44,100 Hz 的采样率,这允许捕获高达 22,050 Hz 的输入音频信号的输入或接收...您没有提及采样率 - 更新您的问题,告诉我们您正在使用什么
三个因素决定了捕获音频所需的存储空间
- 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 输出文件,您将每个输入的 10 位数据点分布在该 PCM 文件中的两个字节中...所以下一步是转换每个 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 ...文件 -> 导入 -> 原始数据 ...您用于编码的值取决于您如何处理音频曲线...通常静音是值 0 然后随着曲线摆动它从正值到负值...如果您的数据从 0 到 1024 变化,这是无符号的,您可能想要对其进行归一化,因此它从 -1 到 + 变化1 所以它被认为是签名的......各种这样的格式都可以工作
您有两个挑战:(1) 验证您的音频捕获和 (2) 使用原始音频正确剪切二进制文件...我强烈建议您编写一个循环以将 sin 曲线写入 PCM 文件在进行捕获验证战斗之前确定该过程
更新 这是一些文档 http://www.mpja.com/download/31072mp.pdf
和规格 sheet http://www.ti.com/lit/ds/symlink/lm393-n.pdf 如https://forum.arduino.cc/index.php?topic=292533.0
所述看起来你正在使用数字输出,它是一个声音指示器(比较器),根据麦克风音量是否超过电位器控制的阈值,它会给出高 1024 或低 0 ......板可能有一个模拟应该为您提供音频曲线的输出,但是您必须将其输入 ADC(模拟数字转换器)以输入整数流
让我们知道您的进展情况...这是非常可行的