Sample rate switcher for CamillaDSP

What happens? There will be some error in the CamillaDSP logs, what does it say?
It is now working.

Yesterday I connected up the RCA jacks to the SPDIF on board headers of the MCHStreamer kit, and I flashed it with the SPDIF_Only firmware. Then I changed from from using TosLink to using RCA cables.

Changing from TosLink to RCA should not have made a difference, though. Perhaps cold booting the Raspberry Pi and/or the MCHStreamer was needed, it is hard to tell. I don't see any issues in the log file.
 
  • Like
Reactions: HenrikEnquist
Hi,

I have a small issue, and would greatly appreciate any advice if setrate can be the answer in my case. I need to free up some channels from my surround processor so I can add more subwoofers later in the year. Now I use the active crossover in the processor, and that eats up 6 channels for front LR. I have a Motu Ultralite on order, and would prefer to use the spdif output from my processor. I could add a asrc box between the processor and the Motu to set a constant sample rate, but would greatly prefer if everything runs at native sample rates. The processor (Trinnov amplitude 16) is basically a linux computer, but I have no idea if it can present the sample rate on a usb port so the RP has something to sync to.
Signal would be: processor spdif to Motu spdif, Motu usb to/from RP4 camilladsp, Motu to power amplifiers
Any suggestions?
 
@Stian ,
I would like to state first that I am not familiar with the devices you mentioned and with the use case described.
That said, if I understand correctly, the usb port of the Motu is meant for connection to a computer, so the Motu most likely acts as a peripheral. A USB host port is however required on the source side to use the RPi's USB Gadget as a capture device. Also it is not clear to me what the playback device on the rpi would be, as the Motu has only one usb port.
A possible solution would be using the spdif hat for the rpi mentioned by @HenrikEnquist in post #116, but it is a non-trivial diy project.
 
route the audio from the motu to camilladsp
If you want to route usb audio from the motu to the rpi and use rpi's USB gadget as a capture device, then the motu (not the trinnov) must act as host, but this seems not to be the case.
Most likely, the trinnov features a host-type USB port. If audio can be sent to that port, then you could connect the trinnov directly to the rpi, if that makes sense for you.
If you manage to use the rpi's USB gadget as a capture device, then camilladsp-setrate will work for sure.
 
I got a WiiM Ultra with a USB output, trying to get camilladsp-setrate to work for me. I have setup USB gadget on my Raspberry Pi, and I am able to stream through the USB-C connector to CamillaDSP. However, camilladsp-setrate still is not changing the stream rate. I assume that I have a configuration error, but I am not sure what it is.

I am getting the following error from camilladsp-setrate:

camilladsp-setrate[1162]: fsm_transit WAIT_RESPONSE Fatal error: Event -1 out of range

What does "Event -1 out of range" mean?

Capture Rate appears to be enabled, but I am not sure whether notifications are enabled for it. If they are not, how do I enable them?

amixer -D hw:UAC2Gadget controls outputs the following:

numid=5,iface=MIXER,name='Master'
numid=2,iface=MIXER,name='PCM Capture Switch'
numid=3,iface=MIXER,name='PCM Capture Volume'
numid=1,iface=PCM,name='Capture Pitch 1000000'
numid=4,iface=PCM,name='Capture Rate'

The Capture Rate settings for hw:UAC2Gadget are as follows:

numid=4,iface=PCM,name='Capture Rate'
; type=INTEGER,access=r--v----,values=1,min=44100,max=384000,step=0
: values=44100


Here is a more complete list of the camilladsp-setrate log entries:

-- Boot b0f445c7862e420591942735fe8f699c --
Aug 01 22:36:51 dspserver systemd[1]: Starting camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP...
Aug 01 22:36:52 dspserver systemd[1]: Started camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
Aug 01 22:46:58 dspserver camilladsp-setrate[655]: fsm_transit WAIT_RESPONSE Fatal error: Event -1 out of range
Aug 01 22:46:58 dspserver systemd[1]: camilladsp-setrate.service: Main process exited, code=exited, status=255/EXCEPTION
Aug 01 22:46:58 dspserver systemd[1]: camilladsp-setrate.service: Failed with result 'exit-code'.
Aug 01 22:47:00 dspserver systemd[1]: camilladsp-setrate.service: Scheduled restart job, restart counter is at 1.
Aug 01 22:47:00 dspserver systemd[1]: Stopped camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
Aug 01 22:47:00 dspserver systemd[1]: Starting camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP...
Aug 01 22:47:00 dspserver systemd[1]: Started camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
Aug 01 22:50:48 dspserver camilladsp-setrate[1162]: fsm_transit WAIT_RESPONSE Fatal error: Event -1 out of range
Aug 01 22:50:48 dspserver systemd[1]: camilladsp-setrate.service: Main process exited, code=exited, status=255/EXCEPTION
Aug 01 22:50:48 dspserver systemd[1]: camilladsp-setrate.service: Failed with result 'exit-code'.
Aug 01 22:50:49 dspserver systemd[1]: camilladsp-setrate.service: Scheduled restart job, restart counter is at 2.
Aug 01 22:50:49 dspserver systemd[1]: Stopped camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
Aug 01 22:50:49 dspserver systemd[1]: Starting camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP...
Aug 01 22:50:50 dspserver systemd[1]: Started camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
Aug 01 23:09:02 dspserver camilladsp-setrate[1176]: fsm_transit WAIT_RESPONSE Fatal error: Event -1 out of range
Aug 01 23:09:02 dspserver systemd[1]: camilladsp-setrate.service: Main process exited, code=exited, status=255/EXCEPTION
Aug 01 23:09:02 dspserver systemd[1]: camilladsp-setrate.service: Failed with result 'exit-code'.
Aug 01 23:09:03 dspserver systemd[1]: camilladsp-setrate.service: Scheduled restart job, restart counter is at 3.
Aug 01 23:09:03 dspserver systemd[1]: Stopped camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
Aug 01 23:09:03 dspserver systemd[1]: Starting camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP...
Aug 01 23:09:03 dspserver systemd[1]: Started camilladsp-setrate.service - Automatic Sample Rate Changer Daemon for CamillaDSP.
 
I'm not a c programmer, but I gave it a shot. I tried adding the following after line 52:

writelog(NOTICE, "$received_data\n");

That would not compile. Then I tried the following:

FILE* fp;
fp = fopen ("$HOME/debug.log", "w");
char* data = "$received_data\n";
fputs(data, fp);

That compiled, but nothing is generated in debug.log. If you have a suggestion for making the logging work, I would appreciate it.

Here are some additional observations:

CamillaDSP is detecting the correct sample rate. In the left panel on the CamillaDSP GUI it is showing the correct Capt. samplerate. I stream a song at 96k and it shows "96000". I stream a song at 44.1k and it shows "44100".

The issue is that when Capt. rate does not match samplerate at the top of devices, which I assume is the output samplerate, it starts throwing errors rather than changing the output samplerate.
 
Thank you! Have a nice holiday!

I just now got camilladsp-setrate working!!!

I got the logging to work, sort of, but good enough to figure out what was happening. I noticed in the log file that all of my filter settings were contained in the "received_data", and I have a lot of biquads setup in my configuration, probably between 30 and 40 for each channel. There was a lot of data in the log. Perhaps there was so much data in the "received_data" that it was creating a buffer overflow or something, but this is just a guess on my part.

I then changed to a CamillaDSP configuration with no filters, and camilladsp-setrate is working beautifully.

Next I changed to a CamillaDSP configuration using convolution for equalization. Again, camilladsp-setrate is working beautifully.

I don't know what the limit is for the number of biquads that can be used when using camilladsp-setrate, but you may add a note to the README file explaining that there may be a limit as to the number that can be used.

Again, THANK YOU for providing camilladsp-setrate!!!
 
What does "Event -1 out of range" mean?
The process evolves depending on the current state and on the event occurred. States and events are briefly described in doc/setrate_fsm.pdf.
"Event -1 out of range" means that an event occurred but it was unforeseen and could not be identified. As a consequence, the software does not know how to proceed and exits (the software is not resilient enough to handle unforeseen events).

@phofman, I took a look at the code and yes the error is most likely caused by unexpected data received from CamillaDSP. Thank you for having spotted it out.

@TerryForsythe, you could log the data received from CamillaDSP as follows:
  • add the following line at the top of the file setrate_util.c
#include <libwebsockets.h>
  • add the following line after line #52 of the file setrate_util.c, just before the "return(-1)" statement:
writelog(ERR, "Unexpected data received from CamillaDSP: %s\n", received_data);

Then, please, set the highest log level (--loglevel notice) and attach the resulting log file. This will help identifying at which point in the process the error occurs and, possibly, what caused the error.
 
Last edited:
  • Like
Reactions: TerryForsythe
@TerryForsythe , you wrote your post #133 while I was adding some further notes.
I am really happy you got success with camilladsp-setrate.

As pointed out in the "Final Notes" section, if the configuration file is huge, you need to increase the maximum size of the receive buffer (constant BUFLEN in the file setrate.h). It is currently set to 32768 bytes, but note that the maximum size of the payload is a bit less as some bytes are required for the data header.
 
  • Like
Reactions: TerryForsythe
@TerryForsythe, your guess was right. Your big configuration file caused a buffer overflow.
Note that the limitation does not lie in the number or type of filters, but simply in the size of the configuration file.
Please try to increase the value of the BUFLEN constant in the setrate.h file. The maximum allowed size of the configuration file is a few bytes smaller than the BUFLEN value.
 
Thank you @mevang, and enjoy your holiday!!!

Please don't worry about it. I am fine with convolution.

But, if you want me to do some troubleshooting when you get back, I certainly am up for it.

Here is the latest:

1. I added "#include <libwebsockets.h>" and "writelog(ERR, "Unexpected data received from CamillaDSP: %s\n", received_data);" to the file setrate_util.c, and got the following compile error for the writelog statement:

setrate_util.c: In function ‘check_received_data’:
setrate.h:39:57: error: ‘state’ undeclared (first use in this function); did you mean ‘states’?
39 | lwsl_##A("%-20s %-20s " fmt, func, decode_state(state), ##VA_ARGS)
| ^~~~~
setrate_util.c:54:5: note: in expansion of macro ‘writelog’
54 | writelog(ERR, "Unexpected data received from CamillaDSP: %s\n", received_data);
| ^~~~~~~~
setrate.h:39:57: note: each undeclared identifier is reported only once for each function it appears in
39 | lwsl_##A("%-20s %-20s " fmt, func, decode_state(state), ##VA_ARGS)
| ^~~~~
setrate_util.c:54:5: note: in expansion of macro ‘writelog’
54 | writelog(ERR, "Unexpected data received from CamillaDSP: %s\n", received_data);
| ^~~~~~~~
make: *** [Makefile:12: setrate_util.o] Error 1


2. I have been recursively doubling the BUFLEN in the file setrate.h, now up to 16M (16777216), and still it is not working with my biquads configuration.

I'll check back later, but not this week since I want you to enjoy your holiday. 😉
 
@mevang you may want to compare the received data size to BUFLEN in the websocket callback and log a warning, or perhaps pass the length to check_received_data so it can do the check. Also, I don't know enough about websockets to know whether the config file is guaranteed to all arrive in one packet. If a config file can be split across multiple receive()s then it might get messy.