diff --git a/README.md b/README.md index cd31e26..96d4ae9 100644 --- a/README.md +++ b/README.md @@ -435,11 +435,11 @@ Features & TODO https://amei.or.jp/midistandardcommittee/Recommended_Practice/e/rp49.pdf) Three Dimensional Sound Controllers - [ ] Non Registered Parameter Numbers (NRPN) - - [ ] Program Changes, Bank Select & Patches - - [ ] [General MIDI System (MMA)]( + - [x] *(WIP)* Program Changes, Bank Select & Patches + - [ ] *(WIP)* [General MIDI System (MMA)]( https://www.midi.org/specifications/midi1-specifications/general-midi-specifications) (GM) - - [ ] Level 1 (GM1/GM-1) (1991) + - [ ] *(WIP)* Level 1 (GM1/GM-1) (1991) [MMA0007/RP-003]( https://www.midi.org/specifications/midi1-specifications/general-midi-specifications/general-midi-1) General MIDI System Level 1 @@ -484,7 +484,7 @@ Features & TODO - [x] Manufacturer ID - [x] Device ID - [x] Raw payload - - [ ] *(WIP)* Universal System Exclusive (Realtime & Non-Realtime) + - [x] *(WIP)* Universal System Exclusive (Realtime & Non-Realtime) - [x] Sub-IDs 1 & 2 type decoding - [ ] Payloads decoding - [ ] MIDI Show Control (MSC) diff --git a/src/midiexplorer/gui/windows/mon/__init__.py b/src/midiexplorer/gui/windows/mon/__init__.py index 8ce4af2..8f3e1f2 100644 --- a/src/midiexplorer/gui/windows/mon/__init__.py +++ b/src/midiexplorer/gui/windows/mon/__init__.py @@ -103,6 +103,12 @@ def create() -> None: # ---------------------------- for indicator in get_supported_indicators(): dpg.add_float_value(tag=f'{indicator}_active_until', default_value=0) # seconds + # ---------------- + # Program decoding + # ---------------- + dpg.add_string_value(tag='pc_num') + dpg.add_string_value(tag='pc_group_name') + dpg.add_string_value(tag='pc_name') # --------------- # SysEx decoding # --------------- @@ -533,7 +539,7 @@ def create() -> None: # ------ # Notes # ------ - with dpg.collapsing_header(label="Notes", default_open=True): + with dpg.collapsing_header(label="Notes", default_open=not DEBUG): dpg.add_child_window(tag='mon_notes_container', height=180, border=False) # TODO: Staff? @@ -587,10 +593,15 @@ def create() -> None: else: bxpos += width + margin + ### + # TODO: Polyphonic Key Pressure (Aftertouch) + ### + # Value timegraph + # ------------ # Controllers # ------------ - with dpg.collapsing_header(label="Controllers", default_open=True): + with dpg.collapsing_header(label="Controllers", default_open=not DEBUG): dpg.add_child_window(tag='mon_controllers_container', height=400, border=False) with dpg.table(tag='mon_controllers', parent='mon_controllers_container', header_row=False, @@ -645,15 +656,38 @@ def create() -> None: ### # Value timegraph + # -------------- + # Program change + # -------------- ### - # TODO: Polyphonic Key Pressure (Aftertouch) + # TODO: Bank Select? + # Value timegraph ### - # Value timegraph + mon_prog_height=70 + if DEBUG: + mon_prog_height=120 - ### - # TODO: Program change status? (+ Bank Select?) - ### - # Value timegraph + with dpg.collapsing_header(label="Program", default_open=True): + with dpg.child_window(tag='mon_program_container', height=mon_prog_height, border=False): + with dpg.group(horizontal=True): + dpg.add_text("Num") + dpg.add_input_text(source='pc_num', readonly=True, width=50) # 0-127 + if DEBUG: + with dpg.group(horizontal=True): + dpg.add_text("Resource") + # TODO: Autoset on receiving Defined Universal Sysex non real time + dpg.add_combo(["GM", "GM2", "GS", "XG"], default_value="GM") + # TODO: Add logo + with dpg.group(horizontal=True): # TODO: Not GM modes only + dpg.add_text("Bank") + dpg.add_input_text(source='pc_bank_num', readonly=True, width=50) # 0-16383 + dpg.add_input_text(source='pc_bank_name', readonly=True, width=250) + with dpg.group(horizontal=True): # TODO: GM mode only + dpg.add_text("Group") + dpg.add_input_text(source='pc_group_name', readonly=True, width=250) + with dpg.group(horizontal=True): + dpg.add_text("Name") + dpg.add_input_text(source='pc_name', readonly=True, width=250) ### # TODO: Pitch bend change @@ -687,7 +721,7 @@ def create() -> None: # ----------------- # System Exclusive # ----------------- - with dpg.collapsing_header(label="System Exclusive", default_open=True): + with dpg.collapsing_header(label="System Exclusive", default_open=not DEBUG): with dpg.child_window(tag='mon_sysex_container', height=120, border=False): with dpg.group(): diff --git a/src/midiexplorer/gui/windows/mon/blink.py b/src/midiexplorer/gui/windows/mon/blink.py index bca7d8a..a852464 100644 --- a/src/midiexplorer/gui/windows/mon/blink.py +++ b/src/midiexplorer/gui/windows/mon/blink.py @@ -70,6 +70,9 @@ def get_supported_indicators() -> list: def get_supported_decoders() -> list: decoders = [ + 'pc_num', + 'pc_group_name', + 'pc_name', 'syx_id_group', 'syx_id_region', 'syx_id_name', diff --git a/src/midiexplorer/gui/windows/mon/data.py b/src/midiexplorer/gui/windows/mon/data.py index f76749a..483da1b 100644 --- a/src/midiexplorer/gui/windows/mon/data.py +++ b/src/midiexplorer/gui/windows/mon/data.py @@ -7,7 +7,7 @@ """ Monitor data management. """ - +import midi_const import mido from dearpygui import dearpygui as dpg from midi_const import NOTE_OFF_VELOCITY @@ -89,8 +89,11 @@ def update_gui_monitor(data: mido.Message, static: bool = False) -> None: elif 'control_change' == data.type: cc(data.control, data.value, static) elif 'program_change' == data.type: - # TODO: Optionally decode General MIDI names. - pass + dpg.set_value('pc_num', data.program) + # Decode General MIDI names. + dpg.set_value('pc_group_name', midi_const.GENERAL_MIDI_SOUND_SET_GROUPINGS[data.program]) + dpg.set_value('pc_name', midi_const.GENERAL_MIDI_SOUND_SET[data.program]) + # TODO: Optionally decode other modes names. elif 'aftertouch' == data.type: # TODO: display pass @@ -109,5 +112,3 @@ def update_gui_monitor(data: mido.Message, static: bool = False) -> None: elif 'song_select' == data.type: # TODO: display pass - -