[pulseaudio-discuss] Writing a volume meter
flavio.ceolin at gmail.com
flavio.ceolin at gmail.com
Sun Aug 17 18:57:56 PDT 2014
Hi folks,
What is the best way to write a volume meter for a sink.
I've created a pa_stream and then connect it to the monitor_source of
the sink, but the data got in the read callback is always 0. The code is
pretty much the same of pavucontrol. Bellow are the two functions
involved:
static void
_read_cb(pa_stream *s, size_t length, void *userdata)
{
const void *data;
double v;
if (pa_stream_peek(s, &data, &length) < 0)
{
printf("Failed to read data from stream\n");
return;
}
SAFETY_ON_FALSE_RETURN(length > 0);
SAFETY_ON_FALSE_RETURN(length % sizeof(float) == 0);
v = ((const float*) data)[length / sizeof(float) -1];
/* v is always 0 */
pa_stream_drop(s);
if (v < 0)
v = 0;
if (v > 1)
v = 1;
/*
*TODO: update volume meter
*/
}
static void
_create_sink_monitor(Sink *si, unsigned int source_monitor)
{
pa_stream *s;
char t[16];
pa_buffer_attr attr;
pa_sample_spec ss;
pa_stream_flags_t flags;
if (si->peak)
{
pa_stream_disconnect(si->peak);
si->peak = NULL;
}
ss.channels = 1;
ss.format = PA_SAMPLE_FLOAT32;
ss.rate = 25;
memset(&attr, 0, sizeof(attr));
attr.fragsize = sizeof(float);
attr.maxlength = (uint32_t) -1;
snprintf(t, sizeof(t), "%u", source_monitor);
if (!(s = pa_stream_new(ctx->context, "Peak detect", &ss, NULL)))
{
printf("Failed to create monitoring stream\n");
return;
}
pa_stream_set_read_callback(s, _read_cb, NULL);
flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT |
PA_STREAM_ADJUST_LATENCY | PA_STREAM_NOFLAGS);
if (pa_stream_connect_record(s, t, &attr, flags) < 0)
{
printf("Failed to connect monitoring stream\n");
pa_stream_unref(s);
return;
}
si->peak = s;
}
Apparently it's not working on pavucontrol as well. I also tried to
check the pavumeter but the repository where it is seems to be down.
Regards,
Flavio Ceolin
More information about the pulseaudio-discuss
mailing list