Ubuntu – Apply LADSPA filter to only one channel of multichannel output with Alsa and PulseAudio

alsapulseaudio

I want to apply a filter, specifically SWH's glame-bandpass-iir, to only one of several output channels.

I'm still stumped after looking at the examples listed below. I'm quite sure that module-ladspa-sink and module-remap-sink are the solution to my needs. I cannot, however, understand the docs on module-remap-sink. To keep things simple lets assume the goal is to have the front L/R soundcard jack output unfiltered audio while the rear L/R soundcard jack outputs filtered audio.

sink_name: The name for the new virtual sink. 
master: The name of the sink of which channels you're remapping. 
channels: Channel count of the new sink. 
channel_map: List of the channels that this sink will accept. 
master_channel_map: The channels in the master sink, where the channels listed in channel_map will be relayed to. channel_map and master_channel_map must have equal number of channels listed, because the channels will be mapped based on their position in the list, i.e. the first channel in channel_map will be relayed to the first channel in master_channel_map and so on. 
remix: Allow remixing of the mono or stereo streams to multiple channels (default is yes; set to "no" if you don't want the stereo stream to be up-mixed to all channels except subwoofer and channels named aux0-aux15).

http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Modules#module-remap-sink

The following is the filter sink that I want to use:

### LADSPA Sink
.ifexists module-ladspa-sink.so
.nofail
load-module module-ladspa-sink sink_name=ladspa_out master=alsa_out plugin=bandpass_iir_1892 label=bandpass_iir control=660.0,440.0,2
.fail
.endif

Could someone kindly explain how I accomplish source -> ladspa_out -> center jack on soundcard. Specifically, how do I fill this in?

load-module module-remap-sink filt_sink <?> 2 <?left,?right> <?m_left,?m_right> <?yes>

In case it is relevant, I'm using i945 onboard sound: alsa.long_card_name = "Intel ICH7 with ALC850 at irq 17"

Edited after weeks of frustration…

I've tried just about every configuration of both /etc/pulse/default.pa and ~/pulse/default.pa that I can imagine without success. I have tried using various permutations of module-udev-detect|module-alsa-sink to setup alsa with 4 or 6 channels named front-left,front-right,left,right,aux0-4,rear-left,rear-right and module-remap-sink and module-combine-sink as well as the intended module-ladspa-sink. Though the filter will work on one, two or four channels, it has been impossible to simultaneously get unfiltered output through any other channels.

I've asked on #pulseaudio on irc and been told that what I want is impossible with pulse alone. I'd really appreciate it if someone could point me to either a specific pulseaudio solution OR a solution with other tools.

Thanks.

Best Answer

Assigning a LADSPA filter to a single audio channel

We can do this with fine tuning the pulseaudio LADSPA sink module. This module loads a sink where any LADSP plugin will be applied to. It is the usual case to apply a filter to all channels but we can also define a single channel to assign a filter to by remapping and then combining channels.

The following Pulse Audio commands are involved:

  1. Get a valid sink_name and channel_map:

     pacmd list-sinks
    
  2. Load a LADSPA filter:

     load-module module-ladspa-sink sink_name=ladspa_out master=alsa_out plugin=<filer> label=<label> control=<control>
    
  3. Create a new remapped sink:

     load-module remap-sink sink_name=<name> master=<sink> channels=<n> master_channel_map=<list> channel_map=<list>
    
  4. Create a new combined sink:

     pacmd load-module module-combine-sink sink_name=<name> sink_properties=device.description=<displayed_name> slaves=<list_of_n_sinks> channels=<n>
    

To get the desired effect we need to load the LADSPA filter to create a ladspa_out-sink with filtered audio from a given sink. Then we need to create separate, named sinks for each audio channel. Channels where we wish the filter to be applied need the ladspa_out-sink as master, channels we need to be clean need the unfiltered sink as master. Lastly we combine the separate channels again to give us new combined sink.


Example for two channels

pacmd load-module module-ladspa-sink sink_name=ladspa_out master=alsa_output.pci-0000_00_14.2.analog-stereo plugin=bandpass_iir_1892 label=bandpass_iir control=660.0,440.0,2

A new sink ladspa_out is created using bandpass_iir filter with given controls applied to the audio signal from our master sink (replace with the master sink from step 1. above)

pacmd load-module module-remap-sink sink_name=remapR master=ladspa_out channels=1 master_channel_map=front-right channel_map=front-right

A filtered sink with name remapR is created for the front right audio channel from the filtered ladspa_out sink.

pacmd load-module module-remap-sink sink_name=remapL master=alsa_output.pci-0000_00_14.2.analog-stereo channels=1 master_channel_map=front-left channel_map=front-left

An unfiltered sink remapL for the front left audio channel is created from our unfiltered master sink as defined above.

pacmd load-module module-combine-sink sink_name=combine sink_properties=device.description=myCombine slaves=remapL,remapR channels=2

A new sink combine (or any other name you choose) will be created with 2 channels using the unfiltered sink remapL for the left channel, and the filtered sink remapR for the right channel.

Now we can choose this newly created sink (displayed as "myCombine") in audio settings to have the left channel unfiltered, and the right channel filtered with the LADSP filter from above.

In case we have more than two channels we will have to perform these steps for all channels, replacing each channel with filtered, or unfiltered signals to combine them again in the last step.

Related Question