From 71cc888e1320b754e692fb39ab3b7220276f2ca7 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Mon, 24 Jan 2022 23:40:37 -0800 Subject: [PATCH 01/11] add midi channel UI --- jack_mixer/channel.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index 7943f20..eef1984 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -1073,38 +1073,47 @@ def create_ui(self): cc_tooltip = _( "{param} MIDI Control Change number " "(0-127, set to -1 to assign next free CC #)" ) + channel_label = Gtk.Label.new_with_mnemonic(_("_Channel")) + channel_label.set_halign(Gtk.Align.START) + grid.attach(channel_label,0,0,1,1) + self.entry_midi_channel = Gtk.SpinButton.new_with_range(1, 16, 1) + self.entry_midi_channel.set_tooltip_text(cc_tooltip.format(param=_("Channel"))) + channel_label.set_mnemonic_widget(self.entry_midi_channel) + grid.attach(self.entry_midi_channel, 1, 0, 1, 1) + volume_label = Gtk.Label.new_with_mnemonic(_("_Volume")) volume_label.set_halign(Gtk.Align.START) - grid.attach(volume_label, 0, 0, 1, 1) + grid.attach(volume_label, 0, 1, 1, 1) self.entry_volume_cc = Gtk.SpinButton.new_with_range(-1, 127, 1) self.entry_volume_cc.set_tooltip_text(cc_tooltip.format(param=_("Volume"))) volume_label.set_mnemonic_widget(self.entry_volume_cc) - grid.attach(self.entry_volume_cc, 1, 0, 1, 1) + grid.attach(self.entry_volume_cc, 1, 1, 1, 1) self.button_sense_midi_volume = Gtk.Button(_("Learn")) self.button_sense_midi_volume.connect("clicked", self.on_sense_midi_volume_clicked) - grid.attach(self.button_sense_midi_volume, 2, 0, 1, 1) + grid.attach(self.button_sense_midi_volume, 2, 1, 1, 1) balance_label = Gtk.Label.new_with_mnemonic(_("_Balance")) balance_label.set_halign(Gtk.Align.START) - grid.attach(balance_label, 0, 1, 1, 1) + grid.attach(balance_label, 0, 2, 1, 1) self.entry_balance_cc = Gtk.SpinButton.new_with_range(-1, 127, 1) self.entry_balance_cc.set_tooltip_text(cc_tooltip.format(param=_("Balance"))) balance_label.set_mnemonic_widget(self.entry_balance_cc) - grid.attach(self.entry_balance_cc, 1, 1, 1, 1) + grid.attach(self.entry_balance_cc, 1, 2, 1, 1) + self.button_sense_midi_balance = Gtk.Button(_("Learn")) self.button_sense_midi_balance.connect("clicked", self.on_sense_midi_balance_clicked) - grid.attach(self.button_sense_midi_balance, 2, 1, 1, 1) + grid.attach(self.button_sense_midi_balance, 2, 2, 1, 1) mute_label = Gtk.Label.new_with_mnemonic(_("M_ute")) mute_label.set_halign(Gtk.Align.START) - grid.attach(mute_label, 0, 2, 1, 1) + grid.attach(mute_label, 0, 3, 1, 1) self.entry_mute_cc = Gtk.SpinButton.new_with_range(-1, 127, 1) self.entry_mute_cc.set_tooltip_text(cc_tooltip.format(param=_("Mute"))) mute_label.set_mnemonic_widget(self.entry_mute_cc) - grid.attach(self.entry_mute_cc, 1, 2, 1, 1) + grid.attach(self.entry_mute_cc, 1, 3, 1, 1) self.button_sense_midi_mute = Gtk.Button(_("Learn")) self.button_sense_midi_mute.connect("clicked", self.on_sense_midi_mute_clicked) - grid.attach(self.button_sense_midi_mute, 2, 2, 1, 1) + grid.attach(self.button_sense_midi_mute, 2, 3, 1, 1) if isinstance(self, NewInputChannelDialog) or ( self.channel and isinstance(self.channel, InputChannel) @@ -1122,14 +1131,14 @@ def create_ui(self): ): solo_label = Gtk.Label.new_with_mnemonic(_("S_olo")) solo_label.set_halign(Gtk.Align.START) - grid.attach(solo_label, 0, 3, 1, 1) + grid.attach(solo_label, 0, 4, 1, 1) self.entry_solo_cc = Gtk.SpinButton.new_with_range(-1, 127, 1) self.entry_solo_cc.set_tooltip_text(cc_tooltip.format(param=_("Solo"))) solo_label.set_mnemonic_widget(self.entry_solo_cc) - grid.attach(self.entry_solo_cc, 1, 3, 1, 1) + grid.attach(self.entry_solo_cc, 1, 4, 1, 1) self.button_sense_midi_solo = Gtk.Button(_("Learn")) self.button_sense_midi_solo.connect("clicked", self.on_sense_midi_solo_clicked) - grid.attach(self.button_sense_midi_solo, 2, 3, 1, 1) + grid.attach(self.button_sense_midi_solo, 2, 4, 1, 1) self.vbox.show_all() From a4538d6ba3a4e0a5fb63c60e095e67e16dda3204 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Tue, 25 Jan 2022 12:58:30 -0800 Subject: [PATCH 02/11] GUI runs but new channel kwarg error --- jack_mixer/channel.py | 13 ++++++++++++- meson_options.txt | 2 +- src/jack_mixer.c | 26 ++++++++++++++++++++++++++ src/jack_mixer.h | 13 +++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index eef1984..ef147ce 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -57,6 +57,7 @@ def __init__(self, app, name, stereo=True, direct_output=True, initial_vol=None) self.post_fader_output_channel = None self.future_out_mute = None self.future_volume_midi_cc = None + self.future_midi_channel = None self.future_balance_midi_cc = None self.future_mute_midi_cc = None self.future_solo_midi_cc = None @@ -577,6 +578,8 @@ def serialize(self, object_backend): if hasattr(self.channel, "out_mute"): object_backend.add_property("out_mute", str(self.channel.out_mute)) + if self.channel.midi_channel != -1: + object_backend.add_property("midi_channel", str(self.channel.midi_channel)) if self.channel.volume_midi_cc != -1: object_backend.add_property("volume_midi_cc", str(self.channel.volume_midi_cc)) if self.channel.balance_midi_cc != -1: @@ -599,8 +602,10 @@ def unserialize_property(self, name, value): elif name == "meter_prefader": self.meter_prefader = (value == "True") return True + elif name == "midi_channel": + self.future_midi_channel = int(value) + return True elif name == "volume_midi_cc": - self.future_volume_midi_cc = int(value) return True elif name == "balance_midi_cc": @@ -642,6 +647,8 @@ def realize(self): super().realize() + if self.future_midi_channel is not None: + self.channel.midi_channel = self.future_midi_channel if self.future_volume_midi_cc is not None: self.channel.volume_midi_cc = self.future_volume_midi_cc if self.future_balance_midi_cc is not None: @@ -859,6 +866,8 @@ def realize(self): super().realize() + if self.future_midi_channel is not None: + self.channel.midi_channel = self.future_midi_channel if self.future_volume_midi_cc is not None: self.channel.volume_midi_cc = self.future_volume_midi_cc if self.future_balance_midi_cc is not None: @@ -1150,6 +1159,7 @@ def fill_ui(self): self.mono.set_active(True) self.mono.set_sensitive(False) self.stereo.set_sensitive(False) + self.entry_midi_channel.set_value(self.channel.channel.midi_channel) self.entry_volume_cc.set_value(self.channel.channel.volume_midi_cc) self.entry_balance_cc.set_value(self.channel.channel.balance_midi_cc) self.entry_mute_cc.set_value(self.channel.channel.mute_midi_cc) @@ -1289,6 +1299,7 @@ def get_result(self): "name": self.entry_name.get_text(), "stereo": self.stereo.get_active(), "direct_output": self.direct_output.get_active(), + "midi_channel": int(self.entry_midi_channel.get_value()), "volume_cc": int(self.entry_volume_cc.get_value()), "balance_cc": int(self.entry_balance_cc.get_value()), "mute_cc": int(self.entry_mute_cc.get_value()), diff --git a/meson_options.txt b/meson_options.txt index 87e7671..c14aaa4 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -15,7 +15,7 @@ option('check-py-modules', ) option('verbose', type: 'boolean', - value: false, + value: true, description: 'Turn on debug logging (for development)' ) option('wheel', diff --git a/src/jack_mixer.c b/src/jack_mixer.c index b8a9cc5..c874ed6 100644 --- a/src/jack_mixer.c +++ b/src/jack_mixer.c @@ -104,6 +104,7 @@ struct channel { bool NaN_detected; + int8_t midi_channel_index; int8_t midi_cc_volume_index; int8_t midi_cc_balance_index; int8_t midi_cc_mute_index; @@ -427,6 +428,23 @@ channel_set_balance_midi_cc( return 0; } +int8_t +channel_get_midi_channel( + jack_mixer_channel_t channel) +{ + // prolly need to set this index somewhere else + return channel_ptr->midi_channel_index; +} + +int +channel_set_midi_channel( + jack_mixer_channel_t channel, + int8_t new_channel) +{ + // def need to make a real function do things here + return 0; +} + int8_t channel_get_volume_midi_cc( jack_mixer_channel_t channel) @@ -529,6 +547,14 @@ channel_set_solo_midi_cc( return 0; } +int +channel_autoset_midi_channel( + jack_mixer_channel_t channel) +{ + // check out what the autoset things really do + return 0; +} + int channel_autoset_volume_midi_cc( jack_mixer_channel_t channel) diff --git a/src/jack_mixer.h b/src/jack_mixer.h index 8bf334d..542dcc1 100644 --- a/src/jack_mixer.h +++ b/src/jack_mixer.h @@ -250,6 +250,15 @@ channel_set_balance_midi_cc( jack_mixer_channel_t channel, int8_t new_cc); +int8_t +channel_get_midi_channel( + jack_mixer_channel_t channel); + +int +channel_set_midi_channel( + jack_mixer_channel_t channel, + int8_t new_channel); + int8_t channel_get_volume_midi_cc( jack_mixer_channel_t channel); @@ -287,6 +296,10 @@ channel_set_midi_cc_balance_picked_up( jack_mixer_channel_t channel, bool status); +int +channel_autoset_midi_channel( + jack_mixer_channel_t channel); + int channel_autoset_volume_midi_cc( jack_mixer_channel_t channel); From e5f56cb25892669e0407b3a67b7887b357a7c64f Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Tue, 25 Jan 2022 15:16:30 -0800 Subject: [PATCH 03/11] add types and getter/setter --- src/_jack_mixer.pxd | 3 +++ src/_jack_mixer.pyx | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/_jack_mixer.pxd b/src/_jack_mixer.pxd index 4065707..1b9560f 100644 --- a/src/_jack_mixer.pxd +++ b/src/_jack_mixer.pxd @@ -128,15 +128,18 @@ cdef extern from "jack_mixer.h": cdef int channel_autoset_mute_midi_cc(jack_mixer_channel_t channel) cdef int channel_autoset_solo_midi_cc(jack_mixer_channel_t channel) cdef int channel_autoset_volume_midi_cc(jack_mixer_channel_t channel) + cdef int channel_autoset_midi_channel(jack_mixer_channel_t channel) cdef int channel_get_balance_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_mute_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_solo_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_volume_midi_cc(jack_mixer_channel_t channel) + cdef int channel_get_midi_channel(jack_mixer_channel_t channel) cdef int channel_set_balance_midi_cc(jack_mixer_channel_t channel, int new_cc) cdef int channel_set_mute_midi_cc(jack_mixer_channel_t channel, int new_cc) cdef int channel_set_solo_midi_cc(jack_mixer_channel_t channel, int new_cc) cdef int channel_set_volume_midi_cc(jack_mixer_channel_t channel, int new_cc) + cdef int channel_set_midi_channel(jack_mixer_channel_t channel, int new_channel) cdef void channel_set_midi_scale(jack_mixer_channel_t channel, jack_mixer_scale_t scale) diff --git a/src/_jack_mixer.pyx b/src/_jack_mixer.pyx index 0a977dc..a6dedd1 100644 --- a/src/_jack_mixer.pyx +++ b/src/_jack_mixer.pyx @@ -442,6 +442,16 @@ cdef class Channel: if channel_set_solo_midi_cc(self._channel, cc) != 0: raise ValueError(jack_mixer_error_str().decode('utf-8')) + @property + def midi_channel(self): + """MIDI channel to control audio channel.""" + return channel_get_midi_channel(self._channel) + + @midi_channel.setter + def midi_channel(self, int channel): + if channel_set_midi_channel(self._channel, channel) != 0: + raise ValueError(jack_mixer_error_str().decode('utf-8')) + @property def volume_midi_cc(self): """MIDI CC assigned to control channel volume.""" From f72530d72a458ea1753b8a6d05a98aabe8355959 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Tue, 25 Jan 2022 20:41:52 -0800 Subject: [PATCH 04/11] add midi_channel to function --- jack_mixer/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/jack_mixer/app.py b/jack_mixer/app.py index 5606c81..4e72c2c 100644 --- a/jack_mixer/app.py +++ b/jack_mixer/app.py @@ -371,6 +371,7 @@ def add_channel( name, stereo=True, direct_output=True, + midi_channel=1, volume_cc=-1, balance_cc=-1, mute_cc=-1, From e59d18a7dd866845d1d157c479161d463e1f54af Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Tue, 25 Jan 2022 22:39:58 -0800 Subject: [PATCH 05/11] set midi channel value explicitly --- jack_mixer/app.py | 1 + jack_mixer/channel.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/jack_mixer/app.py b/jack_mixer/app.py index 4e72c2c..ee47946 100644 --- a/jack_mixer/app.py +++ b/jack_mixer/app.py @@ -433,6 +433,7 @@ def add_output_channel( self, name, stereo=True, + midi_channel=1, volume_cc=-1, balance_cc=-1, mute_cc=-1, diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index ef147ce..0f737d7 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -56,8 +56,8 @@ def __init__(self, app, name, stereo=True, direct_output=True, initial_vol=None) self.wants_direct_output = direct_output self.post_fader_output_channel = None self.future_out_mute = None - self.future_volume_midi_cc = None self.future_midi_channel = None + self.future_volume_midi_cc = None self.future_balance_midi_cc = None self.future_mute_midi_cc = None self.future_solo_midi_cc = None @@ -420,6 +420,7 @@ def on_monitor_button_toggled(self, button): if self.app.monitored_channel is self: self.app.monitored_channel = None + # should probs have a param here for MIDI channel def assign_midi_ccs(self, volume_cc, balance_cc, mute_cc, solo_cc=None): try: if volume_cc != -1: @@ -1255,7 +1256,7 @@ def on_entry_name_changed(self, entry): sensitive = True self.ok_button.set_sensitive(sensitive) - +# prolly where the values of the dialog persist? class NewChannelDialog(ChannelPropertiesDialog): def create_ui(self): super().create_ui() @@ -1286,6 +1287,7 @@ def fill_ui(self, **values): self.direct_output.set_active(values.get("direct_output", True)) # don't set MIDI CCs to previously used values, because they # would overwrite existing mappings, if accepted. + self.entry_midi_channel.set_value(1) self.entry_volume_cc.set_value(-1) self.entry_balance_cc.set_value(-1) self.entry_mute_cc.set_value(-1) From 56754c5b20bdf3dfd1e6444e936a8383b0097b69 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Wed, 26 Jan 2022 00:21:48 -0800 Subject: [PATCH 06/11] change names as string h4x --- jack_mixer/app.py | 4 ++-- jack_mixer/channel.py | 34 ++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/jack_mixer/app.py b/jack_mixer/app.py index ee47946..6504ad5 100644 --- a/jack_mixer/app.py +++ b/jack_mixer/app.py @@ -371,7 +371,7 @@ def add_channel( name, stereo=True, direct_output=True, - midi_channel=1, + midi_channel_cc=1, volume_cc=-1, balance_cc=-1, mute_cc=-1, @@ -433,7 +433,7 @@ def add_output_channel( self, name, stereo=True, - midi_channel=1, + midi_channel_cc=1, volume_cc=-1, balance_cc=-1, mute_cc=-1, diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index 0f737d7..242f8ad 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -56,7 +56,7 @@ def __init__(self, app, name, stereo=True, direct_output=True, initial_vol=None) self.wants_direct_output = direct_output self.post_fader_output_channel = None self.future_out_mute = None - self.future_midi_channel = None + self.future_midi_channel_midi_cc = None self.future_volume_midi_cc = None self.future_balance_midi_cc = None self.future_mute_midi_cc = None @@ -579,8 +579,8 @@ def serialize(self, object_backend): if hasattr(self.channel, "out_mute"): object_backend.add_property("out_mute", str(self.channel.out_mute)) - if self.channel.midi_channel != -1: - object_backend.add_property("midi_channel", str(self.channel.midi_channel)) + if self.channel.midi_channel_midi_cc != -1: + object_backend.add_property("midi_channel_midi_cc", str(self.channel.midi_channel_midi_cc)) if self.channel.volume_midi_cc != -1: object_backend.add_property("volume_midi_cc", str(self.channel.volume_midi_cc)) if self.channel.balance_midi_cc != -1: @@ -604,7 +604,7 @@ def unserialize_property(self, name, value): self.meter_prefader = (value == "True") return True elif name == "midi_channel": - self.future_midi_channel = int(value) + self.future_midi_channel_midi_cc = int(value) return True elif name == "volume_midi_cc": self.future_volume_midi_cc = int(value) @@ -648,8 +648,8 @@ def realize(self): super().realize() - if self.future_midi_channel is not None: - self.channel.midi_channel = self.future_midi_channel + if self.future_midi_channel_midi_cc is not None: + self.channel.midi_channel = self.future_midi_channel_midi_cc if self.future_volume_midi_cc is not None: self.channel.volume_midi_cc = self.future_volume_midi_cc if self.future_balance_midi_cc is not None: @@ -867,8 +867,8 @@ def realize(self): super().realize() - if self.future_midi_channel is not None: - self.channel.midi_channel = self.future_midi_channel + if self.future_midi_channel_midi_cc is not None: + self.channel.midi_channel_midi_cc = self.future_midi_channel_midi_cc if self.future_volume_midi_cc is not None: self.channel.volume_midi_cc = self.future_volume_midi_cc if self.future_balance_midi_cc is not None: @@ -1086,10 +1086,10 @@ def create_ui(self): channel_label = Gtk.Label.new_with_mnemonic(_("_Channel")) channel_label.set_halign(Gtk.Align.START) grid.attach(channel_label,0,0,1,1) - self.entry_midi_channel = Gtk.SpinButton.new_with_range(1, 16, 1) - self.entry_midi_channel.set_tooltip_text(cc_tooltip.format(param=_("Channel"))) - channel_label.set_mnemonic_widget(self.entry_midi_channel) - grid.attach(self.entry_midi_channel, 1, 0, 1, 1) + self.entry_midi_channel_cc = Gtk.SpinButton.new_with_range(1, 16, 1) + self.entry_midi_channel_cc.set_tooltip_text(cc_tooltip.format(param=_("Channel"))) + channel_label.set_mnemonic_widget(self.entry_midi_channel_cc) + grid.attach(self.entry_midi_channel_cc, 1, 0, 1, 1) volume_label = Gtk.Label.new_with_mnemonic(_("_Volume")) volume_label.set_halign(Gtk.Align.START) @@ -1160,7 +1160,7 @@ def fill_ui(self): self.mono.set_active(True) self.mono.set_sensitive(False) self.stereo.set_sensitive(False) - self.entry_midi_channel.set_value(self.channel.channel.midi_channel) + self.entry_midi_channel_cc.set_value(self.channel.channel.midi_channel_midi_cc) self.entry_volume_cc.set_value(self.channel.channel.volume_midi_cc) self.entry_balance_cc.set_value(self.channel.channel.balance_midi_cc) self.entry_mute_cc.set_value(self.channel.channel.mute_midi_cc) @@ -1235,11 +1235,13 @@ def on_response_cb(self, dlg, response_id, *args): self.channel.post_fader_output_channel.remove() self.channel.post_fader_output_channel = None - for control in ("volume", "balance", "mute", "solo"): + for control in ("midi_channel", "volume", "balance", "mute", "solo"): + # whelp, naming the attribute "midi_channel" rather then "midi_channel_cc" seems like it would be excluded from the following line. widget = getattr(self, "entry_{}_cc".format(control), None) if widget is not None: value = int(widget.get_value()) if value != -1: + # oh, yeah. this won't work...I guess I change the name to "channel" which seems ambiguous, or midichannel setattr(self.channel.channel, "{}_midi_cc".format(control), value) self.hide() @@ -1287,7 +1289,7 @@ def fill_ui(self, **values): self.direct_output.set_active(values.get("direct_output", True)) # don't set MIDI CCs to previously used values, because they # would overwrite existing mappings, if accepted. - self.entry_midi_channel.set_value(1) + self.entry_midi_channel_cc.set_value(1) self.entry_volume_cc.set_value(-1) self.entry_balance_cc.set_value(-1) self.entry_mute_cc.set_value(-1) @@ -1301,7 +1303,7 @@ def get_result(self): "name": self.entry_name.get_text(), "stereo": self.stereo.get_active(), "direct_output": self.direct_output.get_active(), - "midi_channel": int(self.entry_midi_channel.get_value()), + "midi_channel_cc": int(self.entry_midi_channel_cc.get_value()), "volume_cc": int(self.entry_volume_cc.get_value()), "balance_cc": int(self.entry_balance_cc.get_value()), "mute_cc": int(self.entry_mute_cc.get_value()), From 725d8f10aec19af6853c98c316140c43094f340c Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Wed, 26 Jan 2022 01:01:59 -0800 Subject: [PATCH 07/11] I think...I renamed the things --- jack_mixer/channel.py | 2 ++ src/_jack_mixer.pxd | 6 +++--- src/_jack_mixer.pyx | 10 +++++----- src/jack_mixer.c | 6 +++--- src/jack_mixer.h | 4 ++-- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index 242f8ad..b6540ab 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -1362,6 +1362,7 @@ def fill_ui(self, **values): # don't set MIDI CCs to previously used values, because they # would overwrite existing mappings, if accepted. + self.entry_midi_channel_cc.set_value(-1) self.entry_volume_cc.set_value(-1) self.entry_balance_cc.set_value(-1) self.entry_mute_cc.set_value(-1) @@ -1376,6 +1377,7 @@ def get_result(self): return { "name": self.entry_name.get_text(), "stereo": self.stereo.get_active(), + "midi_channel_cc": int(self.entry_midi_channel_cc.get_value()), "volume_cc": int(self.entry_volume_cc.get_value()), "balance_cc": int(self.entry_balance_cc.get_value()), "mute_cc": int(self.entry_mute_cc.get_value()), diff --git a/src/_jack_mixer.pxd b/src/_jack_mixer.pxd index 1b9560f..762779a 100644 --- a/src/_jack_mixer.pxd +++ b/src/_jack_mixer.pxd @@ -128,18 +128,18 @@ cdef extern from "jack_mixer.h": cdef int channel_autoset_mute_midi_cc(jack_mixer_channel_t channel) cdef int channel_autoset_solo_midi_cc(jack_mixer_channel_t channel) cdef int channel_autoset_volume_midi_cc(jack_mixer_channel_t channel) - cdef int channel_autoset_midi_channel(jack_mixer_channel_t channel) + cdef int channel_autoset_midi_channel_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_balance_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_mute_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_solo_midi_cc(jack_mixer_channel_t channel) cdef int channel_get_volume_midi_cc(jack_mixer_channel_t channel) - cdef int channel_get_midi_channel(jack_mixer_channel_t channel) + cdef int channel_get_midi_channel_midi_cc(jack_mixer_channel_t channel) cdef int channel_set_balance_midi_cc(jack_mixer_channel_t channel, int new_cc) cdef int channel_set_mute_midi_cc(jack_mixer_channel_t channel, int new_cc) cdef int channel_set_solo_midi_cc(jack_mixer_channel_t channel, int new_cc) cdef int channel_set_volume_midi_cc(jack_mixer_channel_t channel, int new_cc) - cdef int channel_set_midi_channel(jack_mixer_channel_t channel, int new_channel) + cdef int channel_set_midi_channel_midi_cc(jack_mixer_channel_t channel, int new_channel) cdef void channel_set_midi_scale(jack_mixer_channel_t channel, jack_mixer_scale_t scale) diff --git a/src/_jack_mixer.pyx b/src/_jack_mixer.pyx index a6dedd1..4d0bc47 100644 --- a/src/_jack_mixer.pyx +++ b/src/_jack_mixer.pyx @@ -443,13 +443,13 @@ cdef class Channel: raise ValueError(jack_mixer_error_str().decode('utf-8')) @property - def midi_channel(self): + def midi_channel_midi_cc(self): """MIDI channel to control audio channel.""" - return channel_get_midi_channel(self._channel) + return channel_get_midi_channel_midi_cc(self._channel) - @midi_channel.setter - def midi_channel(self, int channel): - if channel_set_midi_channel(self._channel, channel) != 0: + @midi_channel_midi_cc.setter + def midi_channel_midi_cc(self, int channel): + if channel_set_midi_channel_midi_cc(self._channel, channel) != 0: raise ValueError(jack_mixer_error_str().decode('utf-8')) @property diff --git a/src/jack_mixer.c b/src/jack_mixer.c index c874ed6..ecba27b 100644 --- a/src/jack_mixer.c +++ b/src/jack_mixer.c @@ -429,7 +429,7 @@ channel_set_balance_midi_cc( } int8_t -channel_get_midi_channel( +channel_get_midi_channel_midi_cc( jack_mixer_channel_t channel) { // prolly need to set this index somewhere else @@ -437,7 +437,7 @@ channel_get_midi_channel( } int -channel_set_midi_channel( +channel_set_midi_channel_midi_cc( jack_mixer_channel_t channel, int8_t new_channel) { @@ -548,7 +548,7 @@ channel_set_solo_midi_cc( } int -channel_autoset_midi_channel( +channel_autoset_midi_channel_midi_cc( jack_mixer_channel_t channel) { // check out what the autoset things really do diff --git a/src/jack_mixer.h b/src/jack_mixer.h index 542dcc1..6e4571d 100644 --- a/src/jack_mixer.h +++ b/src/jack_mixer.h @@ -251,11 +251,11 @@ channel_set_balance_midi_cc( int8_t new_cc); int8_t -channel_get_midi_channel( +channel_get_midi_channel_midi_cc( jack_mixer_channel_t channel); int -channel_set_midi_channel( +channel_set_midi_channel_midi_cc( jack_mixer_channel_t channel, int8_t new_channel); From c356f0ddcdf8b9040c3f95f102366e5584708210 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Wed, 26 Jan 2022 20:25:34 -0800 Subject: [PATCH 08/11] add some C headers --- src/_jack_mixer.pyx | 4 ++++ src/jack_mixer.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/_jack_mixer.pyx b/src/_jack_mixer.pyx index 4d0bc47..96fc22e 100644 --- a/src/_jack_mixer.pyx +++ b/src/_jack_mixer.pyx @@ -474,6 +474,10 @@ cdef class Channel: """Auto assign MIDI CC for channel solo status.""" return channel_autoset_solo_midi_cc(self._channel) + def autoset_midi_channel_midi_cc(self): + """Auto assign MIDI channel.""" + return channel_autoset_midi_channel_midi_cc(self._channel) + def autoset_volume_midi_cc(self): """Auto assign MIDI CC for channel volume.""" return channel_autoset_volume_midi_cc(self._channel) diff --git a/src/jack_mixer.h b/src/jack_mixer.h index 6e4571d..14dc80c 100644 --- a/src/jack_mixer.h +++ b/src/jack_mixer.h @@ -297,7 +297,7 @@ channel_set_midi_cc_balance_picked_up( bool status); int -channel_autoset_midi_channel( +channel_autoset_midi_channel_midi_cc( jack_mixer_channel_t channel); int From ac04117e1cbc82bd952b8e192cc26a2b21f19f82 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Wed, 26 Jan 2022 23:47:04 -0800 Subject: [PATCH 09/11] add midi channel to function --- jack_mixer/app.py | 4 ++-- jack_mixer/channel.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/jack_mixer/app.py b/jack_mixer/app.py index 6504ad5..0adb620 100644 --- a/jack_mixer/app.py +++ b/jack_mixer/app.py @@ -387,7 +387,7 @@ def add_channel( error_dialog(self.window, _("Input channel creation failed.")) return - channel.assign_midi_ccs(volume_cc, balance_cc, mute_cc, solo_cc) + channel.assign_midi_ccs(midi_channel_cc, volume_cc, balance_cc, mute_cc, solo_cc) return channel def add_channel_precreated(self, channel): @@ -450,7 +450,7 @@ def add_output_channel( error_dialog(self.window, _("Output channel creation failed.")) return - channel.assign_midi_ccs(volume_cc, balance_cc, mute_cc) + channel.assign_midi_ccs(midi_channel_cc, volume_cc, balance_cc, mute_cc) return channel def add_output_channel_precreated(self, channel): diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index b6540ab..f1ca417 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -421,7 +421,16 @@ def on_monitor_button_toggled(self, button): self.app.monitored_channel = None # should probs have a param here for MIDI channel - def assign_midi_ccs(self, volume_cc, balance_cc, mute_cc, solo_cc=None): + def assign_midi_ccs(self, midi_channel_cc, volume_cc, balance_cc, mute_cc, solo_cc=None): + try: + if midi_channel_cc != -1: + self.channel.midi_channel_midi_cc = midi_channel_cc + else: + midi_channel_cc = self.channel.autoset_midi_channel_midi_cc() + + log.debug("Channel '%s' MIDI channel assigned to #%s.", self.channel.name, midi_channel_cc) + except Exception as exc: + log.error("Channel '%s' MIDI channel assignment failed: %s", self.channel.name, exc) try: if volume_cc != -1: self.channel.volume_midi_cc = volume_cc From c651dd4c9ef62ca2249012c1685b6d71b2021a9d Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Thu, 27 Jan 2022 03:00:48 -0800 Subject: [PATCH 10/11] I'm the best, I did it. at least the GUI persists values. no actually MIDI channel is activated tho. --- jack_mixer/app.py | 1 + jack_mixer/channel.py | 4 ++-- src/jack_mixer.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/jack_mixer/app.py b/jack_mixer/app.py index 0adb620..d81f512 100644 --- a/jack_mixer/app.py +++ b/jack_mixer/app.py @@ -1050,6 +1050,7 @@ def save_to_xml(self, file): b = self.get_xml_serialization() b.save(file) + # I think I broke loading XML (or perhaps saving) with my midi channel changes def load_from_xml(self, file, silence_errors=False, from_nsm=False): log.debug("Loading from XML...") self.unserialized_channels = [] diff --git a/jack_mixer/channel.py b/jack_mixer/channel.py index f1ca417..d3ba6db 100644 --- a/jack_mixer/channel.py +++ b/jack_mixer/channel.py @@ -276,6 +276,7 @@ def unrealize(self): # --------------------------------------------------------------------------------------------- # Signal/event handlers + # this is where the double click happens for channel props def on_label_mouse(self, widget, event): if event.type == Gdk.EventType._2BUTTON_PRESS: if event.button == 1: @@ -1245,12 +1246,11 @@ def on_response_cb(self, dlg, response_id, *args): self.channel.post_fader_output_channel = None for control in ("midi_channel", "volume", "balance", "mute", "solo"): - # whelp, naming the attribute "midi_channel" rather then "midi_channel_cc" seems like it would be excluded from the following line. widget = getattr(self, "entry_{}_cc".format(control), None) if widget is not None: value = int(widget.get_value()) if value != -1: - # oh, yeah. this won't work...I guess I change the name to "channel" which seems ambiguous, or midichannel + # looking for where midi_channel_midi_cc can persist in a running session. Is this in the C function? setattr(self.channel.channel, "{}_midi_cc".format(control), value) self.hide() diff --git a/src/jack_mixer.c b/src/jack_mixer.c index ecba27b..463c4e2 100644 --- a/src/jack_mixer.c +++ b/src/jack_mixer.c @@ -441,7 +441,17 @@ channel_set_midi_channel_midi_cc( jack_mixer_channel_t channel, int8_t new_channel) { - // def need to make a real function do things here + if (new_channel < 0) { + _jack_mixer_error = JACK_MIXER_ERROR_INVALID_CC; + return -1; + } + + unset_midi_cc_mapping(channel_ptr->mixer_ptr, new_channel); + if (channel_ptr->midi_channel_index != -1) { + channel_ptr->mixer_ptr->midi_cc_map[channel_ptr->midi_channel_index] = NULL; + } + channel_ptr->mixer_ptr->midi_cc_map[new_channel] = channel_ptr; + channel_ptr->midi_channel_index = new_channel; return 0; } @@ -551,8 +561,21 @@ int channel_autoset_midi_channel_midi_cc( jack_mixer_channel_t channel) { - // check out what the autoset things really do - return 0; + struct jack_mixer *mixer_ptr = channel_ptr->mixer_ptr; + + for (int i = 1 ; i < 16 ; i++) + { + if (!mixer_ptr->midi_cc_map[i]) + { + mixer_ptr->midi_cc_map[i] = channel_ptr; + channel_ptr->midi_channel_index = i; + + LOG_DEBUG("New channel \"%s\" MIDI channel mapped to %i.\n", channel_ptr->name, i); + return i; + } + } + _jack_mixer_error = JACK_MIXER_ERROR_NO_FREE_CC; + return -1; } int From cbd88014591aa5b9bd0b000aeae3d1bbc6b57738 Mon Sep 17 00:00:00 2001 From: Lee Azzarello Date: Sun, 30 Jan 2022 02:25:00 -0800 Subject: [PATCH 11/11] isolated the MIDI channel! --- src/jack_mixer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/jack_mixer.c b/src/jack_mixer.c index 463c4e2..a9a05a6 100644 --- a/src/jack_mixer.c +++ b/src/jack_mixer.c @@ -1603,7 +1603,7 @@ process( void * midi_buffer; double volume, balance; uint8_t cc_channel_index; - uint8_t cc_num, cc_val, cur_cc_val; + uint8_t cc_num, cc_val, cur_cc_val, cc_channel; #endif /* Get input ports buffer pointers */ @@ -1638,14 +1638,17 @@ process( assert(in_event.time < nframes); + // mask out the first bits, keep the second bits for MIDI channel + cc_channel = (uint8_t)(in_event.buffer[0] & 0x0F ); cc_num = (uint8_t)(in_event.buffer[1] & 0x7F); cc_val = (uint8_t)(in_event.buffer[2] & 0x7F); mixer_ptr->last_midi_cc = (int8_t)cc_num; - - LOG_DEBUG("%u: CC#%u -> %u\n", (unsigned int)(in_event.buffer[0]), cc_num, cc_val); + LOG_DEBUG("MIDI CHANNEL %u: CC#%u -> %u\n", cc_channel, cc_num, cc_val); /* Do we have a mapping for particular CC? */ channel_ptr = mixer_ptr->midi_cc_map[cc_num]; + // this is our global channel + mixer_ptr->midi_cc_map[cc_channel]; if (channel_ptr) { if (channel_ptr->midi_cc_balance_index == cc_num)