Subversion Repositories svn.mios32

Rev

Rev 758 | Rev 1024 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
167 tk 1
// $Id: seq_ui_edit.c 828 2010-01-12 22:06:46Z tk $
2
/*
3
 * Edit page
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
19
#include "seq_lcd.h"
20
#include "seq_ui.h"
21
 
22
#include "seq_core.h"
168 tk 23
#include "seq_cc.h"
741 tk 24
#include "seq_cc_labels.h"
176 tk 25
#include "seq_layer.h"
167 tk 26
#include "seq_par.h"
27
#include "seq_trg.h"
690 tk 28
#include "seq_chord.h"
600 tk 29
#include "seq_hwcfg.h"
167 tk 30
 
31
 
32
/////////////////////////////////////////////////////////////////////////////
729 tk 33
// Local Variables
34
/////////////////////////////////////////////////////////////////////////////
35
 
36
static u8 show_step_selection_page;
37
static u16 selected_steps = 0xffff; // will only be initialized once after startup
38
 
39
 
40
/////////////////////////////////////////////////////////////////////////////
178 tk 41
// Local prototypes
42
/////////////////////////////////////////////////////////////////////////////
43
 
747 tk 44
static s32 ChangeSingleEncValue(u8 track, u16 par_step, u16 trg_step, s32 incrementer, s32 forced_value, u8 change_gate, u8 dont_change_gate);
178 tk 45
 
46
 
47
/////////////////////////////////////////////////////////////////////////////
240 tk 48
// LED handler function (globally accessible, since it's re-used by UTIL page)
167 tk 49
/////////////////////////////////////////////////////////////////////////////
240 tk 50
s32 SEQ_UI_EDIT_LED_Handler(u16 *gp_leds)
167 tk 51
{
52
  u8 visible_track = SEQ_UI_VisibleTrackGet();
53
 
729 tk 54
  if( show_step_selection_page )
55
    *gp_leds = selected_steps;
56
  else
57
    *gp_leds =
58
      (SEQ_TRG_Get8(visible_track, 2*ui_selected_step_view+1, ui_selected_trg_layer, ui_selected_instrument) << 8) |
59
      (SEQ_TRG_Get8(visible_track, 2*ui_selected_step_view+0, ui_selected_trg_layer, ui_selected_instrument) << 0);
167 tk 60
 
61
  return 0; // no error
62
}
63
 
64
 
65
/////////////////////////////////////////////////////////////////////////////
168 tk 66
// Local encoder callback function
67
// Should return:
68
//   1 if value has been changed
69
//   0 if value hasn't been changed
70
//  -1 if invalid or unsupported encoder
167 tk 71
/////////////////////////////////////////////////////////////////////////////
168 tk 72
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
167 tk 73
{
168 tk 74
#if 0
75
  // leads to: comparison is always true due to limited range of data type
76
  if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) || encoder == SEQ_UI_ENCODER_Datawheel ) {
77
#else
78
  if( encoder <= SEQ_UI_ENCODER_GP16 || encoder == SEQ_UI_ENCODER_Datawheel ) {
79
#endif
729 tk 80
    if( show_step_selection_page ) {
81
      if( incrementer > 0 )
82
    selected_steps |= (1 << encoder);
83
      else
84
    selected_steps &= ~(1 << encoder);
85
      return 1; // value changed
86
    }
87
 
178 tk 88
    ui_selected_step = ((encoder == SEQ_UI_ENCODER_Datawheel) ? (ui_selected_step%16) : encoder) + ui_selected_step_view*16;
167 tk 89
 
182 tk 90
    u8 visible_track = SEQ_UI_VisibleTrackGet();
91
 
178 tk 92
    s32 value_changed = 0;
93
    s32 forced_value = -1;
94
    u8  change_gate = 1;
168 tk 95
 
182 tk 96
    // due to historical reasons (from old times where MBSEQ CS was stuffed with pots): 
97
    // in arp mode, we increment in steps of 4
98
    if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator &&
333 tk 99
    SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer) == SEQ_PAR_Type_Note )
182 tk 100
      incrementer *= 4;
101
 
102
 
178 tk 103
    // first change the selected value
104
    if( seq_ui_button_state.CHANGE_ALL_STEPS && seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
652 tk 105
      u16 num_steps = SEQ_PAR_NumStepsGet(visible_track);
106
      u16 par_step = ui_selected_step;
107
      u16 trg_step = ui_selected_step;
108
 
109
      // mirrored layer in drum mode?
110
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
111
      if( event_mode == SEQ_EVENT_MODE_Drum && par_step >= num_steps )
112
    par_step %= num_steps;
113
 
747 tk 114
      forced_value = ChangeSingleEncValue(visible_track, par_step, trg_step, incrementer, forced_value, change_gate, 0);
178 tk 115
      if( forced_value < 0 )
116
    return 0; // no change
117
      value_changed |= 1;
168 tk 118
    }
119
 
178 tk 120
    // change value of all selected steps
121
    u8 track;
122
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
123
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 124
    u16 num_steps = SEQ_PAR_NumStepsGet(track);
652 tk 125
    u16 trg_step = (ui_selected_step & ~(num_steps-1));
126
 
127
    u16 par_step;
128
    for(par_step=0; par_step<num_steps; ++par_step, ++trg_step) {
729 tk 129
      if( !seq_ui_button_state.CHANGE_ALL_STEPS || par_step == ui_selected_step || (selected_steps & (1 << (par_step % 16))) ) {
130
        change_gate = trg_step == ui_selected_step;
747 tk 131
        u8 dont_change_gate = par_step != ui_selected_step;
729 tk 132
        if( change_gate || seq_ui_button_state.CHANGE_ALL_STEPS ) {
747 tk 133
          if( ChangeSingleEncValue(track, par_step, trg_step, incrementer, forced_value, change_gate, dont_change_gate) >= 0 )
729 tk 134
        value_changed |= 1;
135
        }
178 tk 136
      }
137
    }
138
      }
176 tk 139
    }
168 tk 140
 
178 tk 141
    return value_changed;
168 tk 142
  }
143
 
144
  return -1; // invalid or unsupported encoder
167 tk 145
}
146
 
147
 
148
/////////////////////////////////////////////////////////////////////////////
168 tk 149
// Local button callback function
150
// Should return:
151
//   1 if value has been changed
152
//   0 if value hasn't been changed
153
//  -1 if invalid or unsupported button
167 tk 154
/////////////////////////////////////////////////////////////////////////////
758 tk 155
s32 SEQ_UI_EDIT_Button_Handler(seq_ui_button_t button, s32 depressed)
167 tk 156
{
306 tk 157
  u8 visible_track = SEQ_UI_VisibleTrackGet();
158
 
168 tk 159
#if 0
160
  // leads to: comparison is always true due to limited range of data type
161
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
162
#else
163
  if( button <= SEQ_UI_BUTTON_GP16 ) {
164
#endif
729 tk 165
    if( depressed ) return 0; // ignore when button depressed
166
 
167
    if( show_step_selection_page ) {
168
      selected_steps ^= (1 << button);
169
      return 1; // value changed
170
    }
171
 
180 tk 172
    ui_selected_step = button + ui_selected_step_view*16;
168 tk 173
    // toggle trigger layer
600 tk 174
    // if seq_hwcfg_button_beh.all_with_triggers set, we've three cases:
178 tk 175
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
176
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
177
    // c) ALL function not active: toggle step
600 tk 178
    if( seq_hwcfg_button_beh.all_with_triggers && seq_ui_button_state.CHANGE_ALL_STEPS ) {
178 tk 179
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
180
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
303 tk 181
    u16 step = ui_selected_step;
328 tk 182
    u8 new_value = SEQ_TRG_Get(visible_track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
178 tk 183
 
184
    u8 track;
185
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
318 tk 186
      if( SEQ_UI_IsSelectedTrack(track) ) {
187
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
188
        for(step=0; step<num_steps; ++step)
328 tk 189
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
318 tk 190
      }
178 tk 191
      } else {
192
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
303 tk 193
    u8 track;
194
    u16 step;
178 tk 195
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
196
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 197
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
198
        for(step=0; step<num_steps; ++step) {
328 tk 199
          u8 new_value = SEQ_TRG_Get(track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
200
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
178 tk 201
        }
202
      }
203
    }
204
      }
205
    } else {
206
      // c) ALL function not active: toggle step
207
      u8 track;
484 tk 208
 
209
      u8 new_value = SEQ_TRG_Get(visible_track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
178 tk 210
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
211
    if( SEQ_UI_IsSelectedTrack(track) ) {
328 tk 212
      SEQ_TRG_Set(track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument, new_value);
178 tk 213
    }
214
      }
215
    }
168 tk 216
    return 1; // value always changed
178 tk 217
 
168 tk 218
  } else {
219
    switch( button ) {
220
      case SEQ_UI_BUTTON_Select:
729 tk 221
    show_step_selection_page = depressed ? 0 : 1;
222
    return 1; // value always changed
223
 
303 tk 224
      case SEQ_UI_BUTTON_Right: {
729 tk 225
    if( depressed ) return 0; // ignore when button depressed
226
 
303 tk 227
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
306 tk 228
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
303 tk 229
      next_step = 0;
230
    ui_selected_step = next_step;
168 tk 231
    ui_selected_step_view = ui_selected_step / 16;
232
    return 1; // value always changed
303 tk 233
      } break;
167 tk 234
 
168 tk 235
      case SEQ_UI_BUTTON_Left:
729 tk 236
    if( depressed ) return 0; // ignore when button depressed
237
 
168 tk 238
    if( ui_selected_step == 0 )
306 tk 239
      ui_selected_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
168 tk 240
    ui_selected_step_view = ui_selected_step / 16;
241
    return 1; // value always changed
167 tk 242
 
168 tk 243
      case SEQ_UI_BUTTON_Up:
729 tk 244
    if( depressed ) return 0; // ignore when button depressed
168 tk 245
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
246
 
247
      case SEQ_UI_BUTTON_Down:
729 tk 248
    if( depressed ) return 0; // ignore when button depressed
168 tk 249
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
250
    }
167 tk 251
  }
252
 
168 tk 253
  return -1; // invalid or unsupported button
167 tk 254
}
255
 
256
 
257
/////////////////////////////////////////////////////////////////////////////
240 tk 258
// Global Display Handler function
167 tk 259
// IN: <high_prio>: if set, a high-priority LCD update is requested
240 tk 260
//     <edit_page>: selects the normal, or copy/paste/move/scroll view
167 tk 261
/////////////////////////////////////////////////////////////////////////////
240 tk 262
s32 SEQ_UI_EDIT_LCD_Handler(u8 high_prio, seq_ui_edit_mode_t edit_mode)
167 tk 263
{
264
  if( high_prio )
265
    return 0; // there are no high-priority updates
266
 
326 tk 267
 
268
  // layout common track:
269
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
270
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
271
  // G1T1 xxxxxxxxxxxxxxx  PC:Length TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
272
  // ....
273
 
274
  // layout drum track:
275
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
276
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
277
  // G1T1 xxxxxxxxxxxxxxx  PA:Vel.   TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
278
  // ....
279
 
729 tk 280
  // layout step selection:
281
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
282
  //        Select the steps which should be  controlled by the ALL function:        
283
  //   *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *  
326 tk 284
 
729 tk 285
  if( show_step_selection_page ) {
286
    int step;
287
 
288
    SEQ_LCD_CursorSet(0, 0);
289
    SEQ_LCD_PrintString("       Select the steps which should be  controlled by the ALL function:        ");
290
    SEQ_LCD_CursorSet(0, 1);
291
    for(step=0; step<16; ++step)
292
      SEQ_LCD_PrintFormattedString("  %c  ", (selected_steps & (1 << step)) ? '*' : 'o');
293
    return 0; // no error
294
  }
295
 
296
 
167 tk 297
  u8 visible_track = SEQ_UI_VisibleTrackGet();
323 tk 298
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
167 tk 299
 
176 tk 300
  seq_layer_evnt_t layer_event;
336 tk 301
  SEQ_LAYER_GetEvntOfLayer(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
168 tk 302
 
333 tk 303
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
176 tk 304
 
333 tk 305
  // TODO: tmp. solution to print chord velocity correctly
306
  if( layer_type == SEQ_PAR_Type_Velocity && (seq_cc_trk[visible_track].link_par_layer_chord == 0) )
307
    layer_type = SEQ_PAR_Type_Chord;
326 tk 308
 
333 tk 309
 
167 tk 310
  ///////////////////////////////////////////////////////////////////////////
278 tk 311
  SEQ_LCD_CursorSet(0, 0);
167 tk 312
 
326 tk 313
  SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks);
314
  SEQ_LCD_PrintSpaces(1);
315
 
240 tk 316
  switch( edit_mode ) {
317
    case SEQ_UI_EDIT_MODE_COPY: {
318
      if( ui_cursor_flash ) {
319
    SEQ_LCD_PrintSpaces(15);
320
      } else {
321
    char str_buffer[10];
322
    sprintf(str_buffer, "%d-%d", SEQ_UI_UTIL_CopyPasteBeginGet()+1, SEQ_UI_UTIL_CopyPasteEndGet()+1);
278 tk 323
    SEQ_LCD_PrintFormattedString("COPY S%-9s", str_buffer);
240 tk 324
      }
325
    } break;
167 tk 326
 
240 tk 327
    case SEQ_UI_EDIT_MODE_PASTE: {
328
      if( ui_cursor_flash ) {
329
    SEQ_LCD_PrintSpaces(15);
330
      } else {
278 tk 331
    SEQ_LCD_PrintFormattedString("PASTE OFFS.%3d ", ui_selected_step+1);
240 tk 332
      }
333
    } break;
167 tk 334
 
240 tk 335
    case SEQ_UI_EDIT_MODE_MOVE: {
336
      if( ui_cursor_flash ) {
337
    SEQ_LCD_PrintSpaces(15);
338
      } else {
278 tk 339
    SEQ_LCD_PrintString("MOVE STEPS     ");
240 tk 340
      }
341
    } break;
176 tk 342
 
240 tk 343
    case SEQ_UI_EDIT_MODE_SCROLL: {
344
      if( ui_cursor_flash ) {
345
    SEQ_LCD_PrintSpaces(15);
346
      } else {
278 tk 347
    SEQ_LCD_PrintString("SCROLL TRACK   ");
240 tk 348
      }
349
    } break;
176 tk 350
 
240 tk 351
    case SEQ_UI_EDIT_MODE_RANDOM: {
352
      if( ui_cursor_flash ) {
353
    SEQ_LCD_PrintSpaces(15);
354
      } else {
278 tk 355
    SEQ_LCD_PrintString("RANDOMIZED     ");
240 tk 356
      }
357
    } break;
176 tk 358
 
240 tk 359
    case SEQ_UI_EDIT_MODE_RECORD: {
360
      if( ui_cursor_flash ) {
361
    SEQ_LCD_PrintSpaces(15);
362
      } else {
416 tk 363
    SEQ_LCD_PrintString("RECORDING      ");
240 tk 364
      }
365
    } break;
176 tk 366
 
600 tk 367
    case SEQ_UI_EDIT_MODE_MANUAL: {
368
      if( ui_cursor_flash ) {
369
    SEQ_LCD_PrintSpaces(15);
370
      } else {
371
    SEQ_LCD_PrintString("MANUAL TRIGGER ");
372
      }
373
    } break;
374
 
240 tk 375
    default: {
326 tk 376
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
377
    SEQ_LCD_PrintChar(' ');
378
    SEQ_LCD_PrintChar(' ');
379
    SEQ_LCD_PrintMIDIOutPort(SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT));
380
    SEQ_LCD_PrintChar(' ');
381
    SEQ_LCD_PrintFormattedString("Chn.%2d  ", SEQ_CC_Get(visible_track, SEQ_CC_MIDI_CHANNEL)+1);
382
      } else {
383
    SEQ_LCD_PrintTrackLabel(visible_track, (char *)seq_core_trk[visible_track].name);
384
      }
385
    }
386
  }
176 tk 387
 
326 tk 388
  SEQ_LCD_PrintSpaces(2);
176 tk 389
 
326 tk 390
  SEQ_LCD_PrintChar('P');
391
  SEQ_LCD_PrintChar('A' + ui_selected_par_layer);
392
  SEQ_LCD_PrintChar(':');
240 tk 393
 
333 tk 394
  if( layer_type == SEQ_PAR_Type_CC ) {
395
    SEQ_LCD_PrintFormattedString("CC#%3d ", layer_event.midi_package.cc_number);
396
  } else {
397
    SEQ_LCD_PrintString(SEQ_PAR_AssignedTypeStr(visible_track, ui_selected_par_layer));
398
    SEQ_LCD_PrintSpaces(2);
176 tk 399
  }
167 tk 400
 
328 tk 401
  SEQ_LCD_PrintFormattedString("T%c:%s", 'A' + ui_selected_trg_layer, SEQ_TRG_AssignedTypeStr(visible_track, ui_selected_trg_layer));
327 tk 402
 
403
 
167 tk 404
  ///////////////////////////////////////////////////////////////////////////
278 tk 405
  SEQ_LCD_CursorSet(40, 0);
167 tk 406
 
741 tk 407
  SEQ_LCD_PrintFormattedString("Step%3d ", ui_selected_step+1);
167 tk 408
 
176 tk 409
  if( layer_event.midi_package.event == CC ) {
741 tk 410
    mios32_midi_port_t port = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT);
411
    u8 loopback = port == 0xf0;
412
 
413
    if( loopback )
414
      SEQ_LCD_PrintString((char *)SEQ_CC_LABELS_Get(port, layer_event.midi_package.cc_number));
415
    else
416
      SEQ_LCD_PrintFormattedString("  CC#%3d", layer_event.midi_package.cc_number);
417
    SEQ_LCD_PrintFormattedString(" %3d ", layer_event.midi_package.value);
176 tk 418
    SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
419
  } else {
741 tk 420
    SEQ_LCD_PrintSpaces(2);
421
 
178 tk 422
    if( layer_event.midi_package.note && layer_event.midi_package.velocity && (layer_event.len >= 0) ) {
288 tk 423
      if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator ) {
182 tk 424
    SEQ_LCD_PrintArp(layer_event.midi_package.note);
333 tk 425
      } else if( layer_type == SEQ_PAR_Type_Chord ) {
328 tk 426
    u8 par_value = SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
716 tk 427
    u8 chord_ix = par_value & 0x1f;
428
    u8 chord_oct = par_value >> 5;
288 tk 429
    SEQ_LCD_PrintString(SEQ_CHORD_NameGet(chord_ix));
430
    SEQ_LCD_PrintFormattedString("/%d", chord_oct);
431
      } else {
182 tk 432
    SEQ_LCD_PrintNote(layer_event.midi_package.note);
288 tk 433
      }
176 tk 434
      SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
435
    }
436
    else {
278 tk 437
      SEQ_LCD_PrintString("....");
176 tk 438
    }
278 tk 439
    SEQ_LCD_PrintFormattedString(" Vel:%3d", layer_event.midi_package.velocity);
176 tk 440
  }
167 tk 441
 
278 tk 442
  SEQ_LCD_PrintString(" Len:");
176 tk 443
  SEQ_LCD_PrintGatelength(layer_event.len);
167 tk 444
 
740 tk 445
  // print flashing *LOOPED* at right corner if loop mode activated to remind that steps will be played differntly
446
  if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_state.LOOP ) {
447
    SEQ_LCD_PrintString(" *LOOPED*");
828 tk 448
  } else if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_trk[visible_track].play_section > 0 ) {
449
    SEQ_LCD_PrintFormattedString(" *Sect.%c*", 'A'+seq_core_trk[visible_track].play_section);
326 tk 450
  } else {
740 tk 451
    SEQ_LCD_PrintSpaces(4);
452
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
453
      SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name);
454
    } else {
455
      SEQ_LCD_PrintTrackCategory(visible_track, (char *)seq_core_trk[visible_track].name);
456
    }
180 tk 457
  }
167 tk 458
 
459
  ///////////////////////////////////////////////////////////////////////////
460
 
336 tk 461
  u8 show_drum_triggers = (event_mode == SEQ_EVENT_MODE_Drum && (edit_mode || !ui_hold_msg_ctr));
335 tk 462
 
176 tk 463
  // extra handling for gatelength (shows vertical bars)
335 tk 464
  if( !show_drum_triggers && layer_type == SEQ_PAR_Type_Length ) {
167 tk 465
 
176 tk 466
    // we want to show horizontal bars
467
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
167 tk 468
 
176 tk 469
    // initial cursor position
278 tk 470
    SEQ_LCD_CursorSet(0, 1);
167 tk 471
 
176 tk 472
    // determine length of previous step (depends on selected view and track length)
473
    int previous_step = 16*ui_selected_step_view - 1;
474
    if( previous_step < 0 )
475
      previous_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
476
 
477
    seq_layer_evnt_t layer_event;
336 tk 478
    SEQ_LAYER_GetEvntOfLayer(visible_track, previous_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
176 tk 479
    u16 previous_length = layer_event.len;
330 tk 480
 
481
    // show length of 16 steps
336 tk 482
    u16 step;
330 tk 483
    for(step=0; step<16; ++step) {
336 tk 484
      u16 visible_step = step + 16*ui_selected_step_view;
485
      SEQ_LAYER_GetEvntOfLayer(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
330 tk 486
 
338 tk 487
      // muted step? if previous gatelength <= 96, print spaces
488
      if( !layer_event.midi_package.velocity && previous_length < 96 ) {
489
    SEQ_LCD_PrintSpaces(5);
490
      } else {
491
    if( layer_event.len >= 96 )
492
      SEQ_LCD_PrintHBar(15); // glide or stretched event
330 tk 493
    else
338 tk 494
      SEQ_LCD_PrintHBar(((layer_event.len-1)*16)/100);
330 tk 495
      }
338 tk 496
      previous_length = (layer_event.midi_package.velocity || (previous_length >= 96 && layer_event.len >= 96)) ? layer_event.len : 0;
330 tk 497
    }
498
 
176 tk 499
  } else {
500
 
335 tk 501
    if( show_drum_triggers ) {
323 tk 502
      // we want to show triggers
325 tk 503
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_DrumSymbolsBig);
323 tk 504
    } else {
505
      // we want to show vertical bars
506
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
507
    }
176 tk 508
 
509
    // initial cursor position
278 tk 510
    SEQ_LCD_CursorSet(0, 1);
176 tk 511
 
323 tk 512
    int step_region_begin;
513
    int step_region_end;
240 tk 514
    switch( edit_mode ) {
515
      case SEQ_UI_EDIT_MODE_COPY:
516
    step_region_begin = SEQ_UI_UTIL_CopyPasteBeginGet();
517
    step_region_end = SEQ_UI_UTIL_CopyPasteEndGet();
518
    break;
519
      case SEQ_UI_EDIT_MODE_PASTE:
520
    step_region_begin = ui_selected_step;
521
    step_region_end = ui_selected_step + SEQ_UI_UTIL_CopyPasteEndGet() - SEQ_UI_UTIL_CopyPasteBeginGet();
522
    break;
523
      case SEQ_UI_EDIT_MODE_SCROLL:
524
    step_region_begin = ui_selected_step;
525
    step_region_end = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
526
    break;
527
      default:
336 tk 528
    step_region_begin = ui_selected_step;
529
    step_region_end = ui_selected_step;
240 tk 530
    }
531
 
336 tk 532
    u16 step;
176 tk 533
    for(step=0; step<16; ++step) {
336 tk 534
      u16 visible_step = step + 16*ui_selected_step_view;
240 tk 535
 
536
      if( ui_cursor_flash &&
537
      edit_mode != SEQ_UI_EDIT_MODE_NORMAL &&
538
      visible_step >= step_region_begin && visible_step <= step_region_end ) {
539
    SEQ_LCD_PrintSpaces(5);
540
    continue;
541
      }
542
 
176 tk 543
      seq_layer_evnt_t layer_event;
336 tk 544
      SEQ_LAYER_GetEvntOfLayer(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
176 tk 545
 
335 tk 546
      if( show_drum_triggers ) {
336 tk 547
    u8 gate_accent = SEQ_TRG_Get(visible_track, visible_step, 0, ui_selected_instrument);
328 tk 548
    if( SEQ_TRG_NumLayersGet(visible_track) >= 2 )
336 tk 549
      gate_accent |= SEQ_TRG_Get(visible_track, visible_step, 1, ui_selected_instrument) << 1;
335 tk 550
 
323 tk 551
    SEQ_LCD_PrintChar(' ');
552
    SEQ_LCD_PrintChar(' ');
327 tk 553
    SEQ_LCD_PrintChar(gate_accent);
323 tk 554
    SEQ_LCD_PrintChar(' ');
555
    SEQ_LCD_PrintChar(' ');
556
      } else {
333 tk 557
    switch( layer_type ) {
558
          case SEQ_PAR_Type_None:
559
        SEQ_LCD_PrintString("None");
560
        break;
561
 
562
          case SEQ_PAR_Type_Note:
563
          case SEQ_PAR_Type_Velocity:
323 tk 564
        if( layer_event.midi_package.note && layer_event.midi_package.velocity ) {
565
          if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator )
566
        SEQ_LCD_PrintArp(layer_event.midi_package.note);
567
          else
568
        SEQ_LCD_PrintNote(layer_event.midi_package.note);
569
          SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
570
        } else {
571
          SEQ_LCD_PrintString("----");
572
        }
573
        break;
574
 
333 tk 575
      case SEQ_PAR_Type_Chord:
323 tk 576
        if( layer_event.midi_package.note && layer_event.midi_package.velocity ) {
336 tk 577
          u8 par_value;
578
          // more or less dirty - a velocity layer can force SEQ_PAR_Type_Chord
579
          if( SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer) == SEQ_PAR_Type_Velocity )
580
        par_value = SEQ_PAR_ChordGet(visible_track, visible_step, ui_selected_instrument);
581
          else
582
        par_value = SEQ_PAR_Get(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument);
716 tk 583
          u8 chord_ix = par_value & 0x1f;
584
          u8 chord_char = ((chord_ix >= 0x10) ? 'a' : 'A') + (chord_ix & 0xf);
585
          u8 chord_oct = par_value >> 5;
586
          SEQ_LCD_PrintFormattedString("%c/%d", chord_char, chord_oct);
323 tk 587
          SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
588
        } else {
589
          SEQ_LCD_PrintString("----");
590
        }
591
        break;
176 tk 592
 
333 tk 593
      //case SEQ_PAR_Type_Length:
323 tk 594
      //break;
595
      // extra handling -- see code above
176 tk 596
 
333 tk 597
      case SEQ_PAR_Type_CC:
598
      case SEQ_PAR_Type_PitchBend: {
599
        u8 value = layer_event.midi_package.value;
600
        SEQ_LCD_PrintFormattedString("%3d", value);
601
        SEQ_LCD_PrintVBar(value >> 4);
602
      } break;
603
 
604
      case SEQ_PAR_Type_Probability:
336 tk 605
        SEQ_LCD_PrintProbability(SEQ_PAR_ProbabilityGet(visible_track, visible_step, ui_selected_instrument));
323 tk 606
        break;
176 tk 607
 
333 tk 608
      case SEQ_PAR_Type_Delay:
336 tk 609
        SEQ_LCD_PrintStepDelay(SEQ_PAR_StepDelayGet(visible_track, visible_step, ui_selected_instrument));
333 tk 610
        break;
611
 
612
      case SEQ_PAR_Type_Roll:
336 tk 613
        SEQ_LCD_PrintRollMode(SEQ_PAR_RollModeGet(visible_track, visible_step, ui_selected_instrument));
333 tk 614
        break;
615
 
323 tk 616
          default:
617
        SEQ_LCD_PrintString("????");
618
        break;
619
    }
176 tk 620
      }
621
 
336 tk 622
      if( !show_drum_triggers ) {
323 tk 623
    SEQ_LCD_PrintChar((visible_step == step_region_end) ? '<'
624
              : ((visible_step == (step_region_begin-1)) ? '>' : ' '));
625
      }
240 tk 626
 
176 tk 627
    }
167 tk 628
  }
629
 
630
  return 0; // no error
631
}
632
 
633
 
634
/////////////////////////////////////////////////////////////////////////////
240 tk 635
// Local Display Handler function
636
// IN: <high_prio>: if set, a high-priority LCD update is requested
637
/////////////////////////////////////////////////////////////////////////////
638
static s32 LCD_Handler(u8 high_prio)
639
{
640
  return SEQ_UI_EDIT_LCD_Handler(high_prio, SEQ_UI_EDIT_MODE_NORMAL);
641
}
642
 
643
 
644
/////////////////////////////////////////////////////////////////////////////
167 tk 645
// Initialisation
646
/////////////////////////////////////////////////////////////////////////////
647
s32 SEQ_UI_EDIT_Init(u32 mode)
648
{
649
  // install callback routines
758 tk 650
  SEQ_UI_InstallButtonCallback(SEQ_UI_EDIT_Button_Handler);
168 tk 651
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
240 tk 652
  SEQ_UI_InstallLEDCallback(SEQ_UI_EDIT_LED_Handler);
168 tk 653
  SEQ_UI_InstallLCDCallback(LCD_Handler);
167 tk 654
 
729 tk 655
  show_step_selection_page = 0;
656
 
167 tk 657
  return 0; // no error
658
}
178 tk 659
 
660
 
661
 
662
/////////////////////////////////////////////////////////////////////////////
663
// help function to change/set a single encoder value
664
// if forced_value >= 0: new value will be set to the given value
665
// if forced_value < 0: new value will be changed via incrementer
666
// returns >= 0 if new value has been set (value change)
667
// returns < 0 if no change
668
/////////////////////////////////////////////////////////////////////////////
747 tk 669
  static s32 ChangeSingleEncValue(u8 track, u16 par_step, u16 trg_step, s32 incrementer, s32 forced_value, u8 change_gate, u8 dont_change_gate)
178 tk 670
{
333 tk 671
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(track, ui_selected_par_layer);
335 tk 672
  u8 visible_track = SEQ_UI_VisibleTrackGet();
178 tk 673
 
828 tk 674
#if 0
675
  // disabled in MBSEQ V4.0beta15 due to issue reported by Gridracer:
676
  // http://midibox.org/forums/index.php?/topic/13137-midibox-seq-v4-beta-release-feedback/page__st__100
677
 
333 tk 678
  // if note/chord/velocity parameter: only change gate if requested
679
  if( (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord || layer_type == SEQ_PAR_Type_Velocity) &&
178 tk 680
      !change_gate &&
652 tk 681
      !SEQ_TRG_GateGet(track, trg_step, ui_selected_instrument) )
178 tk 682
    return -1;
828 tk 683
#endif
178 tk 684
 
335 tk 685
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
652 tk 686
  if( event_mode == SEQ_EVENT_MODE_Drum ) {
335 tk 687
    ui_hold_msg_ctr = 1000; // show value for 1 second
652 tk 688
  }
335 tk 689
 
652 tk 690
  s32 old_value = SEQ_PAR_Get(track, par_step, ui_selected_par_layer, ui_selected_instrument);
178 tk 691
  s32 new_value = (forced_value >= 0) ? forced_value : (old_value + incrementer);
692
  if( new_value < 0 )
693
    new_value = 0;
694
  else if( new_value >= 128 )
695
    new_value = 127;
696
 
697
  // take over if changed
698
  if( new_value == old_value )
699
    return -1;
700
 
652 tk 701
  SEQ_PAR_Set(track, par_step, ui_selected_par_layer, ui_selected_instrument, (u8)new_value);
178 tk 702
 
747 tk 703
  if( !dont_change_gate &&
704
      (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord || layer_type == SEQ_PAR_Type_Velocity) ) {
178 tk 705
    // (de)activate gate depending on value
706
    if( new_value )
652 tk 707
      SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
178 tk 708
    else
652 tk 709
      SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 0);
178 tk 710
  }
711
 
712
  return new_value;
713
}