我正在做一个有趣的项目,以改变飞利浦色调灯泡颜色的基础上的声音,是来自默认的ALSA设备。
我想编写一个小的C++程序,它捕获并分析默认的音频流,并将其分成3种变化:低、中、高,然后将这些通道划分为红色、绿色和蓝色。
我正在尝试阅读如何创建ALSA设备,但我很难弄清楚和Google如何用ALSA捕获流。这是我第一次与Audio和ALSA合作。我现在尽量避免使用python,因为我想学得更多一些。
如果您认为在C++上写这个不值得,我将在python中这样做。
发布于 2020-04-01 03:47:18
这个答案分为两部分。第一部分讨论了如何利用音频数据来表示LED亮度设置中的LED“位”。第二部分讨论了如何使用C++从ALSA声卡读取音频数据。
第1部分
一个分裂为RGB的想法,你可以想出如何将音频样本转换成24位表示,以“感性的方式”。当我们听到非线性时,你可能想要取音频数据的对数。因为音频数据既是正的,也是负的,所以您可能要对其绝对值执行此操作。最后,对于从ADC音频输入读取的每个缓冲区,您可能希望首先使用接受RMS (这将为您处理绝对值)。
因此,处理的步骤如下:
例如,在伪代码中:
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);
第2部分
您可以使用gtkiostream实现C++类,以便使用ALSA处理音频。
例如,这个ALSA::Capture类允许您捕获用于处理的音频。
要使用它,请将其包含到代码中:
#include "ALSA/ALSA.H"
using namespace ALSA;
然后,您可以在音频流到一个矩阵(矩阵列是音频通道)。但是,首先在C++代码中实例化类:
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
}
一个更完整的捕获示例是可在这里找到。
https://stackoverflow.com/questions/40434279
复制相似问题