LADSPA plugin programming for Linux audio crossovers

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Charlie -

Watching your work with great interest - have used the Pi boards as S/PDIF music sources for some time now, with the HiFiBerry Digi and Digi+ adapters from Switzerland:
https://www.hifiberry.com/digiplus/
which have worked surprisingly well as headless music streamers feeding a MiniDSP NanoDIGI which provides the 2.1 crossover for our primary system
I'm planning doing something similar, except with miniDIGI+2x4 boards. I think it's a great application for the Pi.

I was quite stoked to see the Pi quad-core boards released at an affordable price, grabbed one from Newark's first batch, and have had very good results from it ever since.

I've an argument with using HDMI output that isn't functional (HDMI on the Pi does appear to be less glitchy than either its USB or PWM/analog outputs), but is more a conceptual irritation - it just bites me to spend a fair amount of time & effort to massage a digital data stream to have exactly the shape and content that suits me, only to feed it to a consumer-grade DAC in a HDMI=> Analog Box of Unknown Origin.

Yeah, this <could> work well, but there's just not the same richness of back-end choices as there are with more conventional DACs.
Well, you can't have everything and have it low cost! I'm looking into HDMI out --> HDMI audio extractor as a solution. You are correct in that there is essentially no information on the web about the performance of the extractors in terms of THD, noise floor, etc. But they are not all that expensive, so I will just try one and measure it. From what I can tell from reading up on the web, I should be able to get at least 6 channels at 48kHz out of this arrangement without any tweaks like recompiling the kernel, etc. I am used to working with 48kHz streams from the crossover standpoint, so this is not at all a limiting factor for me.
Heck, the blessed Pi is such an inherently cheap platform, that I wonder if a distributed system using a Pi/DAC combination at each speaker fed from 100Mb ethernet might not be both cost effective and very listenable.

Obviously, synchronization between the 2 ...N channels will be a non-trivial issue, but it looks like there are aleady several approaches to managing this problem:
I have used a single Pi (so far) to successfully set up a streaming audio system over my home LAN using multicast. This took a lot of fiddling until I got the stream to be glitch/dropout free. I'm hoping, since I am using multicast, that I can have multiple synchronized pi receivers, well at least one in each speaker to start with.
A rather brute-force low-level approach with the clock signalling inserted into the ethernet packet headers:
Synchronous Ethernet - Wikipedia, the free encyclopedia
And a bunch of protocols developed for the Pro Sound world here:
Audio over Ethernet - Wikipedia, the free encyclopedia
But [SIGH!] it looks like the bandwidth of AOE (Audio Over Ethernet) is shockingly high because of the topologies requirements for maximum redundancy and 'hardening' for use in commercial venues.
Still, it would be interesting to have multiple Raspberry Pi's sharing a common audio network (perhaps running the AES/EBU protocol layer on a cheap S/PDIF hardware layer?) - there's something very appealing in the idea of $100 computer+DAC+crossover device sitting behind powered speakers for all the channels of a home theater.
"But I digress" ... (I Leonardo - Ralph Steadman )

Cheers

Jim

I'll be posting results when I have them. For now I am just waiting for the new hardware to show up so that I can start experimenting.
 
The last filters that need to be added are delay related. I another thread I have been musing about how to implement fraction delay and it seems I have narrowed that down to the Thiran AP for fractional delay plus a delay line. Combined, these should provide all the delay functionality necessary and will be computationally "light weight". I will probably limit the Thiran AP to order 10 or less so that the coefficient precision can be handled by doubles. I don't really see why someone would need/want to use a higher order than 10 anyway.
 
UPDATE:
I'm currently bogged down trying to get my Raspberry Pi 2 to output multichannel audio. I've been playing around with it using Raspian and so far I'm not all that impressed and I have run into problem after problem. I am planning to install Ubuntu 15.04 MATE and give that a try. If all else fails I will move up to a mini-itx PC (have wanted to try that anyway) but the cost for the hardware just about quadruples with that platform so hopefully I can get the R-Pi 2 to work for me.

Once I get a stable multichannel audio platform working under Linux I will start to compile and test the plugins.

If you have some good Linux Fu and want to help me figure out some Pi-2 issues, drop me a line. It would be much appreciated.
 
UPDATE:
I'm currently bogged down trying to get my Raspberry Pi 2 to output multichannel audio. I've been playing around with it using Raspian and so far I'm not all that impressed and I have run into problem after problem. I am planning to install Ubuntu 15.04 MATE and give that a try. If all else fails I will move up to a mini-itx PC (have wanted to try that anyway) but the cost for the hardware just about quadruples with that platform so hopefully I can get the R-Pi 2 to work for me.

Once I get a stable multichannel audio platform working under Linux I will start to compile and test the plugins.

If you have some good Linux Fu and want to help me figure out some Pi-2 issues, drop me a line. It would be much appreciated.

I believe that problem is that the Pi 2 USB shares throughput with the Ethernet. That means it has limited bandwidth for I/O. There is a way to turn off the Ethernet and maximize the available throughput. If I make progress or someone else knows how that may be enough. I have successfully gotten the PI 2 to play a multi-channel per Richard Taylor's instructions but only when the origin file is in the Pi already.

James
 
I finally got the Pi2 to produce some useful audio. I discovered that a miniDSP miniSTREAMER (USB --> SPDIF out) is recognized on boot up, almost like a PNP device. Shows up with aplay -l with a bunch of modes, including the SPDIF out and multichannel modes up to 7.1 audio. The miniSTREAMER also has an SPDIF input, so this could be a way to get SPDIF into the Pi if I want to do that in the future (I have some evil plans that might work with this). I am almost tempted to get a multichannel spdif or I2S input DAC to pair with it, but I think that is the wrong road (see below) for multichannel audio and crossover work.

Using the Pi2+miniSTREAMER I did some extensive listening trials today using VLC as both the send (from another PC) and receive (on the PI) client, multicasting a transcoded (48kHz AAC/MP4 @320kbps) stream. Works like a charm over my LAN with the PI2 connected via a WiPi USB dongle. So my current near term plans for the Pi are to use a pair of them to implement streaming audio for a pair of loudspeakers (with one PI in each). This will be added to the input of the existing system of: SPDIF input --> miniDIGI --> miniDSP 2x4 --> multichannel amplifiers. That's a lot of hardware!

For the multiway LADSPA crossover client, It seems now very likely that I will throw in the towel with the Raspberry Pi and go with the mini-ITX computer that I have been eyeing. It has onboard 7.1 audio via Realtek ALC892 Audio Codec with analog audio output jacks on the rear panel. The system should be able to handle both streaming audio and the crossover processing with the analog outputs connected directly to the amps. I have seen rightmark testing of the audio from the board and it looks better than many computer sound implementations, and perfectly acceptable for my needs. I think I can put together the system hardware for about $200 and will use the new Ubuntu distro.
 
Did you see this Apr 12, 2015 comment on Taylor's page:

"A good alternative is to send the audio over hdmi. AFAIK there is no alsa driver that can output 6-ch audio directly to hdmi on the Pi, but you could pipe the audio from ecasound to omxplayer, which does do multi-channel audio (a feature I requested for this purpose)."
Digital Crossover/EQ with Open-Source Software: HOWTO | Richard's Stuff
 
Did you see this Apr 12, 2015 comment on Taylor's page:

"A good alternative is to send the audio over hdmi. AFAIK there is no alsa driver that can output 6-ch audio directly to hdmi on the Pi, but you could pipe the audio from ecasound to omxplayer, which does do multi-channel audio (a feature I requested for this purpose)."
Digital Crossover/EQ with Open-Source Software: HOWTO | Richard's Stuff

I believe I tried using omxplayer to play a multichannel WAV file. It either didn't work, only output 2 channels, or the bit depth was not supported (e.g. 24 bit). I have not seen a report of 24 bit audio working on the pi without downsampling to 16 bits when output is through alsa. All-in-all it's too sketchy for me at this time. I did buy TWO hdmi extractors and I may use the Pi2 for this application in the future, but for now I will be pushing on with some other hardware that I believe will prove to be easier to work with in the short term while I use the Pi2s for streaming audio with SPDIF output.
 
UPDATE:

I purchased and put together a mini-ITX FF system and installed Ubuntu 15.04. After taking a couple of days to get used to the desktop and install and setup various components that were needed I attempted to make some headway on this project.

Today I enjoyed some success on several fronts:
  • I tested out the onboard sound - I'm able to play test files using speaker-test and/or audio via apps to all 8 output channels, or a subset thereof.
  • I figured out how to set up a persistent ALSA loopback device.
  • I tested out ecasound using a test file.
  • I tested out the loopback device by playing to it from an app, set up ecasound to accept that as input, and then had ecasound send that to the onboard sound analog outputs.
I will eventually add ecasound commands to process the audio stream using the LADSPA plugins.

Speaking of the LADSPA plugins, I couldn't get my plugin code to compile successfully, which was a little disappointing. I was able to get Richard's rt-plugins to compile and build into the actual plugin file, so I will have to go back and take a look at my code and re-write it to more closely follow Richard's, at least until I get a better grasp on exactly what is going on within the code.

I'm definitely more confident that I can get this to fly now that I have gotten these things more or less ironed out.
 
UPDATE:

Today I finally got the code up and running for the ACD LADSPA plugin. The plugin implements the full set of filters I outlined in this post, which have been adopted from my ACD tools. Eventually my plan is to build functionality into ACD that will spit out the filter tool chain that can be used in ecasound, much like the miniDSP "advanced biquad" transfer function coefficients are listed for each driver, and for the system, in the current version. My vision is to make it possible for people to do what can currently be done using a miniDSP crossover (2x4, 2x8, 4x10, etc.) on a linux computer and on a Raspberry Pi (once multichannel audio is better supported).

Anyway, I need to do more testing, and then try to implement some new code, before this is really "done done".
 
Last edited:
Member
Joined 2007
Paid Member
Wow! ...am I glad to have found this thread! I need to talk to people like you all. Very fine and interesting work!

Background (please forgive any stating of the obvious):
I'm a motivated Linux noob! :D I have been working with Beaglebone Black (BBB). [BBB background] Two of its advantages for audio are a) it accepts external clocks and b) it offers direct output of I2S via GPIO pins. With four serializers it can output 8 channels of I2S or four channels of DSD. Development work on bit-perfect output is well along. A Debian kernel (called 'Botic'), an isolation cape (called Hermes) and a clock interface (called 'Cronus' - all from Twisted Pear Audio) have been developed to interface with BBB and switch the system clock between one of two high-quality external clocks that match the frequency multiple of the source music file. I have found that the elimination of 44.1/48 resampling really cleans up the sound into my ES9018-based asynchronous DACs.

Meanwhile, advances in free 'headless' player software are getting impressive, with Volumio, RuneAudio, Squeezelite, etc. For example, Volumio will not only serve from a NAS, but will accept any number of server streams like Spotify, accepts AirPlay streams, and allows a wide range of devices to control it. So these little 'headless' players have huge potential as multi-function audio appliances. So - that's the 'Kool-Aid' I'm on... :p

My situation: I need to retire my PC-based player/server, which had nice IIR third-order filters for a bi-amped 2-way system. That source was OK, but resampled everything to 96 kHz. I am hopeful that the 1GHz A8 TI SOC of the BBB can run a pair of IIR 2nd-order filters and one delay filter for my system. Richard Taylor's MPD->Ecasound pipe fixes the sample rate at 44.1kHz, which I would like to avoid. That might be avoided using ALSA plugins that engage LADSPA filters directly, without needing a higher-order user layer like Ecasound.

One question I have is whether the LADSPA hi- and low-pass filters absolutely require a fixed operating frequency, because ideally that should remain untouched all the way out to the DAC. On the one hand, IF the corner frequency shifted somewhat between 44.1 and 48kHz sources, that would be no problem for my speakers because my woofers and midrange are flat over a considerable frequency range. On the other hand, if a file formatted at 96kHz is in the play queue... Trouble? :eek:

Right now: I'm in early stages of the learning curve - fighting to get the Debian Music Player Daemon (used by Botic and Volumio) to output into ANY pcm plugs specified in ALSA's group of configuration files. Fingers crossed that hurdle can be passed, so I can then answer some of the basic LADSPA implementation questions and consider the compromises. Eventually, Charlie's elegant filters might be just the ticket!

Conclusion: Anybody have experience with MPD output to ALSA? [Please don't hesitate to send PM, if you like.]

Best,

Frank
 
Hi Frank,

Let me address a couple of questions you raised:

Richard Taylor's MPD->Ecasound pipe fixes the sample rate at 44.1kHz, which I would like to avoid. That might be avoided using ALSA plugins that engage LADSPA filters directly, without needing a higher-order user layer like Ecasound.
I wasn't sure exactly why Richard did this (use 44100 sampling rate). I believe ecasound has to know the rate, and you either have to feed it an audio file type that has a header with rate information or you have to tell it what the rate is using the -f option. There is no inherent rate limitation to ecasound that I am aware of. I believe that Richard was using a USB based multichannel sound card, and THAT was limited to 44.1k for multi (e.g. 6) channels.

One question I have is whether the LADSPA hi- and low-pass filters absolutely require a fixed operating frequency, because ideally that should remain untouched all the way out to the DAC.
No, see my answer above. LADSPA plugins are passed the sampling rate by the calling program (e.g ecasound). The plugin re-calculates the filter each time it is invoked, because a new set of filter parameters or a different sampling rate may apply.

Anybody have experience with MPD output to ALSA? [Please don't hesitate to send PM, if you like.]

I have been experimenting with VLC and ecasound and perhaps this approach might work for MPD as well. In order to be able to use use VLC to play audio what I did was create an ALSA loopback device. After rebooting this appeared (under Ubuntu) in VLC's list of audio output devices. I can play a file or stream to one subchannel of the loopback device and then select the other subchannel as an ALSA input to ecasound.
 
Member
Joined 2007
Paid Member
Thanks so much for the reply, Charlie!

The plugin re-calculates the filter each time it is invoked, because a new set of filter parameters or a different sampling rate may apply.

Let's say one removed the sample rate specification from Richard Taylor's MPD output pipe, and then used your LADSPA filters in ecasound. Now imagine a typical playlist with files of various file types and sample rates... Does ecasound receive the file parameters that would allow the filters to re-calculate for each successive output file? That would be pretty sweet because it would avoid MPD's problematic ALSA interface (it enlists 'dmix' - very prone to unwanted resampling - unless you use ALSA inputs 'hw:0,0' or 'plughw:0,0'.

In order to be able to use use VLC to play audio what I did was create an ALSA loopback device.
Loopback was an option I was considering, but a simple pipe seems hard to beat if the filters would adapt within ecasound! If there is a chance of that then I should try to get a pipe to ecasound working without resampling. [The 'filter adaptation' part is way over my head, though. :eek: ]

I don't want to hijack this thread, so I will be watching it with great interest. With any kind of success, it might be worth opening a BBB-specific thread, where your input would be huge! Many thanks!

Frank
 
Thanks so much for the reply, Charlie!



Let's say one removed the sample rate specification from Richard Taylor's MPD output pipe, and then used your LADSPA filters in ecasound. Now imagine a typical playlist with files of various file types and sample rates... Does ecasound receive the file parameters that would allow the filters to re-calculate for each successive output file? That would be pretty sweet because it would avoid MPD's problematic ALSA interface (it enlists 'dmix' - very prone to unwanted resampling - unless you use ALSA inputs 'hw:0,0' or 'plughw:0,0'.

Loopback was an option I was considering, but a simple pipe seems hard to beat if the filters would adapt within ecasound! If there is a chance of that then I should try to get a pipe to ecasound working without resampling. [The 'filter adaptation' part is way over my head, though. :eek: ]

I don't want to hijack this thread, so I will be watching it with great interest. With any kind of success, it might be worth opening a BBB-specific thread, where your input would be huge! Many thanks!

Frank
Ah don't worry about it (threadjacking). This is all related to how to implement everything, so it's more or less on topic.

Info on piping stdout to ecasound: Ecasound examples
Also it's helpful to RTFM: Ecasound man pages

Post about your results/findings (good or bad) if you do some experimenting!
 
I have been experimenting with VLC and ecasound and perhaps this approach might work for MPD as well. In order to be able to use use VLC to play audio what I did was create an ALSA loopback device. After rebooting this appeared (under Ubuntu) in VLC's list of audio output devices. I can play a file or stream to one subchannel of the loopback device and then select the other subchannel as an ALSA input to ecasound.

MPD can be compiled with pipe output, and I think most of distribution has it compiled with pipe output. I had use it to pass the stream directly to SOX or brutefir. It don't needs a alsa loopback to pass the audio stream.

@francolargo - defining alsa hw in mpd is the proper way to define a bit perfect playback chain. in order to avoid confusion you can use alsa device alias and use the name eg: hw:X20:0
 
To run ecasound chain with with specific configuration for various samplerates - alsa offers the file plugin ALSA project - the C library reference: PCM (digital audio) plugins which allows piping a wav/raw stream to any external program. The program can be started with params providing actual samplerate, bits per channel, channel count, sample format. All it takes is a simple script.

A device using the plugin can be configured in .asoundrc and its name can be listed in the alsa section of mpd.conf.
 
Member
Joined 2007
Paid Member
Thanks for the above comments and hints! Two questions from low on the learning curve:

* I'm giving the ALSA filter implementation method a try, using a 'type hw' device alias for MPD output. In ALSA I don't see a way to apply one filter type to more than one channel. My confusion arises because pulse code modulated stereo signals alternately transmit left and right channel data, and it seems wasteful to initiate a separate filter for the left and right halves of a stereo pair. In contrast, with one command line Ecasound seems to apply one filter to stereo pairs. I want the best CPU efficiency, and six individual ALSA filters for a 2-way crossover (high, low, delay) seems potentially redundant. Using the same LADSPA filters, would ecasound be more efficient than ALSA?

Related: In ALSA.conf, is there a way to specify more than one input and output channel bindings, so each filter in a chain is processing stereo? If so, example syntax? :eek:

* Looking at the results of the 'analyseplugin' command for my current LADSPA filters, I see some have 'activate() functions'. Is that a trigger for parameter recalculation mentioned above? :rolleyes:

cheers,
Frank
 
Member
Joined 2007
Paid Member
With all three stereo pairs getting different filters, Ecasound was using about 20% of the processor. Ran fine, sounded good.

Great! However, I'm hoping to hot-rod the BBB to adapt to native files up to 96kHz/24bit. It has a floating point co-processer and seems possible if resampling is avoided, but in the end I'm sure everything will matter.

F.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.