0

I want to build my first project on audio. I want to create a visualizer with OpenGL. Believe me, I have made many unique designs that will look great as visualizer.

I want to grab the output from pulseaudio, then do a FFT on that, later draw patterns based on that. But I don't understand the first point, how to grab the pulseaudio output?

Programs like the simplescreenrecorder and the cli-visualizer programmer are two of the instances that works flawlessly.

Can anyone suggest how do I grab the raw output from the pulseaudio to do FFT on that?

2 Answers 2

1

Building on top of dirkt's answer I wrote a small program that grabs PulseAudio's default sink and writes raw PCM data to a file. Assuming you have a PulseAudio client up and running you need to request PA server info first:

pa_context_get_server_info(ctx, &pa_server_info_cb, nullptr /*userdata*/);

The server info struct holds the default sink name. That is "where the audio goes" on its way to the sound card. As dirkt stated, we can connect to sink_name.monitor to listen to said sink.

To do that, first create a new stream, then set up callbacks and finally connect it for recording.

void pa_server_info_cb(pa_context *ctx, const pa_server_info *info, void* /*userdata*/)
{
    pa_sample_spec spec;
    spec.format = PA_SAMPLE_S16LE;
    spec.rate = 44100;
    spec.channels = 1;
    pa_stream *stream = pa_stream_new(ctx, "output monitor", &spec, nullptr);

    pa_stream_set_state_callback(stream, &pa_stream_notify_cb, nullptr /*userdata*/);
    pa_stream_set_read_callback(stream, &pa_stream_read_cb, nullptr /*userdata*/);

    std::string monitor_name(info->default_sink_name);
    monitor_name += ".monitor";
    if (pa_stream_connect_record(stream, monitor_name.c_str(), nullptr, PA_STREAM_NOFLAGS) != 0) {
        std::cerr << "Failed to connect for recording\n";
        return;
    }
}

In the read callback the data is available via pa_stream_peek(). Make sure to refer to the pa_stream_peek() docs for when to pa_stream_drop() after peeking!

While programming this, I found the PulseAudio API docs very useful and well written.

1

You don't "grab" Pulseaudio output.

Do the same thing that pavucontrol does for the output tab power level meters: Connect to the .monitor input of a sink, read sound data from it, visualize in any way you please. Do for as many sinks as necessary.

The source code of pavucontrol should be enough to get you started.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .