brummer10 / Fluida.lv2

Fluidsynth as LV2 plugin
GNU General Public License v2.0
33 stars 4 forks source link

Cannot change instrument when external MIDI keyboard w/ clock is connected #19

Open sebageek opened 1 year ago

sebageek commented 1 year ago

When I run Fluida.lv2 in BespokeSynth, Carla or reaper changing instruments works fine until I connect my MIDI keyboard (a "Novation Launchkey 37 MK3"), then I cannot change the instrument anymore. The instrument changes in the UI, but the instrument I hear does not change. It only changes once I have disconnected the midikeyboard (in my plugin host only, the keyboard remains plugged in via USB the whole time) and THEN choose a new instrument.

I could not reproduce this with a virtual midi keyboard or a self-made midi footswitch (they all don't provide a midi clock).

While trying to figure this out I took a look at the midi loop and one difference I can see is that my keyboard sends out a MIDI clock and that quite frequently, at least there are a lot of messages with type 0xF8 aka LV2_MIDI_MSG_CLOCK in Fluida_::run_dsp_() that otherwise seem to have a zero payload.

Turning off the MIDI clock in the settings of my keyboard seems to do the trick and instrument changing works again. I wonder though, is this is something that is a problem in Fluida that could be fixed there?

brummer10 commented 1 year ago

Hi I tried it with jack_midi_clock sending a 360 bpm beat, but can't reproduce the issue. Fluida receive the MIDI Clock messages and that's it. 693 ->

 case LV2_MIDI_MSG_CLOCK:
                fprintf(stderr, "Clock\n");
                break;

Unfortunately I don't have a midi keyboard which generate midi clock data.

sebageek commented 1 year ago

I can reproduce this on my system with jack_midi_clock. I also used jack_midi_dump to verify that this looks similar to what I can see coming from my keyboard, so it really seems to be the "clock" part on my machine, not the midi keyboard itself.

Now, selecting a sf2 after connecting results in the instrument list staying at None. Connecting it after loading the sf2 leads to the behavior described above.

With something like this in the code I see about 48 messages per second (same as in jack_midi_dump:

std::cout << std::time(0) << " MIDI event " << lv2_midi_message_type(msg) << " msg[0] " << (int)msg[0] << " msg[1] " << (int)msg[1] << " msg[2] " << (int)msg[2] << std::endl;
1672158859 MIDI event 248 msg[0] 248 msg[1] 0 msg[2] 0
1672158859 MIDI event 248 msg[0] 248 msg[1] 0 msg[2] 0
1672158859 MIDI event 248 msg[0] 248 msg[1] 0 msg[2] 0
1672158859 MIDI event 248 msg[0] 248 msg[1] 0 msg[2] 0
1672158859 MIDI event 248 msg[0] 248 msg[1] 0 msg[2] 0
...

If you can't reproduce this do you see a similar amount of midi clock messages? Maybe in the end this is some pipewire-jack weirdness (I'm using pipewire 0.3.60.

brummer10 commented 1 year ago

Ah, now I got it. I just changed the instrument with the midi keyboard and that works. That leads me to find the issue. It's because midi clock signal set the channel to a different one. Here it use channel 8. Then the instrument selector set the instrument for channel 8 and not for the channel used with the keyboard. So I implement a guard to avoid that the midi clock signal set the internal used channel. Works now.

sebageek commented 1 year ago

I did not know that setting the instrument via midi keyboard is an option. How does that work?

And thanks for the fix! Just compiled it and it works now even when the clock is on.

sebageek commented 1 year ago

I just found out that this only fixes this first case, but not the second case.

The instrument list stays at None and I cannot change instruments via GUI. The Path to the sf2 is set in the GUI, though.

brummer10 commented 1 year ago

Oh, yes, I've introduce that with the last commit were I've forgotten to remove a testcase. Fixed now.

sebageek commented 1 year ago

Loading a sf2 when jack_midi_clock is connected still doesn't work for me and I end up with an empty instrument list. This only happens when jack transport is running (and Fluida is also connected to an audio output, as else jack_midi_clock doesn't seem to send out its clock according to jack_midi_dump).

brummer10 commented 1 year ago

Looks like carlas message bus is overwhelmed. I do some debug checks and see that some messages send from dsp to ui don't been forwarded by carla. That happen sporadic when the midi clock is running. ping @falkTX here, maybe he knows more

brummer10 commented 1 year ago

here is a example, Flida send the instrument list in chunks , carla froward them to the UI. [carla] CarlaBridgeFormat::msgReceived("atom") [carla] carla_lv2_ui_write_function(0x7fff36fbb520, 2, 64, 23, 0x55ea6da66350) [carla] CarlaLv2Client::handleUiWrite(2, 64, 23, 0x55ea6da66350) [carla] CarlaPluginLV2::handleUIWrite(2, 64, 23, 0x7f3530207510) send 73 000 072 Piccolo send 74 000 073 Flute send 75 000 074 Recorder send 76 000 075 Pan Flute send 77 000 076 Bottle Chiff send 78 000 077 Shakuhachi send 79 000 078 Whistle send 80 000 079 Ocarina send 81 000 080 Square Lead send 82 000 081 Saw Wave send 83 000 082 Calliope Lead send 84 000 083 Chiffer Lead SEND [carla] CarlaBridgeFormat::msgReceived("atom") [carla] carla_lv2_ui_write_function(0x7fff36fbb520, 2, 64, 23, 0x55ea6da66350) [carla] CarlaLv2Client::handleUiWrite(2, 64, 23, 0x55ea6da66350) [carla] CarlaPluginLV2::handleUIWrite(2, 64, 23, 0x7f3530207510) send 85 000 084 Charang send 86 000 085 Solo Vox send 87 000 086 Fifth Sawtooth Wave send 88 000 087 Bass & Lead send 89 000 088 Fantasia send 90 000 089 Warm Pad send 91 000 090 Polysynth send 92 000 091 Space Voice send 93 000 092 Bowed Glass send 94 000 093 Metal Pad send 95 000 094 Halo Pad send 96 000 095 Sweep Pad SEND here carla should receive the message and froward it to the UI, but nothing happen. That happen sporadic at different timestamps. That works flawless when the clock didn't run.

falkTX commented 1 year ago

did you try specify the minimum size of the atom ports? if it is a matter of message congestion, increasing the size will alleviate the problem.

on the atom ports, use like:

<http://lv2plug.in/ns/ext/resize-port#minimumSize> 8192 ;
atom:bufferType atom:Sequence ;
...
brummer10 commented 1 year ago

Yes, I've used @prefix rsz: http://lv2plug.in/ns/ext/resize-port# .

and rsz:minimumSize 65664 ;

btw. what is the bigest allowed buffersize here? on the Atom ports, didn't help. Tried with your style, also didn't help.

Also, I send chunks of data, contain max 12 strings. So buffersize shouldn't be a issue. I noticed that jalv didn't have this issue.

brummer10 commented 1 year ago

@falkTX To explain it a bit more, Fluida dsp send a chunk of 12 instrument strings to the GUI, the GUI store them and send a messge back to ask for the next chunk. That goes as long the list is empty, then the dsp send ->finish. So, the message buffer itself is always small.

However, when I switch to send all instruments at once, that works, sometimes. But sometimes even then carla didn't deliver the data to the UI. All that only happen when the midi clock run. Otherwise both solutions works flawless within the default buffersize of carla. So it looks to me as if the midi clock eats up the atom buffer of carla.

brummer10 commented 1 year ago

So I've implemented a work around for this issue. It seems that carla fail on handle the amount of messages, so now, when a midi clock is detected, Fluida switch to send the instrument list in one big chunk instead as multiple smaller chunks. That reduce the amount of messages carla needs to handle. But still, that works only 99% of the time.

falkTX commented 1 year ago

Likely fixed in https://github.com/falkTX/Carla/commit/a97fd200fe81e5d64c2db9a3adecac18d17739cf, please test and report back, thanks!