s32 SEQ_MIDI_PORT_OutCheckAvailable(mios32_midi_port_t port) { u8 ix; for(ix=0; ix<NUM_OUT_PORTS; ++ix) { if( out_ports[ix].port == port ) { if( port == 0x80 ) { return SEQ_CV_IfGet() ? 1 : 0; } else if ( port >= 0xf0 ) return 1; // Bus is always available else if( (port & 0xf0) == OSC0 ) return 1; // TODO: check for ethernet connection here else return MIOS32_MIDI_CheckAvailable(port); } } return 0; // port not available }
///////////////////////////////////////////////////////////////////////////// // 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) { switch( encoder ) { case SEQ_UI_ENCODER_GP1: ui_selected_item = ITEM_CV; break; case SEQ_UI_ENCODER_GP2: ui_selected_item = ITEM_CURVE; break; case SEQ_UI_ENCODER_GP3: case SEQ_UI_ENCODER_GP4: ui_selected_item = ITEM_SLEWRATE; break; case SEQ_UI_ENCODER_GP5: ui_selected_item = ITEM_PITCHRANGE; break; case SEQ_UI_ENCODER_GP6: ui_selected_item = ITEM_GATE; break; case SEQ_UI_ENCODER_GP7: case SEQ_UI_ENCODER_GP8: ui_selected_item = ITEM_CALIBRATION; break; case SEQ_UI_ENCODER_GP9: ui_selected_item = ITEM_CLK_SEL; break; case SEQ_UI_ENCODER_GP10: case SEQ_UI_ENCODER_GP11: ui_selected_item = ITEM_CLK_PPQN; break; case SEQ_UI_ENCODER_GP12: ui_selected_item = ITEM_CLK_WIDTH; break; case SEQ_UI_ENCODER_GP13: case SEQ_UI_ENCODER_GP14: return -1; // not mapped case SEQ_UI_ENCODER_GP15: case SEQ_UI_ENCODER_GP16: ui_selected_item = ITEM_MODULE; break; } // for GP encoders and Datawheel switch( ui_selected_item ) { case ITEM_CV: if( SEQ_UI_Var8_Inc(&selected_cv, 0, SEQ_CV_NUM-1, incrementer) >= 0 ) { SEQ_CV_CaliModeSet(selected_cv, SEQ_CV_CaliModeGet()); // change calibration mode to new pin return 1; } return 0; case ITEM_CURVE: { u8 curve = SEQ_CV_CurveGet(selected_cv); if( SEQ_UI_Var8_Inc(&curve, 0, SEQ_CV_NUM_CURVES-1, incrementer) >= 0 ) { SEQ_CV_CurveSet(selected_cv, curve); store_file_required = 1; return 1; } return 0; } case ITEM_SLEWRATE: { u8 rate = SEQ_CV_SlewRateGet(selected_cv); if( SEQ_UI_Var8_Inc(&rate, 0, 255, incrementer) >= 0 ) { SEQ_CV_SlewRateSet(selected_cv, rate); store_file_required = 1; return 1; } return 0; } case ITEM_PITCHRANGE: { u8 range = SEQ_CV_PitchRangeGet(selected_cv); if( SEQ_UI_Var8_Inc(&range, 0, 127, incrementer) >= 0 ) { SEQ_CV_PitchRangeSet(selected_cv, range); store_file_required = 1; return 1; } return 0; } case ITEM_GATE: { u8 inv = SEQ_CV_GateInversionGet(selected_cv); if( SEQ_UI_Var8_Inc(&inv, 0, 1, incrementer) >= 0 ) { SEQ_CV_GateInversionSet(selected_cv, inv); store_file_required = 1; return 1; } return 0; } case ITEM_CALIBRATION: { u8 mode = SEQ_CV_CaliModeGet(); if( SEQ_UI_Var8_Inc(&mode, 0, SEQ_CV_NUM_CALI_MODES-1, incrementer) >= 0 ) { SEQ_CV_CaliModeSet(selected_cv, mode); store_file_required = 1; return 1; } return 0; } case ITEM_CLK_SEL: if( SEQ_UI_Var8_Inc(&selected_clkout, 0, SEQ_CV_NUM_CLKOUT-1, incrementer) >= 0 ) { return 1; } return 0; case ITEM_CLK_PPQN: { int i; u8 din_sync_div_ix = 0; u16 div = SEQ_CV_ClkDividerGet(selected_clkout); for(i=0; i<sizeof(din_sync_div_presets)/sizeof(u16); ++i) if( div == din_sync_div_presets[i] ) { din_sync_div_ix = i; break; } if( SEQ_UI_Var8_Inc(&din_sync_div_ix, 0, (sizeof(din_sync_div_presets)/sizeof(u16))-1, incrementer) ) { SEQ_CV_ClkDividerSet(selected_clkout, din_sync_div_presets[din_sync_div_ix]); store_file_required = 1; return 1; // value has been changed } else return 0; // value hasn't been changed } break; case ITEM_CLK_WIDTH: { u8 width = SEQ_CV_ClkPulseWidthGet(selected_clkout); if( SEQ_UI_Var8_Inc(&width, 1, 255, incrementer) >= 0 ) { SEQ_CV_ClkPulseWidthSet(selected_clkout, width); store_file_required = 1; return 1; } return 0; } break; case ITEM_MODULE: { u8 if_type = SEQ_CV_IfGet(); if( SEQ_UI_Var8_Inc(&if_type, 0, SEQ_CV_NUM_IF-1, incrementer) >= 0 ) { SEQ_CV_IfSet(if_type); store_file_required = 1; return 1; } 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 // 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; }