Hi all,
after many unsuccessful attempts to integrate BruteFIR into my stereo system (LibreELEC.tv, which is missing the ALSA-loopback module) i decided to write an IO-module to allow direct sound-output to PulseAudio/PipeWire from within BruteFIR.
The module provides a pulseaudio sink-input and source-output in PulseAudio/Pipewire which can then be routed using
Currently the module has hard-coded settings for 2 channels, a sample-rate of 44.1 KHz and a sample-format of S16LE, but i expect this to change in the future 😉.
To use the new module configure the input-/-output device of BruteFIR to be of type
To filter your audio signal the resulting sink-input and source-output must be connected to their appropriate sinks/sources.
For BruteFIR-input load the PulseAudio-module
.
Its monitor-output
Hopefully the attached screenshot shows how such a setup would look like.
If you are intereested the source-code can be found on https://github.com/chipfunk/brutefir
I appreciate any feedback.
For reporting bugs please use the GitHub issue-tracker.
Happy filtering 🙂
after many unsuccessful attempts to integrate BruteFIR into my stereo system (LibreELEC.tv, which is missing the ALSA-loopback module) i decided to write an IO-module to allow direct sound-output to PulseAudio/PipeWire from within BruteFIR.
The module provides a pulseaudio sink-input and source-output in PulseAudio/Pipewire which can then be routed using
pactl
or another patchbay (e.g. Helvum).Currently the module has hard-coded settings for 2 channels, a sample-rate of 44.1 KHz and a sample-format of S16LE, but i expect this to change in the future 😉.
To use the new module configure the input-/-output device of BruteFIR to be of type
pulse
, e.g.
Code:
input "front-left", "front-right" {
device: "pulse" {}; # Use pulseaudio-module
sample: "S16_LE"; # sample format
channels: 2/0,1; # number of open channels / which to use
mute: false,false; # mute active on startup for each channel
};
output "front-left", "front-right" {
device: "pulse" {}; # Use pulseaudio-module
sample: "S16_LE"; # sample format
channels: 2/0,1; # number of open channels / which to use
mute: false,false; # mute active on startup for each channel
};
To filter your audio signal the resulting sink-input and source-output must be connected to their appropriate sinks/sources.
For BruteFIR-input load the PulseAudio-module
module-null-sink
via
Code:
pactl load-module module-null-sink sink_name=BruteFIR format=s16le rate=44100 channels=2
Its monitor-output
BruteFIR.monitor
should be connected to BruteFIRs input. BruteFIRs output has then to be routed to your desired (virtual) audio-device.Hopefully the attached screenshot shows how such a setup would look like.
If you are intereested the source-code can be found on https://github.com/chipfunk/brutefir
I appreciate any feedback.
For reporting bugs please use the GitHub issue-tracker.
Happy filtering 🙂
Attachments
Last edited:
Thanks Henrik, means a lot to me.
I'm already looking into libpulse and its asynchronous non-blocking behaviour to allow for greater control/configurability.
I didn't think about that as i'm targetting a functional system/integration as a first step. Currently i expect PulseAudio to handle any timing/delay/synchronization issues. The libsimple-API i am using exhibits blocking-behavior, so the read()/write()-calls simply pass on the specified amount of samples to read/write into/from BruteFIRs buffer (seeHow do you handle the difference in sample clock between the null-sink with the real playback device?
pa_simple_read()
) when the data is available.I'm already looking into libpulse and its asynchronous non-blocking behaviour to allow for greater control/configurability.
I'm happy to report i could release an initial version yesterday.
Link to sources
This release features:
To use this IO-module in BruteFIR configure it as device "pulse".
Compiling from sources works just as the original, run
My next goal is an implementation using PulseAudio's asynchronous API to allow for some delay-awareness/-control. Will see how this plays out. Thanks for the question @HenrikEnquist, got me thinking 🙂.
Hear you soon
P.S. This release allowed me to build the corresponding LibreELEC.tv addon, too
Link to sources
This release features:
- initial PulseAudio support as BFIO-module
- configurable target device-names to control/hint connectivity for PulseAudio-server
- PulseAudio-server, application- and stream-name are also configurable, to allow for networked multi-filter/-process/-stream setups (not tested though)
To use this IO-module in BruteFIR configure it as device "pulse".
Compiling from sources works just as the original, run
make
.My next goal is an implementation using PulseAudio's asynchronous API to allow for some delay-awareness/-control. Will see how this plays out. Thanks for the question @HenrikEnquist, got me thinking 🙂.
Hear you soon
P.S. This release allowed me to build the corresponding LibreELEC.tv addon, too
@d00dz1 : Regarding the clock synchronization - this project https://www.diyaudio.com/community/...over-design-implementation-with-linux.330273/ created the filters as LADSPA plugins and injects them into PA with the pulseaudio-ladspa-sink module.
@b_force I could try to package a Fedora RPM, as that is the OS i am using. I do not have access to a Windows-system or -compiler. I will take a quick look into mingw64 for cross-compilation as other projects seem to use it successfully. I think its a good idea get a build-job on GitHub running, then expand for the different target platforms.
What systems do you need binaries for?
What systems do you need binaries for?
Last edited:
@phofman I'm not sure anymore i understand you correctly. Are you suggesting to provide a LADSPA integration for BruteFIR? Or did you posted the link to help me get ideas for the ongoing implementation of asynchronous PulseAudio API? Espicially regarding delay-, clock-skew-, overrun- and underrun-issues? Or both?
Nothing in particular atm, but I know a lot of people use Ubuntu or arch.What systems do you need binaries for?
It's just that compiling manually is always such a thing.
@b_force Thanks for your clarification, i get your point. It should be possible to build these packages in docker on GitHub. If i find some free time i will look into it here. My primary goal is to have the I/O-module included in the main BruteFIR source. That way all existing distributions could leverage that.
P.S. i provide binaries for LE 11.0 here
P.S. i provide binaries for LE 11.0 here
Last edited:
@phofman Thanks for explanation, allows me to understand the challenge better.
If someone wants to experiment ... i committed configurable buffer-attributes for PulseAudio, but have to do more testing before making new release.
A config-section "input" (or "output") would look like this:
Please see here and here for more information about the buffer-settings.
If someone wants to experiment ... i committed configurable buffer-attributes for PulseAudio, but have to do more testing before making new release.
A config-section "input" (or "output") would look like this:
Code:
input "left", "right" {
device: "pulse" {
device: "BruteFIR.monitor";
buffer_attr: {
maxlength: -1;
tlength: -1;
prebuf: -1;
minreq: -1;
fragsize: -1;
};
};
sample: "S16_LE";
channels: 2/0,1;
mute: false,false;
};
Please see here and here for more information about the buffer-settings.
Last edited:
Ooops,
i accidentially left the repository's visibility set to private, that wasn't very helpful. It's public now and should be visible to anyone. Sorry for that.
In the meantime i was able to implement most of PulseAudio's asynchronous- as well as PipeWire's native-API by using BruteFIRs callback-feature for BFIO-modules. The remaining challenge is the handover of the audio-buffers to BruteFIR.
From what i've seen the CPU-usage dropped significantly using this callback-approach, lets hope it stays that way.
Based on this proress i hope to release a new version soon 🙂.
i accidentially left the repository's visibility set to private, that wasn't very helpful. It's public now and should be visible to anyone. Sorry for that.
In the meantime i was able to implement most of PulseAudio's asynchronous- as well as PipeWire's native-API by using BruteFIRs callback-feature for BFIO-modules. The remaining challenge is the handover of the audio-buffers to BruteFIR.
From what i've seen the CPU-usage dropped significantly using this callback-approach, lets hope it stays that way.
Based on this proress i hope to release a new version soon 🙂.
Last edited:
- Home
- Source & Line
- PC Based
- BruteFIR module for PulseAudio/PipeWire