麦克风或声音会产生不同的电流。我想从原始音频文件中提取此信息。
我使用以下命令从麦克风获取原始数据:
arecord -t raw -f cd
现在我想分析原始数据,以便从0V提取信号到5V。但我不知道如何继续。
我尝试了一下,但绝对没有成功,我认为我离解决方案很远。
#define BUFSIZE 8
uint8_t analogRead() {
uint8_t buf[BUFSIZE];
//cout << "analogRead" << endl;
read(STDIN_FILENO, buf, sizeof(buf));
size_t size = sizeof(buf);
double accum = 0;
int const n_samples = size/2;
for (int i = 0; i < size; i += 2)
{
// put two bytes into one __signed__ integer
uint8_t val = buf[i] + ((uint8_t)buf[i+1] << 8);
accum += val*val;
}
accum /= n_samples;
cout << accum << endl;
return accum;
}
int main(int argc, char** argv) {
while(1) {
cout << analogRead() << endl;
}
return 0;
}
然后我像这样运行我的测试:
arecord -t raw -f cd | ./mytest
答案 0 :(得分:1)
你的类型到处都是。模拟读取被声明为返回uint8_t,但它在实际实现中返回一个double。您似乎误解了read()
函数或sizeof
运算符。第一个参数是正确的,它是文件descritpor。第二个参数是缓冲区,它也是正确的。第三个参数是缓冲区的大小。这不是由sizeof
运算符获得的,而是使用BUFFER_SIZE*sizeof(uint8_t)
。
此外,您的命令行争论说要以cd格式输出音频。 CD格式使用两个轨道来创建立体声效果,我们只对uspeech感兴趣。如果查看arecord
的手册页,它指定:
-f --format=FORMAT
Sample format
Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE
S24_LE S24_BE U24_LE U24_BE S32_LE S32_BE U32_LE U32_BE FLOAT_LE
FLOAT_BE FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE IEC958_SUB-
FRAME_BE MU_LAW A_LAW IMA_ADPCM MPEG GSM
Some of these may not be available on selected hardware
There are also two format shortcuts available:
-f cd (16 bit little endian, 44100, stereo [-f S16_LE -c2 -r44100]
-f dat (16 bit little endian, 48000, stereo) [-f S16_LE -c2 -r48000]
If no format is given U8 is used.
为简单起见,您更喜欢-c1。您可以使用上述任何格式。既然您选择了uint8_t,那么使用U8最简单。然后您可以将模拟读取功能重写为:
uint8_t analogRead() {
uint8_t buf[1]; //This will read 1 byte at a time. Its not efficient but its the closest you will get to analogRead() if you're thinking in arduino terms.
read(STDIN_FILENO, buf, 1);
return buf[0];
}
因此,一旦你修复它,你就可以使用像
这样的程序arecord -t raw -f u8 -c 1 | ./mytest