///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // re-use encoder handler - only select UI item, don't increment, flags will be toggled return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; SetSubpageBasedOnItem(ui_selected_item); return 1; // value always changed case SEQ_UI_BUTTON_Left: if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; SetSubpageBasedOnItem(ui_selected_item); return 1; // value always changed case SEQ_UI_BUTTON_Up: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Transposer Section MIDI Ext. Bus Port Chn. Lower/Upper Mode Reset // and Arp. Control Router Ctrl Misc. 1 IN1 #16 --- --- T&A Stacks // Transposer Section MIDI Ext. Port Chn. G1 G2 G3 G4 Fwd Reset // and Arp. Control Router Ctrl Misc. All #16 C-1 C-2 C-3 C-4 USB1 Stcks // Transposer Section MIDI Ext. Node IN P/Chn OUT P/Chn | DefaultPort // and Arp. Control Router Ctrl Misc. #1 Def. All Def. # 1 | USB1 // Transposer Section MIDI Ext. Port Chn. Function CC# // Transposer Section MIDI Ext. IN OUT Chn.| Function CC# // and Arp. Control Router Ctrl Misc. All off --- | Morph Value 1 // Transposer Section MIDI Ext. BLM_SCALAR MIDI // and Arp. Control Router Ctrl Misc.Port: OUT2 Monitor seq_midi_router_node_t *n = &seq_midi_router_node[selected_router_node]; /////////////////////////////////////////////////////////////////////////// //<<<<<<< .mine /* const char leftpage[2][41] = { "Transposer Section MIDI ", " and Arp. Control Router Misc. " }; ======= */ SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Transposer Section MIDI Ext. "); SEQ_LCD_CursorSet(0, 1); SEQ_LCD_PrintString(" and Arp. Control Router Ctrl Misc."); //>>>>>>> .r1826 if( ui_cursor_flash && selected_subpage <= 5 ) { const u8 select_pos1[5] = { 0, 10, 20, 30, 35 }; const u8 select_width[5] = { 10, 10, 10, 5, 5 }; int line; for(line=0; line<2; ++line) { SEQ_LCD_CursorSet(select_pos1[selected_subpage], line); SEQ_LCD_PrintSpaces(select_width[selected_subpage]); } } /* SEQ_LCD_CursorSet(0, 0); if (selected_subpage == SUBPAGE_TRANSPOSE && ui_cursor_flash) { SEQ_LCD_PrintSpaces(21); } else { SEQ_LCD_PrintString(" Transposer and Arp "); } SEQ_LCD_CursorSet(0, 1); if (selected_subpage == SUBPAGE_SECTIONS && ui_cursor_flash) { SEQ_LCD_PrintSpaces(21); } else { SEQ_LCD_PrintString(" Section control "); } SEQ_LCD_CursorSet(0, 2); if (selected_subpage == SUBPAGE_ROUTER && ui_cursor_flash) { SEQ_LCD_PrintSpaces(21); } else { SEQ_LCD_PrintString(" MIDI router "); } SEQ_LCD_CursorSet(0, 3); if (selected_subpage == SUBPAGE_MISC && ui_cursor_flash) { SEQ_LCD_PrintSpaces(21); } else { SEQ_LCD_PrintString(" Miscilenious "); } */ SEQ_LCD_CursorSet(0, 4); switch( selected_subpage ) { /////////////////////////////////////////////////////////////////////////// case SUBPAGE_TRANSPOSE: { //SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintString(" Bus Port Chn. Mode "); SEQ_LCD_CursorSet(0, 6); SEQ_LCD_PrintString(" Lower/Upper Reset "); SEQ_LCD_CursorSet(0, 5); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_BUS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintFormattedString(" %d ", selected_bus+1); } /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( seq_midi_in_port[selected_bus] ) SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(SEQ_MIDI_PORT_InIxGet(seq_midi_in_port[selected_bus]))); else SEQ_LCD_PrintString(" All"); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_CHN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { if( seq_midi_in_channel[selected_bus] ) SEQ_LCD_PrintFormattedString("#%2d", seq_midi_in_channel[selected_bus]); else SEQ_LCD_PrintString("---"); } SEQ_LCD_PrintSpaces(3); /* /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_MODE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(seq_midi_in_options[selected_bus].MODE_PLAY ? "Play" : "T&A "); } SEQ_LCD_PrintSpaces(3); SEQ_LCD_CursorSet(0, 7); */ /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_LOWER && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_lower[selected_bus]); } SEQ_LCD_PrintSpaces(3); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_UPPER && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_upper[selected_bus]); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_MODE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(seq_midi_in_options[selected_bus].MODE_PLAY ? "Play" : "T&A "); } SEQ_LCD_PrintSpaces(3); SEQ_LCD_PrintString("Stacks"); } break; /////////////////////////////////////////////////////////////////////////// case SUBPAGE_SECTIONS: { //SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintString(" Port Chn. G1 G2 "); SEQ_LCD_CursorSet(0, 6); SEQ_LCD_PrintString(" G3 G4 Fwd Reset "); SEQ_LCD_CursorSet(0, 5); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( seq_midi_in_sect_port ) SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(SEQ_MIDI_PORT_InIxGet(seq_midi_in_sect_port))); else SEQ_LCD_PrintString(" All"); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_CHN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { if( seq_midi_in_sect_channel ) SEQ_LCD_PrintFormattedString("#%2d", seq_midi_in_sect_channel); else SEQ_LCD_PrintString("---"); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_OCT_G1 && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_sect_note[0]); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_OCT_G2 && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_sect_note[1]); } SEQ_LCD_PrintSpaces(2); SEQ_LCD_CursorSet(0, 5); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_OCT_G3 && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_sect_note[2]); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_OCT_G4 && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_sect_note[3]); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_S_FWD_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( seq_midi_in_sect_fwd_port == 0 ) SEQ_LCD_PrintString("----"); else SEQ_LCD_PrintString(SEQ_MIDI_PORT_OutNameGet(SEQ_MIDI_PORT_OutIxGet(seq_midi_in_sect_fwd_port))); } SEQ_LCD_PrintSpaces(1); SEQ_LCD_PrintString("Stcks"); } break; /////////////////////////////////////////////////////////////////////////// case SUBPAGE_ROUTER: { //<<<<<<< .mine //SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintString(" Node IN Port/Chn "); SEQ_LCD_CursorSet(0, 6); SEQ_LCD_PrintString("OUT Port/Chn Def.Port"); SEQ_LCD_CursorSet(0, 5); /* ======= SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintString("Node IN P/Chn OUT P/Chn | DefaultPort"); SEQ_LCD_CursorSet(40, 1); >>>>>>> .r1826 */ /////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintSpaces(1); if( ui_selected_item == ITEM_R_NODE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintFormattedString("#%2d", selected_router_node+1); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_R_SRC_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(SEQ_MIDI_PORT_InIxGet(n->src_port))); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_R_SRC_CHN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { if( !n->src_chn ) { SEQ_LCD_PrintString("---"); } else if( n->src_chn > 16 ) { SEQ_LCD_PrintString("All"); } else { SEQ_LCD_PrintFormattedString("#%2d", n->src_chn); } } SEQ_LCD_PrintSpaces(2); SEQ_LCD_CursorSet(0, 7); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_R_DST_PORT && ui_cursor_flash ) { if( n->dst_chn >= 18 ) { SEQ_LCD_PrintSpaces(2); } else { SEQ_LCD_PrintSpaces(4); } } else { if( n->dst_chn >= 18 ) { SEQ_LCD_PrintSpaces(2); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_OutNameGet(SEQ_MIDI_PORT_OutIxGet(n->dst_port))); } } /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_R_DST_CHN && ui_cursor_flash ) { if( n->dst_chn >= 18 ) { SEQ_LCD_PrintSpaces(7); } else { SEQ_LCD_PrintSpaces(5); } } else { if( !n->dst_chn ) { SEQ_LCD_PrintString(" --- "); } else if( n->dst_chn == 17 ) { SEQ_LCD_PrintString(" All "); } else if( n->dst_chn == 18 ) { SEQ_LCD_PrintString(" Track"); } else if( n->dst_chn >= 19 ) { SEQ_LCD_PrintString("Sel.Trk"); } else { SEQ_LCD_PrintFormattedString(" #%2d ", n->dst_chn); } } SEQ_LCD_PrintSpaces(3); /////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintChar('|'); SEQ_LCD_PrintSpaces(4); if( ui_selected_item == ITEM_DEF_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_OutNameGet(SEQ_MIDI_PORT_OutIxGet(MIOS32_MIDI_DefaultPortGet()))); } SEQ_LCD_PrintSpaces(4); } break; /////////////////////////////////////////////////////////////////////////// case SUBPAGE_EXT_CTRL: { SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintString(" IN OUT Chn.|Function "); if( selected_ext_ctrl < SEQ_MIDI_IN_EXT_CTRL_NUM_IX_CC ) { SEQ_LCD_PrintString("CC# "); } else { SEQ_LCD_PrintSpaces(10); } SEQ_LCD_CursorSet(40, 1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_EXT_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( seq_midi_in_ext_ctrl_port == 0xff ) SEQ_LCD_PrintString(" All"); else if( !seq_midi_in_ext_ctrl_port ) SEQ_LCD_PrintString(" off"); else SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(SEQ_MIDI_PORT_InIxGet(seq_midi_in_ext_ctrl_port))); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_EXT_PORT_OUT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( seq_midi_in_ext_ctrl_out_port ) SEQ_LCD_PrintString(SEQ_MIDI_PORT_OutNameGet(SEQ_MIDI_PORT_OutIxGet(seq_midi_in_ext_ctrl_out_port))); else SEQ_LCD_PrintString("off "); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_EXT_CHN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { if( seq_midi_in_ext_ctrl_channel ) SEQ_LCD_PrintFormattedString("#%2d", seq_midi_in_ext_ctrl_channel); else SEQ_LCD_PrintString("---"); } SEQ_LCD_PrintString(" |"); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_EXT_CTRL && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(15); } else { SEQ_LCD_PrintStringPadded((char *)SEQ_MIDI_IN_ExtCtrlStr(selected_ext_ctrl), 15); } /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_EXT_VALUE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(10); } else { SEQ_LCD_PrintSpaces(1); if( selected_ext_ctrl == SEQ_MIDI_IN_EXT_CTRL_NRPN_ENABLED ) { SEQ_LCD_PrintStringPadded(seq_midi_in_ext_ctrl_asg[selected_ext_ctrl] ? "enabled" : "disabled", 9); } else if( selected_ext_ctrl == SEQ_MIDI_IN_EXT_CTRL_PC_MODE ) { SEQ_LCD_PrintStringPadded((char *)SEQ_MIDI_IN_ExtCtrlPcModeStr(seq_midi_in_ext_ctrl_asg[selected_ext_ctrl]), 9); } else { u8 cc = seq_midi_in_ext_ctrl_asg[selected_ext_ctrl]; if( cc >= 0x80 ) SEQ_LCD_PrintString("off"); else SEQ_LCD_PrintFormattedString("%3d", cc); SEQ_LCD_PrintSpaces(7); } } } break; /////////////////////////////////////////////////////////////////////////// case SUBPAGE_MISC: { //SEQ_LCD_CursorSet(40, 0); //<<<<<<< .mine SEQ_LCD_PrintString("BLM_SCALAR "); SEQ_LCD_PrintString(blm_timeout_ctr ? "connected " : "not found "); SEQ_LCD_CursorSet(0, 6); SEQ_LCD_PrintString(" MIDI "); SEQ_LCD_CursorSet(0, 5); /* ======= SEQ_LCD_PrintString("BLM_SCALAR MIDI "); SEQ_LCD_CursorSet(40, 1); >>>>>>> .r1826 */ /////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintString("Port: "); if( ui_selected_item == ITEM_BLM_SCALAR_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( !seq_blm_port ) SEQ_LCD_PrintString(" off"); else SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(SEQ_MIDI_PORT_InIxGet(seq_blm_port))); } //<<<<<<< .mine SEQ_LCD_CursorSet(0, 7); //======= SEQ_LCD_PrintString(blm_timeout_ctr ? " (found) " : " "); // free for new parameters SEQ_LCD_PrintSpaces(12); //>>>>>>> .r1826 /////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintString("Monitor "); } break; } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Local exit function ///////////////////////////////////////////////////////////////////////////// static s32 EXIT_Handler(void) { s32 status = 0; if( store_file_required ) { // write config files MUTEX_SDCARD_TAKE; if( (status=SEQ_FILE_C_Write(seq_file_session_name)) < 0 ) SEQ_UI_SDCardErrMsg(2000, status); MUTEX_SDCARD_GIVE; MUTEX_SDCARD_TAKE; if( (status=SEQ_FILE_GC_Write()) < 0 ) SEQ_UI_SDCardErrMsg(2000, status); MUTEX_SDCARD_GIVE; } return status; }
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // USB1 USB2 USB3 USB4 IN1 IN2 IN3 IN4 OSC1 OSC2 OSC3 OSC4 // USB1 USB2 USB3 USB4 OUT1 OUT2 OUT3 OUT4 IIC1 IIC2 IIC3 IIC4 OSC1 OSC2 OSC3 OSC4 // Filter Filter // MIDI Clock: on Active Sense: on if( seq_ui_button_state.SELECT_PRESSED ) { if( high_prio ) return 0; seq_midi_port_mon_filter_t mon_filter = SEQ_MIDI_PORT_MonFilterGet(); SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintSpaces(2); SEQ_LCD_PrintString("Filter"); SEQ_LCD_PrintSpaces(15); SEQ_LCD_PrintString("Filter"); SEQ_LCD_PrintSpaces(11 + 40); SEQ_LCD_CursorSet(0, 1); SEQ_LCD_PrintFormattedString("MIDI Clock: %s", mon_filter.MIDI_CLOCK ? "on " : "off"); SEQ_LCD_PrintSpaces(5); SEQ_LCD_PrintFormattedString("Active Sense: %s", mon_filter.ACTIVE_SENSE ? "on " : "off"); SEQ_LCD_PrintSpaces(3 + 40); } /////////////////////////////////////////////////////////////////////////// u8 port_num = SEQ_MIDI_PORT_OutNumGet(); if( port_num > 17 ) port_num = 17; u8 port_ix; if( high_prio ) { u16 in_activity = 0; u16 out_activity = 0; for(port_ix=1; port_ix<port_num; ++port_ix) { SEQ_LCD_CursorSet(5*(port_ix-1), 0); // dirty! but only way to ensure that OSC1..OSC4 are aligned if( port_ix >= 9 && port_ix <= 12 ) { SEQ_LCD_PrintSpaces(5); } else { u8 port_ix_midi_in = (port_ix >= 9) ? (port_ix - 4) : port_ix; mios32_midi_port_t port = SEQ_MIDI_PORT_InPortGet(port_ix_midi_in); mios32_midi_package_t package = SEQ_MIDI_PORT_InPackageGet(port); if( port == 0xff ) { SEQ_LCD_PrintSpaces(5); } else if( package.type ) { SEQ_LCD_PrintEvent(package, 5); in_activity |= (1 << (port_ix-1)); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(port_ix_midi_in)); SEQ_LCD_PrintChar(' '); } } SEQ_LCD_CursorSet(5*(port_ix-1), 1); mios32_midi_port_t port = SEQ_MIDI_PORT_OutPortGet(port_ix); mios32_midi_package_t package = SEQ_MIDI_PORT_OutPackageGet(port); if( port == 0xff ) { SEQ_LCD_PrintSpaces(5); } else if( package.type ) { SEQ_LCD_PrintEvent(package, 5); out_activity |= (1 << (port_ix-1)); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_OutNameGet(port_ix)); SEQ_LCD_PrintChar(' '); } } midi_activity = in_activity | out_activity; return 0; } return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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 0 // leads to: comparison is always true due to limited range of data type if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) ) { #else if( encoder <= SEQ_UI_ENCODER_GP16 ) { #endif if( seq_ui_button_state.SELECT_PRESSED && !seq_ui_button_state.CHANGE_ALL_STEPS ) { // select button pressed: indirect MUTED flag modification (taken over when select button depressed) u16 mask = 1 << encoder; if( incrementer < 0 || (incrementer == 0 && !(latched_mute & mask)) ) latched_mute |= mask; else latched_mute &= ~mask; } else { // select button not pressed: direct MUTED flag modification // access to seq_core_trk[] must be atomic! portENTER_CRITICAL(); u8 visible_track = SEQ_UI_VisibleTrackGet(); u16 mask = 1 << encoder; u16 *muted = (u16 *)&seq_core_trk_muted; if( seq_ui_button_state.CHANGE_ALL_STEPS ) { switch( encoder ) { case SEQ_UI_ENCODER_GP1: case SEQ_UI_ENCODER_GP2: *muted = 0xffff; SEQ_UI_Msg(SEQ_UI_MSG_USER, 1000, "All Tracks", "muted"); break; case SEQ_UI_ENCODER_GP3: case SEQ_UI_ENCODER_GP4: case SEQ_UI_ENCODER_GP5: muted = (u16 *)&seq_core_trk[visible_track].layer_muted; *muted = 0xffff; SEQ_UI_Msg(SEQ_UI_MSG_USER, 1000, "All Layers", "of current Track muted"); break; case SEQ_UI_ENCODER_GP6: case SEQ_UI_ENCODER_GP7: case SEQ_UI_ENCODER_GP8: { *muted = 0xffff; int track; for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) { seq_core_trk[track].layer_muted = 0xffff; } SEQ_UI_Msg(SEQ_UI_MSG_USER, 1000, "All Layers", "and Tracks muted"); } break; case SEQ_UI_ENCODER_GP9: case SEQ_UI_ENCODER_GP10: *muted = 0x0000; SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 1000, "All Tracks", "unmuted"); break; case SEQ_UI_ENCODER_GP11: case SEQ_UI_ENCODER_GP12: case SEQ_UI_ENCODER_GP13: muted = (u16 *)&seq_core_trk[visible_track].layer_muted; *muted = 0x0000; SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 1000, "All Layers", "of current Track unmuted"); break; case SEQ_UI_ENCODER_GP14: case SEQ_UI_ENCODER_GP15: case SEQ_UI_ENCODER_GP16: { *muted = 0x0000; int track; for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) { seq_core_trk[track].layer_muted = 0x0000; } SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 1000, "All Layers", "and Tracks unmuted"); } break; } } else { if( seq_ui_button_state.MUTE_PRESSED ) muted = (u16 *)&seq_core_trk[visible_track].layer_muted; else if( SEQ_BPM_IsRunning() ) { // Synched Mutes only when sequencer is running if( !(*muted & mask) && seq_core_options.SYNCHED_MUTE && !seq_ui_button_state.FAST_ENCODERS ) { // Fast button will disable synched mute muted = (u16 *)&seq_core_trk_synched_mute; } else if( (*muted & mask) && seq_core_options.SYNCHED_UNMUTE && !seq_ui_button_state.FAST_ENCODERS ) { // Fast button will disable synched unmute muted = (u16 *)&seq_core_trk_synched_unmute; } } else { // clear synched mutes/unmutes if sequencer not running seq_core_trk_synched_mute = 0; seq_core_trk_synched_unmute = 0; } if( incrementer < 0 ) *muted |= mask; else if( incrementer > 0 ) *muted &= ~mask; else *muted ^= mask; } portEXIT_CRITICAL(); if( muted == ((u16 *)&seq_core_trk_muted) ) { // send to external SEQ_MIDI_IN_ExtCtrlSend(SEQ_MIDI_IN_EXT_CTRL_MUTES, (*muted & mask) ? 127 : 0, encoder); } } return 1; // value changed } return -1; // invalid or unsupported encoder } ///////////////////////////////////////////////////////////////////////////// // 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) { #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif if( depressed ) return 0; // ignore when button depressed // re-using encoder routine return Encoder_Handler(button, 0); } switch( button ) { case SEQ_UI_BUTTON_Select: portENTER_CRITICAL(); if( depressed ) { // select button released: take over latched mutes if( seq_ui_button_state.MUTE_PRESSED ) { u8 visible_track = SEQ_UI_VisibleTrackGet(); seq_core_trk[visible_track].layer_muted = latched_mute; } else { u16 new_mutes = latched_mute & ~seq_core_trk_muted; if( SEQ_BPM_IsRunning() && seq_core_options.SYNCHED_MUTE && !seq_ui_button_state.FAST_ENCODERS ) // Fast button will disable synched mute seq_core_trk_synched_mute |= new_mutes; else seq_core_trk_muted |= new_mutes; u16 new_unmutes = ~latched_mute & seq_core_trk_muted; if( SEQ_BPM_IsRunning() && seq_core_options.SYNCHED_UNMUTE && !seq_ui_button_state.FAST_ENCODERS ) // Fast button will disable synched unmute seq_core_trk_synched_unmute |= new_unmutes; else seq_core_trk_muted &= ~new_unmutes; } } else { // select pressed: init latched mutes which will be taken over once SELECT button released if( seq_ui_button_state.MUTE_PRESSED ) { u8 visible_track = SEQ_UI_VisibleTrackGet(); latched_mute = seq_core_trk[visible_track].layer_muted; } else { latched_mute = seq_core_trk_muted; } } portEXIT_CRITICAL(); return 1; } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // > 1< 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // ...horizontal VU meters... // Mute All screen: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Mute Mute Mute all Tracks Unmute Unmute Unmute all Tracks // all Tracks G1T1 Layers and all Layersall Tracks G1T1 Layers and all Layers if( seq_ui_button_state.CHANGE_ALL_STEPS ) { if( high_prio ) return 0; SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString(" Mute Mute Mute all Tracks Unmute Unmute Unmute all Tracks"); SEQ_LCD_CursorSet(0, 1); SEQ_LCD_PrintString("all Tracks "); SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); SEQ_LCD_PrintString(" Layers and all Layersall Tracks "); SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); SEQ_LCD_PrintString(" Layers and all Layers"); return 0; } if( high_prio ) { /////////////////////////////////////////////////////////////////////////// // frequently update VU meters SEQ_LCD_CursorSet(0, 1); u8 track; u16 mute_flags = 0; u16 mute_flags_from_midi = 0; if( !ui_cursor_flash && seq_ui_button_state.SELECT_PRESSED ) { mute_flags = latched_mute; } else { if( seq_ui_button_state.MUTE_PRESSED ) { u8 visible_track = SEQ_UI_VisibleTrackGet(); mute_flags = seq_core_trk[visible_track].layer_muted; mute_flags_from_midi = seq_core_trk[visible_track].layer_muted_from_midi; } else { mute_flags = seq_core_trk_muted; } } if( seq_ui_button_state.MUTE_PRESSED ) { u8 layer; u16 mask = (1 << 0); for(layer=0; layer<16; ++layer, mask <<= 1) if( mute_flags_from_midi & mask ) { SEQ_LCD_PrintString("MIDI "); } else if( mute_flags & mask ) { SEQ_LCD_PrintString("Mute "); } else { SEQ_LCD_PrintHBar((seq_layer_vu_meter[layer] >> 3) & 0xf); } } else { int remaining_steps = (seq_core_steps_per_measure - seq_core_state.ref_step) + 1; seq_core_trk_t *t = &seq_core_trk[0]; u16 mask = (1 << 0); for(track=0; track<16; ++t, ++track, mask <<= 1) if( mute_flags & mask ) { if( !seq_ui_button_state.SELECT_PRESSED && (seq_core_trk_synched_unmute & mask) ) { SEQ_LCD_PrintFormattedString("U%3d ", remaining_steps); } else { SEQ_LCD_PrintString("Mute "); } } else { if( !seq_ui_button_state.SELECT_PRESSED && (seq_core_trk_synched_mute & mask) ) { SEQ_LCD_PrintFormattedString("M%3d ", remaining_steps); } else { SEQ_LCD_PrintHBar(t->vu_meter >> 3); } } } } else {
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // re-use encoder handler - only select UI item, don't increment, flags will be toggled return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( depressed ) return -1; if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; return 1; // value always changed case SEQ_UI_BUTTON_Left: if( depressed ) return -1; if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; return 1; // value always changed case SEQ_UI_BUTTON_Up: if( depressed ) return -1; return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: if( depressed ) return -1; return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // CV Curve SlewRate PRng Gate Calibr. Clk Rate Width Module // 1 V/Oct 0 mS 2 Pos. off 1 24 PPQN 1 mS AOUT_NG /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString(" CV Curve SlewRate PRng Gate Calibr. Clk Rate Width Module "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CV && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintFormattedString(" %2d ", selected_cv+1); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CURVE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { SEQ_LCD_PrintString((char *)SEQ_CV_CurveNameGet(selected_cv)); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_SLEWRATE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(9); } else { SEQ_LCD_PrintFormattedString(" %3d mS ", SEQ_CV_SlewRateGet(selected_cv)); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_PITCHRANGE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { SEQ_LCD_PrintFormattedString("%3d ", SEQ_CV_PitchRangeGet(selected_cv)); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GATE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { SEQ_LCD_PrintFormattedString(SEQ_CV_GateInversionGet(selected_cv) ? "Neg. " : "Pos. "); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CALIBRATION && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(8); } else { SEQ_LCD_PrintFormattedString(" %s ", SEQ_CV_CaliNameGet()); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CLK_SEL && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString("%3d ", selected_clkout + 1); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CLK_PPQN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(9); } else { u16 divider = SEQ_CV_ClkDividerGet(selected_clkout); if( !divider ) { SEQ_LCD_PrintFormattedString("StartStop", 384 / divider); } else { SEQ_LCD_PrintFormattedString("%3d PPQN ", 384 / divider); } } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CLK_WIDTH && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { SEQ_LCD_PrintFormattedString("%3d mS", SEQ_CV_ClkPulseWidthGet(selected_clkout)); } SEQ_LCD_PrintSpaces(12); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_MODULE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(8); } else { SEQ_LCD_PrintString((char *)SEQ_CV_IfNameGet(SEQ_CV_IfGet())); } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Local exit function ///////////////////////////////////////////////////////////////////////////// static s32 EXIT_Handler(void) { s32 status = 0; // ensure that calibration mode disabled SEQ_CV_CaliModeSet(selected_cv, AOUT_CALI_MODE_OFF); if( store_file_required ) { // write config file MUTEX_SDCARD_TAKE; if( (status=SEQ_FILE_GC_Write()) < 0 ) SEQ_UI_SDCardErrMsg(2000, status); MUTEX_SDCARD_GIVE; store_file_required = 0; } return status; }
///////////////////////////////////////////////////////////////////////////// // 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) { u8 visible_track = SEQ_UI_VisibleTrackGet(); int num_steps = SEQ_TRG_NumStepsGet(visible_track); int track_length = (int)SEQ_CC_Get(visible_track, SEQ_CC_LENGTH) + 1; #if 0 // leads to: comparison is always true due to limited range of data type if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) ) { #else if( encoder <= SEQ_UI_ENCODER_GP16 ) { #endif if( seq_ui_button_state.SELECT_PRESSED ) { int section; if( num_steps > 128 ) section = encoder / (track_length / 16); else if( num_steps > 64 ) section = encoder / ((2 * track_length) / 16); else section = encoder / ((4 * track_length) / 16); // operation should be atomic (change all selected tracks) u8 track; seq_core_trk_t *t = &seq_core_trk[0]; MIOS32_IRQ_Disable(); for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t) if( ui_selected_tracks & (1 << track) ) t->play_section = section; MIOS32_IRQ_Enable(); } else { // won't work if Follow function active! if( seq_core_state.FOLLOW ) { // print message and exit SEQ_UI_Msg((encoder <= SEQ_UI_ENCODER_GP8) ? SEQ_UI_MSG_USER : SEQ_UI_MSG_USER_R, 2000, "\"Follow\" active!", "Please deactivate!"); return 1; } } // select new step view ui_selected_step_view = (encoder * (num_steps/16)) / 16; // select step within view if( !seq_ui_button_state.CHANGE_ALL_STEPS ) { // don't change the selected step if ALL function is active, otherwise the ramp can't be changed over multiple views ui_selected_step = (ui_selected_step_view << 4) | (ui_selected_step & 0xf); } if( seq_hwcfg_button_beh.step_view ) { // if toggle function active: jump back to previous menu // this is especially useful for the emulated MBSEQ, where we can only click on a single button // (stepview gets deactivated when clicking on GP button) if( seq_ui_button_state.STEP_VIEW ) { seq_ui_button_state.STEP_VIEW = 0; SEQ_UI_PageSet(ui_stepview_prev_page); } } return 1; // value changed } else if( encoder == SEQ_UI_ENCODER_Datawheel ) { if( SEQ_UI_Var8_Inc(&ui_selected_step_view, 0, (num_steps-1)/16, incrementer) >= 1 ) { // select step within view if( !seq_ui_button_state.CHANGE_ALL_STEPS ) { // don't change the selected step if ALL function is active, otherwise the ramp can't be changed over multiple views ui_selected_step = (ui_selected_step_view << 4) | (ui_selected_step & 0xf); } } else { return 0; } } return -1; // invalid or unsupported encoder } ///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // -> same handling like for encoders return Encoder_Handler(button, 0); } switch( button ) { case SEQ_UI_BUTTON_Select: return 1; // selects section mode, checked via seq_ui_button_state.SELECT_PRESSED case SEQ_UI_BUTTON_Right: case SEQ_UI_BUTTON_Up: if( depressed ) return 0; // ignore when button depressed return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Left: case SEQ_UI_BUTTON_Down: if( depressed ) return 0; // ignore when button depressed return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // 1 17 33 49 // *... *... *... *... *... *... *... *... *... *... *... *... *... *... *... *... // 5 character usage in 256 step view (5 chars have to display 16 steps, 8 special chars available, // due to this limitation, we only display 15 steps (shouldn't really hurt)) // 43210 43210 43210 43210 43210 // * * * * . . . * . . . * . . . (Small charset) // 5 character usage in 128 step view (5 chars have to display 8 steps): // 43210 43210 43210 43210 43210 // * * . * * . . . (Medium charset) // 5 character usage in 64 step view (5 chars have to display 4 steps): // 43210 43210 43210 43210 43210 // * * * * * (Big charset) u8 visible_track = SEQ_UI_VisibleTrackGet(); u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE); int num_steps = SEQ_TRG_NumStepsGet(visible_track); int steps_per_item = num_steps / 16; int played_step = SEQ_BPM_IsRunning() ? seq_core_trk[visible_track].step : -1; int i; if( !high_prio ) { SEQ_LCD_CursorSet(0, 0); for(i=0; i<16; ++i) if( ((i*steps_per_item) % 16) || ((((i*steps_per_item)/16) == ui_selected_step_view) && ui_cursor_flash) ) SEQ_LCD_PrintSpaces(5); else SEQ_LCD_PrintFormattedString("%-3d ", i*steps_per_item+1); // print flashing *LOOPED* at right corner if loop mode activated to remind that steps will be played differntly if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_state.LOOP ) { SEQ_LCD_CursorSet(71, 0); SEQ_LCD_PrintString(" *LOOPED*"); } else if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_trk[visible_track].play_section > 0 ) { SEQ_LCD_CursorSet(71, 0); SEQ_LCD_PrintFormattedString(" *Sect.%c*", 'A'+seq_core_trk[visible_track].play_section); } else { if( event_mode == SEQ_EVENT_MODE_Drum ) { // print drum name at the rightmost side SEQ_LCD_CursorSet(75, 0); SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name); } else { // print trigger layer and name at the rightmost side SEQ_LCD_CursorSet(73, 0); SEQ_LCD_PrintFormattedString("%c:%s", 'A' + ui_selected_trg_layer, SEQ_TRG_AssignedTypeStr(visible_track, ui_selected_trg_layer)); } } } SEQ_LCD_CursorSet(0, 1); if( steps_per_item > 8 ) { SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_DrumSymbolsSmall); for(i=0; i<16; ++i) { u16 step = i*steps_per_item; u8 step8 = step / 8; u8 layer = (event_mode == SEQ_EVENT_MODE_Drum) ? 0 : ui_selected_trg_layer; u16 steps = (SEQ_TRG_Get8(visible_track, step8+1, layer, ui_selected_instrument) << 8) | (SEQ_TRG_Get8(visible_track, step8+0, layer, ui_selected_instrument) << 0); if( played_step >= step && played_step < (step+16) ) steps ^= (1 << (played_step % 16)); int j; for(j=0; j<5; ++j) { SEQ_LCD_PrintChar(steps & 0x7); steps >>= 3; } } } else if( steps_per_item > 4 ) {
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Trk. off Transpose Bus Hold Sort Restart ForceScale Sustain // G1T1 >Normal< Arpeggiator 1 on on on on on u8 visible_track = SEQ_UI_VisibleTrackGet(); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Trk."); SEQ_LCD_CursorSet(0, 1); if( ui_selected_item == ITEM_GXTY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(9); } else { SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); SEQ_LCD_PrintSpaces(5); } /////////////////////////////////////////////////////////////////////////// const char mode_names[7][14] = { ">off< ", ">Normal< ", ">Transpose< ", ">Arpeggiator<" }; int i; int selected_mode = SEQ_CC_Get(visible_track, SEQ_CC_MODE); for(i=0; i<4; ++i) { u8 x = 4 + 5*i; SEQ_LCD_CursorSet(x, i%2); // print unmodified name if item selected // replace '>' and '<' by space if item not selected // flash item (print only '>'/'<' and spaces) if cursor position == 1 and flash flag set by timer int j; for(j=0; j<13; ++j) { u8 c = mode_names[i][j]; if( ++x > 35 ) // don't print more than 35 characters per line break; if( c == '>' || c == '<' ) { SEQ_LCD_PrintChar((i == selected_mode) ? c : ' '); } else { if( ui_selected_item == ITEM_MODE && i == selected_mode && ui_cursor_flash ) SEQ_LCD_PrintChar(' '); else SEQ_LCD_PrintChar(c); } } } // additional spaces to fill LCD (avoids artefacts on page switches) SEQ_LCD_CursorSet(25, 0); SEQ_LCD_PrintSpaces(15); SEQ_LCD_CursorSet(32, 1); SEQ_LCD_PrintSpaces(8); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(35, 0); SEQ_LCD_PrintString(" Bus Hold Sort Restart ForceScale Sustain "); SEQ_LCD_CursorSet(35, 1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_BUS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintFormattedString(" %d", SEQ_CC_Get(visible_track, SEQ_CC_BUSASG) + 1); } SEQ_LCD_PrintSpaces(3); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_HOLD && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_MODE_FLAGS) & (1 << 1)) ? "on " : "off"); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_SORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_MODE_FLAGS) & (1 << 0)) ? "off" : "on "); // SORT is inverted! } SEQ_LCD_PrintSpaces(4); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_RESTART && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_MODE_FLAGS) & (1 << 2)) ? "on " : "off"); } SEQ_LCD_PrintSpaces(7); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_FORCE_SCALE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_MODE_FLAGS) & (1 << 3)) ? "on " : "off"); } SEQ_LCD_PrintSpaces(8); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_SUSTAIN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_MODE_FLAGS) & (1 << 4)) ? "on " : "off"); } SEQ_LCD_PrintSpaces(3); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // re-use encoder handler - only select UI item, don't increment return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; return 1; // value always changed case SEQ_UI_BUTTON_Left: if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; return 1; // value always changed case SEQ_UI_BUTTON_Up: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Trk. Wave Amp. Phs. Steps Rst OneShot Note Vel. Len. CC ExtraCC# Offs. PPQN // GxTy Sine 64 0% 16 16 on off off off off 001 64 384 u8 visible_track = SEQ_UI_VisibleTrackGet(); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Trk. Wave Amp. Phs. Steps Rst OneShot Note Vel. Len. CC ExtraCC# Offs. PPQN"); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( ui_selected_item == ITEM_GXTY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_WAVEFORM && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { u8 value = SEQ_CC_Get(visible_track, SEQ_CC_LFO_WAVEFORM); if( value <= 3 ) { const char waveform_str[4][6] = { " off ", "Sine ", "Tri. ", "Saw. " }; SEQ_LCD_PrintString((char *)waveform_str[value]); } else { SEQ_LCD_PrintFormattedString(" R%02d ", (value-4+1)*5); } } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_AMPLITUDE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { int value = (int)SEQ_CC_Get(visible_track, SEQ_CC_LFO_AMPLITUDE) - 128; SEQ_LCD_PrintFormattedString("%4d ", value); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_PHASE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { SEQ_LCD_PrintFormattedString("%3d%% ", SEQ_CC_Get(visible_track, SEQ_CC_LFO_PHASE)); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_STEPS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintFormattedString("%3d ", (int)SEQ_CC_Get(visible_track, SEQ_CC_LFO_STEPS)+1); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_STEPS_RST && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString("%3d ", (int)SEQ_CC_Get(visible_track, SEQ_CC_LFO_STEPS_RST)+1); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_ENABLE_ONE_SHOT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_LFO_ENABLE_FLAGS) & (1 << 0)) ? " on " : " off "); } SEQ_LCD_PrintSpaces(5); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_ENABLE_NOTE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_LFO_ENABLE_FLAGS) & (1 << 1)) ? " on " : " off "); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_ENABLE_VELOCITY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_LFO_ENABLE_FLAGS) & (1 << 2)) ? " on " : " off "); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_ENABLE_LENGTH && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_LFO_ENABLE_FLAGS) & (1 << 3)) ? " on " : " off "); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_ENABLE_CC && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintString((SEQ_CC_Get(visible_track, SEQ_CC_LFO_ENABLE_FLAGS) & (1 << 4)) ? " on " : " off "); } /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintSpaces(5); if( ui_selected_item == ITEM_CC && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { u8 current_value = SEQ_CC_Get(visible_track, SEQ_CC_LFO_CC); u8 edit_value = (ui_selected_item == ITEM_CC) ? edit_cc_number : current_value; if( edit_value ) SEQ_LCD_PrintFormattedString(" %03d", edit_value); else SEQ_LCD_PrintString(" ---"); SEQ_LCD_PrintChar((current_value != edit_value) ? '!' : ' '); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CC_OFFSET && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintFormattedString(" %3d ", SEQ_CC_Get(visible_track, SEQ_CC_LFO_CC_OFFSET)); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CC_PPQN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { u8 value = SEQ_CC_Get(visible_track, SEQ_CC_LFO_CC_PPQN); int ppqn = 1; if( value ) ppqn = 3 << (value-1); SEQ_LCD_PrintFormattedString(" %3d ", ppqn); } /////////////////////////////////////////////////////////////////////////// return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Initialisation ///////////////////////////////////////////////////////////////////////////// s32 SEQ_UI_FX_LFO_Init(u32 mode) { // install callback routines SEQ_UI_InstallButtonCallback(Button_Handler); SEQ_UI_InstallEncoderCallback(Encoder_Handler); SEQ_UI_InstallLEDCallback(LED_Handler); SEQ_UI_InstallLCDCallback(LCD_Handler); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Select MIDI Device with GP Button: 2 Devices found under /SYSEX // MBSID MBFM .... // Select MIDI Device with GP Button: 10 Devices found under /SYSEX // xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx> /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintSpaces(80); SEQ_LCD_CursorSet(0, 0); if( dir_num_items < 0 ) { if( dir_name[0] != 0 && dir_num_items == FILE_ERR_NO_DIR ) SEQ_LCD_PrintFormattedString("/SYSEX/%s directory not found on SD Card!", dir_name); else if( dir_num_items == FILE_ERR_NO_DIR ) SEQ_LCD_PrintString("/SYSEX directory not found on SD Card!"); else SEQ_LCD_PrintFormattedString("SD Card Access Error: %d", dir_num_items); } else if( dir_num_items == 0 ) { if( dir_name[0] != 0 ) SEQ_LCD_PrintFormattedString("No .SYX files found under /SYSEX/%s!", dir_name); else SEQ_LCD_PrintString("No subdirectories found in /SYSEX directory on SD Card!"); } else { if( dir_name[0] != 0 ) { SEQ_LCD_PrintString("Select .SYX file with GP Button:"); SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintFormattedString("%d files found under /SYSEX/%s", dir_num_items, dir_name); } else { SEQ_LCD_PrintString("Select MIDI Device with GP Button:"); SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintFormattedString("%d Devices found under /SYSEX", dir_num_items); } } /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( !dir_name[0] ) { SEQ_LCD_PrintList((char *)ui_global_dir_list, LIST_ENTRY_WIDTH, dir_num_items, NUM_LIST_DISPLAYED_ITEMS, ui_selected_item, dir_view_offset); } else { SEQ_LCD_PrintList((char *)ui_global_dir_list, LIST_ENTRY_WIDTH, dir_num_items, NUM_LIST_DISPLAYED_ITEMS-1, ui_selected_item, dir_view_offset); SEQ_LCD_PrintChar(' '); SEQ_LCD_PrintString((char *)SEQ_MIDI_PORT_OutNameGet(SEQ_MIDI_PORT_OutIxGet(sysex_port))); SEQ_LCD_PrintString(" EXIT"); } return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // re-use encoder handler - only select UI item, don't increment return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; return 1; // value always changed case SEQ_UI_BUTTON_Left: if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; return 1; // value always changed case SEQ_UI_BUTTON_Up: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Trk. Repeats Delay Vel.Level FB Velocity Note Gatelen. Ticks // GxTy 3 1/16 75% 120% + 0 100% 100% u8 visible_track = SEQ_UI_VisibleTrackGet(); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Trk. Repeats Delay Vel.Level FB Velocity Note Gatelen. Ticks "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( ui_selected_item == ITEM_GXTY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); } SEQ_LCD_PrintSpaces(10); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_REPEATS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(2); } else { SEQ_LCD_PrintFormattedString("%2d", SEQ_CC_Get(visible_track, SEQ_CC_ECHO_REPEATS)); } SEQ_LCD_PrintSpaces(7); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_DELAY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString((char *)SEQ_CORE_Echo_GetDelayModeName(SEQ_CC_Get(visible_track, SEQ_CC_ECHO_DELAY))); } SEQ_LCD_PrintSpaces(6); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_VELOCITY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString("%3d%%", 5*SEQ_CC_Get(visible_track, SEQ_CC_ECHO_VELOCITY)); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(40, 1); SEQ_LCD_PrintSpaces(4); if( ui_selected_item == ITEM_FB_VELOCITY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString("%3d%%", 5*SEQ_CC_Get(visible_track, SEQ_CC_ECHO_FB_VELOCITY)); } SEQ_LCD_PrintSpaces(7); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_FB_NOTE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { u8 note_delta = SEQ_CC_Get(visible_track, SEQ_CC_ECHO_FB_NOTE); if( note_delta < 24 ) SEQ_LCD_PrintFormattedString("-%2d", 24-note_delta); else if( note_delta < 49 ) SEQ_LCD_PrintFormattedString("+%2d", note_delta-24); else SEQ_LCD_PrintString("Rnd"); } SEQ_LCD_PrintSpaces(5); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_FB_GATELENGTH && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString("%3d%%", 5*SEQ_CC_Get(visible_track, SEQ_CC_ECHO_FB_GATELENGTH)); } SEQ_LCD_PrintSpaces(7); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_FB_TICKS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString("%3d%%", 5*SEQ_CC_Get(visible_track, SEQ_CC_ECHO_FB_TICKS)); } SEQ_LCD_PrintSpaces(2); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Initialisation ///////////////////////////////////////////////////////////////////////////// s32 SEQ_UI_FX_ECHO_Init(u32 mode) { // install callback routines SEQ_UI_InstallButtonCallback(Button_Handler); SEQ_UI_InstallEncoderCallback(Encoder_Handler); SEQ_UI_InstallLEDCallback(LED_Handler); SEQ_UI_InstallLCDCallback(LCD_Handler); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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 0 // leads to: comparison is always true due to limited range of data type if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) ) { #else if( encoder <= SEQ_UI_ENCODER_GP16 ) { #endif if( seq_ui_button_state.SELECT_PRESSED ) { // select button pressed: indirect MUTED flag modification (taken over when select button depressed) u16 mask = 1 << encoder; if( incrementer < 0 || (incrementer == 0 && !(latched_mute & mask)) ) latched_mute |= mask; else latched_mute &= ~mask; } else { // select button not pressed: direct MUTED flag modification // access to seq_core_trk[] must be atomic! portENTER_CRITICAL(); u8 visible_track = SEQ_UI_VisibleTrackGet(); u16 mask = 1 << encoder; u16 *muted = seq_ui_button_state.MUTE_PRESSED ? (u16 *)&seq_core_trk[visible_track].layer_muted : (u16 *)&seq_core_trk_muted; if( incrementer < 0 ) *muted |= mask; else if( incrementer > 0 ) *muted &= ~mask; else *muted ^= mask; portEXIT_CRITICAL(); } return 1; // value changed } return -1; // invalid or unsupported encoder } ///////////////////////////////////////////////////////////////////////////// // 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) { #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif if( depressed ) return 0; // ignore when button depressed // re-using encoder routine return Encoder_Handler(button, 0); } switch( button ) { case SEQ_UI_BUTTON_Select: portENTER_CRITICAL(); if( depressed ) { // select button released: take over latched mutes if( seq_ui_button_state.MUTE_PRESSED ) { u8 visible_track = SEQ_UI_VisibleTrackGet(); seq_core_trk[visible_track].layer_muted = latched_mute; } else { seq_core_trk_muted = latched_mute; } } else { // select pressed: init latched mutes which will be taken over once SELECT button released if( seq_ui_button_state.MUTE_PRESSED ) { u8 visible_track = SEQ_UI_VisibleTrackGet(); latched_mute = seq_core_trk[visible_track].layer_muted; } else { latched_mute = seq_core_trk_muted; } } portEXIT_CRITICAL(); return 1; } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // > 1< 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // ...horizontal VU meters... if( high_prio ) { /////////////////////////////////////////////////////////////////////////// // frequently update VU meters SEQ_LCD_CursorSet(0, 1); u8 track; u16 mute_flags = 0; if( !ui_cursor_flash && seq_ui_button_state.SELECT_PRESSED ) { mute_flags = latched_mute; } else { if( seq_ui_button_state.MUTE_PRESSED ) { u8 visible_track = SEQ_UI_VisibleTrackGet(); mute_flags = seq_core_trk[visible_track].layer_muted; } else { mute_flags = seq_core_trk_muted; } } if( seq_ui_button_state.MUTE_PRESSED ) { u8 layer; for(layer=0; layer<16; ++layer) if( mute_flags & (1 << layer) ) SEQ_LCD_PrintString("Mute "); else SEQ_LCD_PrintHBar((seq_layer_vu_meter[layer] >> 3) & 0xf); } else { seq_core_trk_t *t = &seq_core_trk[0]; for(track=0; track<16; ++t, ++track) if( mute_flags & (1 << track) ) SEQ_LCD_PrintString("Mute "); else SEQ_LCD_PrintHBar(t->vu_meter >> 3); } } else {
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed u8 visible_track = SEQ_UI_VisibleTrackGet(); #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP15 ) { #endif // re-use encoder handler - only select UI item, don't increment return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_GP16: { if( SEQ_GROOVE_Clear(SEQ_CC_Get(visible_track, SEQ_CC_GROOVE_STYLE)) < 0 ) SEQ_UI_Msg(SEQ_UI_MSG_USER, 1000, "Preset", "not editable!"); else SEQ_UI_Msg(SEQ_UI_MSG_USER, 1000, "Groove", "cleared!"); } break; case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; return 1; // value always changed case SEQ_UI_BUTTON_Left: if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; return 1; // value always changed case SEQ_UI_BUTTON_Up: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Trk. Groove Style Intensity Change forStep Dly. Len. Vel. NumSteps Clr // G1T1 Inv. Shuffle 15 all Tracks 1 0 0 0 Preset not editable! u8 visible_track = SEQ_UI_VisibleTrackGet(); u8 selected_groove = SEQ_CC_Get(visible_track, SEQ_CC_GROOVE_STYLE); seq_groove_entry_t *g; if( selected_groove >= SEQ_GROOVE_NUM_PRESETS ) g = (seq_groove_entry_t *)&seq_groove_templates[selected_groove-SEQ_GROOVE_NUM_PRESETS]; else g = (seq_groove_entry_t *)&seq_groove_presets[selected_groove]; /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Trk. Groove Style Intensity "); if( ui_selected_item == ITEM_GROOVE_VALUE_GLB && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(10); } else { SEQ_LCD_PrintString("Change for"); } SEQ_LCD_PrintString("Step Dly. Len. Vel. NumSteps Clr "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( ui_selected_item == ITEM_GXTY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_STYLE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(12); } else { SEQ_LCD_PrintString(SEQ_GROOVE_NameGet(selected_groove)); } SEQ_LCD_PrintSpaces(5); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_VALUE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintFormattedString("%3d", SEQ_CC_Get(visible_track, SEQ_CC_GROOVE_VALUE)); } SEQ_LCD_PrintSpaces(4); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_VALUE_GLB && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(10); } else { SEQ_LCD_PrintString("all Tracks"); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_STEP && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintFormattedString(" %2d ", edit_step+1); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_DELAY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { int value = g->add_step_delay[edit_step]; if( value <= -128 ) SEQ_LCD_PrintString("VNEG "); else if( value >= 127 ) SEQ_LCD_PrintString("VPOS "); else SEQ_LCD_PrintFormattedString("%4d ", value); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_LENGTH && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { int value = g->add_step_length[edit_step]; if( value <= -128 ) SEQ_LCD_PrintString("VNEG "); else if( value >= 127 ) SEQ_LCD_PrintString("VPOS "); else SEQ_LCD_PrintFormattedString("%4d ", value); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_GROOVE_VELOCITY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { int value = g->add_step_velocity[edit_step]; if( value <= -128 ) SEQ_LCD_PrintString("VNEG "); else if( value >= 127 ) SEQ_LCD_PrintString("VPOS "); else SEQ_LCD_PrintFormattedString("%4d ", value); } /////////////////////////////////////////////////////////////////////////// if( selected_groove >= SEQ_GROOVE_NUM_PRESETS ) { if( ui_selected_item == ITEM_GROOVE_NUM_STEPS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { SEQ_LCD_PrintFormattedString(" %2d ", g->num_steps); } SEQ_LCD_PrintSpaces(15); } else { if( ui_cursor_flash && ui_selected_item >= ITEM_GROOVE_LENGTH && ui_selected_item <= ITEM_GROOVE_DELAY ) SEQ_LCD_PrintSpaces(21); else SEQ_LCD_PrintString(" Preset not editable!"); } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Local exit function ///////////////////////////////////////////////////////////////////////////// static s32 EXIT_Handler(void) { s32 status = 0; if( ui_store_file_required ) { // write config file MUTEX_SDCARD_TAKE; if( (status=SEQ_FILE_G_Write(seq_file_session_name)) < 0 ) SEQ_UI_SDCardErrMsg(2000, status); MUTEX_SDCARD_GIVE; ui_store_file_required = 0; } return status; }
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // re-use encoder handler - only select UI item, don't increment, flags will be toggled return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( depressed ) return -1; if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; return 1; // value always changed case SEQ_UI_BUTTON_Left: if( depressed ) return -1; if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; return 1; // value always changed case SEQ_UI_BUTTON_Up: if( depressed ) return -1; return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: if( depressed ) return -1; return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Control Root Selected Scale // Global Keyb 50:Hungarian Gypsy /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString(" Control Root Selected Scale "); SEQ_LCD_PrintSpaces(40); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); SEQ_LCD_PrintSpaces(1); if( ui_selected_item == ITEM_SCALE_CTRL && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(8); } else { if( seq_core_global_scale_ctrl ) SEQ_LCD_PrintFormattedString("Group G%d", seq_core_global_scale_ctrl); else SEQ_LCD_PrintString("Global "); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// // determine the selected scale and root note selection depending on // global/group specific settings u8 scale, root_selection, root; SEQ_CORE_FTS_GetScaleAndRoot(&scale, &root_selection, &root); if( ui_selected_item == ITEM_SCALE_ROOT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { const char root_str[13][5] = { "Keyb", " C ", " C# ", " D ", " D# ", " E ", " F ", " F# ", " G ", " G# ", " A ", " A# ", " B " }; SEQ_LCD_PrintString((char *)root_str[root_selection]); } SEQ_LCD_PrintSpaces(2); if( ui_selected_item == ITEM_SCALE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(24); } else { SEQ_LCD_PrintFormattedString("%3d:", scale); SEQ_LCD_PrintString(SEQ_SCALE_NameGet(scale)); } /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintSpaces(40); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Local exit function ///////////////////////////////////////////////////////////////////////////// static s32 EXIT_Handler(void) { s32 status = 0; if( ui_store_file_required ) { // write config file MUTEX_SDCARD_TAKE; if( (status=SEQ_FILE_C_Write(seq_file_session_name)) < 0 ) SEQ_UI_SDCardErrMsg(2000, status); MUTEX_SDCARD_GIVE; ui_store_file_required = 0; } return status; }
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { if( high_prio ) { SEQ_LCD_CursorSet(32, 0); mios32_sys_time_t t = MIOS32_SYS_TimeGet(); int hours = (t.seconds / 3600) % 24; int minutes = (t.seconds % 3600) / 60; int seconds = (t.seconds % 3600) % 60; SEQ_LCD_PrintFormattedString("%02d:%02d:%02d", hours, minutes, seconds); return 0; } // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // About this MIDIbox: 00:00:00Stopwatch: 100/ 300 uS CPU Load: 40% // System Globals Tracks TrackInfo>MIDI Scheduler: Alloc 0/ 0 Drops: 0 // Select MIDI Device with GP Button: 10 Devices found under /sysex // xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx> /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("About this MIDIbox: "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); SEQ_LCD_PrintList((char *)ui_global_dir_list, LIST_ENTRY_WIDTH, NUM_LIST_ITEMS, NUM_LIST_DISPLAYED_ITEMS, ui_selected_item, list_view_offset); /////////////////////////////////////////////////////////////////////////// switch( ui_selected_item + list_view_offset ) { case LIST_ITEM_SYSTEM: { u32 stopwatch_value_max = SEQ_STATISTICS_StopwatchGetValueMax(); u32 stopwatch_value = SEQ_STATISTICS_StopwatchGetValue(); SEQ_LCD_CursorSet(40, 0); if( stopwatch_value_max == 0xffffffff ) { SEQ_LCD_PrintFormattedString("Stopwatch: Overrun! "); } else if( !stopwatch_value_max ) { SEQ_LCD_PrintFormattedString("Stopwatch: no result yet"); } else { SEQ_LCD_PrintFormattedString("Stopwatch: %4d/%4d uS ", stopwatch_value, stopwatch_value_max); } SEQ_LCD_PrintSpaces(3); SEQ_LCD_PrintFormattedString("CPU Load: %02d%%", SEQ_STATISTICS_CurrentCPULoad()); SEQ_LCD_CursorSet(40, 1); if( seq_midi_out_allocated > 1000 || seq_midi_out_max_allocated > 1000 || seq_midi_out_dropouts > 1000 ) { SEQ_LCD_PrintFormattedString("MIDI Scheduler: Alloc %4d/%4d Dr: %4d", seq_midi_out_allocated, seq_midi_out_max_allocated, seq_midi_out_dropouts); } else { SEQ_LCD_PrintFormattedString("MIDI Scheduler: Alloc %3d/%3d Drops: %3d", seq_midi_out_allocated, seq_midi_out_max_allocated, seq_midi_out_dropouts); } } break; default: SEQ_LCD_CursorSet(40, 0); // <----------------------------------------> SEQ_LCD_PrintString("Press SELECT to send Informations "); SEQ_LCD_CursorSet(40, 1); SEQ_LCD_PrintString("to MIOS Terminal "); } return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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) { // ensure that original screen will be print immediately ui_hold_msg_ctr = 0; #if 0 // leads to: comparison is always true due to limited range of data type if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) ) { #else if( encoder <= SEQ_UI_ENCODER_GP16 ) { #endif // select step within view ui_selected_step = (ui_selected_step_view << 4) | (u8)encoder; // show edit page for 2 seconds ui_hold_msg_ctr = 2000; // forward manual trigger to SEQ_CORE SEQ_CORE_ManualTrigger(ui_selected_step); return 1; // value changed } return -1; // invalid or unsupported encoder } ///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed // ensure that original screen will be print immediately ui_hold_msg_ctr = 0; #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // -> same handling like for encoders return Encoder_Handler(button, 0); } switch( button ) { case SEQ_UI_BUTTON_Select: { // Request synch to measure for all selected tracks SEQ_CORE_ManualSynchToMeasure(); return 1; } break; case SEQ_UI_BUTTON_Right: case SEQ_UI_BUTTON_Up: if( depressed ) return 0; // ignore when button depressed return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Left: case SEQ_UI_BUTTON_Down: if( depressed ) return 0; // ignore when button depressed return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { // branch to edit page if requested if( ui_hold_msg_ctr ) return SEQ_UI_EDIT_LCD_Handler(high_prio, SEQ_UI_EDIT_MODE_MANUAL); // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Selected Tracks: 1234 1234 1234 1234 Press SELECT to Synch to Measure! // lower line: print step 1..16/17..32/... /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString(" Selected Tracks: "); u8 track; for(track=0; track<16; ++track) { if( seq_core_trk[track].state.SYNC_MEASURE ) SEQ_LCD_PrintChar('S'); else if( SEQ_UI_IsSelectedTrack(track) ) SEQ_LCD_PrintChar('*'); else SEQ_LCD_PrintChar('1' + (track&3)); if( (track&3) == 3 ) SEQ_LCD_PrintChar(' '); } SEQ_LCD_PrintSpaces(1); SEQ_LCD_PrintString(" Press SELECT to Synch to Measure! "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); u8 step; for(step=0; step<16; ++step) SEQ_LCD_PrintFormattedString(" %2d ", 16*ui_selected_step_view + step + 1); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Initialisation ///////////////////////////////////////////////////////////////////////////// s32 SEQ_UI_MANUAL_Init(u32 mode) { // install callback routines SEQ_UI_InstallButtonCallback(Button_Handler); SEQ_UI_InstallEncoderCallback(Encoder_Handler); SEQ_UI_InstallLEDCallback(LED_Handler); SEQ_UI_InstallLCDCallback(LCD_Handler); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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 0 // leads to: comparison is always true due to limited range of data type if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) ) { #else if( encoder <= SEQ_UI_ENCODER_GP16 ) { #endif last_bookmark = encoder; SEQ_UI_Bookmark_Restore(last_bookmark); return 1; } // all other encoders return -1; } ///////////////////////////////////////////////////////////////////////////// // button callback function // Also used by SEQ_UI_Button_DirectBookmark // Should return: // 1 if value has been changed // 0 if value hasn't been changed // -1 if invalid or unsupported button ///////////////////////////////////////////////////////////////////////////// s32 SEQ_UI_BOOKMARKS_Button_Handler(seq_ui_button_t button, s32 depressed) { #if 0 // leads to: comparison is always true due to limited range of data type if( (button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16) ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif if( depressed ) { SEQ_UI_UnInstallDelayedActionCallback(Button_StoreRequest); if( store_state == 1 ) { // depressed within 1 second: select bookmark SEQ_UI_Bookmark_Restore(last_bookmark); } return 0; } last_bookmark = button; store_state = 1; SEQ_UI_InstallDelayedActionCallback(Button_StoreRequest, 500, 0); return 1; } #if 0 // doesn't make much sense here switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: case SEQ_UI_BUTTON_Up: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Left: case SEQ_UI_BUTTON_Down: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } #endif return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Global Bookmarks Session Bookmarks // BM 1 BM 2 BM 3 BM 4 BM 5 BM 6 BM 7 BM 8 BM 9 BM10 BM11 BM12 BM13 BM14 BM15 BM16 SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString(" Global Bookmarks Session Bookmarks "); SEQ_LCD_CursorSet(0, 1); int i; for(i=0; i<SEQ_UI_BOOKMARKS_NUM; ++i) { if( i >= 16 ) break; // just to ensure... seq_ui_bookmark_t *bm = (seq_ui_bookmark_t *)&seq_ui_bookmarks[i]; if( ui_cursor_flash && (i == last_bookmark) ) SEQ_LCD_PrintSpaces(5); else SEQ_LCD_PrintStringPadded(bm->name, 5); } return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Initialisation ///////////////////////////////////////////////////////////////////////////// s32 SEQ_UI_BOOKMARKS_Init(u32 mode) { // install callback routines SEQ_UI_InstallButtonCallback(SEQ_UI_BOOKMARKS_Button_Handler); SEQ_UI_InstallEncoderCallback(Encoder_Handler); SEQ_UI_InstallLEDCallback(LED_Handler); SEQ_UI_InstallLCDCallback(LCD_Handler); store_state = 0; return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // help function for delayed store action ///////////////////////////////////////////////////////////////////////////// static void Button_StoreRequest(u32 state) { if( store_state == 1 ) { SEQ_UI_Msg(last_bookmark >= 8 ? SEQ_UI_MSG_DELAYED_ACTION_R : SEQ_UI_MSG_DELAYED_ACTION, 2001, "Hold Button", "to store Bookmark!"); SEQ_UI_InstallDelayedActionCallback(Button_StoreRequest, 2000, 0); store_state = 2; } else { store_state = 0; // store into selected slot SEQ_UI_Bookmark_Store(last_bookmark); SEQ_UI_Msg(last_bookmark >= 8 ? SEQ_UI_MSG_USER_R : SEQ_UI_MSG_USER, 2000, "Storing", "Bookmark!"); #if !defined(MIOS32_FAMILY_EMULATION) // this yield ensures, that the display will be updated before storing the file taskYIELD(); #endif // and store file MUTEX_SDCARD_TAKE; s32 error = SEQ_FILE_BM_Write(seq_file_session_name, (last_bookmark < 8) ? 1 : 0); MUTEX_SDCARD_GIVE; if( error < 0 ) SEQ_UI_SDCardErrMsg(2000, error); else { // return to bookmarked page SEQ_UI_PageSet((seq_ui_page_t)seq_ui_bookmarks[last_bookmark].page); // and print message SEQ_UI_Msg(last_bookmark >= 8 ? SEQ_UI_MSG_USER_R : SEQ_UI_MSG_USER, 2000, "Bookmark", "stored!"); } } }
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Trk. Length Loop QuickSel Quick Selection: Length // G1T1 256/256 1 Length 4 8 16 24 32 64 128 256 // Trk. Length Loop QuickSel 1 5 9 13 1 1 17 25 // G1T1 256/256 1 Loops 4 8 12 16 16 32 32 32 u8 visible_track = SEQ_UI_VisibleTrackGet(); s32 quicksel_item = QUICKSEL_SearchItem(SEQ_UI_VisibleTrackGet()); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Trk. Length Loop "); SEQ_LCD_CursorSet(0, 2); SEQ_LCD_PrintString("QuickSel: "); SEQ_LCD_CursorSet(0, 3); SEQ_LCD_PrintSpaces(21); SEQ_LCD_CursorSet(0, 4); if( quicksel_mode == QUICKSEL_MODE_LENGTH ) { //SEQ_LCD_PrintString("Quick Selection: Length "); SEQ_LCD_PrintSpaces(21); } else { int i; for(i=0; i<8; ++i) { switch( i ) { case 0: SEQ_LCD_CursorSet(0, 4); break; case 4: SEQ_LCD_CursorSet(0, 6); break; } if( quicksel_item == i && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { int loop = (int)ui_quicksel_loop_loop[i] + 1; PrintLengthOrLoop(loop); } } } /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( ui_selected_item == ITEM_GXTY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(7); } else { SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); SEQ_LCD_PrintSpaces(3); } /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintSpaces(8); if( ui_selected_item == ITEM_LENGTH && ui_cursor_flash ) { } else { SEQ_LCD_CursorSet(7, 1); u16 num_steps = SEQ_TRG_NumStepsGet(visible_track); u16 len = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1; if( len > num_steps ) SEQ_LCD_PrintFormattedString("!!!/%d", num_steps); else SEQ_LCD_PrintFormattedString("%d/%d", len, num_steps); } // to allow variable string lengths... SEQ_LCD_CursorSet(15, 1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_LOOP && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { u16 num_steps = SEQ_TRG_NumStepsGet(visible_track); u16 loop = SEQ_CC_Get(visible_track, SEQ_CC_LOOP)+1; if( loop > num_steps ) SEQ_LCD_PrintString("!!! "); else SEQ_LCD_PrintFormattedString("%3d ", loop); } /////////////////////////////////////////////////////////////////////////// //SEQ_LCD_PrintSpaces(14); SEQ_LCD_CursorSet(11, 2); // free for sale /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_QUICKSEL_MODE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(7); } else { if( quicksel_mode == QUICKSEL_MODE_LENGTH ) { SEQ_LCD_PrintString("Length "); } else { SEQ_LCD_PrintString("Loops "); } } /////////////////////////////////////////////////////////////////////////// int i; for(i=0; i<8; ++i) { switch( i ) { case 0: SEQ_LCD_CursorSet(0, 5); break; case 4: SEQ_LCD_CursorSet(0, 7); break; } if( quicksel_item == i && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { int length = (int)((quicksel_mode == QUICKSEL_MODE_LENGTH) ? ui_quicksel_length[i] : ui_quicksel_loop_length[i]) + 1; if( length > SEQ_TRG_NumStepsGet(visible_track) ) SEQ_LCD_PrintString(" --- "); else { PrintLengthOrLoop(length); } } } return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif // -> same handling like for encoders return Encoder_Handler(button, 0); } switch( button ) { case SEQ_UI_BUTTON_Select: return -1; // unsupported (yet) case SEQ_UI_BUTTON_Right: case SEQ_UI_BUTTON_Up: if( depressed ) return 0; // ignore when button depressed return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Left: case SEQ_UI_BUTTON_Down: if( depressed ) return 0; // ignore when button depressed return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { // layout normal mode: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Gate Acc. Roll Glide Skip R.G R.V No Fx // A B C D E F G H // layout drum mode (lower line shows drum labels): // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Select Drum Instrument: // BD SD LT MT HT CP MA RS CB CY OH CH Smp1 Smp2 Smp3 Smp4 // ...horizontal VU meters... u8 visible_track = SEQ_UI_VisibleTrackGet(); u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE); if( high_prio && event_mode == SEQ_EVENT_MODE_Drum ) { /////////////////////////////////////////////////////////////////////////// // frequently update VU meters SEQ_LCD_CursorSet(0, 1); u8 drum; u8 num_instruments = SEQ_TRG_NumInstrumentsGet(visible_track); for(drum=0; drum<num_instruments; ++drum) { if( seq_core_trk[visible_track].layer_muted & (1 << drum) ) SEQ_LCD_PrintString("Mute "); else SEQ_LCD_PrintHBar((seq_layer_vu_meter[drum] >> 3) & 0xf); } return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: if set, a high-priority LCD update is requested ///////////////////////////////////////////////////////////////////////////// static s32 LCD_Handler(u8 high_prio) { u8 visible_track = SEQ_UI_VisibleTrackGet(); if( high_prio ) return 0; // there are no high-priority updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Trk. Mute Oct. Vel. FTS Fx Bus Port Chn. Lower/Upper Mode Reset // G1T1 +0 100 on on 1 IN1 #16 --- --- T&A Stacks // The selected Bus1 is not configured Bus Port Chn. Lower/Upper Mode Reset // for Play mode (but for Transposer&Arp.) 1 IN1 #16 --- --- T&A Stacks /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); if( !seq_midi_in_options[selected_bus].MODE_PLAY ) { SEQ_LCD_PrintFormattedString("The selected Bus%d is not configured ", selected_bus+1); } else { SEQ_LCD_PrintString("Trk. Mute Oct. Vel. FTS Fx "); } SEQ_LCD_CursorSet(40, 0); SEQ_LCD_PrintString(" Bus Port Chn. Lower/Upper Mode Reset "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( !seq_midi_in_options[selected_bus].MODE_PLAY ) { SEQ_LCD_PrintString("for Play mode (but for Transposer&Arp.) "); } else { if( ui_selected_item == ITEM_GXTY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_MUTE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintSpaces(2); SEQ_LCD_PrintChar((seq_core_trk_muted & (1 << visible_track)) ? '*' : 'o'); SEQ_LCD_PrintSpaces(2); } /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_OCT_TRANSPOSE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE); if( event_mode == SEQ_EVENT_MODE_Drum ) { SEQ_LCD_PrintString("Drum"); } else { SEQ_LCD_PrintFormattedString(" %c%d ", (seq_live_options.OCT_TRANSPOSE < 0) ? '-' : '+', abs(seq_live_options.OCT_TRANSPOSE)); } } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_LIVE_VELOCITY && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintFormattedString("%3d", seq_live_options.VELOCITY); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_LIVE_FORCE_SCALE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString(seq_live_options.FORCE_SCALE ? " on" : "off"); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_LIVE_FX && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString(seq_live_options.FX ? " on" : "off"); } SEQ_LCD_PrintSpaces(2 + 10); } /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_BUS && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { SEQ_LCD_PrintFormattedString(" %d ", selected_bus+1); } /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { if( seq_midi_in_port[selected_bus] ) SEQ_LCD_PrintString(SEQ_MIDI_PORT_InNameGet(SEQ_MIDI_PORT_InIxGet(seq_midi_in_port[selected_bus]))); else SEQ_LCD_PrintString(" All"); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_CHN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { if( seq_midi_in_channel[selected_bus] ) SEQ_LCD_PrintFormattedString("#%2d", seq_midi_in_channel[selected_bus]); else SEQ_LCD_PrintString("---"); } SEQ_LCD_PrintSpaces(3); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_LOWER && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_lower[selected_bus]); } SEQ_LCD_PrintSpaces(3); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_UPPER && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_midi_in_upper[selected_bus]); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_IN_MODE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(seq_midi_in_options[selected_bus].MODE_PLAY ? "Play" : "T&A "); } SEQ_LCD_PrintSpaces(3); SEQ_LCD_PrintString("Stacks"); return 0; // no error }
///////////////////////////////////////////////////////////////////////////// // 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) { if( depressed ) return 0; // ignore when button depressed // reset tap tempo if any button != GP16 has been pressed if( button != SEQ_UI_BUTTON_GP16 ) resetTapTempo(); #if 0 // leads to: comparison is always true due to limited range of data type if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) { #else if( button <= SEQ_UI_BUTTON_GP16 ) { #endif switch( button ) { case SEQ_UI_BUTTON_GP6: case SEQ_UI_BUTTON_GP7: // fire preset SEQ_CORE_BPM_Update(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num], seq_core_bpm_preset_ramp[seq_core_bpm_preset_num]); return 1; case SEQ_UI_BUTTON_GP8: // enter preset selection page SEQ_UI_PageSet(SEQ_UI_PAGE_BPM_PRESETS); return 1; } // re-use encoder handler - only select UI item, don't increment return Encoder_Handler((int)button, 0); } // remaining buttons: switch( button ) { case SEQ_UI_BUTTON_Select: case SEQ_UI_BUTTON_Right: if( ++ui_selected_item >= NUM_OF_ITEMS ) ui_selected_item = 0; return 1; // value always changed case SEQ_UI_BUTTON_Left: if( ui_selected_item == 0 ) ui_selected_item = NUM_OF_ITEMS-1; else --ui_selected_item; return 1; // value always changed case SEQ_UI_BUTTON_Up: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1); case SEQ_UI_BUTTON_Down: return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1); } return -1; // invalid or unsupported button } ///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Mode Preset Tempo Ramp Fire Preset MClk In/Out Ext. Tap // Master 1 140.0 1s Preset Page USB1 I:on O:off Restart Tempo /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString(" Mode Preset Tempo Ramp Fire Preset MClk In/Out "); SEQ_LCD_PrintString(seq_core_state.EXT_RESTART_REQ ? "Ongoing" : " Ext. "); SEQ_LCD_PrintString(" Tap "); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); if( ui_selected_item == ITEM_MODE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(6); } else { const char mode_str[3][7] = { " Auto ", "Master", "Slave "}; SEQ_LCD_PrintString((char *)mode_str[SEQ_BPM_ModeGet()]); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_PRESET && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(2); } else { SEQ_LCD_PrintFormattedString("%2d", seq_core_bpm_preset_num+1); } SEQ_LCD_PrintSpaces(3); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_BPM && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(5); } else { float bpm = seq_core_bpm_preset_tempo[seq_core_bpm_preset_num]; SEQ_LCD_PrintFormattedString("%3d.%d", (int)bpm, (int)(10*bpm)%10); } SEQ_LCD_PrintSpaces(2); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_RAMP && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { float ramp = seq_core_bpm_preset_ramp[seq_core_bpm_preset_num]; SEQ_LCD_PrintFormattedString("%2ds", (int)ramp); } /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintString(" Preset Page "); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_MCLK_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_ClkNameGet(SEQ_MIDI_PORT_ClkIxGet(selected_mclk_port))); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintString("I:"); if( ui_selected_item == ITEM_MCLK_IN && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { s32 status = SEQ_MIDI_ROUTER_MIDIClockInGet(selected_mclk_port); if( !SEQ_MIDI_PORT_ClkCheckAvailable(selected_mclk_port) ) status = -1; // MIDI In port not available switch( status ) { case 0: SEQ_LCD_PrintString("off"); break; case 1: SEQ_LCD_PrintString("on "); break; default: SEQ_LCD_PrintString("---"); } } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintString("O:"); if( ui_selected_item == ITEM_MCLK_OUT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { s32 status = SEQ_MIDI_ROUTER_MIDIClockOutGet(selected_mclk_port); if( !SEQ_MIDI_PORT_ClkCheckAvailable(selected_mclk_port) ) status = -1; // MIDI Out port not available switch( status ) { case 0: SEQ_LCD_PrintString("off"); break; case 1: SEQ_LCD_PrintString("on "); break; default: SEQ_LCD_PrintString("---"); } } SEQ_LCD_PrintSpaces(3); // DIN Sync moved to CV configuration SEQ_LCD_PrintSpaces(3+4); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_PrintString("Restart Tempo"); return 0; // no error } ///////////////////////////////////////////////////////////////////////////// // Local exit function ///////////////////////////////////////////////////////////////////////////// static s32 EXIT_Handler(void) { s32 status = 0; if( store_file_required ) { // write config file MUTEX_SDCARD_TAKE; if( (status=SEQ_FILE_C_Write(seq_file_session_name)) < 0 ) SEQ_UI_SDCardErrMsg(2000, status); MUTEX_SDCARD_GIVE; store_file_required = 0; } return status; }
///////////////////////////////////////////////////////////////////////////// // Local Display Handler function // IN: <high_prio>: 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 updates // layout: // 00000000001111111111222222222233333333330000000000111111111122222222223333333333 // 01234567890123456789012345678901234567890123456789012345678901234567890123456789 // <--------------------------------------><--------------------------------------> // Metronome Port Chn. Meas.Note BeatNote // off Def. #10 C#1 C#1 /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 0); SEQ_LCD_PrintString("Metronome Port Chn. Meas.Note BeatNote "); SEQ_LCD_PrintSpaces(40); /////////////////////////////////////////////////////////////////////////// SEQ_LCD_CursorSet(0, 1); SEQ_LCD_PrintSpaces(3); if( ui_selected_item == ITEM_ENABLE && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintString(seq_core_state.METRONOME ? "on " : "off"); } SEQ_LCD_PrintSpaces(4); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_PORT && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(4); } else { SEQ_LCD_PrintString(SEQ_MIDI_PORT_OutNameGet(SEQ_MIDI_PORT_OutIxGet(seq_core_metronome_port))); } SEQ_LCD_PrintSpaces(1); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_CHANNEL && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { if( !seq_core_metronome_chn ) SEQ_LCD_PrintString("---"); else SEQ_LCD_PrintFormattedString("#%2d", seq_core_metronome_chn); } SEQ_LCD_PrintSpaces(5); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_NOTE_M && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_core_metronome_note_m); } SEQ_LCD_PrintSpaces(7); /////////////////////////////////////////////////////////////////////////// if( ui_selected_item == ITEM_NOTE_B && ui_cursor_flash ) { SEQ_LCD_PrintSpaces(3); } else { SEQ_LCD_PrintNote(seq_core_metronome_note_b); } SEQ_LCD_PrintSpaces(4 + 40); return 0; // no error }