Esempio n. 1
0
/////////////////////////////////////////////////////////////////////////////
// Local encoder callback function
// Should return:
//   1 if value has been changed
//   0 if value hasn't been changed
//  -1 if invalid or unsupported encoder
/////////////////////////////////////////////////////////////////////////////
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
{
  // any encoder changes the dir view
  if( !dir_name[0] ) {
    if( SEQ_UI_SelectListItem(incrementer, dir_num_items, NUM_LIST_DISPLAYED_ITEMS, &ui_selected_item, &dir_view_offset) ) {
      SEQ_UI_SYSEX_UpdateDirList();
    }
  } else {
    switch( encoder ) {
      case SEQ_UI_ENCODER_GP13: {
	// select MIDI port
	u8 port_ix = SEQ_MIDI_PORT_OutIxGet(sysex_port);
	if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) {
	  sysex_port = SEQ_MIDI_PORT_OutPortGet(port_ix);
	  store_file_required = 1;
	  return 1; // value changed
	}
	return 0; // no change
      } break;

      case SEQ_UI_ENCODER_GP14:
      case SEQ_UI_ENCODER_GP15: {
	// select delay
	if( SEQ_UI_Var16_Inc(&sysex_delay_between_dumps, 0, 999, incrementer) >= 0 ) {
	  store_file_required = 1;
	  return 1; // value changed
	}
	return 0; // no change
      } break;

      case SEQ_UI_ENCODER_GP16:
	// EXIT only via button
	if( incrementer == 0 ) {
	  if( store_file_required )
	    SEQ_UI_SYSEX_StoreConfig();

	  // Exit
	  dir_name[0] = 0;
	  ui_selected_item = 0;
	  dir_view_offset = 0;
	  SEQ_UI_SYSEX_UpdateDirList();
	}
	return 1;

      default:
	if( SEQ_UI_SelectListItem(incrementer, dir_num_items, NUM_LIST_DISPLAYED_ITEMS-2, &ui_selected_item, &dir_view_offset) )
	  SEQ_UI_SYSEX_UpdateDirList();
    }
  }

  return 1;
}
/////////////////////////////////////////////////////////////////////////////
// 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)
{
  seq_midi_router_node_t *n = &seq_midi_router_node[selected_router_node];

  if( encoder <= SEQ_UI_ENCODER_GP8 ) {
    switch( encoder ) {
    case SEQ_UI_ENCODER_GP1:
    case SEQ_UI_ENCODER_GP2:
      selected_subpage = SUBPAGE_TRANSPOSE;
      ui_selected_item = ITEM_IN_BUS;
      break;

    case SEQ_UI_ENCODER_GP3:
    case SEQ_UI_ENCODER_GP4:
      selected_subpage = SUBPAGE_SECTIONS;
      ui_selected_item = ITEM_S_PORT;
      break;

    case SEQ_UI_ENCODER_GP5:
    case SEQ_UI_ENCODER_GP6:
      selected_subpage = SUBPAGE_ROUTER;
      ui_selected_item = ITEM_R_NODE;
      break;

    case SEQ_UI_ENCODER_GP7:
      selected_subpage = SUBPAGE_EXT_CTRL;
      ui_selected_item = ITEM_EXT_PORT;
      break;

    default:
      selected_subpage = SUBPAGE_MISC;
      ui_selected_item = ITEM_BLM_SCALAR_PORT;
    }

    return 1;
  }

  switch( selected_subpage ) {
    case SUBPAGE_TRANSPOSE:
      switch( encoder ) {
        case SEQ_UI_ENCODER_GP9:
	  ui_selected_item = ITEM_IN_BUS;
	  break;

        case SEQ_UI_ENCODER_GP10:
	  ui_selected_item = ITEM_IN_PORT;
	  break;

        case SEQ_UI_ENCODER_GP11:
	  ui_selected_item = ITEM_IN_CHN;
	  break;

        case SEQ_UI_ENCODER_GP12:
	  ui_selected_item = ITEM_IN_LOWER;
	  break;

        case SEQ_UI_ENCODER_GP13:
	  ui_selected_item = ITEM_IN_UPPER;
	  break;

        case SEQ_UI_ENCODER_GP14:
	  ui_selected_item = ITEM_IN_MODE;
	  break;

        case SEQ_UI_ENCODER_GP15:
	  return -1; // not mapped

        case SEQ_UI_ENCODER_GP16:
	  ui_selected_item = ITEM_RESET_STACKS;
	  break;
      }
      break;

    case SUBPAGE_SECTIONS:
      switch( encoder ) {
        case SEQ_UI_ENCODER_GP9:
	  ui_selected_item = ITEM_S_PORT;
	  break;

        case SEQ_UI_ENCODER_GP10:
	  ui_selected_item = ITEM_S_CHN;
	  break;

        case SEQ_UI_ENCODER_GP11:
	  ui_selected_item = ITEM_S_OCT_G1;
	  break;

        case SEQ_UI_ENCODER_GP12:
	  ui_selected_item = ITEM_S_OCT_G2;
	  break;

        case SEQ_UI_ENCODER_GP13:
	  ui_selected_item = ITEM_S_OCT_G3;
	  break;

        case SEQ_UI_ENCODER_GP14:
	  ui_selected_item = ITEM_S_OCT_G4;
	  break;

        case SEQ_UI_ENCODER_GP15:
	  ui_selected_item = ITEM_S_FWD_PORT;
	  break;

        case SEQ_UI_ENCODER_GP16:
	  ui_selected_item = ITEM_S_RESET_STACKS;
	  break;
      }
      break;

    case SUBPAGE_ROUTER:
      switch( encoder ) {
        case SEQ_UI_ENCODER_GP9:
	  ui_selected_item = ITEM_R_NODE;
	  break;

        case SEQ_UI_ENCODER_GP10:
	  ui_selected_item = ITEM_R_SRC_PORT;
	  break;

        case SEQ_UI_ENCODER_GP11:
	  ui_selected_item = ITEM_R_SRC_CHN;
	  break;

        case SEQ_UI_ENCODER_GP12:
	  ui_selected_item = ITEM_R_DST_PORT;
	  break;

        case SEQ_UI_ENCODER_GP13:
	  ui_selected_item = ITEM_R_DST_CHN;
	  break;

        case SEQ_UI_ENCODER_GP14:
	  return -1; // not used (yet)

        case SEQ_UI_ENCODER_GP15:
        case SEQ_UI_ENCODER_GP16:
	  ui_selected_item = ITEM_DEF_PORT;
	  break;
      }
      break;

    case SUBPAGE_EXT_CTRL:
      switch( encoder ) {
        case SEQ_UI_ENCODER_GP9:
	  ui_selected_item = ITEM_EXT_PORT;
	  break;

        case SEQ_UI_ENCODER_GP10:
	  ui_selected_item = ITEM_EXT_PORT_OUT;
	  break;

        case SEQ_UI_ENCODER_GP11:
	  ui_selected_item = ITEM_EXT_CHN;
	  break;

        case SEQ_UI_ENCODER_GP12:
        case SEQ_UI_ENCODER_GP13:
        case SEQ_UI_ENCODER_GP14:
	  ui_selected_item = ITEM_EXT_CTRL;
	  break;

        case SEQ_UI_ENCODER_GP15:
        case SEQ_UI_ENCODER_GP16:
	  ui_selected_item = ITEM_EXT_VALUE;
	  break;
      }
      break;

    case SUBPAGE_MISC:
      switch( encoder ) {
        case SEQ_UI_ENCODER_GP9:
        case SEQ_UI_ENCODER_GP10:
	  ui_selected_item = ITEM_BLM_SCALAR_PORT;
	  break;

        case SEQ_UI_ENCODER_GP11:
        case SEQ_UI_ENCODER_GP12:
        case SEQ_UI_ENCODER_GP13:
        case SEQ_UI_ENCODER_GP14:
	  return -1; // not used (yet)

        case SEQ_UI_ENCODER_GP15:
        case SEQ_UI_ENCODER_GP16:
	  // enter midi monitor page
	  SEQ_UI_PageSet(SEQ_UI_PAGE_MIDIMON);
	  return 1;
      }
      break;

    default:
      return -1; // unsupported subpage
  }

  // for GP encoders and Datawheel
  switch( ui_selected_item ) {
    case ITEM_IN_BUS: {
      if( SEQ_UI_Var8_Inc(&selected_bus, 0, SEQ_MIDI_IN_NUM_BUSSES-1, incrementer) >= 0 ) {
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_IN_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_InIxGet(seq_midi_in_port[selected_bus]);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_InNumGet()-1-4, incrementer) >= 0 ) { // don't allow selection of Bus1..Bus4
	seq_midi_in_port[selected_bus] = SEQ_MIDI_PORT_InPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_IN_CHN:
      if( SEQ_UI_Var8_Inc(&seq_midi_in_channel[selected_bus], 0, 16, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_IN_LOWER:
      if( SEQ_UI_Var8_Inc(&seq_midi_in_lower[selected_bus], 0, 127, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_IN_UPPER:
      if( SEQ_UI_Var8_Inc(&seq_midi_in_upper[selected_bus], 0, 127, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_IN_MODE: {
      u8 fwd = seq_midi_in_options[selected_bus].MODE_PLAY;
      if( SEQ_UI_Var8_Inc(&fwd, 0, 1, incrementer) >= 0 ) {
	seq_midi_in_options[selected_bus].MODE_PLAY = fwd;
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_RESET_STACKS: {
      SEQ_MIDI_IN_ResetTransArpStacks();
      SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Transposer/Arp.", "Stacks cleared!");

      // send to external
      SEQ_MIDI_IN_ExtCtrlSend(SEQ_MIDI_IN_EXT_CTRL_ALL_NOTES_OFF, 127, 0);

      return 1;
    } break;


    case ITEM_S_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_InIxGet(seq_midi_in_sect_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_InNumGet()-1, incrementer) >= 0 ) {
	seq_midi_in_sect_port = SEQ_MIDI_PORT_InPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_S_CHN:
      if( SEQ_UI_Var8_Inc(&seq_midi_in_sect_channel, 0, 16, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change


    case ITEM_S_OCT_G1: {
      u8 oct = seq_midi_in_sect_note[0] / 12;
      if( SEQ_UI_Var8_Inc(&oct, 0, 11, incrementer) >= 0 ) {
	seq_midi_in_sect_note[0] = 12*oct;
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_S_OCT_G2: {
      u8 oct = seq_midi_in_sect_note[1] / 12;
      if( SEQ_UI_Var8_Inc(&oct, 0, 11, incrementer) >= 0 ) {
	seq_midi_in_sect_note[1] = 12*oct;
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_S_OCT_G3: {
      u8 oct = seq_midi_in_sect_note[2] / 12;
      if( SEQ_UI_Var8_Inc(&oct, 0, 11, incrementer) >= 0 ) {
	seq_midi_in_sect_note[2] = 12*oct;
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_S_OCT_G4: {
      u8 oct = seq_midi_in_sect_note[3] / 12;
      if( SEQ_UI_Var8_Inc(&oct, 0, 11, incrementer) >= 0 ) {
	seq_midi_in_sect_note[3] = 12*oct;
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_S_FWD_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_OutIxGet(seq_midi_in_sect_fwd_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) {
	seq_midi_in_sect_fwd_port = SEQ_MIDI_PORT_OutPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_S_RESET_STACKS: {
      SEQ_MIDI_IN_ResetChangerStacks();
      SEQ_UI_Msg(SEQ_UI_MSG_USER_R, 2000, "Section Changer", "Stacks cleared!");

      // send to external
      SEQ_MIDI_IN_ExtCtrlSend(SEQ_MIDI_IN_EXT_CTRL_ALL_NOTES_OFF, 127, 0);

      return 1;
    } break;



    case ITEM_R_NODE:
      if( SEQ_UI_Var8_Inc(&selected_router_node, 0, SEQ_MIDI_ROUTER_NUM_NODES-1, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_R_SRC_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_InIxGet(n->src_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_InNumGet()-1, incrementer) >= 0 ) {
	n->src_port = SEQ_MIDI_PORT_InPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_R_SRC_CHN:
      if( SEQ_UI_Var8_Inc(&n->src_chn, 0, 17, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_R_DST_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_OutIxGet(n->dst_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) {
	n->dst_port = SEQ_MIDI_PORT_OutPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_R_DST_CHN:
      if( SEQ_UI_Var8_Inc(&n->dst_chn, 0, 19, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change


    case ITEM_DEF_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_OutIxGet(MIOS32_MIDI_DefaultPortGet());
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) {
	MIOS32_MIDI_DefaultPortSet(SEQ_MIDI_PORT_OutPortGet(port_ix));
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_EXT_PORT: {
      u8 numPorts = SEQ_MIDI_PORT_InNumGet();
      u8 port_ix = (seq_midi_in_ext_ctrl_port == 0xff) ? numPorts : SEQ_MIDI_PORT_InIxGet(seq_midi_in_ext_ctrl_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, numPorts, incrementer) >= 0 ) {
	seq_midi_in_ext_ctrl_port = (port_ix == numPorts) ? 0xff : SEQ_MIDI_PORT_InPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_EXT_PORT_OUT: {
      u8 port_ix = SEQ_MIDI_PORT_OutIxGet(seq_midi_in_ext_ctrl_out_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) {
	seq_midi_in_ext_ctrl_out_port = SEQ_MIDI_PORT_OutPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_EXT_CHN:
      if( SEQ_UI_Var8_Inc(&seq_midi_in_ext_ctrl_channel, 0, 16, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_EXT_CTRL:
      if( SEQ_UI_Var8_Inc(&selected_ext_ctrl, 0, SEQ_MIDI_IN_EXT_CTRL_NUM-1, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_EXT_VALUE:
      if( selected_ext_ctrl == SEQ_MIDI_IN_EXT_CTRL_NRPN_ENABLED ) {
	if( SEQ_UI_Var8_Inc(&seq_midi_in_ext_ctrl_asg[selected_ext_ctrl], 0, 1, incrementer) >= 0 ) {
	  store_file_required = 1;
	  return 1; // value changed
	}
      } else if( selected_ext_ctrl == SEQ_MIDI_IN_EXT_CTRL_PC_MODE ) {
	if( SEQ_UI_Var8_Inc(&seq_midi_in_ext_ctrl_asg[selected_ext_ctrl], 0, SEQ_MIDI_IN_EXT_CTRL_PC_MODE_NUM-1, incrementer) >= 0 ) {
	  store_file_required = 1;
	  return 1; // value changed
	}
      } else if( selected_ext_ctrl <= SEQ_MIDI_IN_EXT_CTRL_NUM ) {
	if( SEQ_UI_Var8_Inc(&seq_midi_in_ext_ctrl_asg[selected_ext_ctrl], 0, 128, incrementer) >= 0 ) {
	  store_file_required = 1;
	  return 1; // value changed
	}
      }
      return 0; // no change

    case ITEM_BLM_SCALAR_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_InIxGet(seq_blm_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_InNumGet()-1, incrementer) >= 0 ) {
	seq_blm_port = SEQ_MIDI_PORT_InPortGet(port_ix);
	MUTEX_MIDIOUT_TAKE;
	blm_timeout_ctr = 0; // fake timeout (so that "BLM not found" message will be displayed)
	SEQ_BLM_SYSEX_SendRequest(0x00); // request layout from BLM_SCALAR
	MUTEX_MIDIOUT_GIVE;
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;
  }

  return -1; // invalid or unsupported encoder
}
Esempio n. 3
0
/////////////////////////////////////////////////////////////////////////////
// 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
}
Esempio n. 4
0
/////////////////////////////////////////////////////////////////////////////
// Local encoder callback function
// Should return:
//   1 if value has been changed
//   0 if value hasn't been changed
//  -1 if invalid or unsupported encoder
/////////////////////////////////////////////////////////////////////////////
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
{
  switch( encoder ) {
    case SEQ_UI_ENCODER_GP1:
    case SEQ_UI_ENCODER_GP2:
      ui_selected_item = ITEM_ENABLE;
      break;

    case SEQ_UI_ENCODER_GP3:
      ui_selected_item = ITEM_PORT;
      break;

    case SEQ_UI_ENCODER_GP4:
      ui_selected_item = ITEM_CHANNEL;
      break;

    case SEQ_UI_ENCODER_GP5:
    case SEQ_UI_ENCODER_GP6:
      ui_selected_item = ITEM_NOTE_M;
      break;

    case SEQ_UI_ENCODER_GP7:
    case SEQ_UI_ENCODER_GP8:
      ui_selected_item = ITEM_NOTE_B;
      break;

    case SEQ_UI_ENCODER_GP9:
    case SEQ_UI_ENCODER_GP10:
    case SEQ_UI_ENCODER_GP11:
    case SEQ_UI_ENCODER_GP12:
    case SEQ_UI_ENCODER_GP13:
    case SEQ_UI_ENCODER_GP14:
    case SEQ_UI_ENCODER_GP15:
    case SEQ_UI_ENCODER_GP16:
      return -1; // not used (yet)
  }

  // for GP encoders and Datawheel
  switch( ui_selected_item ) {
    case ITEM_ENABLE:
      if( incrementer )
	seq_core_state.METRONOME = (incrementer > 0) ? 1 : 0;
      return 1;

    case ITEM_PORT: {
      u8 port_ix = SEQ_MIDI_PORT_OutIxGet(seq_core_metronome_port);
      if( SEQ_UI_Var8_Inc(&port_ix, 0, SEQ_MIDI_PORT_OutNumGet()-1, incrementer) >= 0 ) {
	seq_core_metronome_port = SEQ_MIDI_PORT_OutPortGet(port_ix);
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
    } break;

    case ITEM_CHANNEL:
      if( SEQ_UI_Var8_Inc(&seq_core_metronome_chn, 0, 16, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_NOTE_M:
      if( SEQ_UI_Var8_Inc(&seq_core_metronome_note_m, 0, 127, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change

    case ITEM_NOTE_B:
      if( SEQ_UI_Var8_Inc(&seq_core_metronome_note_b, 0, 127, incrementer) >= 0 ) {
	store_file_required = 1;
	return 1; // value changed
      }
      return 0; // no change
  }

  return -1; // invalid or unsupported encoder
}