Raspberry Pi with Piano2.1 DAC DSP and Volumio2

Thanks for the URL, I'll have a look at it. BruteFir2 also has up sampling in the plugin. I typically stay with one sample rate (48KHz) as I move between a PC and the RPI to compare the filters.
Just a bit additional info; it uses brutefir and sox and the usual suspects under the hood, but what I like more and more is the flexibility. If I upload just a 48KHz filter and activate upsampling 48->96 and also 48->192 I can test the sound of 48, 96 and 192 by just selecting the relevant song on the client (so, within seconds), they're all available. If I want to test the difference between 2 filters I can upload both and again switch in seconds. And also the possibility to try the different clients with the same convolving is great. But yea, many options these days :)
 
Hi DonVK, thank you! I won't have much time to play around this week, but might be posting here for some more help next weekend... Quick question: what is the purpose of the "click remove" block in the subwoofer PWF? Also, what do the different output multipliers (4x, 8x, etc) represent? Finally, in the past you seem to have mentioned a Java app for converting the output files to bin format, is that available still?
 
Last edited:
The sample files are what Allo gave me. They are very useful because if your tool process is working you should be able to replicate the stock bin files. They also have embedded configurations to allow you to generate the suite of sample rate files for a given design.

I use a java converter to translate TI "cfg" to Allo "bin" files. I like to develop on a single platform and my TI GDE license runs on Windows. The converter is in this thread at Raspberry Pi with Piano2.1 DAC DSP and Volumio2

The 1x,4x,8x output muxes are used to "oversample" outputs. They are referenced to the base sample clock. So if base=44.1KHz, the selecting 8x would update the output interpolation filter at 352.8KHz.

When you are designing low freq filters you need to be careful about how the filter coefficients are represented. You should use extended precision, but it looks like Allo used default precision. At LFs, the coeffs are nearly =1 (ie. 0.99999754) and any rounding error will cause the filter to act like an integrator. So the outputs will slowly saturate (DC shift) and "bounce" against the min/max output causing noise. I think that is why the click block was put in. I have simulated the LP IIR filters with "rounded" coeffs and that is the behaviour I see. When I get a better solution for sub outputs I'll post it.
 
Starting software DSP.

I've been primarily using Volumio in stock form. I does everything I need out of the box (supports Piano2.1, connects to my NAS, supports web radio) and its headless and I like it.

However I would like to start adding some DSP processing. Primarily to EQ a speaker (ecasound ?) and to EQ the room (Brutefir ?).

The question is "can I wedge this stuff underneath Volumio". The problem is my Linux knowledge is very limited. Volumio's architecture Technical Overview * Volumio looks like it has mpd, alsa, and sox. So from what I've gleened on other threads its a starting point.
 
Remote access to the RPI

I'm going to list steps, as a way of "talking out loud" in order to get help when I stumble.

I need remote network access to the RPI to configure it and transfer files to it without having a keyboard and monitor attached.

It seems Volumio does not enable the SSH server by default. So...

Step#1 On the PC install the free SSH client (BitVise https://www.bitvise.com/) on RPI add an empty SSH file ("/Boot/ssh" ) to wake up the SSH server. Reboot.

Step#2 Lock the RPIs IP address on the router with DHCP reservation. I actually use a wired connection for this because its faster than the pi's wifi.

Step#3 Start BitVise and log into the RPI. It looks like the pic below, you get a Bitvise window, a RPI terminal window, SFTP file browser, and the Volumio page.
 

Attachments

  • bitvise volumio desktop reduced.jpg
    bitvise volumio desktop reduced.jpg
    222.4 KB · Views: 591
Missing system tools

I've already read a number of threads from Charlie Laub, and PhofMan and visited Richard Taylors site Digital Crossover/EQ with Open-Source Software: HOWTO | Richard's Stuff as well as Charlie's site software to know that a few tools are required. So this is what I installed that seems to be required to build the tools from Charlie and Richard. The instructions on those sites are clear but I think they assume you have a fuller featured build like Raspbian.

Step#1 Install compilers and make utility
"sudo apt-get update"
"sudo apt-get install build-essential gcc automake1.9 libtool flex bison gdb"
"sudo apt-get install cmake

Step#2 Install "htop" to monitor cpu core use
"sudo apt-get update && sudo apt-get install htop"
 
Last edited:
Installing the DSP tools and plugins

At this point ecasound and associated plugins need to be installed. I'm assuming the compile tools needed are already installed from previous posts. I don't really know what plugin subset I'll use, so I'll just load a bunch.

Step#1 from RT's site get ALSA, ecasound, etc

Get alsa drivers and utilities
"sudo apt-get install alsa alsa-base alsa-utils alsa-tools libasound2-plugins"

Get ecasound
"sudo apt-get install ecasound"

Get ladspa sdk headers
"sudo apt-get install ladspa-sdk"

Get computer music toolkit
"sudo apt-get install cmt"

Get Steve Harris's plugins
"sudo apt-get install swh-plugins"​


Step#2 Get plugins from Richard Taylor's site, I use a PC to download the file "rt-plugins-0.0.6.tar.gz" and bitvise to transfer it to the pi

Extract the files from the tar
"tar -xvf rt-plugins-0.0.6.tar.gz"

Go into the build subdirectory, and compile
"cd rt-plugins-0.0.6"
"cd build"
"cmake .."
"make"

Install the Rtaylor plugins (will auto go into /usr/local/lib/ladspa)
"sudo make install"​

Step#3 Get Charlie Laub's LADSPA plugins from his site

Get the tar file (LAUB-LADSPA-PLUGINS-11JUN2016.tar) I used my PC and downloaded it, then transferred to over to the pi with bitvise sftp
, make a directory for the tar, transfer the tar, then

Extract tar using
"tar -xvf LAUB-LADSPA-PLUGINS-11JUN2016.tar"

Compile the plugins, go into each subdirectory (mTAP, OnOffDelay, ACDf_v2.0) and type
"cd LAUB-LADSPA-PLUGINS-11JUN2016
"cd mTAP"
"make -f Makefile
repeat for each subdirectory​


Step#4 Check to see what plugins you have, list the plugins. There should be approx 90 of them.
"listplugins"​
 
Locating plugins + list

Forgot a step in the last post.

The system needs to find the plugins.

"cd /home/volumio"
"nano .profile"

Add this line to the end of the .profile file

export LADSPA_PATH=/usr/local/lib/ladspa:/usr/lib/ladspa

Save and close the file and reboot​


And for completeness the list of plugins from "listplugins".
 

Attachments

  • plugins1.jpg
    plugins1.jpg
    299.8 KB · Views: 510
  • plugins2.jpg
    plugins2.jpg
    332.4 KB · Views: 496
  • plugins3.jpg
    plugins3.jpg
    162.6 KB · Views: 507
Checking the soundcard, ecasound, plugins

We should check if things are installed and working at this point.

To see how the Piano2.1 is named use the following. You should see a listing like pic#1.

"aplay -L"​

To test the soundcard using a built in test file (says "right-left-right...") use the following. It has l=2 (2 loops) and c=2 (2 channel stereo) and use the test files (-t). Should look like pic#2.

"speaker-test -D plughw:pianoDACPlus,0 -l 2 -c 2 -t wav"​

To test ecasound is installed and working using some built in functions ecasound - manned.org . I've included a short sample file that can be placed at /home/volumio or you can use any wav for mp3 file. There are ton of options and this is stripped with only file input (-i:) and alsa output (-o:). Should look like pic#3

"ecasound -i:xylophones.mp3 -o:alsa,plughw:pianoDACPlus"​

To hear a difference, that processing is being done. This adds reverb 120ms, with amplification 150%

"ecasound -i:xylophones.mp3 -o:alsa,plughw:pianoDACPlus -etr:120,10,60 -ea:150​

This adds reverb 120ms with a pitch shift down of 90%.

"ecasound -i:xylophones.mp3 -o:alsa,plughw:pianoDACPlus -etr:120,10,60 -ei:90"​

To test ecasound with a LADSPA plugin. I found this at Ecasound Examples and it produces a metronome. Use [ctrl][c] to stop it.

"ecasound -i:null -o:alsa,plughw:pianoDACPlus -el:sine_fcac,880,1 -eemb:120,10 -efl:2000"​
 

Attachments

  • aplay-L listing.jpg
    aplay-L listing.jpg
    142.1 KB · Views: 462
  • xylophones.zip
    211.3 KB · Views: 90
  • ecasound test.jpg
    ecasound test.jpg
    275.7 KB · Views: 125
  • speaker test.jpg
    speaker test.jpg
    204.5 KB · Views: 124
conflicts RT filters and sine.so causing "double free error"

I trying more of RT's filters, they worked but I was getting a "double free corruption" error (see pic). Its a known issue listed in RT's site Richard Taylor -- Thompson Rivers University and the solution is to remove sine.so

Code:
 sudo -rm -f /usr/lib/ladspa/sine.so

Then you can play something like this error free.

Code:
 "ecasound -i:xylophones.wav -eadb:3 -el:RTlr4lowpass,1500 -o:alsa,hw:PianoDACPlus
 

Attachments

  • double free corruption from sine RT.jpg
    double free corruption from sine RT.jpg
    164.8 KB · Views: 766
Adding loopback and ecasound script files

It seems that whenever you touch the Volumio Playback options, it will auto generate a new /etc/mpd.conf file. So anything placed in that file could be overwritten, so if you mod it, make a copy.

There are many threads like ecasound in MPD - problem of Device or resource busy and NEW: the Active Crossover Designer for ecasound/LADSPA (ACD-L) - Techtalk Speaker Building, Audio, Video Discussion Forum, most of these are sourced by Charlie Laub (CL), that recommend an ALSA loopback and that looks reasonable. The strategy being [MPD]->[Loopback]->[Ecasound]->PianoDAC.

In the edit (nano) file "/etc/modules" and add line "snd-aloop" and it should look like this. Then reboot Volumio, and you will have another sound card called "Loopback" that you can select in the Volumio Playback menu, or you can pick "Piano2.1" as before. However, the soundcard numbering has changed as shown in the pic below. It still plays as normal via the Piano2.1 at this stage.

Code:
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-dev
snd-aloop

My /etc/mpd.conf after reboot contains this. Notice the Piano2.1 is still selected but this time its soundcard#2 :

Code:
# Audio Output ################################################################

resampler {      
  		plugin "soxr"
  		quality "high"
  		threads "1"
}

audio_output {
		type		"alsa"
		name		"alsa"
		device		"hw:2,0"
		dop			"no"
		
		format      "44100:16:2"

}

The ecasound files are getting more complex than a single line and you can put them in an executable file. These scripts exist at /usr/local/bin and must be executable (chmod 777 file). Ecasound's parser is picky, so I use windows Notepad++ editor to see all the spaces and hidden characters. A space in the wrong spot causes it to spew error messages, sometimes not related to source of the problem.

The following is a simple ecasound file. Its located at /usr/local/bin/ecatest4. It's a single chain called "test4", that bandwidth limits 20Hz-16Khz, and 3 parametric equalizers. From the command line "ecatest4" will run it and you'll hear the xylophones. It's easy to change the parameters to check that its working.

Code:
#!/bin/bash

# test file input + filters 

ecasound \
	-n:test4 -a:1 \
	-f:s16_le,2,44100 \
	-i:/home/volumio/xylophones.wav \
	-el:RTlr4hipass,20 \
	-el:RTlr4lowpass,16000 \
	-el:RTparaeq,3,30,2.8 \
	-el:RTparaeq,2,1000,2.8 \
	-el:RTparaeq,-2,5000,2.8 \
	-a:1 \
	-f:s16_le,2,44100 \
	-o:alsa,hw:CARD=PianoDACPlus,DEV=0
 

Attachments

  • soundcards after loopback.jpg
    soundcards after loopback.jpg
    202.4 KB · Views: 760
Last edited:
Connecting loopback ...... and we're stuck

I selected Loopback in Volumio playback options and checked the /etc/mpd.conf which looked what I expected. My Loopback is card#0, and Volumio takes device#0 as loopback input.

Code:
# Audio Output ################################################################

resampler {      
  		plugin "soxr"
  		quality "high"
  		threads "1"
}

audio_output {
		type		"alsa"
		name		"alsa"
		device		"hw:0,0"
		dop			"no"
		
		format      "48000:32:2"

}

Then check the output of Volumio by capturing the loopback output with Volumio playback off, then on again. When playback is off I get a file of "nulls" , and when playback is on I get a file of random stuff. So The loopback appears to work.

Code:
arecord -f S32_LE -c2 -r48000 -v -d 5 -D hw:0,1 check.wav

Then I stopped Volumio playback, and tested access to the piano with this and it worked fine.


Code:
#!/bin/bash

# test file input + filters 

ecasound \
	-n:test4 -B:rt -a:1 \
	-f:s32_le,2,48000 \
	-i:/home/volumio/xylophones.wav \
	-el:RTlr4hipass,20 \
	-el:RTlr4lowpass,16000 \
	-el:RTparaeq,3,30,2.8 \
	-el:RTparaeq,2,1000,2.8 \
	-el:RTparaeq,-2,5000,2.8 \
	-a:1 \
	-o:alsa,hw:PianoDACPlus,0

Then switched ecasound input to use the loopback output using this.
Code:
#!/bin/bash

# test file input + filters 

ecasound \
	-ddd -n:test5c -B:rt -a:1 \
	-f:s32_le,2,48000 \
	-i:alsa,hw:Loopback,1 \
	-el:RTlr4hipass,20 \
	-el:RTlr4lowpass,16000 \
	-el:RTparaeq,3,30,2.8 \
	-el:RTparaeq,2,1000,2.8 \
	-el:RTparaeq,-2,5000,2.8 \
	-a:1 \
	-o:alsa,hw:PianoDACPlus,0


Turned on Volumio playback, started ecasound and "nothing" except an audio blip that hints of something being connected. Checked ecasound using interactive mode with debug option (-c -ddd) and there are no errors. Checked aio-status and the buffers seem to be working / moving / delay variations.

So I'm stumped (with limited Linux knowledge) and could use another set of eyes on this and some suggestions.
 
Last edited:
Working loopback and ecasound... fixed

I have a working solution now.

I don't understand why the syntax appears to be different for addressing the loopback and the soundcard within the script. I don't understand why ecasound didn't throw errors before and it worked for files. I don't like hardcoding card numbers but labels don't work here. Complaints aside, this script does work, and it opens a lot of possibilities with LADPSA plugins. The ecasound filters and parametric equalizers are working, no xruns. Sounds good.

I have temporarily broken the volume control on Volumio during loopback. I think its because I switched Volumio playback device = loopback, and it lacks an associated volume control (mixer) for now. So in the interm I use the alsamixer volume controls. Its also the only place I can access the subwoofer volume controls.

I added some CPU loading snaps for webradio and mp3 over NAS. Lots of capacity left.

Code:
#!/bin/bash

# test file input + filters 

ecasound \
	-ddd -B:rt \
	-n:test5f -b:256\
	-f:s32_le,2,48000 \
	-i:alsahw,0,1 \
	-el:RTlr4hipass,20 \
	-el:RTlr4lowpass,18000 \
	-el:RTparaeq,3,30,2.8 \
	-el:RTparaeq,2,1000,2.8 \
	-el:RTparaeq,-2,5000,2.8 \
	-o:alsahw,2,0
 

Attachments

  • ecasound web radio htop.jpg
    ecasound web radio htop.jpg
    181.4 KB · Views: 737
  • ecasound mp3@320kbps NASjpg.jpg
    ecasound mp3@320kbps NASjpg.jpg
    191.7 KB · Views: 723
... adding more loopbacks

Now that ecasound is connected, I need another loopback. After much googling and reading.

The signal flow plan is [mpd] -> loopback -> [ecasound] -> loopback -> [brutefir] -> PianoDAC. The speaker is equalized using ecasound (done), then once the FR is flat, the phase (or room) is corrected using a rephase FIR filter with brutefir. I realize it can all be done in one step with the convolution engine, I just find it easier to separate the amplitude correction from the phase / room correction. It also lets me listen to incremental improvements.

It always seems that there are many places to do anything in Linux. I found that adding a line to /etc/modprobe.d/alsa-base.conf does the trick. You get the following soundcard list. I now have 2 loopback soundcards and I changed the index# to be after the physical soundcards.

Code:
options snd_aloop enable=1,1 index=2,3 id=EcaLoop,BfLoop
 

Attachments

  • multiple loopbacks.jpg
    multiple loopbacks.jpg
    135.7 KB · Views: 712
... adding Brutefir to the path

I have a working path [mpd]->loopback->[ecasound]->loopback->[brutefir]. Loopback#1 is selected via Volumio as playback device. I'm using web radio as a source.

I'm still messing with settings on Brutefir but using a known working FIR filter for phase correction. The filter is a mono 32b float, 16384 taps, at 48Khz using on both the right and left channels.

Ecasound now has 8 * para eqs + 1 * LR4 HP + 1 * LR4 LP running.

The RPI + Piano2.1 are in plastic box, cpu_temp=61C steady state. The CPU load is still reasonable, shown in the pic. There are also 4 Bitvise SSH +SFTP sessions running as I need 4 console windows to manually start and monitor at this stage.
 

Attachments

  • bruteifr + ecasound cpu load.jpg
    bruteifr + ecasound cpu load.jpg
    187.8 KB · Views: 181
Last edited:
Brutefir configuration

I forgot to mention the install for Brutefir. I've played a bit with the Volumio plugin Brutefir2 but had some issues with it. The Brutefir docs and other examples I based this on at :
- BruteFIR
- Setting up BruteFIR
- [Guide] High quality room correction with Raspberry Pi & Roon - Raspberry Pi - Roon Labs Community

I put everything related to Brutefir in /home/brutefir.

Code:
mkdir /home/brutefir
cd /home/brutefir
sudo apt-get install brutefir 
nano brutefir_config

If you don't have a filter, or you're debugging a configuration you can use a built in filter file called "dirac pulse" in place of your filter coefficient file below. It does not affect the sound output, and uses the filter length (#taps) and sample rate specified in the config file.

Code:
coeff "c-l" {
   filename: "dirac pulse";
   format: "FLOAT_LE";
};

Information on the accepted filter coefficient file is hard to find. I use RePhase to generate the filter file and it has multiple formats as well. After trying a few times it appears that Brutefir needs a raw file like Rephase *.bin or *.dbl formats, and they should be mono format. Even a *.wav file "might" work as long as you can get the right offset to skip the header, otherwise the header will become part of your filter.;). The tap length, data format, and sample rates all must be explicitly stated. Brutefir uses floating point internally, so I give it floating point filter coefficients, the I/O s32_le are converted by Brutefir. The config file I used as follows:

Code:
## BruteFir config   ##

float_bits: 32;             # internal floating point precision, 32b or 64b
sampling_rate: 48000;       # sampling rate in Hz of audio interfaces
filter_length: 16384,4;     # length of filters, divided into 4 partions
#config_file: "~/.brutefir_config"; # standard location of main config file
overflow_warnings: true;    # echo warnings to stderr if overflow occurs
show_progress: false;       # echo filtering progress to stderr
max_dither_table_size: 0;   # maximum size in bytes of precalculated dither
allow_poll_mode: false;     # allow use of input poll mode
modules_path: ".";          # extra path where to find BruteFIR modules
monitor_rate: false;        # monitor sample rate
powersave: true;            # pause filtering when input is zero
lock_memory: true;          # try to lock memory if realtime prio is set
sdf_length: 31,9;           # sinc subsample filter half length in samples, kaiser window
safety_limit: -2;           # abort if output > safety limit, if non-zero max dB
convolver_config: "/home/brutefir/brutefir_convolver"; # location of convolver config file
logic: "cli" { port: 3030; };  # attempt to access the command line ** failed ***

## COEFF DEFAULTS ##

coeff "c-l" {
   filename: "mono48Kieee32b.bin";
   format: "FLOAT_LE";
};

coeff "c-r" {
   filename:"mono48Kieee32b.bin";
   format: "FLOAT_LE";

## INPUT DEFAULTS ##
#
input "left_in", "right_in" {
        device: "alsa" { device: "hw:3,1"; ignore_xrun: true; };
        sample: "S32_LE";
        channels: 2/0,1;
        mute: false,false;
};

## OUTPUT analog
#
output "left_out", "right_out" {
        device: "alsa" { device: "hw:1,0"; ignore_xrun: true; };
        sample: "S32_LE";
        channels: 2/0,1;
        dither: false;
};

## FILTER DEFAULTS ##

filter "PhaseCorr_l" {
   from_inputs: "left_in"/3;    # attenuate input -3dB
   to_outputs: "left_out";
   process: -1;                 # auto assign process load balance on multicore
   coeff: "c-l";
};

filter "PhaseCorr_r" {
   from_inputs: "right_in"/3;   # attenutate input -3dB
   to_outputs: "right_out";

Run "brutefir brutefir_config" in the /home/brutefir directory and it will generate a "brutefir_convolver" file specific to the RPI.
 
running Brutefir and Ecasound at startup

I added brutefir and ecasound to /etc/rc.local so they run on startup. This is the /etc/rc.local file.

Code:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing

# start brutefir 

cd /home/brutefir
brutefir /home/brutefir/brutefir_config5 &

# start ecasound,  must start in "-q" quiet mode, so no terminal is reqd

/usr/local/bin/ecatest7.sh &

exit 0

The /home/brutefir/brutefir_config is the same as the previous post. Note that the ecasound script now uses ecasound in "quiet" mode otherwise a terminal window will be required for its output. This is /usr/local/bin/ecatest7.sh script.

Code:
#!/bin/bash

# OmniV5 equalization, start in quiet mode for rc.local 
# input from mpd via EcaLoop (#2) and output to BfLoop (#3) then to Piano
/usr/bin/ecasound \
	-q \
	-B:rt \
	-n:OmniV5eq -b:256\
	-f:s32_le,2,48000 \
	-i:alsahw,2,1 \
	-el:RTlr4hipass,18 \
	-el:RTlr4lowpass,18000 \
	-el:RTparaeq,5,31,4.3 \
	-el:RTparaeq,3,40,4.3 \
	-el:RTparaeq,3,1000,4.3 \
	-el:RTparaeq,2,1250,4.3 \
	-el:RTparaeq,1,2500,4.3 \
	-el:RTparaeq,-2,4000,4.3 \
	-el:RTparaeq,-2.6,5000,4.3 \
	-el:RTparaeq,-2,6300,4.3 \
	-o:alsahw,3,0

exit 0
 
Last edited:
Volumio upgrade

I'm always nervous about "updates". So after a system backup, I allowed Volumio to self update to the latest version 2.389.

Much to my relief (surprise?) all the changes that I made remained in tack, and the Volumio update worked with no ill effects.
 
Delay in filters in on-board TI DSP

Hi folks.

I saw some smart-sounding discussion above on setting up filters in PurePath for the Piano 2.1.

I'm interested in doing an active digital crossover[1] on the DSP itself, but I saw the talk about buffer length and got worried, because one thing I need to do is to delay two of the four channels by 6ms.

I'm handy with computers, but not very good with analog sound science or digital logic, so I'm having trouble decoding the TI datasheet for the relevant DAC chip on the Piano. Do those of you who have played around with PurePath and the two PCM5142's know if what I want to do is likely to work?

I understand that a rpi or equivalent has plenty of horsepower to do this kind of thing in software, but I'm not sure how to get access to the BOTH dacs on the Piano that way. Perhaps someone who's got a Piano 2.1 can let me know if all 4 channels are available to ALSA?

Before I send in the money and get boards shipped from India, I was hoping to find out if what I want to do is possible; I know there's no guarantee :)


1: I am making some of these and would like to skip adding the stand-alone DSP unit: LXmini Challenge