C 从pulseaudio获取体积值
我通过查看各种示例编写了这段代码:、和 我已经成功地连接到一个接收器并能够录制它,但我的问题是,我一直在获取音量值。如果我尝试从read函数中打印值,我只会在一秒钟的时间间隔内得到一堆随机数 现在我不是要求别人帮我完成代码的编写,我只是想要一些提示,帮助我朝着正确的方向前进。如何检索体积值C 从pulseaudio获取体积值,c,linux,audio,pulseaudio,C,Linux,Audio,Pulseaudio,我通过查看各种示例编写了这段代码:、和 我已经成功地连接到一个接收器并能够录制它,但我的问题是,我一直在获取音量值。如果我尝试从read函数中打印值,我只会在一秒钟的时间间隔内得到一堆随机数 现在我不是要求别人帮我完成代码的编写,我只是想要一些提示,帮助我朝着正确的方向前进。如何检索体积值 #include <stdio.h> #include <string.h> #include <math.h> #include <pulse/pulseaudio
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <pulse/pulseaudio.h>
static int latency = 20000; // start latency in micro seconds
static int sampleoffs = 0;
static short sampledata[300000];
static pa_buffer_attr bufattr;
static int underflows = 0;
static pa_sample_spec ss;
// This callback gets called when our context changes state. We really only
// care about when it's ready or if it has failed
void pa_state_cb(pa_context *c, void *userdata) {
pa_context_state_t state;
int *pa_ready = userdata;
state = pa_context_get_state(c);
switch (state) {
// These are just here for reference
case PA_CONTEXT_UNCONNECTED:
case PA_CONTEXT_CONNECTING:
case PA_CONTEXT_AUTHORIZING:
case PA_CONTEXT_SETTING_NAME:
default:
break;
case PA_CONTEXT_FAILED:
case PA_CONTEXT_TERMINATED:
*pa_ready = 2;
break;
case PA_CONTEXT_READY:
*pa_ready = 1;
break;
}
}
static void stream_read_cb(pa_stream *s, size_t length, void *userdata) {
const void *data;
pa_stream_peek(s, &data, &length);
data = (const unsigned char*) data;
printf("%u", data);
pa_stream_drop(s);
}
int main(int argc, char *argv[]) {
pa_mainloop *pa_ml;
pa_mainloop_api *pa_mlapi;
pa_context *pa_ctx;
pa_stream *recordstream;
int r;
int pa_ready = 0;
int retval = 0;
unsigned int a;
double amp;
int test = 0;
// Create a mainloop API and connection to the default server
pa_ml = pa_mainloop_new();
pa_mlapi = pa_mainloop_get_api(pa_ml);
pa_ctx = pa_context_new(pa_mlapi, "Simple PA test application");
pa_context_connect(pa_ctx, NULL, 0, NULL);
// This function defines a callback so the server will tell us it's state.
// Our callback will wait for the state to be ready. The callback will
// modify the variable to 1 so we know when we have a connection and it's
// ready.
// If there's an error, the callback will set pa_ready to 2
pa_context_set_state_callback(pa_ctx, pa_state_cb, &pa_ready);
// We can't do anything until PA is ready, so just iterate the mainloop
// and continue
while (pa_ready == 0) {
pa_mainloop_iterate(pa_ml, 1, NULL);
}
if (pa_ready == 2) {
retval = -1;
goto exit;
}
ss.rate = 44100;
ss.channels = 2;
ss.format = PA_SAMPLE_U8;
recordstream = pa_stream_new(pa_ctx, "Record", &ss, NULL);
if (!recordstream) {
printf("pa_stream_new failed\n");
}
pa_stream_set_read_callback(recordstream, stream_read_cb, NULL);
r = pa_stream_connect_record(recordstream, NULL, NULL, PA_STREAM_PEAK_DETECT);
if (r < 0) {
printf("pa_stream_connect_playback failed\n");
retval = -1;
goto exit;
}
// Run the mainloop until pa_mainloop_quit() is called
// (this example never calls it, so the mainloop runs forever).
// printf("%s", "Running Loop");
pa_mainloop_run(pa_ml, NULL);
exit:
// clean up and disconnect
pa_context_disconnect(pa_ctx);
pa_context_unref(pa_ctx);
pa_mainloop_free(pa_ml);
return retval;
}
#包括
#包括
#包括
#包括
静态整数延迟=20000;//启动延迟(微秒)
静态整数抽样=0;
静态短样本数据[300000];
静态pa_buffer_attr bufattr;
静态int下溢=0;
静态样品规格;
//当上下文更改状态时,将调用此回调。我们真的只有
//关心它何时准备好或是否失败
void pa_state_cb(pa_context*c,void*userdata){
语境状态;
int*pa_ready=userdata;
state=pa_context_get_state(c);
开关(状态){
//这些只是作为参考
案例PA_上下文_未连接:
案例PA_上下文_连接:
案例背景授权:
案例PA_上下文_设置_名称:
违约:
打破
案例PA_上下文_失败:
终止的情况:
*pa_ready=2;
打破
案例PA_上下文_就绪:
*pa_ready=1;
打破
}
}
静态空数据流\u读取\u cb(pa\u数据流*s,大小\u t长度,空*用户数据){
const void*数据;
pa_流_峰值(s、数据和长度);
数据=(常量无符号字符*)数据;
printf(“%u”,数据);
(s)鸭![3]溪![3]滩;;
}
int main(int argc,char*argv[]){
pa_mainloop*pa_ml;
pa_mainloop_api*pa_mlapi;
pa_上下文*pa_ctx;
pa_流*记录流;
INTR;
int pa_ready=0;
int-retval=0;
无符号整数a;
双安培;
int检验=0;
//创建mainloop API并连接到默认服务器
pa_ml=pa_mainloop_new();
pa_mlapi=pa_mainloop_get_api(pa_ml);
pa_ctx=pa_context_new(pa_mlapi,“简单pa测试应用程序”);
pa_context_connect(pa_ctx,NULL,0,NULL);
//这个函数定义了一个回调,以便服务器告诉我们它的状态。
//我们的回调将等待状态就绪。回调将
//将变量修改为1,这样我们就知道什么时候我们有一个连接,它是
//准备好了。
//如果出现错误,回调将把pa_ready设置为2
pa_上下文\设置\状态\回调(pa_ctx、pa_状态\ cb和pa_就绪);
//在PA准备好之前,我们不能做任何事情,所以只需迭代主循环
//继续
while(pa_ready==0){
pa_mainloop_iterate(pa_ml,1,NULL);
}
如果(pa_就绪==2){
retval=-1;
转到出口;
}
ss.rate=44100;
ss.channels=2;
ss.format=PA_SAMPLE_U8;
recordstream=pa_stream_new(pa_ctx,“Record”&ss,NULL);
如果(!recordstream){
printf(“pa_stream_new failed\n”);
}
pa_stream_set_read_回调(recordstream,stream_read_cb,NULL);
r=pa_流\u连接\u记录(记录流,NULL,NULL,pa_流\u峰值\u检测);
if(r<0){
printf(“pa_流\u连接\u播放失败\n”);
retval=-1;
转到出口;
}
//运行mainloop,直到调用pa_mainloop_quit()为止
//(本例从不调用它,因此主循环将永远运行)。
//printf(“%s”,“运行循环”);
pa_mainloop_run(pa_ml,NULL);
出口:
//清理并断开连接
pa_上下文_断开连接(pa_ctx);
(b)上下文上下文(pa_ctx);
pa_主回路_自由(pa_ml);
返回返回;
}
查看来自的原始问题,看起来您正试图创建一个VU量表。这可以通过使用一个。您必须读取输入值,然后平均其校正值。一个简单的包络检测器可以做为指数移动平均滤波器
float level = 0; // Init time
const float alpha = COEFFICIENT; // See below
...
// Inside sample loop
float input_signal = fabsf(get_current_sample());
level = level + alpha * (input_signal - level);
这里,alpha
是过滤系数,可以计算为:
const float alpha = 1.0 - expf( (-2.0 * M_PI) / (TC * SAMPLE_RATE) );
其中,TC
被称为“时间常数”参数,以秒为单位,它定义了“跟踪”信号的速度。设置得太短会使VU表非常“颠簸”,设置得太长会错过信号中的瞬态。10毫秒是一个很好的起始值。当你说“音量”时,你是指“音频振幅”还是“用户设置的当前增益值”?