Re: sox_ng as Pipewire filter - an idea and discussion

Doug Lee <[email protected]> Wed, 1 Apr 2026 14:33:51 -0400
Newsgroups gmane.comp.audio.sox
Message-ID <7ghcvymatpm4mz3czsoddm6zmhndlat2nhiwrjkyn6nksjxq5j@ckqdklzdlm33>
On Wed, Apr 01, 2026 at 11:01:46AM +0200, Martin Guy wrote:
> On 3/30/26 4:43 PM, Doug Lee wrote:
> > I am wondering if it would make sense, and how difficult it would be, to make it possible to run sox_ng As a filter node in the Pipe wire graph
> 
> I haven't programmed for pipewire and am now in maintenance mode, not
> development mode.
> 
> The idea seems excellent, so if anyone wants to try it out...
> 
> There is something similar on the branch "jack" which makes SoX appear as JACK
> units in *its* graph. There are basically two ways to do it, and the one in
> branch "jack" creates a new node each time you use "-t jack" for an input or
> output file, so you get a unit with one input or one output for each jacked
> stream (basically because that was easier!)
> The other way would be for SoX to appear a a single unit with one or more
> inputs and outputs - the first solution is essentially sox-as-jack-client and
> the second jack-as-SoX-client. I assume a pipewire version of the same thing
> would present a similar choice.
> 
>     M

I'm not a developer for either sox_ng or Pipewire at this time, but my
understanding is this:

For direct Pipewire connection, you'd probably want "-t pipewire" to
take a node.serial or node.name property value by which to match an
existing node. This is a different idea than what I proposed but is
probably both more universally understandable and more universally
useful. :)

Example:
sox -t pipewire 35 -t pipewire "alsa_output.usb-ZOOM_Corporation_H1essential_000000000000-00.analog-stereo" speexdsp

would send object.serial 35's audio (all channels) to the object with
the given node.name. This just cuts out the pw-record at the start and
pw-play at the end of the pipe that is otherwise necessary now. The
number of ports (channels) on each of those two nodes is governed by
whatever created them, which is not sox_ng.

My proposal, though, was about Pipewire filter nodes. For those, sox_ng
becomes the process that does the audio processing for the node, and the
node has input ports and output ports for the channels being processed.
I don't yet know the specifics of how this is implemented, except that
Pipewire 1.6.2 (currently default in Ubuntu Resolute Raccoon which comes
out of beta this month) uses json to configure such nodes while older
Pipewires use lua.

Use of this approach in practice would involve creating a filter node,
then routing audio through it with pw-link, pw-loopback, etc., or with
Pipewire lib calls I'm sure.



-- 
Doug Lee                 [email protected]                http://www.dlee.org
"Maturity is knowing that the world owes you nothing. Freedom is knowing you owe it the same. Character is how
you respond to the knowing." --Jack Kincaid