libremidi icon indicating copy to clipboard operation
libremidi copied to clipboard

plans for pipewire?

Open cpyarger opened this issue 4 years ago • 2 comments

Are we planning on integrating pipe wires MIDI backend?

cpyarger avatar Apr 06 '21 03:04 cpyarger

That would make a lot of sense, do you know relevant docs on this ?

jcelerier avatar Apr 06 '21 07:04 jcelerier

I tried buildling the MIDI pipewire example but it does not build yet here... certainly it'll be good in a few months :)

jcelerier avatar Apr 12 '21 10:04 jcelerier

Doesn't pipewire just use the alsa sequencer API? Not sure what would be the advantage of a pipewire specific implementation other than adding more technical debt :shrug:

dromer avatar Feb 05 '24 09:02 dromer

looks like it can use both ALSA or JACK as a backend. It would have one improvement over just using the ALSA Seq backend: if you are making a pipewire app, you would see all your ports under the same client instead of seeing one client for the midi part, one client for the audio part, etc... Maybe it'd allow timing midi events sample-accurately in an easy way like JACK allows?

jcelerier avatar Feb 05 '24 19:02 jcelerier

What do you mean with "one client for the midi part, one client for the audio part"?

Qtractor under pipewire, using jack for audio and alsa for midi:

[Edit: ok I guess in qpwgraph it doesn't look nearly as good]

dromer avatar Feb 05 '24 20:02 dromer

yes ahah. I imagine some client-side GUI logic can apply heuristics... but it's in general not too clean, and programmatically every app inspecting the graph would have to reimplement the same kind of logic.

how does that work in the first graph if you launch the same app twice ??

jcelerier avatar Feb 06 '24 03:02 jcelerier

Haha, yup you got me there. Raysession then groups all the midi ports into one of the blocks -_-

For applications with jack midi this works correctly though (but port naming is off):

dromer avatar Feb 06 '24 06:02 dromer

:'D

nevertheless, it's definitely not critical but if someone can implement such a back-end I'd happily look into it, especially if it allows reusing an existing pw_context / pw_main_loop like the other backends now allow

jcelerier avatar Feb 07 '24 18:02 jcelerier

Another benefit I'd add by supporting pipewire is the ability to use bluetooth MIDI devices.

tsankuanglee avatar Feb 08 '24 05:02 tsankuanglee

@tsankuanglee you don't need any native pipewire MIDI implementation for that. Any alsa or jack midi application can get access to that support from pipewire. That's kind of the whole point.

dromer avatar Feb 08 '24 09:02 dromer

@dromer could you confirm this with an actual midi BLE device? I thought that since bluez 5 BLE-MIDI had to go through another daemon and wasn't exposing audio / midi devices directly through alsa. But I don't have any of those...

jcelerier avatar Feb 11 '24 16:02 jcelerier

hmmm maybe there's something to simulate one with an android app ? or something I could flash on an ESP32

jcelerier avatar Feb 11 '24 16:02 jcelerier

It would be strange if pipewire wouldn't expose such midi ports to all other midi software/devices.

(I don't own any bluetooth midi devices myself, so indeed would need to emulate something ..)

dromer avatar Feb 11 '24 16:02 dromer

see e.g. https://github.com/arkq/bluez-alsa

jcelerier avatar Feb 11 '24 18:02 jcelerier

I'm using pipewire with a bluetooth midi device and a few other wired ones here. I can see all midi devices in qpwgraph, and am able to patch them freely with other apps.

amidi -l shows the wired devices, but not the bluetooth one.

I'm assuming this is because of pipewire's support for bluetooth MIDI, but I may be wrong in that some other utility is exposing it as a wired one instead.

tsankuanglee avatar Feb 11 '24 19:02 tsankuanglee

okay, got nerd-sniped by this, I started some work on it yesterday, there should be results soon :)

jcelerier avatar Feb 12 '24 15:02 jcelerier

https://github.com/jcelerier/libremidi/assets/2772730/682771b4-954d-4c97-8dd6-253161df69bc

getting there...

jcelerier avatar Feb 16 '24 05:02 jcelerier

okay, current master has basic support for input and output (virtual ports only - e.g. right now you need to patch manually in qpwgraph or helvum).

TODO:

  • [x] observer and port enumeration support
  • [x] observer hotplug
  • [x] auto-connect to the relevant port
  • [x] support using an existing pipewire runloop and / or filter
  • [ ] test-drive it :)

jcelerier avatar Feb 19 '24 13:02 jcelerier

some more progress and bugfix, now it should support hotpug events. please note that the pipewire API is somewhat involved and intricate - I'd really really like others to test-drive and torture it as i'm pretty sure there's a heavy amount of corner cases that may still fail spectacularly.

jcelerier avatar Feb 24 '24 04:02 jcelerier

also i'd really like to know if it works with bluetooth midi :) if you build with LIBREMIDI_EXAMPLES there will be a midi1_in_pipewire and midi1_out_pipewire that can easily be modified to test things while making sure the pw api is the one being used

jcelerier avatar Feb 24 '24 04:02 jcelerier

@jcelerier OK, I'll give it a try with my bluetooth midi device and report back. May take a while though.

tsankuanglee avatar Feb 25 '24 18:02 tsankuanglee

@jcelerier I'm not an expert in c++, here's what I got:

$ g++ -I./include/ -I/usr/include/pipewire-0.3/ -I/usr/include/spa-0.2/ -I_deps/readerwriterqueue-src/ -lliblibremidi examples/backends/midi1_in_pipewire.cpp -o midi1_in_pipewire

...omit...

./include/libremidi/backends/pipewire/helpers.hpp:101:23: error: ‘class libremidi::observer_pipewire’ has no member named ‘process’
  101 |                  self.process(position);
      |                  ~~~~~^~~~~~~

tsankuanglee avatar Feb 26 '24 07:02 tsankuanglee

weird, builds fine here. I added it to the CI to see where things go wrong. Just in case can you try passing -std=c++20 to g++ ?

jcelerier avatar Feb 27 '24 03:02 jcelerier

damn

well this build matrix is certainly putting sadness in my soul

jcelerier avatar Feb 27 '24 03:02 jcelerier

okay those were minor issues - CI is now green with pipewire across three debian versions so I'd say the error is most likely somewhere else..

jcelerier avatar Feb 27 '24 03:02 jcelerier

I ended up just using LIBREMIDI_EXAMPLES for building examples, rather than compiling it manually. The result: it worked and my bluetooth MIDI device is shown in midi1_in_pipewire's output! It's also confirmed in qpwgraph!

Great job! Thanks so much!! @jcelerier

tsankuanglee avatar Feb 27 '24 07:02 tsankuanglee

et voilà :)

https://github.com/jcelerier/libremidi/assets/2772730/9f39a950-9593-44c3-b354-cfaa00fdd167

jcelerier avatar Mar 02 '24 02:03 jcelerier

it's where i want it to be at df33d0abacd8a5cf8b64ea93c0d397dea2d6b55f ; again i'm pretty sure there could be subtle concurrency issues, but I test-drived it with fsanitize=address fsanitize=undefined fsanitize=thread until it came out clean

jcelerier avatar Mar 02 '24 03:03 jcelerier