jamulussoftware / jamulus

Jamulus enables musicians to perform real-time jam sessions over the internet.
https://jamulus.io
Other
1k stars 224 forks source link

Midi control faders in headless build #483

Closed surjeon closed 4 years ago

surjeon commented 4 years ago

I'd like to be able to change fader levels from a terminal, which I'm trying to achieve with a separate curses midi controller program (midifade from the perl Midi-Alsa library). But it looks at the minute like the MIDI controller code works by setting the GUI faders and triggering their on change signals, and none of that code is present in a headless build. I'm not brilliant with C++ and Qt and it seems like rather a big refactor (to separate the GUI specific code from the client control) to take on without a little guidance: I'm trying to follow the sequence of signals around in audiomixerboard.cpp but I'm going in circles and can't find where it actually emits a signal that connects back to a CChannel.

Background: I'm setting up headless Jamulus boxes on Raspberry Pi Zeros to distribute to my choir, many of whom don't have real computers. I've done it very much on the cheap (about 30 GBP per person including a Respeaker 2-mic hat for the microphones) and so I have no display or keyboard, so there's no way to see or set faders. Furthermore I think many of them might not get the idea of setting levels. So the intention is to log in to each client remotely (autossh reverse tunnels) and set their levels for them at the start of the session. The basics of getting the audio in and out with reasonable quality and latency are going ok.

gilgongo commented 4 years ago

I'm setting up headless Jamulus boxes on Raspberry Pi Zeros to distribute to my choir,

Wow, that's amazing!

corrados commented 4 years ago

But it looks at the minute like the MIDI controller code works by setting the GUI faders and triggering their on change signals

That‘s correct. Should not be a big deal to support it for headless, too. I‘ll take a look at the code when I‘m back from vacation.

corrados commented 4 years ago

BTW, I also did tests with a Pi Zero. This is the Jack configuration I have used: https://github.com/corrados/jamulus/blob/master/distributions/raspijamulus.sh#L162 I was using a USB Ethernet adapter. Are you planning to use the Pi Zero W internal WLAN?

melcon commented 4 years ago

I'm setting up headless Jamulus boxes on Raspberry Pi Zeros to distribute to my choir

Just out of curiosity, have you tried/heard about PiSound? https://blokas.io/pisound/ Of course it would increase your budget.

surjeon commented 4 years ago

Thanks for having a look at the MIDI control; that'd be brilliant. I will attempt to write up what I do if it might be of help to others.

I cribbed heavily from the raspijamulus script (thanks), but ended up building debian packages of jackd (- dbus) and libopus (with your patches) just so that they were easy to upgrade if I needed to make some change to them once they are in other people's homes.

I'm using a Waveshare USB/ethernet hat for wired ethernet, and stacked on top of that a Seeed Respeaker audio interface, which has a pair of MEMs mics on the board. Each hat was about GBP 10. There are slightly cheaper ethernet alternatives. I was worried about the USB based ethernet creating xruns with interrupt traffic, but it doesn't seem to be a problem. Wireless was out anyway because of the complexity of trying to get non-tech savvy users to get their wifi credentials in to a headless box; the prospective users don't seem too troubled by plugging a long ethernet cable in to their router for the duration of choir practice, which will anyway be better. Also the Pi Zero Ws are even harder to get hold of at the minute than the original ones.

@corrados : I read one of your posts on the Sourceforge forum where you said that the Pi Zero wasn't able to keep up with encoding/decoding on high quality, but for me it's about 50% CPU for Jamulus (high quality stereo), and another 10% for jackd, and I'm not getting overly many xruns or a massive jitter. Did something change?

@melcon : I saw the PiSound while I was looking for interfaces, but it's really quite expensive for me mostly because it offers much more than I'd need on the board, but then needs a microphone and appropriate cabling adding on top. My budget was about GBP 30--40 for everything (Pi, audio interface, microphone) because I'm somewhere between giving them away and pushing them on people.

The respeaker hat I'm using has something like 14ms of hardware round-trip time (measured with jack_iodelay); which is similar to other non-specialised audio interfaces I've tried (Behringer UM2 is the next cheapest option I came up with, and that has slightly more hardware latency). The PiSound has a quoted 2ms of hardware latency, so looks like a very good option if the budget isn't so constrained.

corrados commented 4 years ago

for me it's about 50% CPU for Jamulus (high quality stereo), and another 10% for jackd

That's very interesting. I could not run Jamulus in high quality stereo mode. Now I am very much interested in what is the difference between my raspijamulus.sh file and your implementation :-).

I cribbed heavily from the raspijamulus script (thanks), but ended up building debian packages

Interesting approach. But I like the simpliness of a single script. If there is a bug in my script which does not allow high quality stereo, it would be good to fix it.

corrados commented 4 years ago

I just implemented the support for MIDI control data in headless mode: https://github.com/corrados/jamulus/commit/e5174ef461dfe507efa0798fe7869f50106cded0. Unfortunately, I cannot test the implementation. Could you please verify that it works? If possible, could you also check that the non-headless MIDI support still works (to make sure I did not break existing functionality)?

surjeon commented 4 years ago

On 31/07/2020 15:34, Volker Fischer wrote:

I just implemented the support for MIDI control data in headless mode: e5174ef https://github.com/corrados/jamulus/commit/e5174ef461dfe507efa0798fe7869f50106cded0. Unfortunately, I cannot test the implementation. Could you please verify that it works? If possible, could you also check that the non-headless MIDI support still works (to make sure I did not break existing functionality)?

Wow, that was quick :)  I'm (also) on vacation at the minute and don't have any audio hardware with me. But with debug messages in Channel::SetGain on my server I can now see the gain changes getting applied when I send midi messages to the client.

I've also tried the GUI client and the fader moves and the server sees the gain changes.

One small gotcha I noticed whilst testing that: it still won't work with --nogui with a normal (not headless) build.  That doesn't actually impact my use case, but might be confusing for someone later.

I'll go through my raspi build when I'm back and see if I can find anything different to your script.  There wasn't anything intentional, but maybe the libopus source version wasn't exactly as specified as it came from the raspian source package, which I then applied the patch in the script to.  Is there a better place to continue discussion of that?

corrados commented 4 years ago

Thanks for testing.

it still won't work with --nogui with a normal (not headless) build.

Yes, this is a known issue. But I think it is ok not to support it because most of the users will compile with "headless" anyway.

for me it's about 50% CPU for Jamulus (high quality stereo), and another 10% for jackd, and I'm not getting overly many xruns or a massive jitter.

Are you running Jack with 128 samples? Or do you use a larger number, like 256? That would explain the lower CPU usage.

Is there a better place to continue discussion of that?

I'll close this issue now since the original request is implemented now. But we can continue discuss Pi Zero related stuff here even if the Issue is closed.

surjeon commented 4 years ago

Jack's running with 128 frames/period; its command line is

/usr/bin/jackd -R -P95 -p16 -t2000 -d alsa -d hw:0 -p 128 -n 2 -r 48000 -s -S

(I disabled the bcm2835 sound in config.txt, hence hw:0).

I just tried with jack at 64 frames; that's definitely out for Jamulus: CPU at about 90% and chopped audio. I've not tested whether it's possible to use jack at all with that.

My Jamulus.ini looks like

<client>
  <name_base64>dGVzdAo=</name_base64>
  <autojitbuf>1</autojitbuf>
  <jitbuf>3</jitbuf>
  <jitbufserver>3</jitbufserver>
  <audiochannels>2</audiochannels>
  <audioquality>2</audioquality>
  <enableopussmall>0</enableopussmall>
</client>

With opussmall=1 I get slight crackling when there's lots of audio going on; seems ok when it's just a single person speaking. I read opus has a speech vs. music mode with an automatic changeover; maybe it's that?

The client side of the jitter buffer is tuning to about 7 or 8 on the pi, whereas my desktop machine on the same network tunes to 3 or 4 in the same circumstance (and 7 or 8 with 64 sample buffers).

The libopus I've used is based on the debian source package which is 1.3 (not 1.3.1), dated Dec 2018. I don't see anything in the Debian changelog that's any different to upstream. Jackd is v1.9.14 from git master.

corrados commented 4 years ago

Ok, so you are also running with 128 samples. I have to do some more investigation with my Pi Zero to find out what goes wrong. BTW, there is another one doing something similar as you want to do: https://25ms.org/2020/06/27/first-singing-test-june-24th/?fbclid=IwAR3C9gFx6sIoqF6yTKflL7zA43hOmVw51D-qO6xPeVlOX9JylYgGsEtAyvA but he is using a Raspberry Pi 4 which is more expensive. Your solution would be the cheapest possible I guess.

cormacusscripsit commented 4 years ago

Thank you for continuing this discussion here, I'm trying to do exactly the same thing so I'm following this issue closely!

gilgongo commented 4 years ago

Just a documentation question on this. The changelog for the 3.5.10 release says "support MIDI control faders in headless build" has been added. Does this need to be documented somewhere? There is this section on the wiki at the moment:

https://github.com/corrados/jamulus/wiki/Tips,-Tricks-&-More#using-the---ctrlmidich-midi-controller-channel-option

But I don't know much about MIDI so I'm not sure it's relevant.

corrados commented 4 years ago

No, I don't think you need to change anything in the Wiki. It was more like a bug fix than adding new functionality.