cpp原始音频到模拟值

时间:2016-09-17 13:34:28

标签: c++ audio

麦克风或声音会产生不同的电流。我想从原始音频文件中提取此信息。

我使用以下命令从麦克风获取原始数据:

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

1 个答案:

答案 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