Subversion Repositories svn.mios32

Rev

Rev 2564 | 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 2628 2018-12-30 21:14:09Z 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>
2101 tk 19
#include "tasks.h"
20
 
167 tk 21
#include "seq_lcd.h"
22
#include "seq_ui.h"
23
 
2101 tk 24
#include "seq_file_gc.h"
25
 
167 tk 26
#include "seq_core.h"
168 tk 27
#include "seq_cc.h"
741 tk 28
#include "seq_cc_labels.h"
176 tk 29
#include "seq_layer.h"
167 tk 30
#include "seq_par.h"
31
#include "seq_trg.h"
690 tk 32
#include "seq_chord.h"
1349 tk 33
#include "seq_record.h"
600 tk 34
#include "seq_hwcfg.h"
167 tk 35
 
36
 
37
/////////////////////////////////////////////////////////////////////////////
1203 tk 38
// Global Variables
1142 tk 39
/////////////////////////////////////////////////////////////////////////////
1203 tk 40
seq_ui_edit_view_t seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS;
2101 tk 41
seq_ui_edit_datawheel_mode_t seq_ui_edit_datawheel_mode = SEQ_UI_EDIT_DATAWHEEL_MODE_SCROLL_CURSOR;
1142 tk 42
 
1203 tk 43
 
1142 tk 44
/////////////////////////////////////////////////////////////////////////////
729 tk 45
// Local Variables
46
/////////////////////////////////////////////////////////////////////////////
47
 
48
static u16 selected_steps = 0xffff; // will only be initialized once after startup
49
 
1350 tk 50
// activated by pressing EDIT button: encoder value will be taken over by releasing EDIT button
51
// mode 0: function not active (EDIT button released)
52
// mode 1: function activated (EDIT button pressed)
53
// mode 2: value has been changed while EDIT button pressed (a message will pop up on screen)
54
static u8 edit_passive_mode;
55
static u8 edit_passive_value;      // the tmp. edited value
56
static u8 edit_passive_track;      // to store the track of the edit value
57
static u8 edit_passive_step;       // to store the step of the edit value
58
static u8 edit_passive_par_layer;  // to store the layer of the edit value
59
static u8 edit_passive_instrument; // to store the instrument of the edit value
1348 tk 60
 
2533 tk 61
static u8 edit_ramp;
2101 tk 62
 
2533 tk 63
 
729 tk 64
/////////////////////////////////////////////////////////////////////////////
2047 tk 65
 
66
typedef enum {
67
  MIDI_LEARN_MODE_OFF = 0,
68
  MIDI_LEARN_MODE_ON,
69
} midi_learn_mode_t;
70
 
71
static midi_learn_mode_t midi_learn_mode = MIDI_LEARN_MODE_OFF;
2563 tk 72
static u8 midi_learn_mode_used;
2047 tk 73
 
74
 
75
/////////////////////////////////////////////////////////////////////////////
178 tk 76
// Local prototypes
77
/////////////////////////////////////////////////////////////////////////////
78
 
2101 tk 79
static s32 CheckStoreFile(void);
747 tk 80
static s32 ChangeSingleEncValue(u8 track, u16 par_step, u16 trg_step, s32 incrementer, s32 forced_value, u8 change_gate, u8 dont_change_gate);
1350 tk 81
static s32 PassiveEditEnter(void);
82
static s32 PassiveEditValid(void);
83
static s32 PassiveEditTakeOver(void);
178 tk 84
 
85
 
86
/////////////////////////////////////////////////////////////////////////////
240 tk 87
// LED handler function (globally accessible, since it's re-used by UTIL page)
167 tk 88
/////////////////////////////////////////////////////////////////////////////
240 tk 89
s32 SEQ_UI_EDIT_LED_Handler(u16 *gp_leds)
167 tk 90
{
91
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1142 tk 92
 
2048 tk 93
  if( seq_ui_button_state.EDIT_PRESSED ) {
1142 tk 94
    switch( seq_ui_edit_view ) {
95
    case SEQ_UI_EDIT_VIEW_STEPS: *gp_leds = (1 << 0); break;
96
    case SEQ_UI_EDIT_VIEW_TRG: *gp_leds = (1 << 1); break;
97
    case SEQ_UI_EDIT_VIEW_LAYERS: *gp_leds = (1 << 2); break;
98
    case SEQ_UI_EDIT_VIEW_303: *gp_leds = (1 << 3); break;
99
    case SEQ_UI_EDIT_VIEW_STEPSEL: *gp_leds = (1 << 8); break;
100
    }
101
  } else {
167 tk 102
 
2533 tk 103
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS && (seq_ui_button_state.CHANGE_ALL_STEPS || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE) && midi_learn_mode == MIDI_LEARN_MODE_OFF && !seq_record_state.ENABLED ) {
1751 tk 104
      *gp_leds = ui_cursor_flash ? 0x0000 : selected_steps;
105
    } else if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
1142 tk 106
      *gp_leds = selected_steps;
107
    } else {
167 tk 108
 
1142 tk 109
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
110
 
111
      if( event_mode != SEQ_EVENT_MODE_Drum &&
112
      (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
113
 
114
    if( SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument) )
115
      *gp_leds |= (1 << 1);
116
    if( SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument) )
117
      *gp_leds |= (1 << 2);
118
    if( SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument) )
119
      *gp_leds |= (1 << 3);
120
 
121
    if( ui_selected_par_layer == 0 )
122
      *gp_leds |= (3 << 4);
123
    else
124
      *gp_leds |= (1 << (ui_selected_par_layer+5));
125
 
2553 tk 126
      } else if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
1142 tk 127
 
128
    u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
129
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
130
      // maximum 7 parameter layers due to "Step" item!
2553 tk 131
      // if drum: only 6 parameter layers due to additional "Drum" item!
132
      u8 max_t_layers = (event_mode == SEQ_EVENT_MODE_Drum) ? 6 : 7;
133
      if( num_t_layers >= max_t_layers )
134
        num_t_layers = max_t_layers;
1142 tk 135
    } else {
136
      // single trigger layer (gate)
137
      num_t_layers = 1;
138
    }
139
 
2553 tk 140
    u8 t_layer_offset = (event_mode == SEQ_EVENT_MODE_Drum) ? 2 : 1;
1142 tk 141
    int i;
142
    for(i=0; i<num_t_layers; ++i)
143
      if( SEQ_TRG_Get(visible_track, ui_selected_step, i, ui_selected_instrument) )
2553 tk 144
        *gp_leds |= (1 << (i+t_layer_offset));
1142 tk 145
 
146
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
147
      *gp_leds |= (1 << (ui_selected_par_layer+8));
148
    } else {
2553 tk 149
      *gp_leds |= (1 << (ui_selected_par_layer+t_layer_offset+1));
1142 tk 150
    }
151
      } else {
152
    *gp_leds =
153
      (SEQ_TRG_Get8(visible_track, 2*ui_selected_step_view+1, ui_selected_trg_layer, ui_selected_instrument) << 8) |
154
      (SEQ_TRG_Get8(visible_track, 2*ui_selected_step_view+0, ui_selected_trg_layer, ui_selected_instrument) << 0);
155
      }
156
    }
157
  }
158
 
167 tk 159
  return 0; // no error
160
}
161
 
162
 
163
/////////////////////////////////////////////////////////////////////////////
168 tk 164
// Local encoder callback function
165
// Should return:
166
//   1 if value has been changed
167
//   0 if value hasn't been changed
168
//  -1 if invalid or unsupported encoder
167 tk 169
/////////////////////////////////////////////////////////////////////////////
168 tk 170
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
167 tk 171
{
1348 tk 172
  u8 visible_track = SEQ_UI_VisibleTrackGet();
173
 
174
  if( encoder == SEQ_UI_ENCODER_Datawheel ) {
175
    u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
176
 
2101 tk 177
    switch( seq_ui_edit_datawheel_mode ) {
178
    case SEQ_UI_EDIT_DATAWHEEL_MODE_SCROLL_CURSOR:
1753 tk 179
      if( SEQ_UI_Var8_Inc(&ui_selected_step, 0, num_steps-1, incrementer) >= 1 ) {
180
    ui_selected_step_view = ui_selected_step / 16;
1348 tk 181
    return 1;
1753 tk 182
      } else
1348 tk 183
    return 0;
184
 
2101 tk 185
    case SEQ_UI_EDIT_DATAWHEEL_MODE_SCROLL_VIEW:
1348 tk 186
      if( SEQ_UI_Var8_Inc(&ui_selected_step_view, 0, (num_steps-1)/16, incrementer) >= 1 ) {
2533 tk 187
    if( !seq_ui_button_state.CHANGE_ALL_STEPS && !seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
1753 tk 188
      // select step within view
189
      ui_selected_step = (ui_selected_step_view << 4) | (ui_selected_step & 0xf);
190
    }
1348 tk 191
    return 1;
192
      } else {
193
    return 0;
194
      }
195
 
2101 tk 196
    case SEQ_UI_EDIT_DATAWHEEL_MODE_CHANGE_VALUE:
1348 tk 197
      break; // drop... continue below with common encoder value change routine
198
 
2101 tk 199
    case SEQ_UI_EDIT_DATAWHEEL_MODE_CHANGE_PARLAYER: {
1348 tk 200
      u8 num_layers = SEQ_PAR_NumLayersGet(visible_track);
201
 
202
      if( SEQ_UI_Var8_Inc(&ui_selected_par_layer, 0, num_layers-1, incrementer) >= 1 )
203
    return 1;
204
      else
205
    return 0;
206
    } break;
207
 
2101 tk 208
    case SEQ_UI_EDIT_DATAWHEEL_MODE_CHANGE_TRGLAYER: {
1348 tk 209
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
210
 
211
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
212
    u8 num_layers = SEQ_TRG_NumInstrumentsGet(visible_track);
213
    if( SEQ_UI_Var8_Inc(&ui_selected_instrument, 0, num_layers-1, incrementer) >= 1 )
214
      return 1;
215
    else
216
      return 0;
217
      } else {
218
    u8 num_layers = SEQ_TRG_NumLayersGet(visible_track);
219
    if( SEQ_UI_Var8_Inc(&ui_selected_trg_layer, 0, num_layers-1, incrementer) >= 1 )
220
      return 1;
221
    else
222
      return 0;
223
      }
224
    } break;
225
    }
226
  }
227
 
168 tk 228
#if 0
229
  // leads to: comparison is always true due to limited range of data type
230
  if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) || encoder == SEQ_UI_ENCODER_Datawheel ) {
231
#else
232
  if( encoder <= SEQ_UI_ENCODER_GP16 || encoder == SEQ_UI_ENCODER_Datawheel ) {
233
#endif
1142 tk 234
 
2048 tk 235
    if( seq_ui_button_state.EDIT_PRESSED ) {
1142 tk 236
      switch( encoder ) {
237
      case SEQ_UI_ENCODER_GP1: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS; break;
238
      case SEQ_UI_ENCODER_GP2: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_TRG; break;
239
      case SEQ_UI_ENCODER_GP3: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_LAYERS; break;
240
      case SEQ_UI_ENCODER_GP4: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_303; break;
1483 tk 241
      case SEQ_UI_ENCODER_GP8: seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPSEL; break;
1348 tk 242
 
1483 tk 243
      case SEQ_UI_ENCODER_GP9:
244
      case SEQ_UI_ENCODER_GP10: {
1348 tk 245
    if( incrementer == 0 ) // button
1753 tk 246
      incrementer = (encoder == SEQ_UI_ENCODER_GP9) ? -1 : 1;
1348 tk 247
 
2101 tk 248
    if( SEQ_UI_Var8_Inc(&seq_ui_edit_datawheel_mode, 0, SEQ_UI_EDIT_DATAWHEEL_MODE_NUM-1, incrementer) >= 1 ) {
2102 tk 249
      ui_store_file_required = 1;
1348 tk 250
      return 1;
2101 tk 251
    } else
1348 tk 252
      return 0;
1142 tk 253
      }
1483 tk 254
 
2050 tk 255
      case SEQ_UI_ENCODER_GP11:
256
      case SEQ_UI_ENCODER_GP12:
2164 tk 257
    SEQ_UI_PageSet(SEQ_UI_PAGE_TRKJAM);
2050 tk 258
    break;
259
 
1483 tk 260
      case SEQ_UI_ENCODER_GP13:
261
      case SEQ_UI_ENCODER_GP14:
262
    SEQ_UI_PageSet(SEQ_UI_PAGE_TRKRND);
263
    break;
264
 
265
      case SEQ_UI_ENCODER_GP15:
266
      case SEQ_UI_ENCODER_GP16:
267
    SEQ_UI_PageSet(SEQ_UI_PAGE_TRKEUCLID);
268
    break;
1348 tk 269
      }
270
 
2048 tk 271
      seq_ui_button_state.EDIT_PRESSED = 0; // switch back to view
1142 tk 272
      return 1; // value changed
273
    }
274
 
275
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
729 tk 276
      if( incrementer > 0 )
277
    selected_steps |= (1 << encoder);
278
      else
279
    selected_steps &= ~(1 << encoder);
280
      return 1; // value changed
281
    }
282
 
1142 tk 283
    u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
182 tk 284
 
1142 tk 285
    if( event_mode != SEQ_EVENT_MODE_Drum &&
286
    (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
287
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
288
 
289
      if( encoder == SEQ_UI_ENCODER_GP1 ) {
1348 tk 290
    if( SEQ_UI_Var8_Inc(&ui_selected_step, 0, num_steps-1, incrementer) >= 1 )
1142 tk 291
      return 1;
292
    else
293
      return 0;
294
      } else if( encoder == SEQ_UI_ENCODER_GP2 ) {
295
    SEQ_TRG_GateSet(visible_track, ui_selected_step, ui_selected_instrument, incrementer > 0 ? 1 : 0);
296
    return 1;
297
      } else if( encoder == SEQ_UI_ENCODER_GP3 ) {
298
    SEQ_TRG_AccentSet(visible_track, ui_selected_step, ui_selected_instrument, incrementer > 0 ? 1 : 0);
299
    return 1;
300
      } else if( encoder == SEQ_UI_ENCODER_GP4 ) {
301
    SEQ_TRG_GlideSet(visible_track, ui_selected_step, ui_selected_instrument, incrementer > 0 ? 1 : 0);
302
    return 1;
303
      } else if( encoder == SEQ_UI_ENCODER_GP5 ) {
304
    ui_selected_par_layer = 0;
305
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
306
    u8 note_octave = note / 12;
307
    u8 note_key = note % 12;
308
 
309
    if( SEQ_UI_Var8_Inc(&note_octave, 0, 9, incrementer) >= 1 ) {
310
      SEQ_PAR_Set(visible_track, ui_selected_step, 0, ui_selected_instrument, 12*note_octave + note_key);
311
      return 1;
312
    }
313
    return 0;
314
      } else if( encoder == SEQ_UI_ENCODER_GP6 ) {
315
    ui_selected_par_layer = 0;
316
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
317
    u8 note_octave = note / 12;
318
    u8 note_key = note % 12;
319
 
320
    if( SEQ_UI_Var8_Inc(&note_key, 0, 11, incrementer) >= 1 ) {
321
      SEQ_PAR_Set(visible_track, ui_selected_step, 0, ui_selected_instrument, 12*note_octave + note_key);
322
      return 1;
323
    }
324
    return 0;
325
      } else if( encoder <= SEQ_UI_ENCODER_GP16 ) {
326
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
327
    if( ((int)encoder-5) >= num_p_layers )
328
        return 0; // ignore
329
      ui_selected_par_layer = encoder-5;
330
      }
331
 
332
      if( !incrementer ) // button selection only...
333
    return 1;
334
    }
335
 
2553 tk 336
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
337
      u16 num_instruments = SEQ_PAR_NumInstrumentsGet(visible_track);
1142 tk 338
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
2553 tk 339
      u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
340
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
1142 tk 341
 
2553 tk 342
      seq_ui_encoder_t drum_encoder;
343
      seq_ui_encoder_t step_encoder;
344
      seq_ui_encoder_t gate_encoder;
345
      u8 trg_encoder_offset;
346
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
347
    drum_encoder = SEQ_UI_ENCODER_GP1;
348
    step_encoder = SEQ_UI_ENCODER_GP2;
349
    gate_encoder = SEQ_UI_ENCODER_GP3;
350
    trg_encoder_offset = 2;
351
      } else {
352
    drum_encoder = 0xff; // no drum selection
353
    step_encoder = SEQ_UI_ENCODER_GP1;
354
    gate_encoder = SEQ_UI_ENCODER_GP2;
355
    trg_encoder_offset = 1;
356
      }
357
 
358
      if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
359
    if( num_t_layers > (8-trg_encoder_offset) )
360
        num_t_layers = 8-trg_encoder_offset;
361
      }
362
 
363
      if( encoder == drum_encoder ) {
364
    if( SEQ_UI_Var8_Inc(&ui_selected_instrument, 0, num_instruments-1, incrementer) >= 1 )
1142 tk 365
      return 1;
366
    else
367
      return 0;
2553 tk 368
      } else if( encoder == step_encoder ) {
369
    if( SEQ_UI_Var8_Inc(&ui_selected_step, 0, num_steps-1, incrementer) >= 1 ) {
370
      ui_selected_step_view = ui_selected_step / 16;
371
      return 1;
372
    } else
373
      return 0;
374
      } else if( encoder == gate_encoder ||
375
         (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG && encoder < trg_encoder_offset+num_t_layers) ) {
376
    u8 sel = (u8)encoder-trg_encoder_offset;
1142 tk 377
    SEQ_TRG_Set(visible_track, ui_selected_step, sel, ui_selected_instrument, incrementer > 0 ? 1 : 0);
2230 tk 378
    SEQ_CORE_CancelSustainedNotes(visible_track); // cancel sustain if there are no notes played by the track anymore
1142 tk 379
    return 1;
380
      } else if( encoder <= SEQ_UI_ENCODER_GP16 ) {
381
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
2553 tk 382
      u8 par_encoder_offset = trg_encoder_offset + num_t_layers;
383
      if( ((int)encoder-par_encoder_offset) >= num_p_layers )
384
        return 0; // ignore
385
      ui_selected_par_layer = encoder-par_encoder_offset;
1142 tk 386
    } else {
2553 tk 387
      if( ((int)encoder-trg_encoder_offset-1) >= num_p_layers )
1142 tk 388
        return 0; // ignore
2553 tk 389
      ui_selected_par_layer = encoder-trg_encoder_offset-1;
1142 tk 390
    }
391
 
392
    if( !incrementer ) // button selection only...
393
      return 1;
394
      }
395
    }
396
 
1809 tk 397
    u8 changed_step;
2553 tk 398
    u8 view_steps = seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS || (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303 && event_mode == SEQ_EVENT_MODE_Drum);
399
    if( view_steps ) {
1809 tk 400
      changed_step = ((encoder == SEQ_UI_ENCODER_Datawheel) ? (ui_selected_step%16) : encoder) + ui_selected_step_view*16;
401
    } else {
402
      changed_step = ui_selected_step;
403
    }
2533 tk 404
 
405
    edit_ramp = 0;
2553 tk 406
    if( view_steps ) {
1142 tk 407
 
1350 tk 408
      // in passive edit mode: take over the edit value if step has changed, thereafter switch to new step
1751 tk 409
      if( ui_selected_step != changed_step && edit_passive_mode ) {
1350 tk 410
    PassiveEditTakeOver();
1751 tk 411
    ui_selected_step = changed_step;
1350 tk 412
    PassiveEditEnter();
413
      } else {
1751 tk 414
    // take over new step if "ALL" button not pressed to support "ramp" editing
2533 tk 415
    if( !seq_ui_button_state.CHANGE_ALL_STEPS && !seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
1751 tk 416
      ui_selected_step = changed_step;
417
    } else {
418
      if( ui_selected_step != changed_step )
419
        edit_ramp = 1;
420
    }
1350 tk 421
      }
422
 
423
    }
424
 
425
 
426
    // in passive edit mode: change value, but don't take over yet!
427
    if( edit_passive_mode ) {
428
      if( SEQ_UI_Var8_Inc(&edit_passive_value, 0, 127, incrementer) >= 1 ) {
429
    edit_passive_mode = 2; // value has been changed
430
    return 1;
431
      } else
432
    return 0;
433
    }
434
 
435
    // normal edit mode
178 tk 436
    s32 value_changed = 0;
437
    s32 forced_value = -1;
438
    u8  change_gate = 1;
168 tk 439
 
182 tk 440
    // due to historical reasons (from old times where MBSEQ CS was stuffed with pots): 
441
    // in arp mode, we increment in steps of 4
1143 tk 442
    u8 par_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
182 tk 443
    if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator &&
1143 tk 444
    par_type == SEQ_PAR_Type_Note )
182 tk 445
      incrementer *= 4;
446
 
178 tk 447
    // first change the selected value
2533 tk 448
    if( (seq_ui_button_state.CHANGE_ALL_STEPS && edit_ramp) || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
652 tk 449
      u16 num_steps = SEQ_PAR_NumStepsGet(visible_track);
1751 tk 450
      u16 par_step = changed_step;
451
      u16 trg_step = changed_step;
652 tk 452
 
453
      // mirrored layer in drum mode?
454
      u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
455
      if( event_mode == SEQ_EVENT_MODE_Drum && par_step >= num_steps )
456
    par_step %= num_steps;
457
 
747 tk 458
      forced_value = ChangeSingleEncValue(visible_track, par_step, trg_step, incrementer, forced_value, change_gate, 0);
178 tk 459
      if( forced_value < 0 )
460
    return 0; // no change
461
      value_changed |= 1;
168 tk 462
    }
463
 
1751 tk 464
    int value_selected_step = SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
465
    int value_changed_step = SEQ_PAR_Get(visible_track, changed_step, ui_selected_par_layer, ui_selected_instrument);
466
 
178 tk 467
    // change value of all selected steps
468
    u8 track;
469
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
470
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 471
    u16 num_steps = SEQ_PAR_NumStepsGet(track);
1751 tk 472
    u16 trg_step = (changed_step & ~(num_steps-1));
2628 tk 473
    u16 first_step = seq_ui_options.ALL_FOR_STEP_VIEW_ONLY ? (ui_selected_step_view * 16) : 0;
474
    u16 last_step  = seq_ui_options.ALL_FOR_STEP_VIEW_ONLY ? (first_step + 15) : (num_steps-1);
1751 tk 475
 
652 tk 476
    u16 par_step;
2628 tk 477
    for(par_step=first_step; (par_step <= last_step) && (par_step < num_steps); ++par_step, ++trg_step) {
2533 tk 478
      if( !(seq_ui_button_state.CHANGE_ALL_STEPS || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE) || (!edit_ramp && par_step == changed_step) || (selected_steps & (1 << (par_step % 16))) ) {
1751 tk 479
        change_gate = trg_step == changed_step;
2564 tk 480
 
1751 tk 481
        u8 dont_change_gate = par_step != changed_step;
2533 tk 482
        if( change_gate || seq_ui_button_state.CHANGE_ALL_STEPS || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
1751 tk 483
          s32 local_forced_value = edit_ramp ? -1 : forced_value;
484
 
485
          s32 edit_ramp_num_steps = 0;
486
          if( edit_ramp ) {
487
        if( changed_step > ui_selected_step && par_step > ui_selected_step && par_step < changed_step ) {
488
          edit_ramp_num_steps = changed_step - ui_selected_step;
489
        } else if( changed_step < ui_selected_step && par_step < ui_selected_step && par_step > changed_step ) {
490
          edit_ramp_num_steps = ui_selected_step - changed_step;
491
        }
492
 
493
        if( edit_ramp_num_steps ) {
494
          if( par_step == changed_step ) {
495
            local_forced_value = value_changed_step;
496
          } else {
497
            int diff = value_changed_step - value_selected_step;
498
            if( diff == 0 ) {
499
              local_forced_value = value_changed_step;
500
            } else {
501
              if( changed_step > ui_selected_step ) {
502
            local_forced_value = value_selected_step + (((par_step - ui_selected_step) * diff) / edit_ramp_num_steps);
503
              } else {
504
            local_forced_value = value_selected_step + (((ui_selected_step - par_step) * diff) / edit_ramp_num_steps);
505
              }
506
            }
507
          }
508
        }
509
          }
510
 
511
          if( !edit_ramp || edit_ramp_num_steps ) {
512
        if( ChangeSingleEncValue(track, par_step, trg_step, incrementer, local_forced_value, change_gate, dont_change_gate) >= 0 )
513
          value_changed |= 1;
514
          }
729 tk 515
        }
178 tk 516
      }
517
    }
518
      }
176 tk 519
    }
1142 tk 520
 
178 tk 521
    return value_changed;
168 tk 522
  }
523
 
524
  return -1; // invalid or unsupported encoder
167 tk 525
}
526
 
527
 
528
/////////////////////////////////////////////////////////////////////////////
168 tk 529
// Local button callback function
530
// Should return:
531
//   1 if value has been changed
532
//   0 if value hasn't been changed
533
//  -1 if invalid or unsupported button
167 tk 534
/////////////////////////////////////////////////////////////////////////////
758 tk 535
s32 SEQ_UI_EDIT_Button_Handler(seq_ui_button_t button, s32 depressed)
167 tk 536
{
306 tk 537
  u8 visible_track = SEQ_UI_VisibleTrackGet();
538
 
168 tk 539
#if 0
540
  // leads to: comparison is always true due to limited range of data type
541
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
542
#else
543
  if( button <= SEQ_UI_BUTTON_GP16 ) {
544
#endif
2047 tk 545
 
2063 tk 546
    if( !seq_ui_button_state.EDIT_PRESSED &&
2533 tk 547
    ((seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPS && (seq_ui_button_state.CHANGE_ALL_STEPS || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE)) ||
2063 tk 548
     seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL) ) {
549
      if( depressed ) return 0; // ignore when button depressed
550
 
551
      selected_steps ^= (1 << button);
552
      return 1; // value changed
553
    }
554
 
2047 tk 555
    // enable/disable MIDI Learn mode
556
    midi_learn_mode = depressed ? MIDI_LEARN_MODE_OFF : MIDI_LEARN_MODE_ON;
2563 tk 557
    if( midi_learn_mode_used && midi_learn_mode == MIDI_LEARN_MODE_OFF ) {
558
      midi_learn_mode_used = 0;
559
      SEQ_RECORD_AllNotesOff();
560
    }
2047 tk 561
 
2168 tk 562
    if( depressed )
563
      return 0; // ignore when button depressed
729 tk 564
 
2048 tk 565
    if( seq_ui_button_state.EDIT_PRESSED )
1142 tk 566
      return Encoder_Handler(button, 0);
567
 
568
    u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
569
 
570
    if( event_mode != SEQ_EVENT_MODE_Drum &&
571
    (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
572
 
573
      if( button == SEQ_UI_BUTTON_GP1 ) {
574
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
575
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
576
      next_step = 0;
577
    ui_selected_step = next_step;
578
    ui_selected_step_view = ui_selected_step / 16;
579
    return 1; // value always changed
580
      } else if( button == SEQ_UI_BUTTON_GP2 ) {
581
    u8 trg = SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument);
582
    return Encoder_Handler(button, trg ? -1 : 1);
583
      } else if( button == SEQ_UI_BUTTON_GP3 ) {
584
    u8 trg = SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument);
585
    return Encoder_Handler(button, trg ? -1 : 1);
586
      } else if( button == SEQ_UI_BUTTON_GP4 ) {
587
    u8 trg = SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument);
588
    return Encoder_Handler(button, trg ? -1 : 1);
589
      } else if( button <= SEQ_UI_BUTTON_GP16 ) {
590
    return Encoder_Handler(button, 0);
591
      }
592
    }
593
 
594
 
2553 tk 595
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
596
      u16 num_instruments = SEQ_PAR_NumInstrumentsGet(visible_track);
597
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
1142 tk 598
 
2553 tk 599
      seq_ui_button_t drum_button;
600
      seq_ui_button_t step_button;
601
      seq_ui_button_t gate_button;
602
      u8 trg_button_offset;
603
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
604
    drum_button = SEQ_UI_BUTTON_GP1;
605
    step_button = SEQ_UI_BUTTON_GP2;
606
    gate_button = SEQ_UI_BUTTON_GP3;
607
    trg_button_offset = 2;
608
      } else {
609
    drum_button = 0xff; // no drum selection
610
    step_button = SEQ_UI_BUTTON_GP1;
611
    gate_button = SEQ_UI_BUTTON_GP2;
612
    trg_button_offset = 1;
613
      }
614
 
615
 
616
      if( button == drum_button ) {
617
    u8 next_instrument = ui_selected_instrument + 1;
618
    if( next_instrument >= num_instruments )
619
      next_instrument = 0;
620
    ui_selected_instrument = next_instrument;
621
    return 1; // value always changed
622
      } else if( button == step_button ) {
1142 tk 623
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
2553 tk 624
    if( next_step >= num_steps )
1142 tk 625
      next_step = 0;
626
    ui_selected_step = next_step;
627
    ui_selected_step_view = ui_selected_step / 16;
628
    return 1; // value always changed
2553 tk 629
      } else if( button == gate_button ||
1142 tk 630
         (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG && button <= SEQ_UI_BUTTON_GP8) ) {
2553 tk 631
    u8 trg = SEQ_TRG_Get(visible_track, ui_selected_step, (u8)button-trg_button_offset, ui_selected_instrument);
1142 tk 632
    return Encoder_Handler(button, trg ? -1 : 1);
633
      } else if( button <= SEQ_UI_BUTTON_GP16 ) {
634
    return Encoder_Handler(button, 0);
635
      }
636
    }
637
 
180 tk 638
    ui_selected_step = button + ui_selected_step_view*16;
1142 tk 639
 
168 tk 640
    // toggle trigger layer
600 tk 641
    // if seq_hwcfg_button_beh.all_with_triggers set, we've three cases:
178 tk 642
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
643
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
644
    // c) ALL function not active: toggle step
2533 tk 645
    if( seq_hwcfg_button_beh.all_with_triggers && (seq_ui_button_state.CHANGE_ALL_STEPS || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE) ) {
178 tk 646
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
647
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
303 tk 648
    u16 step = ui_selected_step;
328 tk 649
    u8 new_value = SEQ_TRG_Get(visible_track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
1142 tk 650
 
178 tk 651
    u8 track;
652
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
318 tk 653
      if( SEQ_UI_IsSelectedTrack(track) ) {
654
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
655
        for(step=0; step<num_steps; ++step)
328 tk 656
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
2230 tk 657
        SEQ_CORE_CancelSustainedNotes(track); // cancel sustain if there are no notes played by the track anymore
318 tk 658
      }
178 tk 659
      } else {
660
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
303 tk 661
    u8 track;
662
    u16 step;
178 tk 663
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
664
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 665
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
666
        for(step=0; step<num_steps; ++step) {
328 tk 667
          u8 new_value = SEQ_TRG_Get(track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
668
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
178 tk 669
        }
2230 tk 670
        SEQ_CORE_CancelSustainedNotes(track); // cancel sustain if there are no notes played by the track anymore
178 tk 671
      }
672
    }
673
      }
674
    } else {
675
      // c) ALL function not active: toggle step
676
      u8 track;
1142 tk 677
 
484 tk 678
      u8 new_value = SEQ_TRG_Get(visible_track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
178 tk 679
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
680
    if( SEQ_UI_IsSelectedTrack(track) ) {
328 tk 681
      SEQ_TRG_Set(track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument, new_value);
2230 tk 682
      SEQ_CORE_CancelSustainedNotes(track); // cancel sustain if there are no notes played by the track anymore
178 tk 683
    }
684
      }
685
    }
1142 tk 686
 
168 tk 687
    return 1; // value always changed
178 tk 688
 
168 tk 689
  } else {
690
    switch( button ) {
691
      case SEQ_UI_BUTTON_Select:
2048 tk 692
    // toggle MIDI learn
693
    if( !depressed )
694
      midi_learn_mode = (midi_learn_mode == MIDI_LEARN_MODE_ON) ? MIDI_LEARN_MODE_OFF : MIDI_LEARN_MODE_ON;
2563 tk 695
        if( midi_learn_mode_used && midi_learn_mode == MIDI_LEARN_MODE_OFF ) {
696
          midi_learn_mode_used = 0;
697
          SEQ_RECORD_AllNotesOff();
698
        }
729 tk 699
    return 1; // value always changed
700
 
303 tk 701
      case SEQ_UI_BUTTON_Right: {
729 tk 702
    if( depressed ) return 0; // ignore when button depressed
703
 
303 tk 704
    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 705
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
303 tk 706
      next_step = 0;
707
    ui_selected_step = next_step;
168 tk 708
    ui_selected_step_view = ui_selected_step / 16;
709
    return 1; // value always changed
303 tk 710
      } break;
167 tk 711
 
168 tk 712
      case SEQ_UI_BUTTON_Left:
729 tk 713
    if( depressed ) return 0; // ignore when button depressed
714
 
168 tk 715
    if( ui_selected_step == 0 )
306 tk 716
      ui_selected_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1142 tk 717
    else
718
      --ui_selected_step;
719
 
168 tk 720
    ui_selected_step_view = ui_selected_step / 16;
721
    return 1; // value always changed
167 tk 722
 
168 tk 723
      case SEQ_UI_BUTTON_Up:
729 tk 724
    if( depressed ) return 0; // ignore when button depressed
168 tk 725
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
726
 
727
      case SEQ_UI_BUTTON_Down:
729 tk 728
    if( depressed ) return 0; // ignore when button depressed
168 tk 729
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
1350 tk 730
 
731
      // this button is currently only notified to EDIT page
732
      case SEQ_UI_BUTTON_Edit:
733
    if( !depressed )
734
      PassiveEditEnter();
1351 tk 735
    else {
1350 tk 736
      PassiveEditTakeOver();
1351 tk 737
      edit_passive_mode = 0;
738
    }
1350 tk 739
    return 1;
168 tk 740
    }
167 tk 741
  }
742
 
168 tk 743
  return -1; // invalid or unsupported button
167 tk 744
}
745
 
746
 
747
/////////////////////////////////////////////////////////////////////////////
240 tk 748
// Global Display Handler function
167 tk 749
// IN: <high_prio>: if set, a high-priority LCD update is requested
240 tk 750
//     <edit_page>: selects the normal, or copy/paste/move/scroll view
167 tk 751
/////////////////////////////////////////////////////////////////////////////
240 tk 752
s32 SEQ_UI_EDIT_LCD_Handler(u8 high_prio, seq_ui_edit_mode_t edit_mode)
167 tk 753
{
754
  if( high_prio )
755
    return 0; // there are no high-priority updates
756
 
2101 tk 757
  if( !edit_mode && !seq_ui_button_state.EDIT_PRESSED )
758
    CheckStoreFile(); // for Datawheel mode: stored on SD Card when edit has been depressed
326 tk 759
 
2101 tk 760
 
326 tk 761
  // layout common track:
762
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
763
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
764
  // G1T1 xxxxxxxxxxxxxxx  PC:Length TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
765
  // ....
766
 
767
  // layout drum track:
768
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
769
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
770
  // G1T1 xxxxxxxxxxxxxxx  PA:Vel.   TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
771
  // ....
772
 
1142 tk 773
  // layout edit config
774
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
2050 tk 775
  // Step Trg  Layer 303                Step Datawheel:  Record   Random    Euclid   
776
  // View View View View               Select Scroll     Config  Generator Generator 
1142 tk 777
 
778
  // layout trigger view
779
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
780
  // Step Gate Acc. Roll Glide Skip R.G  R.V Note Vel. Len. Roll Note Note Note Note 
781
  //   1    *    o    o    o    o    o    o  C-3  100   75% ---- E-3  G-3  ---- ---- 
782
 
783
  // layout layer view
784
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
785
  // Step Gate Note Vel. Len. Roll Note Note Note Note Note Note Note Note Note Note 
786
  //   1    *  C-3  100   75% ---- E-3  G-3  ---- ---- ---- ---- ---- ---- ---- ---- 
787
 
788
  // layout 303 view
789
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
790
  // Step Gate Acc. Glide Oct, Key Vel. Prob  CC   CC   CC   CC   CC   CC   CC   CC  
791
  //   1    *   o     o    3    C  100  100%  64   64   64   64   64   64   64   64  
792
 
729 tk 793
  // layout step selection:
794
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
795
  //        Select the steps which should be  controlled by the ALL function:        
796
  //   *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *  
326 tk 797
 
2553 tk 798
  u8 visible_track = SEQ_UI_VisibleTrackGet();
799
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
800
 
2048 tk 801
  if( !edit_mode && seq_ui_button_state.EDIT_PRESSED ) {
2101 tk 802
    const char seq_ui_edit_datawheel_mode_str[SEQ_UI_EDIT_DATAWHEEL_MODE_NUM][11] = {
1348 tk 803
      " Cursor   ",
804
      " StepView ",
805
      " Value    ",
806
      " ParLayer ",
807
      " TrgLayer ",
808
    };
809
 
1142 tk 810
    SEQ_LCD_CursorSet(0, 0);
2553 tk 811
    if( event_mode != SEQ_EVENT_MODE_Drum ) {
812
      SEQ_LCD_PrintString("Step Trg  Layer 303                ");
813
    } else {
814
      SEQ_LCD_PrintString("Step Trg  Layer Par                ");
815
    }
816
    SEQ_LCD_PrintString("Step Datawheel:  Record   Random    Euclid   ");
1142 tk 817
    SEQ_LCD_CursorSet(0, 1);
1483 tk 818
    SEQ_LCD_PrintString("View View View View               Select");
2101 tk 819
    SEQ_LCD_PrintString((char *)seq_ui_edit_datawheel_mode_str[seq_ui_edit_datawheel_mode]);
2050 tk 820
    SEQ_LCD_PrintString("  Config  Generator Generator ");
1142 tk 821
    return 0; // no error
822
  }
823
 
824
  if( !edit_mode && seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
729 tk 825
    int step;
826
 
827
    SEQ_LCD_CursorSet(0, 0);
828
    SEQ_LCD_PrintString("       Select the steps which should be  controlled by the ALL function:        ");
829
    SEQ_LCD_CursorSet(0, 1);
830
    for(step=0; step<16; ++step)
831
      SEQ_LCD_PrintFormattedString("  %c  ", (selected_steps & (1 << step)) ? '*' : 'o');
832
    return 0; // no error
833
  }
834
 
835
 
2553 tk 836
  if( event_mode != SEQ_EVENT_MODE_Drum && seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303 ) {
167 tk 837
 
1142 tk 838
    // we want to show vertical bars
839
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
840
 
841
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
842
    // maximum 10 parameter layers
843
    if( num_p_layers >= 11 )
844
      num_p_layers = 11;
845
 
846
    ///////////////////////////////////////////////////////////////////////////
847
    SEQ_LCD_CursorSet(0, 0);
848
    SEQ_LCD_PrintString("Step Gate Acc. Glide Oct. Key ");
849
    int i;
2294 tk 850
    for(i=1; i<num_p_layers; ++i) {
851
      char str_buffer[6];
2551 tk 852
      SEQ_PAR_AssignedTypeStr(visible_track, i, ui_selected_instrument, str_buffer);
2294 tk 853
      SEQ_LCD_PrintString(str_buffer);
854
    }
1142 tk 855
 
856
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
857
 
858
    ///////////////////////////////////////////////////////////////////////////
859
    SEQ_LCD_CursorSet(0, 1);
2049 tk 860
    SEQ_LCD_PrintFormattedString((seq_record_state.ENABLED || midi_learn_mode == MIDI_LEARN_MODE_ON) ? "{%3d}" : " %3d ", ui_selected_step+1);
1142 tk 861
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
862
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
863
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
864
 
1351 tk 865
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
1142 tk 866
    u8 note_octave = note / 12;
867
    u8 note_key = note % 12;
868
 
869
    SEQ_LCD_PrintFormattedString(" %2d  ", (int)note_octave-2);
870
    const char note_tab[12][2] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " };
871
    SEQ_LCD_PrintFormattedString("  %c%c ", note_tab[note_key][0], note_tab[note_key][1]);
872
 
873
    for(i=1; i<num_p_layers; ++i)
874
      if( i == ui_selected_par_layer && ui_cursor_flash )
875
    SEQ_LCD_PrintSpaces(5);
876
      else {
1351 tk 877
    int print_edit_value = PassiveEditValid() ? edit_passive_value : -1;
878
    SEQ_LCD_PrintLayerEvent(visible_track, ui_selected_step, i, ui_selected_instrument, 0, print_edit_value);
1142 tk 879
    SEQ_LCD_PrintChar(' ');
880
      }
881
 
882
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
2553 tk 883
 
1142 tk 884
    return 0;
885
  }
886
 
2553 tk 887
  if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
1142 tk 888
 
889
    // we want to show vertical bars
890
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
891
 
892
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
893
    u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
894
 
895
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
896
      // maximum 7 parameter layers due to "Step" item!
2553 tk 897
      // if drum: only 6 parameter layers due to additional "Drum" item!
898
      u8 max_t_layers = (event_mode == SEQ_EVENT_MODE_Drum) ? 6 : 7;
899
      if( num_t_layers >= max_t_layers )
900
    num_t_layers = max_t_layers;
1142 tk 901
 
902
      // maximum 8 parameter layers
903
      if( num_p_layers >= 8 )
904
    num_p_layers = 8;
905
    } else {
906
      // single trigger layer (gate)
907
      num_t_layers = 1;
908
 
909
      // maximum 14 parameter layers due to "Step" and "Gate" item!
2553 tk 910
      // drum mode: only 13 items
911
      u8 max_p_layers = (event_mode == SEQ_EVENT_MODE_Drum) ? 13 : 14;
912
      if( num_p_layers >= max_p_layers )
913
    num_p_layers = max_p_layers;
1142 tk 914
    }
915
 
916
    ///////////////////////////////////////////////////////////////////////////
917
    SEQ_LCD_CursorSet(0, 0);
2553 tk 918
 
919
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
920
      SEQ_LCD_PrintString("Drum ");
921
    }
922
 
1142 tk 923
    SEQ_LCD_PrintString("Step ");
924
    int i;
925
    for(i=0; i<num_t_layers; ++i)
2294 tk 926
      SEQ_LCD_PrintString(SEQ_TRG_AssignedTypeStr(visible_track, i));
1142 tk 927
 
2294 tk 928
    for(i=0; i<num_p_layers; ++i) {
929
      char str_buffer[6];
2551 tk 930
      SEQ_PAR_AssignedTypeStr(visible_track, i, ui_selected_instrument, str_buffer);
2294 tk 931
      SEQ_LCD_PrintString(str_buffer);
932
    }
933
 
1142 tk 934
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
935
 
936
    ///////////////////////////////////////////////////////////////////////////
937
    SEQ_LCD_CursorSet(0, 1);
2553 tk 938
 
939
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
940
      SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name);
941
    }
942
 
2049 tk 943
    SEQ_LCD_PrintFormattedString((seq_record_state.ENABLED || midi_learn_mode == MIDI_LEARN_MODE_ON) ? "{%3d}" : " %3d ", ui_selected_step+1);
1142 tk 944
    for(i=0; i<num_t_layers; ++i)
945
      SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_Get(visible_track, ui_selected_step, i, ui_selected_instrument) ? '*' : 'o');
946
    for(i=0; i<num_p_layers; ++i)
947
      if( i == ui_selected_par_layer && ui_cursor_flash )
948
    SEQ_LCD_PrintSpaces(5);
949
      else {
1351 tk 950
    int print_edit_value = PassiveEditValid() ? edit_passive_value : -1;
951
    SEQ_LCD_PrintLayerEvent(visible_track, ui_selected_step, i, ui_selected_instrument, 0, print_edit_value);
1142 tk 952
    SEQ_LCD_PrintChar(' ');
953
      }
954
 
955
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
956
 
957
    return 0;
958
  }
959
 
176 tk 960
  seq_layer_evnt_t layer_event;
336 tk 961
  SEQ_LAYER_GetEvntOfLayer(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
168 tk 962
 
333 tk 963
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
2538 tk 964
  seq_par_layer_type_t master_layer_type = SEQ_PAR_AssignmentGet(visible_track, 0); // 1st par layer is master (e.g. relevant for chords)
176 tk 965
 
167 tk 966
  ///////////////////////////////////////////////////////////////////////////
278 tk 967
  SEQ_LCD_CursorSet(0, 0);
167 tk 968
 
326 tk 969
  SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks);
970
  SEQ_LCD_PrintSpaces(1);
971
 
1349 tk 972
 
2166 tk 973
  u8 print_instrument = 0;
1350 tk 974
  if( ui_page == SEQ_UI_PAGE_EDIT && edit_passive_mode == 2 ) {
2166 tk 975
    if( !ui_cursor_flash ) {
1350 tk 976
      SEQ_LCD_PrintString("PASSIVE EDITING");
977
    }
2050 tk 978
  } else if( seq_record_state.ENABLED || edit_mode == SEQ_UI_EDIT_MODE_RECORD || midi_learn_mode == MIDI_LEARN_MODE_ON ) {
2166 tk 979
    if( !ui_cursor_flash ) {
2050 tk 980
      if( midi_learn_mode == MIDI_LEARN_MODE_ON ) {
981
    SEQ_LCD_PrintString("EDIT RECORDING ");
982
      } else if( seq_record_options.STEP_RECORD ) {
983
    SEQ_LCD_PrintString("STEP RECORDING ");
984
      } else {
985
    SEQ_LCD_PrintString("LIVE RECORDING ");
986
      }
1349 tk 987
    }
988
  } else {
989
    switch( edit_mode ) {
240 tk 990
    case SEQ_UI_EDIT_MODE_COPY: {
2166 tk 991
      if( !ui_cursor_flash ) {
240 tk 992
    char str_buffer[10];
993
    sprintf(str_buffer, "%d-%d", SEQ_UI_UTIL_CopyPasteBeginGet()+1, SEQ_UI_UTIL_CopyPasteEndGet()+1);
278 tk 994
    SEQ_LCD_PrintFormattedString("COPY S%-9s", str_buffer);
240 tk 995
      }
996
    } break;
167 tk 997
 
240 tk 998
    case SEQ_UI_EDIT_MODE_PASTE: {
2166 tk 999
      if( !ui_cursor_flash ) {
278 tk 1000
    SEQ_LCD_PrintFormattedString("PASTE OFFS.%3d ", ui_selected_step+1);
240 tk 1001
      }
1002
    } break;
167 tk 1003
 
240 tk 1004
    case SEQ_UI_EDIT_MODE_MOVE: {
2166 tk 1005
      if( !ui_cursor_flash ) {
278 tk 1006
    SEQ_LCD_PrintString("MOVE STEPS     ");
240 tk 1007
      }
1008
    } break;
176 tk 1009
 
240 tk 1010
    case SEQ_UI_EDIT_MODE_SCROLL: {
2166 tk 1011
      if( !ui_cursor_flash ) {
278 tk 1012
    SEQ_LCD_PrintString("SCROLL TRACK   ");
240 tk 1013
      }
1014
    } break;
176 tk 1015
 
240 tk 1016
    case SEQ_UI_EDIT_MODE_RANDOM: {
2166 tk 1017
      if( !ui_cursor_flash ) {
278 tk 1018
    SEQ_LCD_PrintString("RANDOMIZED     ");
240 tk 1019
      }
1020
    } break;
176 tk 1021
 
600 tk 1022
    case SEQ_UI_EDIT_MODE_MANUAL: {
2166 tk 1023
      if( !ui_cursor_flash ) {
600 tk 1024
    SEQ_LCD_PrintString("MANUAL TRIGGER ");
1025
      }
1026
    } break;
1027
 
240 tk 1028
    default: {
2533 tk 1029
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
1030
    if( edit_ramp ) {
1031
      SEQ_LCD_PrintString("VALUE RAMP     ");
1032
    } else {
1033
      SEQ_LCD_PrintString("ALL VALUES     ");
1034
    }
1035
      } else if( seq_ui_button_state.CHANGE_ALL_STEPS ) {
1036
    SEQ_LCD_PrintString("RELATIVE VALUES");
1037
      } else {
1038
    print_instrument = 1;
1039
      }
326 tk 1040
    }
1349 tk 1041
    }
326 tk 1042
  }
176 tk 1043
 
2166 tk 1044
  if( print_instrument || ui_cursor_flash ) {
1045
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
1046
      SEQ_LCD_PrintChar(' ');
1047
      SEQ_LCD_PrintChar(' ');
1048
      SEQ_LCD_PrintMIDIOutPort(SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT));
1049
      SEQ_LCD_PrintChar(' ');
1050
      SEQ_LCD_PrintFormattedString("Chn.%2d  ", SEQ_CC_Get(visible_track, SEQ_CC_MIDI_CHANNEL)+1);
1051
    } else {
1052
      SEQ_LCD_PrintTrackLabel(visible_track, (char *)seq_core_trk[visible_track].name);
1053
    }
1054
  }
1055
 
326 tk 1056
  SEQ_LCD_PrintSpaces(2);
176 tk 1057
 
326 tk 1058
  SEQ_LCD_PrintChar('P');
1059
  SEQ_LCD_PrintChar('A' + ui_selected_par_layer);
1060
  SEQ_LCD_PrintChar(':');
240 tk 1061
 
2294 tk 1062
  {
1063
    char str_buffer[6];
2551 tk 1064
    SEQ_PAR_AssignedTypeStr(visible_track, ui_selected_par_layer, ui_selected_instrument, str_buffer);
2294 tk 1065
    SEQ_LCD_PrintString(str_buffer);
333 tk 1066
    SEQ_LCD_PrintSpaces(2);
176 tk 1067
  }
167 tk 1068
 
328 tk 1069
  SEQ_LCD_PrintFormattedString("T%c:%s", 'A' + ui_selected_trg_layer, SEQ_TRG_AssignedTypeStr(visible_track, ui_selected_trg_layer));
327 tk 1070
 
1071
 
167 tk 1072
  ///////////////////////////////////////////////////////////////////////////
278 tk 1073
  SEQ_LCD_CursorSet(40, 0);
167 tk 1074
 
1316 tk 1075
  SEQ_LCD_PrintFormattedString("Step%3d ", ui_selected_step+1);
167 tk 1076
 
1316 tk 1077
  if( layer_event.midi_package.event == CC ) {
1078
    mios32_midi_port_t port = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT);
1079
    u8 loopback = port == 0xf0;
741 tk 1080
 
1316 tk 1081
    if( loopback )
1082
      SEQ_LCD_PrintString((char *)SEQ_CC_LABELS_Get(port, layer_event.midi_package.cc_number));
1811 tk 1083
    else {
1084
      if( layer_event.midi_package.cc_number >= 0x80 ) {
1085
    SEQ_LCD_PrintFormattedString("  CC#off");
1086
      } else {
1087
    SEQ_LCD_PrintFormattedString("  CC#%3d", layer_event.midi_package.cc_number);
1088
      }
1089
    }
1351 tk 1090
    SEQ_LCD_PrintFormattedString(" %3d ", layer_event.midi_package.value);
1091
    SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
1316 tk 1092
  } else {
1093
    SEQ_LCD_PrintSpaces(2);
741 tk 1094
 
1316 tk 1095
    if( layer_event.midi_package.note && layer_event.midi_package.velocity && (layer_event.len >= 0) ) {
1096
      if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator ) {
1350 tk 1097
    u8 par_value = PassiveEditValid() ? edit_passive_value : layer_event.midi_package.note;
1098
    SEQ_LCD_PrintArp(par_value);
2538 tk 1099
      } else if( layer_type == SEQ_PAR_Type_Chord1 || layer_type == SEQ_PAR_Type_Chord2 || layer_type == SEQ_PAR_Type_Chord3 ||
1100
         (layer_type == SEQ_PAR_Type_Velocity && (master_layer_type == SEQ_PAR_Type_Chord1 || master_layer_type == SEQ_PAR_Type_Chord2 || master_layer_type == SEQ_PAR_Type_Chord3)) ) {
1101
    u8 par_value;
1102
    u8 chord_set;
1350 tk 1103
 
2538 tk 1104
    if( layer_type != SEQ_PAR_Type_Velocity ) {
1105
      par_value = PassiveEditValid()
1106
        ? edit_passive_value
1107
        : SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
2505 tk 1108
 
2538 tk 1109
      chord_set = (layer_type == SEQ_PAR_Type_Chord2) ? 1 : ((layer_type == SEQ_PAR_Type_Chord3) ? 2 : 0);
1110
    } else {
1111
      par_value = PassiveEditValid()
1112
        ? edit_passive_value
1113
        : SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
1114
 
1115
      chord_set = (master_layer_type == SEQ_PAR_Type_Chord2) ? 1 : ((master_layer_type == SEQ_PAR_Type_Chord3) ? 2 : 0);
1116
    }
1117
 
2505 tk 1118
    if( layer_type == SEQ_PAR_Type_Chord3 ) {
1119
      SEQ_LCD_PrintString(SEQ_CHORD_NameGet(chord_set, par_value));
1120
      SEQ_LCD_PrintSpaces(2);
1121
    } else {
1122
      u8 chord_ix = par_value & 0x1f;
1123
      u8 chord_oct = par_value >> 5;
1124
      SEQ_LCD_PrintString(SEQ_CHORD_NameGet(chord_set, chord_ix));
1125
      SEQ_LCD_PrintFormattedString("/%d", chord_oct);
1126
    }
1316 tk 1127
      } else {
1350 tk 1128
    u8 par_value = PassiveEditValid() ? edit_passive_value : layer_event.midi_package.note;
1129
    SEQ_LCD_PrintNote(par_value);
288 tk 1130
      }
1351 tk 1131
      SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
176 tk 1132
    }
1316 tk 1133
    else {
1134
      SEQ_LCD_PrintString("....");
1135
    }
1136
    SEQ_LCD_PrintFormattedString(" Vel:%3d", layer_event.midi_package.velocity);
176 tk 1137
  }
167 tk 1138
 
1316 tk 1139
  SEQ_LCD_PrintString(" Len:");
1140
  SEQ_LCD_PrintGatelength(layer_event.len);
167 tk 1141
 
1316 tk 1142
 
740 tk 1143
  // print flashing *LOOPED* at right corner if loop mode activated to remind that steps will be played differntly
1144
  if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_state.LOOP ) {
1145
    SEQ_LCD_PrintString(" *LOOPED*");
828 tk 1146
  } else if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_trk[visible_track].play_section > 0 ) {
1147
    SEQ_LCD_PrintFormattedString(" *Sect.%c*", 'A'+seq_core_trk[visible_track].play_section);
326 tk 1148
  } else {
740 tk 1149
    SEQ_LCD_PrintSpaces(4);
1150
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
1151
      SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name);
1152
    } else {
1153
      SEQ_LCD_PrintTrackCategory(visible_track, (char *)seq_core_trk[visible_track].name);
1154
    }
180 tk 1155
  }
167 tk 1156
 
1157
  ///////////////////////////////////////////////////////////////////////////
1211 tk 1158
  // Second Line
1159
  ///////////////////////////////////////////////////////////////////////////
167 tk 1160
 
2553 tk 1161
  u8 show_drum_triggers = (event_mode == SEQ_EVENT_MODE_Drum) && (seq_ui_edit_view != SEQ_UI_EDIT_VIEW_303);
2101 tk 1162
  if( show_drum_triggers && !(edit_mode || !ui_hold_msg_ctr) ) {
1163
    if( ui_hold_msg_ctr ) {
1164
      // e.g. during recording: show drum triggers for layers which can't be recorded
1165
      show_drum_triggers =
2106 tk 1166
    !ui_hold_msg_ctr_drum_edit &&
2101 tk 1167
    layer_type != SEQ_PAR_Type_Note &&
2274 tk 1168
    layer_type != SEQ_PAR_Type_Chord1 &&
1169
    layer_type != SEQ_PAR_Type_Chord2 &&
2505 tk 1170
    layer_type != SEQ_PAR_Type_Chord3 &&
2553 tk 1171
    layer_type != SEQ_PAR_Type_Velocity;
2101 tk 1172
    }
1173
  }
335 tk 1174
 
176 tk 1175
  // extra handling for gatelength (shows vertical bars)
335 tk 1176
  if( !show_drum_triggers && layer_type == SEQ_PAR_Type_Length ) {
167 tk 1177
 
176 tk 1178
    // we want to show horizontal bars
1179
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
167 tk 1180
 
176 tk 1181
    // initial cursor position
278 tk 1182
    SEQ_LCD_CursorSet(0, 1);
167 tk 1183
 
176 tk 1184
    // determine length of previous step (depends on selected view and track length)
1185
    int previous_step = 16*ui_selected_step_view - 1;
1186
    if( previous_step < 0 )
1187
      previous_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1188
 
1189
    seq_layer_evnt_t layer_event;
336 tk 1190
    SEQ_LAYER_GetEvntOfLayer(visible_track, previous_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
176 tk 1191
    u16 previous_length = layer_event.len;
330 tk 1192
 
1193
    // show length of 16 steps
336 tk 1194
    u16 step;
330 tk 1195
    for(step=0; step<16; ++step) {
336 tk 1196
      u16 visible_step = step + 16*ui_selected_step_view;
1197
      SEQ_LAYER_GetEvntOfLayer(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
330 tk 1198
 
1143 tk 1199
      u8 gate = SEQ_TRG_GateGet(visible_track, visible_step, ui_selected_instrument);
1200
 
338 tk 1201
      // muted step? if previous gatelength <= 96, print spaces
1143 tk 1202
      if( (!gate || !layer_event.midi_package.velocity) && previous_length < 96 ) {
338 tk 1203
    SEQ_LCD_PrintSpaces(5);
1204
      } else {
1205
    if( layer_event.len >= 96 )
1206
      SEQ_LCD_PrintHBar(15); // glide or stretched event
2159 tk 1207
    else {
1208
      //SEQ_LCD_PrintHBar(((layer_event.len-1)*16)/100);
1209
      SEQ_LCD_PrintHBar(((layer_event.len-1)*16)/110); // so that we see a difference if note not stretched
1210
    }
330 tk 1211
      }
1143 tk 1212
      previous_length = ((gate && layer_event.midi_package.velocity) || (previous_length >= 96 && layer_event.len >= 96)) ? layer_event.len : 0;
330 tk 1213
    }
1214
 
176 tk 1215
  } else {
1216
 
335 tk 1217
    if( show_drum_triggers ) {
323 tk 1218
      // we want to show triggers
325 tk 1219
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_DrumSymbolsBig);
323 tk 1220
    } else {
1221
      // we want to show vertical bars
1222
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
1223
    }
176 tk 1224
 
1225
    // initial cursor position
278 tk 1226
    SEQ_LCD_CursorSet(0, 1);
176 tk 1227
 
323 tk 1228
    int step_region_begin;
1229
    int step_region_end;
240 tk 1230
    switch( edit_mode ) {
1231
      case SEQ_UI_EDIT_MODE_COPY:
1232
    step_region_begin = SEQ_UI_UTIL_CopyPasteBeginGet();
1233
    step_region_end = SEQ_UI_UTIL_CopyPasteEndGet();
1234
    break;
1235
      case SEQ_UI_EDIT_MODE_PASTE:
1236
    step_region_begin = ui_selected_step;
1237
    step_region_end = ui_selected_step + SEQ_UI_UTIL_CopyPasteEndGet() - SEQ_UI_UTIL_CopyPasteBeginGet();
1238
    break;
1239
      case SEQ_UI_EDIT_MODE_SCROLL:
1240
    step_region_begin = ui_selected_step;
1241
    step_region_end = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1242
    break;
1243
      default:
336 tk 1244
    step_region_begin = ui_selected_step;
1245
    step_region_end = ui_selected_step;
240 tk 1246
    }
1247
 
336 tk 1248
    u16 step;
176 tk 1249
    for(step=0; step<16; ++step) {
336 tk 1250
      u16 visible_step = step + 16*ui_selected_step_view;
240 tk 1251
 
1252
      if( ui_cursor_flash &&
1253
      edit_mode != SEQ_UI_EDIT_MODE_NORMAL &&
1254
      visible_step >= step_region_begin && visible_step <= step_region_end ) {
1255
    SEQ_LCD_PrintSpaces(5);
1256
    continue;
1257
      }
1258
 
335 tk 1259
      if( show_drum_triggers ) {
336 tk 1260
    u8 gate_accent = SEQ_TRG_Get(visible_track, visible_step, 0, ui_selected_instrument);
328 tk 1261
    if( SEQ_TRG_NumLayersGet(visible_track) >= 2 )
336 tk 1262
      gate_accent |= SEQ_TRG_Get(visible_track, visible_step, 1, ui_selected_instrument) << 1;
335 tk 1263
 
323 tk 1264
    SEQ_LCD_PrintChar(' ');
1265
    SEQ_LCD_PrintChar(' ');
327 tk 1266
    SEQ_LCD_PrintChar(gate_accent);
323 tk 1267
    SEQ_LCD_PrintChar(' ');
1268
      } else {
1351 tk 1269
    int print_edit_value = (visible_step == edit_passive_step && PassiveEditValid()) ? edit_passive_value : -1;
1270
    SEQ_LCD_PrintLayerEvent(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, 1, print_edit_value);
176 tk 1271
      }
1272
 
2101 tk 1273
      {
2049 tk 1274
    u8 midi_learn = seq_record_state.ENABLED || midi_learn_mode == MIDI_LEARN_MODE_ON;
1275
    char lbr = midi_learn ? '}' : '<';
1276
    char rbr = midi_learn ? '{' : '>';
2047 tk 1277
 
1278
    SEQ_LCD_PrintChar((visible_step == step_region_end) ? lbr
1279
              : ((visible_step == (step_region_begin-1)) ? rbr : ' '));
323 tk 1280
      }
240 tk 1281
 
176 tk 1282
    }
167 tk 1283
  }
1284
 
1285
  return 0; // no error
1286
}
1287
 
1288
 
1289
/////////////////////////////////////////////////////////////////////////////
240 tk 1290
// Local Display Handler function
1291
// IN: <high_prio>: if set, a high-priority LCD update is requested
1292
/////////////////////////////////////////////////////////////////////////////
1293
static s32 LCD_Handler(u8 high_prio)
1294
{
1295
  return SEQ_UI_EDIT_LCD_Handler(high_prio, SEQ_UI_EDIT_MODE_NORMAL);
1296
}
1297
 
1298
 
1299
/////////////////////////////////////////////////////////////////////////////
2047 tk 1300
// MIDI IN
1301
/////////////////////////////////////////////////////////////////////////////
1302
static s32 MIDI_IN_Handler(mios32_midi_port_t port, mios32_midi_package_t p)
1303
{
1304
  if( midi_learn_mode == MIDI_LEARN_MODE_ON ) {
2048 tk 1305
    u8 visible_track = SEQ_UI_VisibleTrackGet();
1306
 
2047 tk 1307
    // quick & dirty for evaluation purposes
1308
    seq_record_options_t prev_seq_record_options = seq_record_options;
2168 tk 1309
    u8 reset_timestamps = p.type == NoteOn && p.velocity > 0;
2563 tk 1310
    midi_learn_mode_used = 1;
2047 tk 1311
 
1312
    seq_record_options.ALL = 0;
1313
    seq_record_options.STEP_RECORD = 1;
1314
    seq_record_options.FWD_MIDI = prev_seq_record_options.FWD_MIDI;
1315
 
2168 tk 1316
    SEQ_RECORD_Enable(1, reset_timestamps);
2047 tk 1317
 
2048 tk 1318
    SEQ_RECORD_Receive(p, visible_track);
2047 tk 1319
 
2048 tk 1320
    if( seq_ui_button_state.CHANGE_ALL_STEPS ) {
1321
      // copy matching par layers into remaining steps
1322
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
1323
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
1324
 
1325
      seq_cc_trk_t *tcc = &seq_cc_trk[visible_track];
1326
      seq_par_layer_type_t rec_layer_type = tcc->lay_const[ui_selected_par_layer];
1327
 
1328
      {
1329
    u8 p_layer;
1330
    for(p_layer=0; p_layer<num_p_layers; ++p_layer) {
1331
      seq_par_layer_type_t layer_type = tcc->lay_const[p_layer];
1332
 
1333
      if( layer_type == rec_layer_type ||
2505 tk 1334
          ((rec_layer_type == SEQ_PAR_Type_Note || rec_layer_type == SEQ_PAR_Type_Chord1 || rec_layer_type == SEQ_PAR_Type_Chord2 || rec_layer_type == SEQ_PAR_Type_Chord3) && (layer_type == SEQ_PAR_Type_Velocity || layer_type == SEQ_PAR_Type_Length)) ) {
2166 tk 1335
        u8 value = SEQ_PAR_Get(visible_track, ui_selected_step, p_layer, ui_selected_instrument);
2048 tk 1336
 
1337
        u16 step;
1338
        for(step=0; step<num_steps; ++step) {
2166 tk 1339
          if( step != ui_selected_step && (selected_steps & (1 << (step % 16))) ) {
2048 tk 1340
        SEQ_PAR_Set(visible_track, step, p_layer, ui_selected_instrument, value);
1341
          }
1342
        }
1343
      }
1344
    }
1345
      }
1346
    }
1347
 
2047 tk 1348
    seq_record_options.ALL = prev_seq_record_options.ALL;
2168 tk 1349
    SEQ_RECORD_Enable(0, 0);
2047 tk 1350
 
2106 tk 1351
    ui_hold_msg_ctr_drum_edit = 0;
1352
 
2047 tk 1353
    seq_ui_display_update_req = 1;
2166 tk 1354
 
1355
    return 1; // don't continue recording/live forwarding processing
2047 tk 1356
  }
1357
 
1358
  return 0;
1359
}
1360
 
1361
 
1362
/////////////////////////////////////////////////////////////////////////////
2101 tk 1363
// Stores config file if required
1364
/////////////////////////////////////////////////////////////////////////////
1365
static s32 CheckStoreFile(void)
1366
{
2102 tk 1367
  if( ui_store_file_required ) {
2101 tk 1368
    // write config file
1369
    MUTEX_SDCARD_TAKE;
1370
    s32 status;
1371
    if( (status=SEQ_FILE_GC_Write()) < 0 )
1372
      SEQ_UI_SDCardErrMsg(2000, status);
1373
    MUTEX_SDCARD_GIVE;
1374
 
2102 tk 1375
    ui_store_file_required = 0;
2101 tk 1376
  }
1377
 
1378
  return 0; // no error
1379
}
1380
 
1381
 
1382
/////////////////////////////////////////////////////////////////////////////
2050 tk 1383
// Exit
1384
/////////////////////////////////////////////////////////////////////////////
1385
static s32 EXIT_Handler(void)
1386
{
1387
  midi_learn_mode = MIDI_LEARN_MODE_OFF;
2101 tk 1388
 
1389
  CheckStoreFile();
1390
 
2050 tk 1391
  return 0;
1392
}
1393
 
1394
/////////////////////////////////////////////////////////////////////////////
167 tk 1395
// Initialisation
1396
/////////////////////////////////////////////////////////////////////////////
1397
s32 SEQ_UI_EDIT_Init(u32 mode)
1398
{
1399
  // install callback routines
758 tk 1400
  SEQ_UI_InstallButtonCallback(SEQ_UI_EDIT_Button_Handler);
168 tk 1401
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
240 tk 1402
  SEQ_UI_InstallLEDCallback(SEQ_UI_EDIT_LED_Handler);
168 tk 1403
  SEQ_UI_InstallLCDCallback(LCD_Handler);
2047 tk 1404
  SEQ_UI_InstallMIDIINCallback(MIDI_IN_Handler);
2050 tk 1405
  SEQ_UI_InstallExitCallback(EXIT_Handler);
167 tk 1406
 
2047 tk 1407
  // disable MIDI learn mode by default
1408
  midi_learn_mode = MIDI_LEARN_MODE_OFF;
1409
 
2106 tk 1410
  ui_hold_msg_ctr_drum_edit = 0;
1411
 
1350 tk 1412
  edit_passive_mode = 0;
2533 tk 1413
  edit_ramp = 0;
729 tk 1414
 
1142 tk 1415
  if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL )
1416
    seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS;
1417
 
167 tk 1418
  return 0; // no error
1419
}
178 tk 1420
 
1421
 
1422
 
1423
/////////////////////////////////////////////////////////////////////////////
1424
// help function to change/set a single encoder value
1425
// if forced_value >= 0: new value will be set to the given value
1426
// if forced_value < 0: new value will be changed via incrementer
1427
// returns >= 0 if new value has been set (value change)
1428
// returns < 0 if no change
1429
/////////////////////////////////////////////////////////////////////////////
1052 tk 1430
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 1431
{
333 tk 1432
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(track, ui_selected_par_layer);
335 tk 1433
  u8 visible_track = SEQ_UI_VisibleTrackGet();
178 tk 1434
 
828 tk 1435
#if 0
1436
  // disabled in MBSEQ V4.0beta15 due to issue reported by Gridracer:
1437
  // http://midibox.org/forums/index.php?/topic/13137-midibox-seq-v4-beta-release-feedback/page__st__100
1438
 
333 tk 1439
  // if note/chord/velocity parameter: only change gate if requested
2505 tk 1440
  if( (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord1 || layer_type == SEQ_PAR_Type_Chord2 || layer_type == SEQ_PAR_Type_Chord3 || layer_type == SEQ_PAR_Type_Velocity) &&
178 tk 1441
      !change_gate &&
652 tk 1442
      !SEQ_TRG_GateGet(track, trg_step, ui_selected_instrument) )
178 tk 1443
    return -1;
828 tk 1444
#endif
178 tk 1445
 
1052 tk 1446
  if( layer_type == SEQ_PAR_Type_Probability ) {
1447
    // due to another issue reported by Gridracer:
1448
    // invert incrementer so that clockwise move increases probability
1449
    incrementer = -incrementer;
1450
  }
1451
 
1452
 
335 tk 1453
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
652 tk 1454
  if( event_mode == SEQ_EVENT_MODE_Drum ) {
335 tk 1455
    ui_hold_msg_ctr = 1000; // show value for 1 second
2106 tk 1456
    ui_hold_msg_ctr_drum_edit = 1;
1457
  } else {
1458
    ui_hold_msg_ctr_drum_edit = 0;
652 tk 1459
  }
335 tk 1460
 
652 tk 1461
  s32 old_value = SEQ_PAR_Get(track, par_step, ui_selected_par_layer, ui_selected_instrument);
178 tk 1462
  s32 new_value = (forced_value >= 0) ? forced_value : (old_value + incrementer);
1463
  if( new_value < 0 )
1464
    new_value = 0;
2448 tk 1465
  else {
1466
    // limit depending on max value
2435 tk 1467
    seq_par_layer_type_t par_layer_type = SEQ_PAR_AssignmentGet(track, ui_selected_par_layer);
2448 tk 1468
    u8 max = SEQ_PAR_MaxValueGet(par_layer_type);
2435 tk 1469
 
2448 tk 1470
    if( new_value >= max ) {
1471
      new_value = max;
2435 tk 1472
    }
1473
  }
178 tk 1474
 
1143 tk 1475
  // extra for more comfortable editing of multi-note tracks:
1476
  // if assigned parameter layer is Note or Chord, and currently 0, re-start at C-3 resp. A/2
1477
  // when value is incremented
2505 tk 1478
  if( incrementer > 0 && forced_value < 0 && old_value == 0x00 && (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord1 || layer_type == SEQ_PAR_Type_Chord2 || layer_type == SEQ_PAR_Type_Chord3) )
1143 tk 1479
    new_value = (layer_type == SEQ_PAR_Type_Note && SEQ_CC_Get(track, SEQ_CC_MODE) != SEQ_CORE_TRKMODE_Arpeggiator) ? 0x3c : 0x40;
1480
 
1345 tk 1481
  if( !dont_change_gate ) {
1482
    u8 event_mode = SEQ_CC_Get(track, SEQ_CC_MIDI_EVENT_MODE);
1483
 
1484
    // we do this always regardless if value has been changed or not (e.g. increment if value already 127)
1485
    if( event_mode == SEQ_EVENT_MODE_CC && layer_type == SEQ_PAR_Type_CC ) {
1486
      // in this mode gates are used to disable CC
1487
      // if a CC value has been changed, set gate
2564 tk 1488
      if( !seq_ui_options.PRINT_AND_MODIFY_WITHOUT_GATES ) {
1489
    SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
1490
      }
1345 tk 1491
    }
1492
  }
1493
 
178 tk 1494
  // take over if changed
1495
  if( new_value == old_value )
1496
    return -1;
1497
 
652 tk 1498
  SEQ_PAR_Set(track, par_step, ui_selected_par_layer, ui_selected_instrument, (u8)new_value);
178 tk 1499
 
747 tk 1500
  if( !dont_change_gate &&
2505 tk 1501
      (layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord1 || layer_type == SEQ_PAR_Type_Chord2 || layer_type == SEQ_PAR_Type_Chord3 || layer_type == SEQ_PAR_Type_Velocity) ) {
178 tk 1502
    // (de)activate gate depending on value
2564 tk 1503
    if( new_value ) {
1504
      if( !seq_ui_options.PRINT_AND_MODIFY_WITHOUT_GATES ) {
1505
    SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
1506
      }
1507
    } else {
1053 tk 1508
      // due to another issue reported by Gridracer:
1509
      // if the track plays multiple notes, only clear gate if all notes are 0
1142 tk 1510
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
1053 tk 1511
      u8 allNotesZero = 1;
1512
      int i;
1142 tk 1513
      for(i=0; i<num_p_layers; ++i) {
1053 tk 1514
    seq_par_layer_type_t localLayerType = SEQ_PAR_AssignmentGet(track, i);
2505 tk 1515
    if( (localLayerType == SEQ_PAR_Type_Note || localLayerType == SEQ_PAR_Type_Chord1 || localLayerType == SEQ_PAR_Type_Chord2 || localLayerType == SEQ_PAR_Type_Chord3) &&
1053 tk 1516
        SEQ_PAR_Get(track, par_step, i, ui_selected_instrument) > 0 ) {
1517
      allNotesZero = 0;
1518
      break;
1519
    }
1520
      }
1521
 
1522
      if( allNotesZero )
1523
    SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 0);
1524
    }
178 tk 1525
  }
1526
 
1527
  return new_value;
1528
}
1350 tk 1529
 
1530
 
1531
/////////////////////////////////////////////////////////////////////////////
1532
// help functions for "passive edit mode"
1533
/////////////////////////////////////////////////////////////////////////////
1534
static s32 PassiveEditEnter(void)
1535
{
1536
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1351 tk 1537
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
1350 tk 1538
 
1351 tk 1539
  // passive edit mode currently only supported for notes/chords
1350 tk 1540
 
2505 tk 1541
  if( layer_type == SEQ_PAR_Type_Note || layer_type == SEQ_PAR_Type_Chord1 || layer_type == SEQ_PAR_Type_Chord2 || layer_type == SEQ_PAR_Type_Chord3 ) {
1351 tk 1542
    // enter passive edit mode and store track/step/layer/instrument for later checks
1543
    edit_passive_mode = 1;
1544
    edit_passive_track = visible_track;
1545
    edit_passive_step = ui_selected_step;
1546
    edit_passive_par_layer = ui_selected_par_layer;
1547
    edit_passive_instrument = ui_selected_instrument;
1548
    edit_passive_value = SEQ_PAR_Get(edit_passive_track, edit_passive_step, edit_passive_par_layer, edit_passive_instrument);
1549
  } else {
1550
    edit_passive_mode = 0;
1551
  }
1552
 
1350 tk 1553
  return 0; // no error
1554
}
1555
 
1556
static s32 PassiveEditValid(void)
1557
{
1558
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1559
 
1560
  return (edit_passive_mode == 2 && // if mode is 2, the value has been changed!
1561
      edit_passive_track == visible_track &&
1562
      edit_passive_step == ui_selected_step &&
1563
      edit_passive_par_layer == ui_selected_par_layer &&
1564
      edit_passive_instrument == ui_selected_instrument) ? 1 : 0;
1565
}
1566
 
1567
static s32 PassiveEditTakeOver(void)
1568
{
1569
 
1570
  // only take over changed value if track/step/layer/instrument still passing
1571
  if( PassiveEditValid() ) {
1572
    // take over change
1573
    // handle it like a single increment/decrement so that no code needs to be duplicated
1574
    int current_value = SEQ_PAR_Get(edit_passive_track, edit_passive_step, edit_passive_par_layer, edit_passive_instrument);
1575
    int incrementer = (int)edit_passive_value - current_value;
1576
 
2048 tk 1577
    seq_ui_button_state.EDIT_PRESSED = 0; // just to avoid any overlay...
1350 tk 1578
    edit_passive_mode = 0; // to avoid recursion in encoder handler
1579
    Encoder_Handler(edit_passive_step % 16, incrementer);
1580
  } else {
1581
    edit_passive_mode = 1;
1582
  }
1583
 
1584
  return 0; // no error
1585
}