Subversion Repositories svn.mios32

Rev

Rev 2553 | 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 2563 2018-03-03 20:46:18Z 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));
473
 
652 tk 474
    u16 par_step;
475
    for(par_step=0; par_step<num_steps; ++par_step, ++trg_step) {
2533 tk 476
      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 477
        change_gate = trg_step == changed_step;
478
        u8 dont_change_gate = par_step != changed_step;
2533 tk 479
        if( change_gate || seq_ui_button_state.CHANGE_ALL_STEPS || seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
1751 tk 480
          s32 local_forced_value = edit_ramp ? -1 : forced_value;
481
 
482
          s32 edit_ramp_num_steps = 0;
483
          if( edit_ramp ) {
484
        if( changed_step > ui_selected_step && par_step > ui_selected_step && par_step < changed_step ) {
485
          edit_ramp_num_steps = changed_step - ui_selected_step;
486
        } else if( changed_step < ui_selected_step && par_step < ui_selected_step && par_step > changed_step ) {
487
          edit_ramp_num_steps = ui_selected_step - changed_step;
488
        }
489
 
490
        if( edit_ramp_num_steps ) {
491
          if( par_step == changed_step ) {
492
            local_forced_value = value_changed_step;
493
          } else {
494
            int diff = value_changed_step - value_selected_step;
495
            if( diff == 0 ) {
496
              local_forced_value = value_changed_step;
497
            } else {
498
              if( changed_step > ui_selected_step ) {
499
            local_forced_value = value_selected_step + (((par_step - ui_selected_step) * diff) / edit_ramp_num_steps);
500
              } else {
501
            local_forced_value = value_selected_step + (((ui_selected_step - par_step) * diff) / edit_ramp_num_steps);
502
              }
503
            }
504
          }
505
        }
506
          }
507
 
508
          if( !edit_ramp || edit_ramp_num_steps ) {
509
        if( ChangeSingleEncValue(track, par_step, trg_step, incrementer, local_forced_value, change_gate, dont_change_gate) >= 0 )
510
          value_changed |= 1;
511
          }
729 tk 512
        }
178 tk 513
      }
514
    }
515
      }
176 tk 516
    }
1142 tk 517
 
178 tk 518
    return value_changed;
168 tk 519
  }
520
 
521
  return -1; // invalid or unsupported encoder
167 tk 522
}
523
 
524
 
525
/////////////////////////////////////////////////////////////////////////////
168 tk 526
// Local button callback function
527
// Should return:
528
//   1 if value has been changed
529
//   0 if value hasn't been changed
530
//  -1 if invalid or unsupported button
167 tk 531
/////////////////////////////////////////////////////////////////////////////
758 tk 532
s32 SEQ_UI_EDIT_Button_Handler(seq_ui_button_t button, s32 depressed)
167 tk 533
{
306 tk 534
  u8 visible_track = SEQ_UI_VisibleTrackGet();
535
 
168 tk 536
#if 0
537
  // leads to: comparison is always true due to limited range of data type
538
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
539
#else
540
  if( button <= SEQ_UI_BUTTON_GP16 ) {
541
#endif
2047 tk 542
 
2063 tk 543
    if( !seq_ui_button_state.EDIT_PRESSED &&
2533 tk 544
    ((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 545
     seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL) ) {
546
      if( depressed ) return 0; // ignore when button depressed
547
 
548
      selected_steps ^= (1 << button);
549
      return 1; // value changed
550
    }
551
 
2047 tk 552
    // enable/disable MIDI Learn mode
553
    midi_learn_mode = depressed ? MIDI_LEARN_MODE_OFF : MIDI_LEARN_MODE_ON;
2563 tk 554
    if( midi_learn_mode_used && midi_learn_mode == MIDI_LEARN_MODE_OFF ) {
555
      midi_learn_mode_used = 0;
556
      SEQ_RECORD_AllNotesOff();
557
    }
2047 tk 558
 
2168 tk 559
    if( depressed )
560
      return 0; // ignore when button depressed
729 tk 561
 
2048 tk 562
    if( seq_ui_button_state.EDIT_PRESSED )
1142 tk 563
      return Encoder_Handler(button, 0);
564
 
565
    u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
566
 
567
    if( event_mode != SEQ_EVENT_MODE_Drum &&
568
    (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303) ) {
569
 
570
      if( button == SEQ_UI_BUTTON_GP1 ) {
571
    int next_step = ui_selected_step + 1; // (required, since ui_selected_step is only u8, but we could have up to 256 steps)
572
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
573
      next_step = 0;
574
    ui_selected_step = next_step;
575
    ui_selected_step_view = ui_selected_step / 16;
576
    return 1; // value always changed
577
      } else if( button == SEQ_UI_BUTTON_GP2 ) {
578
    u8 trg = SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument);
579
    return Encoder_Handler(button, trg ? -1 : 1);
580
      } else if( button == SEQ_UI_BUTTON_GP3 ) {
581
    u8 trg = SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument);
582
    return Encoder_Handler(button, trg ? -1 : 1);
583
      } else if( button == SEQ_UI_BUTTON_GP4 ) {
584
    u8 trg = SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument);
585
    return Encoder_Handler(button, trg ? -1 : 1);
586
      } else if( button <= SEQ_UI_BUTTON_GP16 ) {
587
    return Encoder_Handler(button, 0);
588
      }
589
    }
590
 
591
 
2553 tk 592
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
593
      u16 num_instruments = SEQ_PAR_NumInstrumentsGet(visible_track);
594
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
1142 tk 595
 
2553 tk 596
      seq_ui_button_t drum_button;
597
      seq_ui_button_t step_button;
598
      seq_ui_button_t gate_button;
599
      u8 trg_button_offset;
600
      if( event_mode == SEQ_EVENT_MODE_Drum ) {
601
    drum_button = SEQ_UI_BUTTON_GP1;
602
    step_button = SEQ_UI_BUTTON_GP2;
603
    gate_button = SEQ_UI_BUTTON_GP3;
604
    trg_button_offset = 2;
605
      } else {
606
    drum_button = 0xff; // no drum selection
607
    step_button = SEQ_UI_BUTTON_GP1;
608
    gate_button = SEQ_UI_BUTTON_GP2;
609
    trg_button_offset = 1;
610
      }
611
 
612
 
613
      if( button == drum_button ) {
614
    u8 next_instrument = ui_selected_instrument + 1;
615
    if( next_instrument >= num_instruments )
616
      next_instrument = 0;
617
    ui_selected_instrument = next_instrument;
618
    return 1; // value always changed
619
      } else if( button == step_button ) {
1142 tk 620
    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 621
    if( next_step >= num_steps )
1142 tk 622
      next_step = 0;
623
    ui_selected_step = next_step;
624
    ui_selected_step_view = ui_selected_step / 16;
625
    return 1; // value always changed
2553 tk 626
      } else if( button == gate_button ||
1142 tk 627
         (seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG && button <= SEQ_UI_BUTTON_GP8) ) {
2553 tk 628
    u8 trg = SEQ_TRG_Get(visible_track, ui_selected_step, (u8)button-trg_button_offset, ui_selected_instrument);
1142 tk 629
    return Encoder_Handler(button, trg ? -1 : 1);
630
      } else if( button <= SEQ_UI_BUTTON_GP16 ) {
631
    return Encoder_Handler(button, 0);
632
      }
633
    }
634
 
180 tk 635
    ui_selected_step = button + ui_selected_step_view*16;
1142 tk 636
 
168 tk 637
    // toggle trigger layer
600 tk 638
    // if seq_hwcfg_button_beh.all_with_triggers set, we've three cases:
178 tk 639
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
640
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
641
    // c) ALL function not active: toggle step
2533 tk 642
    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 643
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
644
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
303 tk 645
    u16 step = ui_selected_step;
328 tk 646
    u8 new_value = SEQ_TRG_Get(visible_track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
1142 tk 647
 
178 tk 648
    u8 track;
649
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
318 tk 650
      if( SEQ_UI_IsSelectedTrack(track) ) {
651
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
652
        for(step=0; step<num_steps; ++step)
328 tk 653
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
2230 tk 654
        SEQ_CORE_CancelSustainedNotes(track); // cancel sustain if there are no notes played by the track anymore
318 tk 655
      }
178 tk 656
      } else {
657
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
303 tk 658
    u8 track;
659
    u16 step;
178 tk 660
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
661
      if( SEQ_UI_IsSelectedTrack(track) ) {
318 tk 662
        u16 num_steps = SEQ_TRG_NumStepsGet(track);
663
        for(step=0; step<num_steps; ++step) {
328 tk 664
          u8 new_value = SEQ_TRG_Get(track, step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
665
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, ui_selected_instrument, new_value);
178 tk 666
        }
2230 tk 667
        SEQ_CORE_CancelSustainedNotes(track); // cancel sustain if there are no notes played by the track anymore
178 tk 668
      }
669
    }
670
      }
671
    } else {
672
      // c) ALL function not active: toggle step
673
      u8 track;
1142 tk 674
 
484 tk 675
      u8 new_value = SEQ_TRG_Get(visible_track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument) ? 0 : 1;
178 tk 676
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
677
    if( SEQ_UI_IsSelectedTrack(track) ) {
328 tk 678
      SEQ_TRG_Set(track, ui_selected_step, ui_selected_trg_layer, ui_selected_instrument, new_value);
2230 tk 679
      SEQ_CORE_CancelSustainedNotes(track); // cancel sustain if there are no notes played by the track anymore
178 tk 680
    }
681
      }
682
    }
1142 tk 683
 
168 tk 684
    return 1; // value always changed
178 tk 685
 
168 tk 686
  } else {
687
    switch( button ) {
688
      case SEQ_UI_BUTTON_Select:
2048 tk 689
    // toggle MIDI learn
690
    if( !depressed )
691
      midi_learn_mode = (midi_learn_mode == MIDI_LEARN_MODE_ON) ? MIDI_LEARN_MODE_OFF : MIDI_LEARN_MODE_ON;
2563 tk 692
        if( midi_learn_mode_used && midi_learn_mode == MIDI_LEARN_MODE_OFF ) {
693
          midi_learn_mode_used = 0;
694
          SEQ_RECORD_AllNotesOff();
695
        }
729 tk 696
    return 1; // value always changed
697
 
303 tk 698
      case SEQ_UI_BUTTON_Right: {
729 tk 699
    if( depressed ) return 0; // ignore when button depressed
700
 
303 tk 701
    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 702
    if( next_step >= (SEQ_CC_Get(visible_track, SEQ_CC_LENGTH)+1) )
303 tk 703
      next_step = 0;
704
    ui_selected_step = next_step;
168 tk 705
    ui_selected_step_view = ui_selected_step / 16;
706
    return 1; // value always changed
303 tk 707
      } break;
167 tk 708
 
168 tk 709
      case SEQ_UI_BUTTON_Left:
729 tk 710
    if( depressed ) return 0; // ignore when button depressed
711
 
168 tk 712
    if( ui_selected_step == 0 )
306 tk 713
      ui_selected_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1142 tk 714
    else
715
      --ui_selected_step;
716
 
168 tk 717
    ui_selected_step_view = ui_selected_step / 16;
718
    return 1; // value always changed
167 tk 719
 
168 tk 720
      case SEQ_UI_BUTTON_Up:
729 tk 721
    if( depressed ) return 0; // ignore when button depressed
168 tk 722
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
723
 
724
      case SEQ_UI_BUTTON_Down:
729 tk 725
    if( depressed ) return 0; // ignore when button depressed
168 tk 726
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
1350 tk 727
 
728
      // this button is currently only notified to EDIT page
729
      case SEQ_UI_BUTTON_Edit:
730
    if( !depressed )
731
      PassiveEditEnter();
1351 tk 732
    else {
1350 tk 733
      PassiveEditTakeOver();
1351 tk 734
      edit_passive_mode = 0;
735
    }
1350 tk 736
    return 1;
168 tk 737
    }
167 tk 738
  }
739
 
168 tk 740
  return -1; // invalid or unsupported button
167 tk 741
}
742
 
743
 
744
/////////////////////////////////////////////////////////////////////////////
240 tk 745
// Global Display Handler function
167 tk 746
// IN: <high_prio>: if set, a high-priority LCD update is requested
240 tk 747
//     <edit_page>: selects the normal, or copy/paste/move/scroll view
167 tk 748
/////////////////////////////////////////////////////////////////////////////
240 tk 749
s32 SEQ_UI_EDIT_LCD_Handler(u8 high_prio, seq_ui_edit_mode_t edit_mode)
167 tk 750
{
751
  if( high_prio )
752
    return 0; // there are no high-priority updates
753
 
2101 tk 754
  if( !edit_mode && !seq_ui_button_state.EDIT_PRESSED )
755
    CheckStoreFile(); // for Datawheel mode: stored on SD Card when edit has been depressed
326 tk 756
 
2101 tk 757
 
326 tk 758
  // layout common track:
759
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
760
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
761
  // G1T1 xxxxxxxxxxxxxxx  PC:Length TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
762
  // ....
763
 
764
  // layout drum track:
765
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
766
  // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
767
  // G1T1 xxxxxxxxxxxxxxx  PA:Vel.   TA:Gate Step  1   G#1_ Vel:127_Len: 75%    xxxxx
768
  // ....
769
 
1142 tk 770
  // layout edit config
771
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
2050 tk 772
  // Step Trg  Layer 303                Step Datawheel:  Record   Random    Euclid   
773
  // View View View View               Select Scroll     Config  Generator Generator 
1142 tk 774
 
775
  // layout trigger view
776
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
777
  // Step Gate Acc. Roll Glide Skip R.G  R.V Note Vel. Len. Roll Note Note Note Note 
778
  //   1    *    o    o    o    o    o    o  C-3  100   75% ---- E-3  G-3  ---- ---- 
779
 
780
  // layout layer view
781
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
782
  // Step Gate Note Vel. Len. Roll Note Note Note Note Note Note Note Note Note Note 
783
  //   1    *  C-3  100   75% ---- E-3  G-3  ---- ---- ---- ---- ---- ---- ---- ---- 
784
 
785
  // layout 303 view
786
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
787
  // Step Gate Acc. Glide Oct, Key Vel. Prob  CC   CC   CC   CC   CC   CC   CC   CC  
788
  //   1    *   o     o    3    C  100  100%  64   64   64   64   64   64   64   64  
789
 
729 tk 790
  // layout step selection:
791
  // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
792
  //        Select the steps which should be  controlled by the ALL function:        
793
  //   *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *  
326 tk 794
 
2553 tk 795
  u8 visible_track = SEQ_UI_VisibleTrackGet();
796
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
797
 
2048 tk 798
  if( !edit_mode && seq_ui_button_state.EDIT_PRESSED ) {
2101 tk 799
    const char seq_ui_edit_datawheel_mode_str[SEQ_UI_EDIT_DATAWHEEL_MODE_NUM][11] = {
1348 tk 800
      " Cursor   ",
801
      " StepView ",
802
      " Value    ",
803
      " ParLayer ",
804
      " TrgLayer ",
805
    };
806
 
1142 tk 807
    SEQ_LCD_CursorSet(0, 0);
2553 tk 808
    if( event_mode != SEQ_EVENT_MODE_Drum ) {
809
      SEQ_LCD_PrintString("Step Trg  Layer 303                ");
810
    } else {
811
      SEQ_LCD_PrintString("Step Trg  Layer Par                ");
812
    }
813
    SEQ_LCD_PrintString("Step Datawheel:  Record   Random    Euclid   ");
1142 tk 814
    SEQ_LCD_CursorSet(0, 1);
1483 tk 815
    SEQ_LCD_PrintString("View View View View               Select");
2101 tk 816
    SEQ_LCD_PrintString((char *)seq_ui_edit_datawheel_mode_str[seq_ui_edit_datawheel_mode]);
2050 tk 817
    SEQ_LCD_PrintString("  Config  Generator Generator ");
1142 tk 818
    return 0; // no error
819
  }
820
 
821
  if( !edit_mode && seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL ) {
729 tk 822
    int step;
823
 
824
    SEQ_LCD_CursorSet(0, 0);
825
    SEQ_LCD_PrintString("       Select the steps which should be  controlled by the ALL function:        ");
826
    SEQ_LCD_CursorSet(0, 1);
827
    for(step=0; step<16; ++step)
828
      SEQ_LCD_PrintFormattedString("  %c  ", (selected_steps & (1 << step)) ? '*' : 'o');
829
    return 0; // no error
830
  }
831
 
832
 
2553 tk 833
  if( event_mode != SEQ_EVENT_MODE_Drum && seq_ui_edit_view == SEQ_UI_EDIT_VIEW_303 ) {
167 tk 834
 
1142 tk 835
    // we want to show vertical bars
836
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
837
 
838
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
839
    // maximum 10 parameter layers
840
    if( num_p_layers >= 11 )
841
      num_p_layers = 11;
842
 
843
    ///////////////////////////////////////////////////////////////////////////
844
    SEQ_LCD_CursorSet(0, 0);
845
    SEQ_LCD_PrintString("Step Gate Acc. Glide Oct. Key ");
846
    int i;
2294 tk 847
    for(i=1; i<num_p_layers; ++i) {
848
      char str_buffer[6];
2551 tk 849
      SEQ_PAR_AssignedTypeStr(visible_track, i, ui_selected_instrument, str_buffer);
2294 tk 850
      SEQ_LCD_PrintString(str_buffer);
851
    }
1142 tk 852
 
853
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
854
 
855
    ///////////////////////////////////////////////////////////////////////////
856
    SEQ_LCD_CursorSet(0, 1);
2049 tk 857
    SEQ_LCD_PrintFormattedString((seq_record_state.ENABLED || midi_learn_mode == MIDI_LEARN_MODE_ON) ? "{%3d}" : " %3d ", ui_selected_step+1);
1142 tk 858
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_GateGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
859
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_AccentGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
860
    SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_GlideGet(visible_track, ui_selected_step, ui_selected_instrument) ? '*' : 'o');
861
 
1351 tk 862
    u8 note = SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
1142 tk 863
    u8 note_octave = note / 12;
864
    u8 note_key = note % 12;
865
 
866
    SEQ_LCD_PrintFormattedString(" %2d  ", (int)note_octave-2);
867
    const char note_tab[12][2] = { "C ", "C#", "D ", "D#", "E ", "F ", "F#", "G ", "G#", "A ", "A#", "B " };
868
    SEQ_LCD_PrintFormattedString("  %c%c ", note_tab[note_key][0], note_tab[note_key][1]);
869
 
870
    for(i=1; i<num_p_layers; ++i)
871
      if( i == ui_selected_par_layer && ui_cursor_flash )
872
    SEQ_LCD_PrintSpaces(5);
873
      else {
1351 tk 874
    int print_edit_value = PassiveEditValid() ? edit_passive_value : -1;
875
    SEQ_LCD_PrintLayerEvent(visible_track, ui_selected_step, i, ui_selected_instrument, 0, print_edit_value);
1142 tk 876
    SEQ_LCD_PrintChar(' ');
877
      }
878
 
879
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
2553 tk 880
 
1142 tk 881
    return 0;
882
  }
883
 
2553 tk 884
  if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_LAYERS || seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
1142 tk 885
 
886
    // we want to show vertical bars
887
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
888
 
889
    u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
890
    u8 num_t_layers = SEQ_TRG_NumLayersGet(visible_track);
891
 
892
    if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_TRG ) {
893
      // maximum 7 parameter layers due to "Step" item!
2553 tk 894
      // if drum: only 6 parameter layers due to additional "Drum" item!
895
      u8 max_t_layers = (event_mode == SEQ_EVENT_MODE_Drum) ? 6 : 7;
896
      if( num_t_layers >= max_t_layers )
897
    num_t_layers = max_t_layers;
1142 tk 898
 
899
      // maximum 8 parameter layers
900
      if( num_p_layers >= 8 )
901
    num_p_layers = 8;
902
    } else {
903
      // single trigger layer (gate)
904
      num_t_layers = 1;
905
 
906
      // maximum 14 parameter layers due to "Step" and "Gate" item!
2553 tk 907
      // drum mode: only 13 items
908
      u8 max_p_layers = (event_mode == SEQ_EVENT_MODE_Drum) ? 13 : 14;
909
      if( num_p_layers >= max_p_layers )
910
    num_p_layers = max_p_layers;
1142 tk 911
    }
912
 
913
    ///////////////////////////////////////////////////////////////////////////
914
    SEQ_LCD_CursorSet(0, 0);
2553 tk 915
 
916
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
917
      SEQ_LCD_PrintString("Drum ");
918
    }
919
 
1142 tk 920
    SEQ_LCD_PrintString("Step ");
921
    int i;
922
    for(i=0; i<num_t_layers; ++i)
2294 tk 923
      SEQ_LCD_PrintString(SEQ_TRG_AssignedTypeStr(visible_track, i));
1142 tk 924
 
2294 tk 925
    for(i=0; i<num_p_layers; ++i) {
926
      char str_buffer[6];
2551 tk 927
      SEQ_PAR_AssignedTypeStr(visible_track, i, ui_selected_instrument, str_buffer);
2294 tk 928
      SEQ_LCD_PrintString(str_buffer);
929
    }
930
 
1142 tk 931
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
932
 
933
    ///////////////////////////////////////////////////////////////////////////
934
    SEQ_LCD_CursorSet(0, 1);
2553 tk 935
 
936
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
937
      SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name);
938
    }
939
 
2049 tk 940
    SEQ_LCD_PrintFormattedString((seq_record_state.ENABLED || midi_learn_mode == MIDI_LEARN_MODE_ON) ? "{%3d}" : " %3d ", ui_selected_step+1);
1142 tk 941
    for(i=0; i<num_t_layers; ++i)
942
      SEQ_LCD_PrintFormattedString("  %c  ", SEQ_TRG_Get(visible_track, ui_selected_step, i, ui_selected_instrument) ? '*' : 'o');
943
    for(i=0; i<num_p_layers; ++i)
944
      if( i == ui_selected_par_layer && ui_cursor_flash )
945
    SEQ_LCD_PrintSpaces(5);
946
      else {
1351 tk 947
    int print_edit_value = PassiveEditValid() ? edit_passive_value : -1;
948
    SEQ_LCD_PrintLayerEvent(visible_track, ui_selected_step, i, ui_selected_instrument, 0, print_edit_value);
1142 tk 949
    SEQ_LCD_PrintChar(' ');
950
      }
951
 
952
    SEQ_LCD_PrintSpaces(80 - (5*num_p_layers));
953
 
954
    return 0;
955
  }
956
 
176 tk 957
  seq_layer_evnt_t layer_event;
336 tk 958
  SEQ_LAYER_GetEvntOfLayer(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
168 tk 959
 
333 tk 960
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
2538 tk 961
  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 962
 
167 tk 963
  ///////////////////////////////////////////////////////////////////////////
278 tk 964
  SEQ_LCD_CursorSet(0, 0);
167 tk 965
 
326 tk 966
  SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks);
967
  SEQ_LCD_PrintSpaces(1);
968
 
1349 tk 969
 
2166 tk 970
  u8 print_instrument = 0;
1350 tk 971
  if( ui_page == SEQ_UI_PAGE_EDIT && edit_passive_mode == 2 ) {
2166 tk 972
    if( !ui_cursor_flash ) {
1350 tk 973
      SEQ_LCD_PrintString("PASSIVE EDITING");
974
    }
2050 tk 975
  } else if( seq_record_state.ENABLED || edit_mode == SEQ_UI_EDIT_MODE_RECORD || midi_learn_mode == MIDI_LEARN_MODE_ON ) {
2166 tk 976
    if( !ui_cursor_flash ) {
2050 tk 977
      if( midi_learn_mode == MIDI_LEARN_MODE_ON ) {
978
    SEQ_LCD_PrintString("EDIT RECORDING ");
979
      } else if( seq_record_options.STEP_RECORD ) {
980
    SEQ_LCD_PrintString("STEP RECORDING ");
981
      } else {
982
    SEQ_LCD_PrintString("LIVE RECORDING ");
983
      }
1349 tk 984
    }
985
  } else {
986
    switch( edit_mode ) {
240 tk 987
    case SEQ_UI_EDIT_MODE_COPY: {
2166 tk 988
      if( !ui_cursor_flash ) {
240 tk 989
    char str_buffer[10];
990
    sprintf(str_buffer, "%d-%d", SEQ_UI_UTIL_CopyPasteBeginGet()+1, SEQ_UI_UTIL_CopyPasteEndGet()+1);
278 tk 991
    SEQ_LCD_PrintFormattedString("COPY S%-9s", str_buffer);
240 tk 992
      }
993
    } break;
167 tk 994
 
240 tk 995
    case SEQ_UI_EDIT_MODE_PASTE: {
2166 tk 996
      if( !ui_cursor_flash ) {
278 tk 997
    SEQ_LCD_PrintFormattedString("PASTE OFFS.%3d ", ui_selected_step+1);
240 tk 998
      }
999
    } break;
167 tk 1000
 
240 tk 1001
    case SEQ_UI_EDIT_MODE_MOVE: {
2166 tk 1002
      if( !ui_cursor_flash ) {
278 tk 1003
    SEQ_LCD_PrintString("MOVE STEPS     ");
240 tk 1004
      }
1005
    } break;
176 tk 1006
 
240 tk 1007
    case SEQ_UI_EDIT_MODE_SCROLL: {
2166 tk 1008
      if( !ui_cursor_flash ) {
278 tk 1009
    SEQ_LCD_PrintString("SCROLL TRACK   ");
240 tk 1010
      }
1011
    } break;
176 tk 1012
 
240 tk 1013
    case SEQ_UI_EDIT_MODE_RANDOM: {
2166 tk 1014
      if( !ui_cursor_flash ) {
278 tk 1015
    SEQ_LCD_PrintString("RANDOMIZED     ");
240 tk 1016
      }
1017
    } break;
176 tk 1018
 
600 tk 1019
    case SEQ_UI_EDIT_MODE_MANUAL: {
2166 tk 1020
      if( !ui_cursor_flash ) {
600 tk 1021
    SEQ_LCD_PrintString("MANUAL TRIGGER ");
1022
      }
1023
    } break;
1024
 
240 tk 1025
    default: {
2533 tk 1026
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
1027
    if( edit_ramp ) {
1028
      SEQ_LCD_PrintString("VALUE RAMP     ");
1029
    } else {
1030
      SEQ_LCD_PrintString("ALL VALUES     ");
1031
    }
1032
      } else if( seq_ui_button_state.CHANGE_ALL_STEPS ) {
1033
    SEQ_LCD_PrintString("RELATIVE VALUES");
1034
      } else {
1035
    print_instrument = 1;
1036
      }
326 tk 1037
    }
1349 tk 1038
    }
326 tk 1039
  }
176 tk 1040
 
2166 tk 1041
  if( print_instrument || ui_cursor_flash ) {
1042
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
1043
      SEQ_LCD_PrintChar(' ');
1044
      SEQ_LCD_PrintChar(' ');
1045
      SEQ_LCD_PrintMIDIOutPort(SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT));
1046
      SEQ_LCD_PrintChar(' ');
1047
      SEQ_LCD_PrintFormattedString("Chn.%2d  ", SEQ_CC_Get(visible_track, SEQ_CC_MIDI_CHANNEL)+1);
1048
    } else {
1049
      SEQ_LCD_PrintTrackLabel(visible_track, (char *)seq_core_trk[visible_track].name);
1050
    }
1051
  }
1052
 
326 tk 1053
  SEQ_LCD_PrintSpaces(2);
176 tk 1054
 
326 tk 1055
  SEQ_LCD_PrintChar('P');
1056
  SEQ_LCD_PrintChar('A' + ui_selected_par_layer);
1057
  SEQ_LCD_PrintChar(':');
240 tk 1058
 
2294 tk 1059
  {
1060
    char str_buffer[6];
2551 tk 1061
    SEQ_PAR_AssignedTypeStr(visible_track, ui_selected_par_layer, ui_selected_instrument, str_buffer);
2294 tk 1062
    SEQ_LCD_PrintString(str_buffer);
333 tk 1063
    SEQ_LCD_PrintSpaces(2);
176 tk 1064
  }
167 tk 1065
 
328 tk 1066
  SEQ_LCD_PrintFormattedString("T%c:%s", 'A' + ui_selected_trg_layer, SEQ_TRG_AssignedTypeStr(visible_track, ui_selected_trg_layer));
327 tk 1067
 
1068
 
167 tk 1069
  ///////////////////////////////////////////////////////////////////////////
278 tk 1070
  SEQ_LCD_CursorSet(40, 0);
167 tk 1071
 
1316 tk 1072
  SEQ_LCD_PrintFormattedString("Step%3d ", ui_selected_step+1);
167 tk 1073
 
1316 tk 1074
  if( layer_event.midi_package.event == CC ) {
1075
    mios32_midi_port_t port = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT);
1076
    u8 loopback = port == 0xf0;
741 tk 1077
 
1316 tk 1078
    if( loopback )
1079
      SEQ_LCD_PrintString((char *)SEQ_CC_LABELS_Get(port, layer_event.midi_package.cc_number));
1811 tk 1080
    else {
1081
      if( layer_event.midi_package.cc_number >= 0x80 ) {
1082
    SEQ_LCD_PrintFormattedString("  CC#off");
1083
      } else {
1084
    SEQ_LCD_PrintFormattedString("  CC#%3d", layer_event.midi_package.cc_number);
1085
      }
1086
    }
1351 tk 1087
    SEQ_LCD_PrintFormattedString(" %3d ", layer_event.midi_package.value);
1088
    SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
1316 tk 1089
  } else {
1090
    SEQ_LCD_PrintSpaces(2);
741 tk 1091
 
1316 tk 1092
    if( layer_event.midi_package.note && layer_event.midi_package.velocity && (layer_event.len >= 0) ) {
1093
      if( SEQ_CC_Get(visible_track, SEQ_CC_MODE) == SEQ_CORE_TRKMODE_Arpeggiator ) {
1350 tk 1094
    u8 par_value = PassiveEditValid() ? edit_passive_value : layer_event.midi_package.note;
1095
    SEQ_LCD_PrintArp(par_value);
2538 tk 1096
      } else if( layer_type == SEQ_PAR_Type_Chord1 || layer_type == SEQ_PAR_Type_Chord2 || layer_type == SEQ_PAR_Type_Chord3 ||
1097
         (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)) ) {
1098
    u8 par_value;
1099
    u8 chord_set;
1350 tk 1100
 
2538 tk 1101
    if( layer_type != SEQ_PAR_Type_Velocity ) {
1102
      par_value = PassiveEditValid()
1103
        ? edit_passive_value
1104
        : SEQ_PAR_Get(visible_track, ui_selected_step, ui_selected_par_layer, ui_selected_instrument);
2505 tk 1105
 
2538 tk 1106
      chord_set = (layer_type == SEQ_PAR_Type_Chord2) ? 1 : ((layer_type == SEQ_PAR_Type_Chord3) ? 2 : 0);
1107
    } else {
1108
      par_value = PassiveEditValid()
1109
        ? edit_passive_value
1110
        : SEQ_PAR_Get(visible_track, ui_selected_step, 0, ui_selected_instrument);
1111
 
1112
      chord_set = (master_layer_type == SEQ_PAR_Type_Chord2) ? 1 : ((master_layer_type == SEQ_PAR_Type_Chord3) ? 2 : 0);
1113
    }
1114
 
2505 tk 1115
    if( layer_type == SEQ_PAR_Type_Chord3 ) {
1116
      SEQ_LCD_PrintString(SEQ_CHORD_NameGet(chord_set, par_value));
1117
      SEQ_LCD_PrintSpaces(2);
1118
    } else {
1119
      u8 chord_ix = par_value & 0x1f;
1120
      u8 chord_oct = par_value >> 5;
1121
      SEQ_LCD_PrintString(SEQ_CHORD_NameGet(chord_set, chord_ix));
1122
      SEQ_LCD_PrintFormattedString("/%d", chord_oct);
1123
    }
1316 tk 1124
      } else {
1350 tk 1125
    u8 par_value = PassiveEditValid() ? edit_passive_value : layer_event.midi_package.note;
1126
    SEQ_LCD_PrintNote(par_value);
288 tk 1127
      }
1351 tk 1128
      SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
176 tk 1129
    }
1316 tk 1130
    else {
1131
      SEQ_LCD_PrintString("....");
1132
    }
1133
    SEQ_LCD_PrintFormattedString(" Vel:%3d", layer_event.midi_package.velocity);
176 tk 1134
  }
167 tk 1135
 
1316 tk 1136
  SEQ_LCD_PrintString(" Len:");
1137
  SEQ_LCD_PrintGatelength(layer_event.len);
167 tk 1138
 
1316 tk 1139
 
740 tk 1140
  // print flashing *LOOPED* at right corner if loop mode activated to remind that steps will be played differntly
1141
  if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_state.LOOP ) {
1142
    SEQ_LCD_PrintString(" *LOOPED*");
828 tk 1143
  } else if( (ui_cursor_flash_overrun_ctr & 1) && seq_core_trk[visible_track].play_section > 0 ) {
1144
    SEQ_LCD_PrintFormattedString(" *Sect.%c*", 'A'+seq_core_trk[visible_track].play_section);
326 tk 1145
  } else {
740 tk 1146
    SEQ_LCD_PrintSpaces(4);
1147
    if( event_mode == SEQ_EVENT_MODE_Drum ) {
1148
      SEQ_LCD_PrintTrackDrum(visible_track, ui_selected_instrument, (char *)seq_core_trk[visible_track].name);
1149
    } else {
1150
      SEQ_LCD_PrintTrackCategory(visible_track, (char *)seq_core_trk[visible_track].name);
1151
    }
180 tk 1152
  }
167 tk 1153
 
1154
  ///////////////////////////////////////////////////////////////////////////
1211 tk 1155
  // Second Line
1156
  ///////////////////////////////////////////////////////////////////////////
167 tk 1157
 
2553 tk 1158
  u8 show_drum_triggers = (event_mode == SEQ_EVENT_MODE_Drum) && (seq_ui_edit_view != SEQ_UI_EDIT_VIEW_303);
2101 tk 1159
  if( show_drum_triggers && !(edit_mode || !ui_hold_msg_ctr) ) {
1160
    if( ui_hold_msg_ctr ) {
1161
      // e.g. during recording: show drum triggers for layers which can't be recorded
1162
      show_drum_triggers =
2106 tk 1163
    !ui_hold_msg_ctr_drum_edit &&
2101 tk 1164
    layer_type != SEQ_PAR_Type_Note &&
2274 tk 1165
    layer_type != SEQ_PAR_Type_Chord1 &&
1166
    layer_type != SEQ_PAR_Type_Chord2 &&
2505 tk 1167
    layer_type != SEQ_PAR_Type_Chord3 &&
2553 tk 1168
    layer_type != SEQ_PAR_Type_Velocity;
2101 tk 1169
    }
1170
  }
335 tk 1171
 
176 tk 1172
  // extra handling for gatelength (shows vertical bars)
335 tk 1173
  if( !show_drum_triggers && layer_type == SEQ_PAR_Type_Length ) {
167 tk 1174
 
176 tk 1175
    // we want to show horizontal bars
1176
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
167 tk 1177
 
176 tk 1178
    // initial cursor position
278 tk 1179
    SEQ_LCD_CursorSet(0, 1);
167 tk 1180
 
176 tk 1181
    // determine length of previous step (depends on selected view and track length)
1182
    int previous_step = 16*ui_selected_step_view - 1;
1183
    if( previous_step < 0 )
1184
      previous_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1185
 
1186
    seq_layer_evnt_t layer_event;
336 tk 1187
    SEQ_LAYER_GetEvntOfLayer(visible_track, previous_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
176 tk 1188
    u16 previous_length = layer_event.len;
330 tk 1189
 
1190
    // show length of 16 steps
336 tk 1191
    u16 step;
330 tk 1192
    for(step=0; step<16; ++step) {
336 tk 1193
      u16 visible_step = step + 16*ui_selected_step_view;
1194
      SEQ_LAYER_GetEvntOfLayer(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, &layer_event);
330 tk 1195
 
1143 tk 1196
      u8 gate = SEQ_TRG_GateGet(visible_track, visible_step, ui_selected_instrument);
1197
 
338 tk 1198
      // muted step? if previous gatelength <= 96, print spaces
1143 tk 1199
      if( (!gate || !layer_event.midi_package.velocity) && previous_length < 96 ) {
338 tk 1200
    SEQ_LCD_PrintSpaces(5);
1201
      } else {
1202
    if( layer_event.len >= 96 )
1203
      SEQ_LCD_PrintHBar(15); // glide or stretched event
2159 tk 1204
    else {
1205
      //SEQ_LCD_PrintHBar(((layer_event.len-1)*16)/100);
1206
      SEQ_LCD_PrintHBar(((layer_event.len-1)*16)/110); // so that we see a difference if note not stretched
1207
    }
330 tk 1208
      }
1143 tk 1209
      previous_length = ((gate && layer_event.midi_package.velocity) || (previous_length >= 96 && layer_event.len >= 96)) ? layer_event.len : 0;
330 tk 1210
    }
1211
 
176 tk 1212
  } else {
1213
 
335 tk 1214
    if( show_drum_triggers ) {
323 tk 1215
      // we want to show triggers
325 tk 1216
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_DrumSymbolsBig);
323 tk 1217
    } else {
1218
      // we want to show vertical bars
1219
      SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
1220
    }
176 tk 1221
 
1222
    // initial cursor position
278 tk 1223
    SEQ_LCD_CursorSet(0, 1);
176 tk 1224
 
323 tk 1225
    int step_region_begin;
1226
    int step_region_end;
240 tk 1227
    switch( edit_mode ) {
1228
      case SEQ_UI_EDIT_MODE_COPY:
1229
    step_region_begin = SEQ_UI_UTIL_CopyPasteBeginGet();
1230
    step_region_end = SEQ_UI_UTIL_CopyPasteEndGet();
1231
    break;
1232
      case SEQ_UI_EDIT_MODE_PASTE:
1233
    step_region_begin = ui_selected_step;
1234
    step_region_end = ui_selected_step + SEQ_UI_UTIL_CopyPasteEndGet() - SEQ_UI_UTIL_CopyPasteBeginGet();
1235
    break;
1236
      case SEQ_UI_EDIT_MODE_SCROLL:
1237
    step_region_begin = ui_selected_step;
1238
    step_region_end = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
1239
    break;
1240
      default:
336 tk 1241
    step_region_begin = ui_selected_step;
1242
    step_region_end = ui_selected_step;
240 tk 1243
    }
1244
 
336 tk 1245
    u16 step;
176 tk 1246
    for(step=0; step<16; ++step) {
336 tk 1247
      u16 visible_step = step + 16*ui_selected_step_view;
240 tk 1248
 
1249
      if( ui_cursor_flash &&
1250
      edit_mode != SEQ_UI_EDIT_MODE_NORMAL &&
1251
      visible_step >= step_region_begin && visible_step <= step_region_end ) {
1252
    SEQ_LCD_PrintSpaces(5);
1253
    continue;
1254
      }
1255
 
335 tk 1256
      if( show_drum_triggers ) {
336 tk 1257
    u8 gate_accent = SEQ_TRG_Get(visible_track, visible_step, 0, ui_selected_instrument);
328 tk 1258
    if( SEQ_TRG_NumLayersGet(visible_track) >= 2 )
336 tk 1259
      gate_accent |= SEQ_TRG_Get(visible_track, visible_step, 1, ui_selected_instrument) << 1;
335 tk 1260
 
323 tk 1261
    SEQ_LCD_PrintChar(' ');
1262
    SEQ_LCD_PrintChar(' ');
327 tk 1263
    SEQ_LCD_PrintChar(gate_accent);
323 tk 1264
    SEQ_LCD_PrintChar(' ');
1265
      } else {
1351 tk 1266
    int print_edit_value = (visible_step == edit_passive_step && PassiveEditValid()) ? edit_passive_value : -1;
1267
    SEQ_LCD_PrintLayerEvent(visible_track, visible_step, ui_selected_par_layer, ui_selected_instrument, 1, print_edit_value);
176 tk 1268
      }
1269
 
2101 tk 1270
      {
2049 tk 1271
    u8 midi_learn = seq_record_state.ENABLED || midi_learn_mode == MIDI_LEARN_MODE_ON;
1272
    char lbr = midi_learn ? '}' : '<';
1273
    char rbr = midi_learn ? '{' : '>';
2047 tk 1274
 
1275
    SEQ_LCD_PrintChar((visible_step == step_region_end) ? lbr
1276
              : ((visible_step == (step_region_begin-1)) ? rbr : ' '));
323 tk 1277
      }
240 tk 1278
 
176 tk 1279
    }
167 tk 1280
  }
1281
 
1282
  return 0; // no error
1283
}
1284
 
1285
 
1286
/////////////////////////////////////////////////////////////////////////////
240 tk 1287
// Local Display Handler function
1288
// IN: <high_prio>: if set, a high-priority LCD update is requested
1289
/////////////////////////////////////////////////////////////////////////////
1290
static s32 LCD_Handler(u8 high_prio)
1291
{
1292
  return SEQ_UI_EDIT_LCD_Handler(high_prio, SEQ_UI_EDIT_MODE_NORMAL);
1293
}
1294
 
1295
 
1296
/////////////////////////////////////////////////////////////////////////////
2047 tk 1297
// MIDI IN
1298
/////////////////////////////////////////////////////////////////////////////
1299
static s32 MIDI_IN_Handler(mios32_midi_port_t port, mios32_midi_package_t p)
1300
{
1301
  if( midi_learn_mode == MIDI_LEARN_MODE_ON ) {
2048 tk 1302
    u8 visible_track = SEQ_UI_VisibleTrackGet();
1303
 
2047 tk 1304
    // quick & dirty for evaluation purposes
1305
    seq_record_options_t prev_seq_record_options = seq_record_options;
2168 tk 1306
    u8 reset_timestamps = p.type == NoteOn && p.velocity > 0;
2563 tk 1307
    midi_learn_mode_used = 1;
2047 tk 1308
 
1309
    seq_record_options.ALL = 0;
1310
    seq_record_options.STEP_RECORD = 1;
1311
    seq_record_options.FWD_MIDI = prev_seq_record_options.FWD_MIDI;
1312
 
2168 tk 1313
    SEQ_RECORD_Enable(1, reset_timestamps);
2047 tk 1314
 
2048 tk 1315
    SEQ_RECORD_Receive(p, visible_track);
2047 tk 1316
 
2048 tk 1317
    if( seq_ui_button_state.CHANGE_ALL_STEPS ) {
1318
      // copy matching par layers into remaining steps
1319
      u16 num_steps = SEQ_TRG_NumStepsGet(visible_track);
1320
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
1321
 
1322
      seq_cc_trk_t *tcc = &seq_cc_trk[visible_track];
1323
      seq_par_layer_type_t rec_layer_type = tcc->lay_const[ui_selected_par_layer];
1324
 
1325
      {
1326
    u8 p_layer;
1327
    for(p_layer=0; p_layer<num_p_layers; ++p_layer) {
1328
      seq_par_layer_type_t layer_type = tcc->lay_const[p_layer];
1329
 
1330
      if( layer_type == rec_layer_type ||
2505 tk 1331
          ((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 1332
        u8 value = SEQ_PAR_Get(visible_track, ui_selected_step, p_layer, ui_selected_instrument);
2048 tk 1333
 
1334
        u16 step;
1335
        for(step=0; step<num_steps; ++step) {
2166 tk 1336
          if( step != ui_selected_step && (selected_steps & (1 << (step % 16))) ) {
2048 tk 1337
        SEQ_PAR_Set(visible_track, step, p_layer, ui_selected_instrument, value);
1338
          }
1339
        }
1340
      }
1341
    }
1342
      }
1343
    }
1344
 
2047 tk 1345
    seq_record_options.ALL = prev_seq_record_options.ALL;
2168 tk 1346
    SEQ_RECORD_Enable(0, 0);
2047 tk 1347
 
2106 tk 1348
    ui_hold_msg_ctr_drum_edit = 0;
1349
 
2047 tk 1350
    seq_ui_display_update_req = 1;
2166 tk 1351
 
1352
    return 1; // don't continue recording/live forwarding processing
2047 tk 1353
  }
1354
 
1355
  return 0;
1356
}
1357
 
1358
 
1359
/////////////////////////////////////////////////////////////////////////////
2101 tk 1360
// Stores config file if required
1361
/////////////////////////////////////////////////////////////////////////////
1362
static s32 CheckStoreFile(void)
1363
{
2102 tk 1364
  if( ui_store_file_required ) {
2101 tk 1365
    // write config file
1366
    MUTEX_SDCARD_TAKE;
1367
    s32 status;
1368
    if( (status=SEQ_FILE_GC_Write()) < 0 )
1369
      SEQ_UI_SDCardErrMsg(2000, status);
1370
    MUTEX_SDCARD_GIVE;
1371
 
2102 tk 1372
    ui_store_file_required = 0;
2101 tk 1373
  }
1374
 
1375
  return 0; // no error
1376
}
1377
 
1378
 
1379
/////////////////////////////////////////////////////////////////////////////
2050 tk 1380
// Exit
1381
/////////////////////////////////////////////////////////////////////////////
1382
static s32 EXIT_Handler(void)
1383
{
1384
  midi_learn_mode = MIDI_LEARN_MODE_OFF;
2101 tk 1385
 
1386
  CheckStoreFile();
1387
 
2050 tk 1388
  return 0;
1389
}
1390
 
1391
/////////////////////////////////////////////////////////////////////////////
167 tk 1392
// Initialisation
1393
/////////////////////////////////////////////////////////////////////////////
1394
s32 SEQ_UI_EDIT_Init(u32 mode)
1395
{
1396
  // install callback routines
758 tk 1397
  SEQ_UI_InstallButtonCallback(SEQ_UI_EDIT_Button_Handler);
168 tk 1398
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
240 tk 1399
  SEQ_UI_InstallLEDCallback(SEQ_UI_EDIT_LED_Handler);
168 tk 1400
  SEQ_UI_InstallLCDCallback(LCD_Handler);
2047 tk 1401
  SEQ_UI_InstallMIDIINCallback(MIDI_IN_Handler);
2050 tk 1402
  SEQ_UI_InstallExitCallback(EXIT_Handler);
167 tk 1403
 
2047 tk 1404
  // disable MIDI learn mode by default
1405
  midi_learn_mode = MIDI_LEARN_MODE_OFF;
1406
 
2106 tk 1407
  ui_hold_msg_ctr_drum_edit = 0;
1408
 
1350 tk 1409
  edit_passive_mode = 0;
2533 tk 1410
  edit_ramp = 0;
729 tk 1411
 
1142 tk 1412
  if( seq_ui_edit_view == SEQ_UI_EDIT_VIEW_STEPSEL )
1413
    seq_ui_edit_view = SEQ_UI_EDIT_VIEW_STEPS;
1414
 
167 tk 1415
  return 0; // no error
1416
}
178 tk 1417
 
1418
 
1419
 
1420
/////////////////////////////////////////////////////////////////////////////
1421
// help function to change/set a single encoder value
1422
// if forced_value >= 0: new value will be set to the given value
1423
// if forced_value < 0: new value will be changed via incrementer
1424
// returns >= 0 if new value has been set (value change)
1425
// returns < 0 if no change
1426
/////////////////////////////////////////////////////////////////////////////
1052 tk 1427
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 1428
{
333 tk 1429
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(track, ui_selected_par_layer);
335 tk 1430
  u8 visible_track = SEQ_UI_VisibleTrackGet();
178 tk 1431
 
828 tk 1432
#if 0
1433
  // disabled in MBSEQ V4.0beta15 due to issue reported by Gridracer:
1434
  // http://midibox.org/forums/index.php?/topic/13137-midibox-seq-v4-beta-release-feedback/page__st__100
1435
 
333 tk 1436
  // if note/chord/velocity parameter: only change gate if requested
2505 tk 1437
  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 1438
      !change_gate &&
652 tk 1439
      !SEQ_TRG_GateGet(track, trg_step, ui_selected_instrument) )
178 tk 1440
    return -1;
828 tk 1441
#endif
178 tk 1442
 
1052 tk 1443
  if( layer_type == SEQ_PAR_Type_Probability ) {
1444
    // due to another issue reported by Gridracer:
1445
    // invert incrementer so that clockwise move increases probability
1446
    incrementer = -incrementer;
1447
  }
1448
 
1449
 
335 tk 1450
  u8 event_mode = SEQ_CC_Get(visible_track, SEQ_CC_MIDI_EVENT_MODE);
652 tk 1451
  if( event_mode == SEQ_EVENT_MODE_Drum ) {
335 tk 1452
    ui_hold_msg_ctr = 1000; // show value for 1 second
2106 tk 1453
    ui_hold_msg_ctr_drum_edit = 1;
1454
  } else {
1455
    ui_hold_msg_ctr_drum_edit = 0;
652 tk 1456
  }
335 tk 1457
 
652 tk 1458
  s32 old_value = SEQ_PAR_Get(track, par_step, ui_selected_par_layer, ui_selected_instrument);
178 tk 1459
  s32 new_value = (forced_value >= 0) ? forced_value : (old_value + incrementer);
1460
  if( new_value < 0 )
1461
    new_value = 0;
2448 tk 1462
  else {
1463
    // limit depending on max value
2435 tk 1464
    seq_par_layer_type_t par_layer_type = SEQ_PAR_AssignmentGet(track, ui_selected_par_layer);
2448 tk 1465
    u8 max = SEQ_PAR_MaxValueGet(par_layer_type);
2435 tk 1466
 
2448 tk 1467
    if( new_value >= max ) {
1468
      new_value = max;
2435 tk 1469
    }
1470
  }
178 tk 1471
 
1143 tk 1472
  // extra for more comfortable editing of multi-note tracks:
1473
  // if assigned parameter layer is Note or Chord, and currently 0, re-start at C-3 resp. A/2
1474
  // when value is incremented
2505 tk 1475
  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 1476
    new_value = (layer_type == SEQ_PAR_Type_Note && SEQ_CC_Get(track, SEQ_CC_MODE) != SEQ_CORE_TRKMODE_Arpeggiator) ? 0x3c : 0x40;
1477
 
1345 tk 1478
  if( !dont_change_gate ) {
1479
    u8 event_mode = SEQ_CC_Get(track, SEQ_CC_MIDI_EVENT_MODE);
1480
 
1481
    // we do this always regardless if value has been changed or not (e.g. increment if value already 127)
1482
    if( event_mode == SEQ_EVENT_MODE_CC && layer_type == SEQ_PAR_Type_CC ) {
1483
      // in this mode gates are used to disable CC
1484
      // if a CC value has been changed, set gate
1485
      SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
1486
    }
1487
  }
1488
 
178 tk 1489
  // take over if changed
1490
  if( new_value == old_value )
1491
    return -1;
1492
 
652 tk 1493
  SEQ_PAR_Set(track, par_step, ui_selected_par_layer, ui_selected_instrument, (u8)new_value);
178 tk 1494
 
747 tk 1495
  if( !dont_change_gate &&
2505 tk 1496
      (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 1497
    // (de)activate gate depending on value
1498
    if( new_value )
652 tk 1499
      SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 1);
1053 tk 1500
    else {
1501
      // due to another issue reported by Gridracer:
1502
      // if the track plays multiple notes, only clear gate if all notes are 0
1142 tk 1503
      u8 num_p_layers = SEQ_PAR_NumLayersGet(visible_track);
1053 tk 1504
      u8 allNotesZero = 1;
1505
      int i;
1142 tk 1506
      for(i=0; i<num_p_layers; ++i) {
1053 tk 1507
    seq_par_layer_type_t localLayerType = SEQ_PAR_AssignmentGet(track, i);
2505 tk 1508
    if( (localLayerType == SEQ_PAR_Type_Note || localLayerType == SEQ_PAR_Type_Chord1 || localLayerType == SEQ_PAR_Type_Chord2 || localLayerType == SEQ_PAR_Type_Chord3) &&
1053 tk 1509
        SEQ_PAR_Get(track, par_step, i, ui_selected_instrument) > 0 ) {
1510
      allNotesZero = 0;
1511
      break;
1512
    }
1513
      }
1514
 
1515
      if( allNotesZero )
1516
    SEQ_TRG_GateSet(track, trg_step, ui_selected_instrument, 0);
1517
    }
178 tk 1518
  }
1519
 
1520
  return new_value;
1521
}
1350 tk 1522
 
1523
 
1524
/////////////////////////////////////////////////////////////////////////////
1525
// help functions for "passive edit mode"
1526
/////////////////////////////////////////////////////////////////////////////
1527
static s32 PassiveEditEnter(void)
1528
{
1529
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1351 tk 1530
  seq_par_layer_type_t layer_type = SEQ_PAR_AssignmentGet(visible_track, ui_selected_par_layer);
1350 tk 1531
 
1351 tk 1532
  // passive edit mode currently only supported for notes/chords
1350 tk 1533
 
2505 tk 1534
  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 1535
    // enter passive edit mode and store track/step/layer/instrument for later checks
1536
    edit_passive_mode = 1;
1537
    edit_passive_track = visible_track;
1538
    edit_passive_step = ui_selected_step;
1539
    edit_passive_par_layer = ui_selected_par_layer;
1540
    edit_passive_instrument = ui_selected_instrument;
1541
    edit_passive_value = SEQ_PAR_Get(edit_passive_track, edit_passive_step, edit_passive_par_layer, edit_passive_instrument);
1542
  } else {
1543
    edit_passive_mode = 0;
1544
  }
1545
 
1350 tk 1546
  return 0; // no error
1547
}
1548
 
1549
static s32 PassiveEditValid(void)
1550
{
1551
  u8 visible_track = SEQ_UI_VisibleTrackGet();
1552
 
1553
  return (edit_passive_mode == 2 && // if mode is 2, the value has been changed!
1554
      edit_passive_track == visible_track &&
1555
      edit_passive_step == ui_selected_step &&
1556
      edit_passive_par_layer == ui_selected_par_layer &&
1557
      edit_passive_instrument == ui_selected_instrument) ? 1 : 0;
1558
}
1559
 
1560
static s32 PassiveEditTakeOver(void)
1561
{
1562
 
1563
  // only take over changed value if track/step/layer/instrument still passing
1564
  if( PassiveEditValid() ) {
1565
    // take over change
1566
    // handle it like a single increment/decrement so that no code needs to be duplicated
1567
    int current_value = SEQ_PAR_Get(edit_passive_track, edit_passive_step, edit_passive_par_layer, edit_passive_instrument);
1568
    int incrementer = (int)edit_passive_value - current_value;
1569
 
2048 tk 1570
    seq_ui_button_state.EDIT_PRESSED = 0; // just to avoid any overlay...
1350 tk 1571
    edit_passive_mode = 0; // to avoid recursion in encoder handler
1572
    Encoder_Handler(edit_passive_step % 16, incrementer);
1573
  } else {
1574
    edit_passive_mode = 1;
1575
  }
1576
 
1577
  return 0; // no error
1578
}