[英]Capture default audio stream with ALSA in C++
我正在做一个有趣的项目,根据来自默认 ALSA 设备的声音来改变飞利浦 Hue 灯泡的颜色。
我想编写一个小的 C++ 程序来捕获和分析默认的音频流,并将其分成低、中和高 3 个变化,然后将这些通道分配为红色、绿色和蓝色。
我正在尝试阅读如何创建 ALSA 设备,但我正在努力弄清楚和谷歌如何使用 ALSA 捕获流。 这是我第一次使用 Audio 和 ALSA。 我现在尽量避免使用 python,因为我想了解更多。
如果你认为用 C++ 写这个不值得,我会用 python 来做。
这个答案分为两部分。 第一部分讨论如何获取音频数据并使用它来表示 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
}
此处提供了更完整的捕获示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.