NEW: Control-device manager + controller device "drivers"

Yes, of course! How can I send it?

UPDATE: I’ve reduced the code to a minimal example, and it still happens. This is the code:

from zyngui.zynthian_ctrldev_manager import zynthian_ctrldev_base

class zynthian_ctrldev_akai_apc_key25_mk2(zynthian_ctrldev_base):
	dev_ids = ["APC_Key_25_mk2_MIDI_2"]
	dev_zynmixer = True

	def init(self): pass
	def end(self): pass
	def refresh(self, force=False): pass

	def midi_event(self, ev):
		print(f"midi {ev:06x}")
		return True

UPDATE 2: I’ve edited the “Capture MIDI from” setting of a chain, and removed every source (as you said, ‘Key 25 MIDI 2’ is disabled and I can not enable it). Then, the chain does not receive events from MIDI 1 (or any other source), but is still receiving events from MIDI 2 :sweat_smile:

Could you send the output of this command?

jack_lsp -cA

Thanks

Copy/paste it here, If you can’t, send by email to fernandoARROBAzynthianDOTorg

Regards

Yes. After a reboot, with a single chain, this is the result:

system:playback_1
   alsa_pcm:hw:Device:in1
   zynmixer:output_a
system:playback_2
   alsa_pcm:hw:Device:in2
   zynmixer:output_b
system:midi_capture_1
   in-hw-2-0-0-APC-Key-25-mk2-MIDI-1
   ZynMidiRouter:dev0_in
system:midi_capture_2
   in-hw-2-0-1-APC-Key-25-mk2-MIDI-2
   ZynMidiRouter:dev1_in
system:midi_playback_1
   out-hw-2-0-0-APC-Key-25-mk2-MIDI-1
   ZynMidiRouter:dev0_out
system:midi_playback_2
   out-hw-2-0-1-APC-Key-25-mk2-MIDI-2
   ZynMidiRouter:dev1_out
ttymidi:MIDI_in
   ZynMidiRouter:dev2_in
ttymidi:MIDI_out
   ZynMidiRouter:dev2_out
a2j:Midi Through [14] (capture): Midi Through Port-0
   ZynMidiRouter:dev3_in
a2j:Midi Through [14] (playback): Midi Through Port-0
   ZynMidiRouter:dev3_out
ZynMidiRouter:ch0_out
   synthv1-00:in
ZynMidiRouter:ch1_out
ZynMidiRouter:ch2_out
ZynMidiRouter:ch3_out
ZynMidiRouter:ch4_out
ZynMidiRouter:ch5_out
ZynMidiRouter:ch6_out
ZynMidiRouter:ch7_out
ZynMidiRouter:ch8_out
ZynMidiRouter:ch9_out
ZynMidiRouter:ch10_out
ZynMidiRouter:ch11_out
ZynMidiRouter:ch12_out
ZynMidiRouter:ch13_out
ZynMidiRouter:ch14_out
ZynMidiRouter:ch15_out
ZynMidiRouter:main_out
   zynsmf:midi_in
ZynMidiRouter:mod_out
ZynMidiRouter:midi_out
   ZynMaster:midi_in
ZynMidiRouter:net_out
ZynMidiRouter:step_out
   zynseq:input
ZynMidiRouter:ctrl_out
ZynMidiRouter:dev0_out
   system:midi_playback_1
ZynMidiRouter:dev1_out
   system:midi_playback_2
ZynMidiRouter:dev2_out
   ttymidi:MIDI_out
ZynMidiRouter:dev3_out
   a2j:Midi Through [14] (playback): Midi Through Port-0
ZynMidiRouter:dev4_out
ZynMidiRouter:dev5_out
ZynMidiRouter:dev6_out
ZynMidiRouter:dev7_out
ZynMidiRouter:dev8_out
ZynMidiRouter:dev9_out
ZynMidiRouter:dev10_out
ZynMidiRouter:dev11_out
ZynMidiRouter:dev12_out
ZynMidiRouter:dev13_out
ZynMidiRouter:dev14_out
ZynMidiRouter:dev15_out
ZynMidiRouter:dev0_in
   system:midi_capture_1
ZynMidiRouter:dev1_in
   system:midi_capture_2
ZynMidiRouter:dev2_in
   ttymidi:MIDI_in
ZynMidiRouter:dev3_in
   a2j:Midi Through [14] (capture): Midi Through Port-0
ZynMidiRouter:dev4_in
ZynMidiRouter:dev5_in
ZynMidiRouter:dev6_in
ZynMidiRouter:dev7_in
ZynMidiRouter:dev8_in
ZynMidiRouter:dev9_in
ZynMidiRouter:dev10_in
ZynMidiRouter:dev11_in
ZynMidiRouter:dev12_in
ZynMidiRouter:dev13_in
ZynMidiRouter:dev14_in
ZynMidiRouter:dev15_in
ZynMidiRouter:net_in
ZynMidiRouter:seq_in
   zynsmf:midi_out
ZynMidiRouter:step_in
   zynseq:output
ZynMidiRouter:ctrl_in
ZynMaster:midi_in
   ZynMidiRouter:midi_out
ZynMaster:midi_out
zynmixer:input_moduia
zynmixer:input_moduib
zynmixer:output_moduia
zynmixer:output_moduib
zynmixer:input_01a
   synthv1-00:Out_L
zynmixer:input_01b
   synthv1-00:Out_R
zynmixer:input_02a
zynmixer:input_02b
zynmixer:input_03a
zynmixer:input_03b
zynmixer:input_04a
zynmixer:input_04b
zynmixer:input_05a
zynmixer:input_05b
zynmixer:input_06a
zynmixer:input_06b
zynmixer:input_07a
zynmixer:input_07b
zynmixer:input_08a
zynmixer:input_08b
zynmixer:input_09a
zynmixer:input_09b
zynmixer:input_10a
zynmixer:input_10b
zynmixer:input_11a
zynmixer:input_11b
zynmixer:input_12a
zynmixer:input_12b
zynmixer:input_13a
zynmixer:input_13b
zynmixer:input_14a
zynmixer:input_14b
zynmixer:input_15a
zynmixer:input_15b
zynmixer:input_16a
zynmixer:input_16b
zynmixer:input_17a
   audioplayer:out_01a
   zynseq:metronome
zynmixer:input_17b
   audioplayer:out_01b
   zynseq:metronome
zynmixer:return_a
zynmixer:return_b
zynmixer:output_a
   system:playback_1
zynmixer:output_b
   system:playback_2
zynmixer:send_a
zynmixer:send_b
zynseq:input
   ZynMidiRouter:step_out
zynseq:output
   ZynMidiRouter:step_in
zynseq:metronome
   zynmixer:input_17a
   zynmixer:input_17b
audioplayer:in
audioplayer:out_01a
   zynmixer:input_17a
audioplayer:out_01b
   zynmixer:input_17b
zynsmf:midi_out
   ZynMidiRouter:seq_in
zynsmf:midi_in
   ZynMidiRouter:main_out
synthv1-00:in
   ZynMidiRouter:ch0_out
synthv1-00:in_L
synthv1-00:in_R
synthv1-00:Out_L
   zynmixer:input_01a
synthv1-00:Out_R
   zynmixer:input_01b

How did you update? From webconf? Command line?

Regards

I updated from the webconf, and also, I did an apt upgrade.

Could you try adding this:

lib_zyncore.zmip_set_route_extdev(self.idev - 1, 0)

to your init function?

This call should “unroute” the input device from the chains and it’s called from the “setup” function in the base class. I don’t understand why the device is still routed to the chains in your setup!

You can get the current routing by calling this.

lib_zyncore.zmop_get_route_from(izmop, izmip)

  • izmop is the chain index (well, indeed is the router’s output port index)
  • izmip is the device index (again, it’s the router’s input port index)

Some thing like this will help debugging:

for i in range(17):
    routed = lib_zyncore.zmop_get_route_from(i, self.idev-1)
    logging.debug(f"Routed to izmop {i} => {routed}")

The routes should be set to 0 for all izmop from 0 to 16.

Regards,

1 Like

Ok, I put that line inside the init function, and I printed the routes immediately after, and everything seems fine (all returns 0). BUT, I also put the print in midi_event, and there, channels from 0 to 15 get routed (zmop_get_route_from returns 1), and only channel 16 get 0.

Something between init and midi_event is changing the routing… :thinking:

UPDATE: If I set the route again the first time midi_event is called, then it stops sending events, and it keeps that way.

UPDATE 2: I’ve added a print inside the C function zmip_set_route_extdev, recompiled, and tested again. It is called only once, in the ctrldev’s setup(); the re-routing must be donde elsewhere.

Could you describe the exact steps you follow for testing?
Could you remove the last state snapshot and start from scratch?

rm /zynthian/zynthian-my-data/snapshots/last_state.zss

Thanks

That was it! I removed the last_state.zss and started from scratch, and now I don’t hear any note coming from the control keys! :star_struck: I thought that just removing the chains will do, but there were something bad from any older tinkering…

I’m very sorry for wasting your time :weary:, but thank you very much for your help!

We can chat for more agile communication. The discourse has a chat tool.

I’ve gotten the impression that doing an apt upgrade is a seriously bad idea on a Zynthian because it can write over many carefully balanced and interdependent modules with updated but now incompatible ones.

This is one of the places where I got that impression:

1 Like

Ouch, didn’t know that! :woozy_face: Thanks for the info, I’ll burn a fresh image as soon as I can.

1 Like

An update on this: I’ve switched to branch chain_manager to continue the development, as there are interesting changes on the way control devices work (and I love them! :blush: ). So, I’ve updated, fixed and finished the support for the mixer. Now it works this way:

  • The following is valid only for mixer modes, which are activated using SHIFT + VOLUME or PAN buttons. Modes “send” and “device” are reserved for other purposes… :wink:

  • I’ve extended the bank idea to the knobs, so for every function, you can control the first 8 chains with bank 0, and chains 9 to 16 selecting bank 1. You can change the bank using SHIFT + LEFT or RIGHT buttons.

  • Pressing and holding SHIFT will show the current mode: “volume” or “pan” (in Track buttons), and the current function: “mute” or “solo” (in Scene Launch buttons).

  • Each knob controls volume or pan of each chain (depending on the current mode and the selected bank). Each Track button controls mute or solo of each chain (depending on the current function and selected bank). To control volume or pan of main chain, press SHIFT while using Knob 1. To control mute of main chain, or remove all solos, press SHIFT + STOP ALL CLIPS buttons (action depends on current selected function).

And that’s it! Next thing will be the “device” mode, which will send CUIA messages to the user interface. Stay tuned! :upside_down_face:

3 Likes

It’s great that you are using “chain_manager”. Tell us if you find some issue with it.
Regarding the driver you are writing (and the other ones), i’m thinking that it would we good to have documentation for each one, explaining modes, functionality and how it’s mapped to the controller actuators (knobs, faders, pads, buttons, etc.). Some graphic support will be great too.
I say that because it seems that your driver will be a very good example, having several modes, that include mixer, zynpad and other UI control. I will try to write a little documentation for the 3 drivers i wrote:

  • Novation Lauunchpad MINI
  • Novation Lauunchpad MINI MK3
  • Akai MIDI Mix

Perhaps we could cooordinate our effort and put a good basement that serves as example and guidance for others.

All the best!

2 Likes

Tell us if you find some issue with it.

Sure! I’ll use the github issue tracker, I presume is a better place, isn’t it?

…i’m thinking that it would we good to have documentation for each one, explaining modes, functionality and how it’s mapped to the controller actuators…

Totally agree! I was thinking the same, that without proper documentation, it will be harder to use. I’ll do my best explaining the details and functionality. Where should we put it?

1 Like

Would it be beneficial to have a generic driver that can be configured, e.g. some devices may use MIDI note for state control but just use different values.

3 Likes

Totally agree, but let’s wait until having more driver examples, so we can “abstract” what has more sense.
I.E. perhaps it has more sense to have a “Novation MK3” generic driver because all novation MK3 devices are very similar, etc.

Regards,

1 Like

The place would be the wiki. Let me create the structure and post a first example or template. I will create credentials so you can edit.

The best,

3 Likes

Hi!

One more question: Is there any way for the controller driver to receive updates about the status of Zynthian state? I’m specially interested on:

  • Receive an update of playing/recording audio/midi status, in order to provide correct hardware feedback.
  • Receive an update when the current UI screen has changed (for instance, when the user moves from Mixer to Admin menu).

That would be awesome! :slight_smile: