C++ 在C+中使用ALSA捕获默认音频流+;

C++ 在C+中使用ALSA捕获默认音频流+;,c++,audio,alsa,audio-analysis,C++,Audio,Alsa,Audio Analysis,我正在做一个有趣的项目,根据来自默认ALSA设备的声音更改飞利浦色调灯泡的颜色 我想编写一个小型C++程序,捕获并分析默认音频流,并将其分成低、中、高3个变化,然后将这些通道分别设置为红色、绿色和蓝色。 我正试图阅读如何创建ALSA设备,但我正在努力找出和谷歌如何用ALSA捕获流。这是我第一次使用音频和ALSA。我现在尽量避免使用python,因为我想学习更多 如果你认为不值得在C++上写这个,我会用Python来写。p> 这个答案分为两部分。第一部分讨论如何获取音频数据并使用它表示LED亮度设

我正在做一个有趣的项目,根据来自默认ALSA设备的声音更改飞利浦色调灯泡的颜色

我想编写一个小型C++程序,捕获并分析默认音频流,并将其分成低、中、高3个变化,然后将这些通道分别设置为红色、绿色和蓝色。 我正试图阅读如何创建ALSA设备,但我正在努力找出和谷歌如何用ALSA捕获流。这是我第一次使用音频和ALSA。我现在尽量避免使用python,因为我想学习更多


如果你认为不值得在C++上写这个,我会用Python来写。p> 这个答案分为两部分。第一部分讨论如何获取音频数据并使用它表示LED亮度设置中使用的LED“位”。第二部分讨论了如何使用C++从ALSA声卡读取音频数据。 第1部分

一个分裂成RGB的想法,你可以解决如何以“感知方式”将音频样本转换成24位表示。我们听到的是非线性的,你可能想取音频数据的对数。因为音频数据既有正数也有负数,所以您可能希望根据其绝对值执行此操作。最后,对于从ADC音频输入读取的每个缓冲区,您可能首先需要(这将为您处理绝对值)

因此,处理的步骤是:

  • 捕获音频缓冲区
  • 获取音频缓冲区每列的RMS(每列都是一个音频通道)
  • 取每列RMS值的对数

  • 了解如何将每个通道的日志(RMS)值映射到LED上。一个想法是使用音频数据RMS的log base 2(log2),因为这将为您提供32位数据,您可以将其分解(旋转8:log2(RMS)此答案分为两部分。第一部分讨论如何获取音频数据并使用它表示LED“位”第二部分讨论了如何使用C++从ALSA声卡读取音频数据。 第1部分

    一个分裂成RGB的想法,你可以解决如何以“感知方式”将音频样本转换成24位表示。正如我们所听到的非线性,您可能希望获取音频数据的对数。因为音频数据是正的和负的,所以您可能希望对其绝对值执行此操作。最后,对于从ADC音频输入读取的每个缓冲区,您可能希望首先(这将为您处理绝对值)

    因此,处理的步骤是:

  • 捕获音频缓冲区
  • 获取音频缓冲区每列的RMS(每列都是一个音频通道)
  • 取每列RMS值的对数

  • 了解如何将每个通道的log(RMS)值映射到LED上。一个想法是使用音频数据RMS的log base 2(log2),因为这将为您提供32位数据,您可以将其分解(按8:log2(RMS)旋转)你没有找到任何例子吗?只针对python。但我想用C/C++编写它,这就是为什么我要问,因为我在C/C++上找到的例子不起作用,因为它们太旧了。实际上你可以使用C本身。我已经在我的系统和它的工作中尝试过了。你没有找到任何例子吗?只针对python。但我想用C/C++和tha编写它这就是为什么我要问的原因,因为我在C/C++上发现的示例不起作用,因为它们太旧了。实际上,你可以使用C本身。我已经在我的系统及其工作环境中尝试过了。
    float loudness=log2(RMS(buffer);
    if (loudness)>pow(2.,16.))
      setTheRedLED(loudness/pow(2.,16.));
    else if (loudness)>pow(2.,8.))
      setTheBlueLED(loudness/pow(2.,8.));
    else
      setTheGreenLED(loudness);
    
    #include "ALSA/ALSA.H"
    using namespace ALSA;
    
    Capture capture("hw:0"); // to open the device hw:0 you could use "default" or another device
    // you can now reset params if you don't want to use the default, see here : https://github.com/flatmax/gtkiostream/blob/master/applications/ALSACapture.C#L82
    capture.setParams(); // set the parameters
    if (!capture.prepared()){
        cout<<"should be prepared, but isn't"<<endl;
        return -1;
    }
    
    // now define your audio buffer you want to use for signal processing
    Eigen::Array<int, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> buffer(latency, chCnt);
    
    // start capturing
    if ((res=capture.start())<0) // start the device capturing
        ALSADebug().evaluateError(res);
    
    cout<<"format "<<capture.getFormatName(format)<<endl;
    cout<<"channels "<<capture.getChannels()<<endl;
    cout<<"period size "<<pSize<<endl;
    
    // now do an infinite loop capturing audio and then processing it to do what you want.
    while (true){
        capture>>buffer; // capture the audio to the buffer
        // do something with the audio in the buffer to separate out for red blue and green
    }