CamillaDSP - Cross-platform IIR and FIR engine for crossovers, room correction etc.

Does to new version change the URL? I am getting 404 for the http://localhost:5000/gui/index.html
I do not use your build in releases, because Ubuntu 18.04 does not come with GLIBC_2.29, just 2.27.



What Fedora version do you use with CamillaDSP?


Oh hmm there seems to be something wrong with the zipped version of the backend that is built on the Github servers. But I don't get 404, just a blank page. I'll have to investigate (it works when I build it locally).

EDIT: No it actually works fine, just the browser had an old index.html in the cache, which made it try to look for the wrong .js-files. Did you get the .zip of the backend or just clone the repo? If you clone you don't get the frontend since it lives in a separate repo. It's built and added automatically to the zip. Here it's fine to use the release zip since it not compiled machine code a so doesn't depend on any glibc or such. It's all python or javascript.


I use Fedora 32, both on the computer I use for development and on the one I use for listening to music.
But the releases on Github are built on the Github servers. The linux version is built on Ubuntu 19.10.
 
Last edited:
I finally got all the dependencies installed on picoreplayer. It wasn't easy. numpy and matplotlib were problematic; I had to downgrade pip and do some other tricks.

tc@piCorePlayer:~/camillagui$ pip list
Package Version
----------------- ---------
aiohttp 3.6.2
async-timeout 3.0.1
attrs 20.2.0
camilladsp 0.3.0
camilladsp-plot 0.3.0
certifi 2020.6.20
chardet 3.0.4
cycler 0.10.0
idna 2.10
idna-ssl 1.1.0
kiwisolver 1.2.0
matplotlib 3.3.1
multidict 4.7.6
numpy 1.19.1
Pillow 7.2.0
pip 20.2.2
pyparsing 2.4.7
python-dateutil 2.8.1
PyYAML 5.3.1
setuptools 50.3.0
six 1.14.0
typing-extensions 3.7.4.3
websocket-client 0.57.0
wheel 0.35.1
yarl 1.5.1

But when I try to start the gui I get this :

tc@piCorePlayer:~/camillagui$ python3 main.py
Traceback (most recent call last):
File "main.py", line 5, in <module>
from routes import setup_routes, setup_static_routes
File "/home/tc/camillagui/routes.py", line 1, in <module>
from views import get_param, set_param, eval_filter, eval_filterstep, eval_pipeline, get_config, set_config, config_to_yml, yml_to_json, validate_config, get_version, get_gui_index
File "/home/tc/camillagui/views.py", line 3, in <module>
from camilladsp_plot import plot_pipeline, plot_filter, plot_filterstep
File "/home/tc/.local/lib/python3.6/site-packages/camilladsp_plot/__init__.py", line 1, in <module>
from camilladsp_plot.plot_filters import plot_filters, plot_filter, plot_filterstep, plot_all_filtersteps
File "/home/tc/.local/lib/python3.6/site-packages/camilladsp_plot/plot_filters.py", line 2, in <module>
from camilladsp_plot.filter_eval import Biquad, BiquadCombo, Conv, DiffEq, Gain
File "/home/tc/.local/lib/python3.6/site-packages/camilladsp_plot/filter_eval.py", line 6, in <module>
from matplotlib import pyplot as plt
File "/home/tc/.local/lib/python3.6/site-packages/matplotlib/pyplot.py", line 36, in <module>
import matplotlib.colorbar
File "/home/tc/.local/lib/python3.6/site-packages/matplotlib/colorbar.py", line 44, in <module>
import matplotlib.contour as contour
File "/home/tc/.local/lib/python3.6/site-packages/matplotlib/contour.py", line 17, in <module>
import matplotlib.text as text
File "/home/tc/.local/lib/python3.6/site-packages/matplotlib/text.py", line 16, in <module>
from .textpath import TextPath # Unused, but imported by others.
File "/home/tc/.local/lib/python3.6/site-packages/matplotlib/textpath.py", line 11, in <module>
from matplotlib.mathtext import MathTextParser
File "/home/tc/.local/lib/python3.6/site-packages/matplotlib/mathtext.py", line 27, in <module>
from PIL import Image
File "/home/tc/.local/lib/python3.6/site-packages/PIL/Image.py", line 94, in <module>
from . import _imaging as core
ImportError: cannot import name '_imaging'
tc@piCorePlayer:~/camillagui$
 
There is some issue with PIL (provided by the pillow lib).
Code:
from PIL import Image
  File "/home/tc/.local/lib/python3.6/site-packages/PIL/Image.py", line 94, in <module>
    from . import _imaging as core
ImportError: cannot import name '_imaging'
You could try reinstalling pillow to see if it helps. Then try it by starting python (or ipython if you have it installed) and typing "from PIL import Image".
 
I finally found time to try gadget mode on my RPi4 running standard Raspbian.


Add this at the one of /boot/config.txt:
Code:
dtoverlay=dwc2
Add to the end of /etc/modules-load.d/modules.conf:
Code:
dwc2
Reboot and load the g_audio module:
Code:
sudo modprobe g_audio c_chmask=3 c_srate=96000 c_ssize=4 p_chmask=3 p_srate=96000 p_ssize=4
This sets up a both a playback and a capture stereo device at 96kHz, 32-bits.


Then run CamillaDSP with resampling enabled to match the rates between the Gadget "sound card" and the real one used for playback. The config I experimented with just now looks like this:
Code:
--- 
devices: 
  samplerate: 96000 
  chunksize: 2048 
  target_level: 1024 
  queuelimit: 100 
  adjust_period: 10 
  enable_resampling: true 
  enable_rate_adjust: true 
  capture_samplerate: 96000 
  resampler_type: BalancedAsync 
  capture: 
    type: Alsa 
    channels: 2 
    device: "hw:UAC2Gadget" 
    format: S32LE 
  playback: 
    type: Alsa 
    channels: 2 
    device: "hw:FXAUDIODACX6" 
    format: S24LE3
Then connect a usb cable between the usb-c port of the Pi and some other computer, select the "Audio Gadget" sound card and play some music.

I'm doing that right now and it's working fine. The adaptive resampling takes only about 20-25% of one core.


Next step is to set up the gui on this thing, and maybe make some kind of script to automatize the whole process...
 
Great work. Does your code log by how much the gaudio (= USB host) rate differs from the soundcard one? Might be interesting, thanks.
Yes it measures the capture rate but not in a very precise manner. It's mostly mean to catch sample rate changes, 44100 -> 48000 etc.
I ran a simple test of 1000 seconds, gadget at 96 kHz (10 seconds per point):
96k_rate.png


The rate was logged by this little script:
Code:
import sys 
import time 
from camilladsp import CamillaConnection 
 
host = sys.argv[1] 
port = int(sys.argv[2]) 
 
interval = 10000 
cc = CamillaConnection(host, port) 
cc.connect() 
cc.set_update_interval(interval) 
 
while True: 
    time.sleep(interval/1000.0) 
    print(cc.get_capture_rate_raw())
 
The long-term average of 95,999Hz looks reasonable and plausible figure, thanks.
It would be great to be able to fine-tune the rate of the Gadget, do you know if anyone is working on that?



I noticed that the Gadget behave a bit strange when disconnected or the sender isn't playing anything. It looks like everything is just fine (state is Running), but reading from it gives I/O Error after something like 10 seconds. Maybe this is how it's meant to be. I put in a check for this in CamillaDSP so it can recover as soon as there are samples coming again.
 
It would be great to be able to fine-tune the rate of the Gadget, do you know if anyone is working on that?

It's being worked on by a very skilled guy
Re: usb:gadget:f_uac2: EP OUT is adaptive instead of async - Ruslan Bilovol

Re: usb:gadget:f_uac2: EP OUT is adaptive instead of async - Ruslan Bilovol


I noticed that the Gadget behave a bit strange when disconnected or the sender isn't playing anything. It looks like everything is just fine (state is Running), but reading from it gives I/O Error after something like 10 seconds. Maybe this is how it's meant to be. I put in a check for this in CamillaDSP so it can recover as soon as there are samples coming again.

The existing gaudio code of the gadget has no handling of edge cases. The data flow between an alsa driver and user-space alsa-lib is controlled/timed by snd_pcm_period_elapsed Linux Device Drivers — The Linux Kernel 4.7 documentation . The gaudio driver calls this hook when more than a period of data is consumed/delivered by the USB function. Hence, if no USB stream is running, the method does not get called => alsa stream stuck. Proper handling will require some watchdog timer in the driver or registering some hook at USB disconnect/fail event (if possible).

I've tried to discuss the options at usb:gadget.f_uac2: Options for u_audio.c behavior when UAC2 host is disconnected/idle — Linux USB , no response for now. I will wait for the feedback endpoint with next steps.
 
It's being worked on by a very skilled guy
Re: usb:gadget:f_uac2: EP OUT is adaptive instead of async - Ruslan Bilovol

Re: usb:gadget:f_uac2: EP OUT is adaptive instead of async - Ruslan Bilovol




The existing gaudio code of the gadget has no handling of edge cases. The data flow between an alsa driver and user-space alsa-lib is controlled/timed by snd_pcm_period_elapsed Linux Device Drivers — The Linux Kernel 4.7 documentation . The gaudio driver calls this hook when more than a period of data is consumed/delivered by the USB function. Hence, if no USB stream is running, the method does not get called => alsa stream stuck. Proper handling will require some watchdog timer in the driver or registering some hook at USB disconnect/fail event (if possible).

I've tried to discuss the options at usb:gadget.f_uac2: Options for u_audio.c behavior when UAC2 host is disconnected/idle — Linux USB , no response for now. I will wait for the feedback endpoint with next steps.
This is good news! It works with the asynchronous resampler but it's of course nicer to not have to use it.
The behavior when the stream is stopped is a bit weird but it's not too difficult to get around.
 
... so ready to set Camilla up via GUI... is that OK with a Mac?

//
I'm running the gui on my mac now :)
I used Homebrew. I have not tried with Anaconda but that should also work.
Just follow the instructions here: GitHub - HEnquist/camillagui-backend: Backend server for camillagui


But instead if doing for example "sudo pip3 install numpy" do "pip3 install numpy --user". The "--user" flag tells pip to install the packages under your account, not system-wide. For some reason I could not use the packages after I installed them with sudo, but with --user it's fine.
 
This means I have to compile "stuff"!? I don't have the developer kit on my comp... but I do have a working .py environment... I'll check it out :)

//
No you don't need to compile anything! Just use the beta of 0.3.2: Release v0.3.2-beta3 * HEnquist/camilladsp * GitHub


Also you should get the zipped version of camillagui-backend from the releases, that one is complete with both front- and backend components.



Homebrew and/or pip will probably compile some things for you when installing for example numpy, but that will take care of itself.
 
So I should get Homebrew first? I will need som handholding here :)

//
Yes start with Homebrew. Or do you already have Anaconda?


For Homebrew I just followed the instructions here: The Missing Package Manager for macOS (or Linux) — Homebrew
You just have to copy-paste one line into your terminal.


Once that is done, try installing the dependencies with pip3:
"pip3 install {packagename} --user".
The packages you need are: websocket_client, numpy, matplotlib, aiohttp


Start with this, and then we continue with the camilla stuff!