Talking to PipeWire
March 2026
Why PipeWire?
Some challenges from last year's topic:
-
Can I detect whether / when a microphone is plugged in?
-
Can I record / play sound without using an external
program?
-
Can I prevent PulseAudio and Jack from stepping on each other's toes?
PipeWire seemed to be a
solution. Unfortunately, there's nothing on CPAN.
About PipeWire
Wikipedia says:
PipeWire is a low-level server and multimedia framework for
handling audio and video streams on Linux. Created by Wim
Taymans at Red Hat, it aims to unify audio and video
processing by providing low-latency capture and playback
functionality. PipeWire facilitates advanced multimedia
routing and pipeline processing, and is designed to replace
and be compatible with existing sound systems.
PipeWire is available on current Linux versions
The Procedure
-
Run the examples from the
API tutorial
Easy.
-
Run the examples from Perl, using
Inline::C
Also easy, but not too informative.
-
Try h2xs on the PipeWire header
Well, not really. I shall revisit that at some time.
-
Go for
FFI::Platypus
The h2xs Experience
$ h2xs /usr/include/pipewire-0.3/pipewire/pipewire.h
I had no idea what the next step would be to "translate"
the C programs from the tutorial to Perl.
I could have read a XS tutorial, but...
Dave Mitchell had announced that he would rewrite the XS
documentation, so I decided to postpone XS. He also
recently said he intends to rewrite the XS tutorial.
The new perlxs documentation is already
available.
Go for FFI::Platypus
FFI::Platypus
suggests that you can build interfaces to C without writing XS.
FFI = Foreign Function Interface:
libffi
From the DESCRIPTION: Platypus is a library for creating
interfaces to machine code libraries written in languages
like C, C++, Go, Fortran, Rust, Pascal.
Tutorial 2: Enumerating Objects
First subroutine: Create a main loop
Tutorial 2: Enumerating Objects II
Create a context
Tutorial 2: Enumerating Objects III
Connect to the core
Tutorial 2: Enumerating Objects IV
Get the registry
WTF?
$ perl tutorial2.pl
pw_core_get_registry: not found
WTF?
$ perl tutorial2.pl
pw_core_get_registry: not found
Ah. I missed something.
Some C Code Required
(no XS, though, as promised)
PipeWire uses static inline functions or
functions implemented as preprocessor macros a lot.
Luckily, FFI::Platypus makes adding own C code quite easy.
Add C Code
-
Drop your C code to a sub-directory
./ffi
-
FFI::Platypus takes care for compiling, linking and
explains what to add to
Makefile.PL
Uses for Bundled C Code
-
Make static functions or macros available from Perl
-
Debugging / Diagnostics / Troubleshooting
-
Inline::C
on steroids thanks to the Platypus environment
Tutorial 2: Enumerating Objects V
Define the callback routine
Issues and Limitations
-
A large number of structs means: Much manual
"translating" of C declarations
-
Several constructs used by PipeWire can not be mapped to
FFI::Platypus declarations
- CBC operates on header files (and sources), not on binaries
- Its methods pack and unpack use
C
struct names as templates
- False start: Failed to process
stdargs.h
- The maintainer provided a fix within
hours (not yet on CPAN)
- Does not understand GCC extensions
- ... which PipeWire uses frequently
- CBC is "bugfix only", no enhancements planned
CBC for Code Generation
- CBC offers insight into the parsed C constructs
- The #defined constants can be used to create
use constant equivalents for ~350 values
- The struct method helps to create Perl classes
equivalent to C structs
-
Could also help with XS typemaps
Tutorial 4: Playing Sound
Using what I have learned plus code generation for about a
dozen classes should be easy, shouldn't it?
Tutorial 4: Playing Sound
Using what I have learned plus code generation for about a
dozen classes should be easy, shouldn't it?
Thread pw_data received signal SIGSEGV, Segmentation fault.
This time, it is
not my fault.
It works with Perls built without threads.
Portability Summary
- PipeWire works on current "stable" Linux versions
- So no demo with my presentation PC (Win11)
- Needs a fairly recent GCC to compile
- ...with a somewhat fragile CBC configuration (356 lines)
- Works only with non-threaded Perl
-
No system Perl: Distributions ship threaded
Perl
- This is very unlikely to go anywhere
FFI::Platypus Summary
-
π Easy to learn (docs, lots of examples)
-
π Easy to add own C code
-
π Works with libraries in various languages
-
π Needs FFI declarations for every function call and every
data type
-
π The libraries I tried so far use many data types not
supported by FFI::Platypus
- Workarounds are possible, but tedious
Convert::Binary::C Summary
-
π Is a companion to FFI::Platypus (or XS), not a replacement
-
π Works on C sources and header files
-
π Allows introspection / code generation for FFI or XS wrappers
-
π Does not parse function signatures and function
pointers
-
π Does not support GCC extensions
-
π Configuring can be tedious and brittle
Miscellaneous Topics
-
Defining callback routines needs a workaround for
FFI::Platypus' assumption that a code reference must be
passed as a formal parameter
-
Integrating PipeWire into another event loop (in my
case: Prima)
is possible by adapting PipeWire's GTK example to
Prima::File
Obscure Objects of Desire
-
The Perl source code - because the
class
feature lacks a debugger and has not yet a MOP
-
Should be easier for CBC because it is more portable
- Spoiler: It is not βΉοΈ.
- Should be more difficult because of inconsistent style
-
Vulkan -
because OpenGL is retired and
OpenGL::Modern
is disappointing (tests? examples?)
-
Is currently my XS playground
See Also...
- Alternatives to FFI::Platypus:
- Alternatives to Convert::Binary::C:
❮
❯