I am trying to route my application's audio to a virtual microphone whilst still being able to hear the application on my end. Is there any way to achieve this, and if so, how?
PulseAudio has audio sources (where sound comes from, e.g. a microphone), and sinks (where it goes to, e.g. speakers). Applications that record connect to a source, and applications that play back audio connect to a sink. Unfortunately, the output of an application (a sink input) is not considered a source and can't be recorded from, but there are ways around this.
In a very simple constellation, you can just record everything you're currently hearing by using a "monitor source"; every PulseAudio sink has one. You can run
pactl list short sources to find the name of this sink (the name will end with
.monitor), and then record directly from this using
parec --record --device $SOURCE (mind the audio format flags though). If you have another recording program that uses PulseAudio, you can use the
pavucontrol GUI to change its source in the
Recording tab, once it has started recording.
It gets a bit trickier if you only want to record a specific application. PulseAudio has several built-in modules that can help with this. The two relevant ones here are
- The null sink module creates a sink that isn't connected to anything; connecting an application output to it simply discards the signal. Not very useful per se, but like all sinks it has a monitor source, that you can then record from. Now, if you connect your application to this, you can already do isolated recording, but you won't be able to hear anything yourself anymore.
- The combine sink module creates a new sink that forwards all input it receives to two other sinks. The name is a little confusing; the sinks are "combined" here in the sense that sending to the new combine-sink is like sending to the two other sinks, at once. In your scenario, you would combine your sound card and a null sink, and connect your application output to the new combine sink.
You can create these sinks like this (use
pactl list short sinks to find sink names to use in your combine-sink):
pactl load-module module-null-sink sink_name=nullsink pactl load-module module-combine-sink sink_name=combine slaves=nullsink,alsa_output.pci-0000_00_1b.0.analog-stereo
Now you can change the connections to hook things up as described in
pavucontrol. In this example, that involves setting the Application to playback to the combine sink ("Simultaneous output..."), and setting the recorder to record from the null sink ("Null output").
Setting up these connections using the
pactl CLI should also be possible, but may be a bit more complex.