From b444395fcd240f7cd091f3c7e82c5dac74b18755 Mon Sep 17 00:00:00 2001 From: Rio Date: Wed, 9 Oct 2019 23:45:55 +0200 Subject: [PATCH] Feature: Proteus 2000 Integration - Send Proteus 2000 Parameter Value Edit: Multimode Basic Channel Select - Changed following functions to Proteus2000/XL-Turbo Handler: s32 SEQ_UI_Button_Scrub s32 SEQ_UI_Button_Metronome - Scrub and Metronome functionality is removed by this mod --- apps/sequencers/midibox_seq_v4/Makefile | 9 + .../midibox_seq_v4/core/seq_midi_sysex.c | 41 +++ .../midibox_seq_v4/core/seq_midi_sysex.h | 9 + apps/sequencers/midibox_seq_v4/core/seq_ui.c | 40 ++- apps/sequencers/midibox_seq_v4/core/seq_ui.h | 10 + .../midibox_seq_v4/core/seq_ui_pages.c | 9 + .../midibox_seq_v4/core/seq_ui_pages.h | 10 + .../midibox_seq_v4/core/seq_ui_proteus.c | 254 ++++++++++++++++++ 8 files changed, 380 insertions(+), 2 deletions(-) create mode 100644 apps/sequencers/midibox_seq_v4/core/seq_ui_proteus.c diff --git a/apps/sequencers/midibox_seq_v4/Makefile b/apps/sequencers/midibox_seq_v4/Makefile index 5bf77c12e..dbb9de401 100644 --- a/apps/sequencers/midibox_seq_v4/Makefile +++ b/apps/sequencers/midibox_seq_v4/Makefile @@ -14,6 +14,10 @@ LCD = $(MIOS32_LCD) # Source Files, include paths and libraries ################################################################################ +#################################### +# RIO: Added PROTEUS files +#################################### + THUMB_SOURCE = core/app.c \ mios32/tasks.c \ core/seq_hwcfg.c \ @@ -51,6 +55,7 @@ THUMB_SOURCE = core/app.c \ core/seq_ui_fx_scale.c \ core/seq_ui_manual.c \ core/seq_ui_util.c \ + core/seq_ui_proteus.c \ core/seq_ui_bpm.c \ core/seq_ui_bpm_presets.c \ core/seq_ui_opt.c \ @@ -118,6 +123,10 @@ THUMB_SOURCE = core/app.c \ core/seq_blm8x8.c \ core/seq_tpd.c +#################################### +# RIO: END MODIFICATION +#################################### + # (following source stubs not relevant for Cortex M3 derivatives) THUMB_AS_SOURCE = ARM_SOURCE = diff --git a/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.c b/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.c index 1b71d0ec4..5f2ef3777 100644 --- a/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.c +++ b/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.c @@ -766,4 +766,45 @@ s32 SEQ_MIDI_SYSEX_REMOTE_Server_SendLED(u8 first_sr, u8 *led_sr, u8 num_sr) return status; } +//########################################################################### +//# RIO: Proteus 2000 Parameter Value Edit -> Multimode Basic Channel Select +//########################################################################### +///////////////////////////////////////////////////////////////////////////// +// RIO: This function is called to send a Proteus 2000 Parameter Value Edit +// EXAMPLE:> {F0h, 18h, 0Fh, dd, 55h, 01h, 02h, , F7h} +// +// MULTIMODE_BASIC_CHANNEL (Independent of MULTIMODE_CHANNEL_SELECT) +// xx, xx = id = 139 (0Bh,01h) yy, yy = min = 0; max = 15 +// +// Example for Channel 4: F0 18 0F 02 55 01 02 0B 01 03 00 F7 +///////////////////////////////////////////////////////////////////////////// +s32 SEQ_MIDI_SYSEX_PROTEUS_SendChannel(mios32_midi_port_t port, u8 sysex_device_id, u8 basic_channel) +{ + u8 sysex_buffer[12]; + u8 *sysex_buffer_ptr = &sysex_buffer[0]; + + // send proteus 2000 sysex + *sysex_buffer_ptr++ = 0xf0; // sysex message + *sysex_buffer_ptr++ = 0x18; // EMU ID + *sysex_buffer_ptr++ = 0x0f; // Proteus ID + *sysex_buffer_ptr++ = sysex_device_id; // Device ID + *sysex_buffer_ptr++ = 0x55; // Special Editor designator byte + *sysex_buffer_ptr++ = 0x01; // Command::Parameter Value Edit + *sysex_buffer_ptr++ = 0x02; // Byte count(number of Byte pairs) + *sysex_buffer_ptr++ = 0x0b; // Parameter ID for MULTIMODE_BASIC_CHANNEL 139 LSB + *sysex_buffer_ptr++ = 0x01; // Parameter ID for MULTIMODE_BASIC_CHANNEL 139 MSB + *sysex_buffer_ptr++ = basic_channel; // Parameter Data for MULTIMODE_BASIC_CHANNEL LSB + *sysex_buffer_ptr++ = 0x00; // Parameter Data for MULTIMODE_BASIC_CHANNEL MSB + *sysex_buffer_ptr++ = 0xf7; + + // finally send SysEx stream + MUTEX_MIDIOUT_TAKE; + s32 status = MIOS32_MIDI_SendSysEx(port, (u8 *)sysex_buffer, (u32)sysex_buffer_ptr - ((u32)&sysex_buffer[0])); + MUTEX_MIDIOUT_GIVE; + return status; +} + +//########################################################################### +//# RIO: END MODIFICATION +//########################################################################### \ No newline at end of file diff --git a/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.h b/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.h index f6e6fbcfe..dae607a93 100644 --- a/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.h +++ b/apps/sequencers/midibox_seq_v4/core/seq_midi_sysex.h @@ -53,6 +53,15 @@ extern s32 SEQ_MIDI_SYSEX_REMOTE_Server_SendLCD(u8 x, u8 y, u8 *str, u8 len); extern s32 SEQ_MIDI_SYSEX_REMOTE_Server_SendCharset(u8 charset); extern s32 SEQ_MIDI_SYSEX_REMOTE_Server_SendLED(u8 first_sr, u8 *led_sr, u8 num_sr); +//########################################################################### +//# RIO: Proteus 2000 Parameter Value Edit -> Multimode Basic Channel Select +//########################################################################### + +extern s32 SEQ_MIDI_SYSEX_PROTEUS_SendChannel(mios32_midi_port_t port, u8 proteus_id, u8 basic_channel); + +//########################################################################### +//# RIO: END MODIFICATION +//########################################################################### ///////////////////////////////////////////////////////////////////////////// // Export global variables diff --git a/apps/sequencers/midibox_seq_v4/core/seq_ui.c b/apps/sequencers/midibox_seq_v4/core/seq_ui.c index 38ff142ad..930783ae7 100644 --- a/apps/sequencers/midibox_seq_v4/core/seq_ui.c +++ b/apps/sequencers/midibox_seq_v4/core/seq_ui.c @@ -786,7 +786,11 @@ static s32 SEQ_UI_Button_Follow(s32 depressed) return 0; // no error } -static s32 SEQ_UI_Button_Scrub(s32 depressed) +//#################################### +//# RIO: Replace with PROTEUS Handler +//#################################### + +/*static s32 SEQ_UI_Button_Scrub(s32 depressed) { // double function: -> Loop if menu button pressed if( seq_ui_button_state.MENU_PRESSED ) @@ -803,9 +807,23 @@ static s32 SEQ_UI_Button_Scrub(s32 depressed) SEQ_UI_Msg(SEQ_UI_MSG_USER, 1000, "Scrub Mode", seq_ui_button_state.SCRUB ? " on" : " off"); + return 0; // no error +}*/ + +static s32 SEQ_UI_Button_Scrub(s32 depressed) +{ + if( depressed ) return -1; // ignore when button depressed + + // change to utility page + SEQ_UI_PageSet(SEQ_UI_PAGE_PROTEUS); + return 0; // no error } +//#################################### +//# RIO: END MODIFICATION +//#################################### + static s32 SEQ_UI_Button_TempoPreset(s32 depressed) { static seq_ui_page_t prev_page = SEQ_UI_PAGE_NONE; @@ -854,7 +872,11 @@ static s32 SEQ_UI_Button_ExtRestart(s32 depressed) return 0; // no error } -static s32 SEQ_UI_Button_Metronome(s32 depressed) +//#################################### +//# RIO: Replace with XLTURBO Handler +//#################################### + +/*static s32 SEQ_UI_Button_Metronome(s32 depressed) { // double function: -> ExtRestart if menu button pressed if( seq_ui_button_state.MENU_PRESSED ) @@ -882,9 +904,23 @@ static s32 SEQ_UI_Button_Metronome(s32 depressed) SEQ_PATTERN_FixAll(); #endif + return 0; // no error +}*/ + +static s32 SEQ_UI_Button_Metronome(s32 depressed) +{ + if( depressed ) return -1; // ignore when button depressed + + // change to utility page + SEQ_UI_PageSet(SEQ_UI_PAGE_XLTURBO); + return 0; // no error } +//#################################### +//# RIO: END MODIFICATION +//#################################### + s32 SEQ_UI_Button_Record(s32 depressed) { if( depressed ) return -1; // ignore when button depressed diff --git a/apps/sequencers/midibox_seq_v4/core/seq_ui.h b/apps/sequencers/midibox_seq_v4/core/seq_ui.h index 419d269cd..8da111fb6 100644 --- a/apps/sequencers/midibox_seq_v4/core/seq_ui.h +++ b/apps/sequencers/midibox_seq_v4/core/seq_ui.h @@ -395,6 +395,16 @@ extern s32 SEQ_UI_TRKREPEAT_Init(u32 mode); extern s32 SEQ_UI_PATTERN_RMX_Init(u32 mode); extern s32 SEQ_UI_TRKEUCLID_Init(u32 mode); +//#################################### +//# RIO: PROTEUS added +//#################################### + +extern s32 SEQ_UI_PROTEUS_Init(u32 mode); // RIO: added Proteus +extern s32 SEQ_UI_XLTURBO_Init(u32 mode); // RIO: added Proteus + +//#################################### +//# RIO: END MODIFICATION +//#################################### extern s32 SEQ_UI_EDIT_LED_Handler(u16 *gp_leds); extern s32 SEQ_UI_EDIT_Button_Handler(seq_ui_button_t button, s32 depressed); diff --git a/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.c b/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.c index 349c92d46..da5359c65 100644 --- a/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.c +++ b/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.c @@ -40,6 +40,10 @@ typedef struct { s32 (*init_callback)(u32 mode); // will be called to initialize the page } seq_ui_page_entry_t; +//#################################### +//# RIO: PROTEUS added +//#################################### + static const seq_ui_page_entry_t ui_menu_pages[SEQ_UI_PAGES] = { { "NONE", "TODO ", "TODO page ", 0, (void *)&SEQ_UI_TODO_Init }, { "MENU", "Menu ", "Page Menu ", 1, (void *)&SEQ_UI_MENU_Init }, @@ -102,8 +106,13 @@ static const seq_ui_page_entry_t ui_menu_pages[SEQ_UI_PAGES] = { { "REMIX", "Remix", "Pattern Remix ", 54, (void *)&SEQ_UI_PATTERN_RMX_Init }, { "BOOKMARKS", "BookM", "Bookmarks ", 51, (void *)&SEQ_UI_BOOKMARKS_Init }, { "ABOUT", "About", "About this MIDIbox", 52, (void *)&SEQ_UI_INFO_Init }, + { "PROTEUS", "P2K ", "Proteus Ch Select ", 59, (void *)&SEQ_UI_PROTEUS_Init }, // RIO: added Proteus + { "XL-TURBO", "XL-T ", "XLTurbo Ch Select ", 60, (void *)&SEQ_UI_XLTURBO_Init }, // RIO: added Proteus }; +//#################################### +//# RIO: END MODIFICATION +//#################################### ///////////////////////////////////////////////////////////////////////////// // Access functions to the table diff --git a/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.h b/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.h index ba560cace..a150c8caf 100644 --- a/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.h +++ b/apps/sequencers/midibox_seq_v4/core/seq_ui_pages.h @@ -23,6 +23,10 @@ // Global Types ///////////////////////////////////////////////////////////////////////////// +//#################################### +//# RIO: PROTEUS added +//#################################### + // must be kept in sync with ui_menu_pages table in seq_ui_pages.c typedef enum { SEQ_UI_PAGE_NONE = 0, @@ -85,9 +89,15 @@ typedef enum { SEQ_UI_PAGE_PATTERN_RMX, SEQ_UI_PAGE_BOOKMARKS, SEQ_UI_PAGE_INFO, + SEQ_UI_PAGE_PROTEUS, // RIO: added Proteus + SEQ_UI_PAGE_XLTURBO, // RIO: added Proteus SEQ_UI_PAGE_LAST__UNIMPLEMENTED } seq_ui_page_t; +//#################################### +//# RIO: END MODIFICATION +//#################################### + #define SEQ_UI_PAGES (SEQ_UI_PAGE_LAST__UNIMPLEMENTED) #define SEQ_UI_FIRST_MENU_SELECTION_PAGE SEQ_UI_PAGE_EDIT #define SEQ_UI_NUM_MENU_PAGES (SEQ_UI_PAGES-SEQ_UI_FIRST_MENU_SELECTION_PAGE) diff --git a/apps/sequencers/midibox_seq_v4/core/seq_ui_proteus.c b/apps/sequencers/midibox_seq_v4/core/seq_ui_proteus.c new file mode 100644 index 000000000..c1a9c4bb0 --- /dev/null +++ b/apps/sequencers/midibox_seq_v4/core/seq_ui_proteus.c @@ -0,0 +1,254 @@ +//#################################### +//# RIO: PROTEUS added +//#################################### + +/* + * Proteus page + * + * ========================================================================== + * + * Rio + * + * ========================================================================== + */ + +///////////////////////////////////////////////////////////////////////////// +// Include files +///////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "seq_lcd.h" +#include "seq_ui.h" +#include "seq_midi_port.h" +#include "seq_midi_sysex.h" + + +///////////////////////////////////////////////////////////////////////////// +// Global variables +///////////////////////////////////////////////////////////////////////////// + +u8 proteus_typ; +u8 proteus_id1 = 1; +u8 proteus_id2 = 2; +u8 proteus_out_port1 = 50; +u8 proteus_out_port2 = 51; +u8 proteus_sel_ch1 = 0; +u8 proteus_sel_ch2 = 0; + + +///////////////////////////////////////////////////////////////////////////// +// Local encoder callback function +// Should return: +// 1 if value has been changed +// 0 if value hasn't been changed +// -1 if invalid or unsupported encoder +///////////////////////////////////////////////////////////////////////////// +static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer) +{ + if( (encoder >= SEQ_UI_ENCODER_GP9) && (encoder <= SEQ_UI_ENCODER_GP11) ) { + + u8 port_ix; + + if (proteus_typ == 1) { + port_ix = SEQ_MIDI_PORT_OutIxGet(proteus_out_port1); + if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) { + proteus_out_port1 = SEQ_MIDI_PORT_OutPortGet(port_ix); + return 1; // value changed + } + } else { + port_ix = SEQ_MIDI_PORT_OutIxGet(proteus_out_port2); + if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) { + proteus_out_port2 = SEQ_MIDI_PORT_OutPortGet(port_ix); + return 1; // value changed + } + } + } + + if( encoder >= SEQ_UI_ENCODER_GP12 ) { + + if (proteus_typ == 1) { + if( SEQ_UI_Var8_Inc(&proteus_id1, 0, 126, incrementer) >= 0 ) return 1; // value changed + } else { + if( SEQ_UI_Var8_Inc(&proteus_id2, 0, 126, incrementer) >= 0 ) return 1; // value changed + } + } + + return 0; // no change +} + +///////////////////////////////////////////////////////////////////////////// +// Local button callback function +// Should return: +// 1 if value has been changed +// 0 if value hasn't been changed +// -1 if invalid or unsupported button +///////////////////////////////////////////////////////////////////////////// +static s32 Button_Handler(seq_ui_button_t button, s32 depressed) +{ + switch( button ) { + case SEQ_UI_BUTTON_GP1: + case SEQ_UI_BUTTON_GP2: + case SEQ_UI_BUTTON_GP3: + case SEQ_UI_BUTTON_GP4: + case SEQ_UI_BUTTON_GP5: + case SEQ_UI_BUTTON_GP6: + case SEQ_UI_BUTTON_GP7: + case SEQ_UI_BUTTON_GP8: + case SEQ_UI_BUTTON_GP9: + case SEQ_UI_BUTTON_GP10: + case SEQ_UI_BUTTON_GP11: + case SEQ_UI_BUTTON_GP12: + case SEQ_UI_BUTTON_GP13: + case SEQ_UI_BUTTON_GP14: + case SEQ_UI_BUTTON_GP15: + case SEQ_UI_BUTTON_GP16: + if( depressed ) return 0; // ignore when button depressed + + if (proteus_typ == 1) { + proteus_sel_ch1 = button+1; + SEQ_MIDI_SYSEX_PROTEUS_SendChannel(proteus_out_port1,proteus_id1,proteus_sel_ch1-1); + } else { + proteus_sel_ch2 = button+1; + SEQ_MIDI_SYSEX_PROTEUS_SendChannel(proteus_out_port2,proteus_id2,proteus_sel_ch2-1); + } + + return 1; // nothing to do for button + } + + return -1; // invalid or unsupported button +} + +///////////////////////////////////////////////////////////////////////////// +// Local LED handler function +///////////////////////////////////////////////////////////////////////////// +static s32 LED_Handler(u16 *gp_leds) +{ + if (proteus_typ == 1) { + + if (proteus_sel_ch1) *gp_leds = 1 << (proteus_sel_ch1-1); + else *gp_leds = 0x0000; + + } else { + + if (proteus_sel_ch2) *gp_leds = 1 << (proteus_sel_ch2-1); + else *gp_leds = 0x0000; + + } + + return 0; // no error +} + + +///////////////////////////////////////////////////////////////////////////// +// Local Display Handler function +// IN: : if set, a high-priority LCD update is requested +///////////////////////////////////////////////////////////////////////////// +static s32 LCD_Handler(u8 high_prio) +{ + if( high_prio ) + return 0; // there are no high-priority update + + // layout: + // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 + // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 + // <--------------------------------------><--------------------------------------> + // Trk. Utility Functions Quick Menu Change + // G1T1 Copy Paste Clr Move Scrl Rand Undo Save Rec. Live Opt. PMte Disk Mute UnMte + + /////////////////////////////////////////////////////////////////////////// + SEQ_LCD_CursorSet(0, 0); + + if (proteus_typ == 1) { + + SEQ_LCD_PrintString("Proteus 2000 "); + + SEQ_LCD_PrintString("Port: "); + SEQ_LCD_PrintMIDIOutPort(proteus_out_port1); + SEQ_LCD_PrintString(" ID:"); + + SEQ_LCD_PrintFormattedString("%3d", proteus_id1); + SEQ_LCD_PrintSpaces(18); + + } else { + + SEQ_LCD_PrintString("Proteus XL-Turbo "); + + SEQ_LCD_PrintString("Port: "); + SEQ_LCD_PrintMIDIOutPort(proteus_out_port2); + SEQ_LCD_PrintString(" ID:"); + + SEQ_LCD_PrintFormattedString("%3d", proteus_id2); + SEQ_LCD_PrintSpaces(18); + + } + + + /////////////////////////////////////////////////////////////////////////// + SEQ_LCD_CursorSet(0, 1); + + unsigned char i; + for (i = 1; i < 17; i++) { + + + if (proteus_typ == 1) { + + if ( i == proteus_sel_ch1) { + + if( ui_cursor_flash ) SEQ_LCD_PrintSpaces(5); + else SEQ_LCD_PrintFormattedString(" #%2d ", proteus_sel_ch1); + + } else SEQ_LCD_PrintFormattedString(" #%2d ", i); + + } else { + + if ( i == proteus_sel_ch2) { + + if( ui_cursor_flash ) SEQ_LCD_PrintSpaces(5); + else SEQ_LCD_PrintFormattedString(" #%2d ", proteus_sel_ch2); + + } else SEQ_LCD_PrintFormattedString(" #%2d ", i); + + } + } + + return 0; // no error +} + + +///////////////////////////////////////////////////////////////////////////// +// Initialisation +///////////////////////////////////////////////////////////////////////////// +s32 SEQ_UI_PROTEUS_Init(u32 mode) +{ + proteus_typ = 1; + + // install callback routines + SEQ_UI_InstallButtonCallback(Button_Handler); + SEQ_UI_InstallEncoderCallback(Encoder_Handler); + SEQ_UI_InstallLEDCallback(LED_Handler); + SEQ_UI_InstallLCDCallback(LCD_Handler); + + ui_hold_msg_ctr = 0; + + return 0; // no error +} + +s32 SEQ_UI_XLTURBO_Init(u32 mode) +{ + proteus_typ = 2; + + // install callback routines + SEQ_UI_InstallButtonCallback(Button_Handler); + SEQ_UI_InstallEncoderCallback(Encoder_Handler); + SEQ_UI_InstallLEDCallback(LED_Handler); + SEQ_UI_InstallLCDCallback(LCD_Handler); + + ui_hold_msg_ctr = 0; + + return 0; // no error +} + +//#################################### +//# RIO: END MODIFICATION +//#################################### \ No newline at end of file