Subversion Repositories svn.mios32

Rev

Rev 178 | Rev 182 | 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 180 2008-12-13 21:00:14Z tk $
2
/*
3
 * Edit page
4
 *
5
 * ==========================================================================
6
 *
7
 *  Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
8
 *  Licensed for personal non-commercial use only.
9
 *  All other rights reserved.
10
 *
11
 * ==========================================================================
12
 */
13
 
14
/////////////////////////////////////////////////////////////////////////////
15
// Include files
16
/////////////////////////////////////////////////////////////////////////////
17
 
18
#include <mios32.h>
19
#include "seq_lcd.h"
20
#include "seq_ui.h"
21
 
22
#include "seq_midi.h"
23
#include "seq_bpm.h"
24
#include "seq_core.h"
168 tk 25
#include "seq_cc.h"
176 tk 26
#include "seq_layer.h"
167 tk 27
#include "seq_par.h"
28
#include "seq_trg.h"
29
 
30
 
31
/////////////////////////////////////////////////////////////////////////////
178 tk 32
// Local prototypes
33
/////////////////////////////////////////////////////////////////////////////
34
 
35
static s32 ChangeSingleEncValue(u8 track, u8 step, s32 incrementer, s32 forced_value, u8 change_gate);
36
 
37
 
38
/////////////////////////////////////////////////////////////////////////////
168 tk 39
// Local LED handler function
167 tk 40
/////////////////////////////////////////////////////////////////////////////
173 tk 41
static s32 LED_Handler(u16 *gp_leds)
167 tk 42
{
43
  u8 visible_track = SEQ_UI_VisibleTrackGet();
44
 
45
  *gp_leds =
46
    (trg_layer_value[visible_track][ui_selected_trg_layer][2*ui_selected_step_view+1] << 8) |
47
    trg_layer_value[visible_track][ui_selected_trg_layer][2*ui_selected_step_view+0];
48
 
49
  return 0; // no error
50
}
51
 
52
 
53
/////////////////////////////////////////////////////////////////////////////
168 tk 54
// Local encoder callback function
55
// Should return:
56
//   1 if value has been changed
57
//   0 if value hasn't been changed
58
//  -1 if invalid or unsupported encoder
167 tk 59
/////////////////////////////////////////////////////////////////////////////
168 tk 60
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
167 tk 61
{
168 tk 62
#if 0
63
  // leads to: comparison is always true due to limited range of data type
64
  if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) || encoder == SEQ_UI_ENCODER_Datawheel ) {
65
#else
66
  if( encoder <= SEQ_UI_ENCODER_GP16 || encoder == SEQ_UI_ENCODER_Datawheel ) {
67
#endif
178 tk 68
    ui_selected_step = ((encoder == SEQ_UI_ENCODER_Datawheel) ? (ui_selected_step%16) : encoder) + ui_selected_step_view*16;
167 tk 69
 
178 tk 70
    s32 value_changed = 0;
71
    s32 forced_value = -1;
72
    u8  change_gate = 1;
168 tk 73
 
178 tk 74
    // first change the selected value
75
    if( seq_ui_button_state.CHANGE_ALL_STEPS && seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
76
      forced_value = ChangeSingleEncValue(SEQ_UI_VisibleTrackGet(), ui_selected_step, incrementer, forced_value, change_gate);
77
      if( forced_value < 0 )
78
    return 0; // no change
79
      value_changed |= 1;
168 tk 80
    }
81
 
178 tk 82
    // change value of all selected steps
83
    u8 track;
84
    u8 step;
85
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
86
      if( SEQ_UI_IsSelectedTrack(track) ) {
87
    for(step=0; step<SEQ_CORE_NUM_STEPS; ++step) {
88
      change_gate = step == ui_selected_step;
89
      if( change_gate || seq_ui_button_state.CHANGE_ALL_STEPS ) {
90
        if( ChangeSingleEncValue(track, step, incrementer, forced_value, change_gate) >= 0 )
91
          value_changed |= 1;
92
      }
93
    }
94
      }
176 tk 95
    }
168 tk 96
 
178 tk 97
    return value_changed;
168 tk 98
  }
99
 
100
  return -1; // invalid or unsupported encoder
167 tk 101
}
102
 
103
 
104
/////////////////////////////////////////////////////////////////////////////
168 tk 105
// Local button callback function
106
// Should return:
107
//   1 if value has been changed
108
//   0 if value hasn't been changed
109
//  -1 if invalid or unsupported button
167 tk 110
/////////////////////////////////////////////////////////////////////////////
168 tk 111
static s32 Button_Handler(seq_ui_button_t button, s32 depressed)
167 tk 112
{
168 tk 113
  if( depressed ) return 0; // ignore when button depressed
167 tk 114
 
168 tk 115
#if 0
116
  // leads to: comparison is always true due to limited range of data type
117
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
118
#else
119
  if( button <= SEQ_UI_BUTTON_GP16 ) {
120
#endif
180 tk 121
    ui_selected_step = button + ui_selected_step_view*16;
168 tk 122
    // toggle trigger layer
178 tk 123
    // we've three cases:
124
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
125
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
126
    // c) ALL function not active: toggle step
127
    if( seq_ui_button_state.CHANGE_ALL_STEPS ) {
128
      if( seq_ui_button_state.CHANGE_ALL_STEPS_SAME_VALUE ) {
129
    // b) ALL function active and ALL button pressed: toggle step, set remaining steps to same new value
130
    u8 visible_track = SEQ_UI_VisibleTrackGet();
180 tk 131
    u8 step = ui_selected_step;
178 tk 132
    u8 new_value = SEQ_TRG_Get(visible_track, step, ui_selected_trg_layer) ? 0 : 1;
133
 
134
    u8 track;
135
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track)
136
      if( SEQ_UI_IsSelectedTrack(track) )
137
        for(step=0; step<SEQ_CORE_NUM_STEPS; ++step)
138
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, new_value);
139
      } else {
140
    // a) ALL function active, but ALL button not pressed: invert complete trigger layer
141
    u8 track, step;
142
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
143
      if( SEQ_UI_IsSelectedTrack(track) ) {
144
        for(step=0; step<SEQ_CORE_NUM_STEPS; ++step) {
145
          u8 new_value = SEQ_TRG_Get(track, step, ui_selected_trg_layer) ? 0 : 1;
146
          SEQ_TRG_Set(track, step, ui_selected_trg_layer, new_value);
147
        }
148
      }
149
    }
150
      }
151
    } else {
152
      // c) ALL function not active: toggle step
153
      u8 track;
154
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
155
    if( SEQ_UI_IsSelectedTrack(track) ) {
180 tk 156
      u8 new_value = SEQ_TRG_Get(track, ui_selected_step, ui_selected_trg_layer) ? 0 : 1;
157
      SEQ_TRG_Set(track, ui_selected_step, ui_selected_trg_layer, new_value);
178 tk 158
    }
159
      }
160
    }
168 tk 161
    return 1; // value always changed
178 tk 162
 
168 tk 163
  } else {
164
    switch( button ) {
165
      case SEQ_UI_BUTTON_Select:
166
      case SEQ_UI_BUTTON_Right:
167
    if( ++ui_selected_step >= SEQ_CORE_NUM_STEPS )
168
      ui_selected_step = 0;
169
    ui_selected_step_view = ui_selected_step / 16;
170
    return 1; // value always changed
167 tk 171
 
168 tk 172
      case SEQ_UI_BUTTON_Left:
173
    if( ui_selected_step == 0 )
174
      ui_selected_step = SEQ_CORE_NUM_STEPS-1;
175
    ui_selected_step_view = ui_selected_step / 16;
176
    return 1; // value always changed
167 tk 177
 
168 tk 178
      case SEQ_UI_BUTTON_Up:
179
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
180
 
181
      case SEQ_UI_BUTTON_Down:
182
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
183
    }
167 tk 184
  }
185
 
168 tk 186
  return -1; // invalid or unsupported button
167 tk 187
}
188
 
189
 
190
/////////////////////////////////////////////////////////////////////////////
191
// Local Display Handler function
192
// IN: <high_prio>: if set, a high-priority LCD update is requested
193
/////////////////////////////////////////////////////////////////////////////
194
static s32 LCD_Handler(u8 high_prio)
195
{
196
  if( high_prio )
197
    return 0; // there are no high-priority updates
198
 
199
  u8 visible_track = SEQ_UI_VisibleTrackGet();
200
 
176 tk 201
  seq_layer_evnt_t layer_event;
180 tk 202
  SEQ_LAYER_GetEvntOfParLayer(visible_track, ui_selected_step, ui_selected_par_layer, &layer_event);
168 tk 203
 
176 tk 204
 
167 tk 205
  ///////////////////////////////////////////////////////////////////////////
206
  MIOS32_LCD_DeviceSet(0);
207
  MIOS32_LCD_CursorSet(0, 0);
208
 
209
  SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks);
210
  SEQ_LCD_PrintSpaces(2);
211
 
176 tk 212
  MIOS32_LCD_PrintChar('A' + ui_selected_par_layer);
213
  MIOS32_LCD_PrintChar(':');
167 tk 214
 
176 tk 215
  switch( SEQ_LAYER_GetVControlType(visible_track, ui_selected_par_layer) ) {
216
    case SEQ_LAYER_ControlType_Note:
217
      MIOS32_LCD_PrintString("Note   ");
218
      break;
219
 
220
    case SEQ_LAYER_ControlType_Velocity:
178 tk 221
    case SEQ_LAYER_ControlType_Chord1_Velocity:
222
    case SEQ_LAYER_ControlType_Chord2_Velocity:
176 tk 223
      MIOS32_LCD_PrintString("Vel.   ");
224
      break;
225
 
226
    case SEQ_LAYER_ControlType_Chord1:
227
      MIOS32_LCD_PrintString("Chord1 ");
228
      break;
229
 
230
    case SEQ_LAYER_ControlType_Chord2:
231
      MIOS32_LCD_PrintString("Chord2 ");
232
      break;
233
 
234
    case SEQ_LAYER_ControlType_Length:
235
      MIOS32_LCD_PrintString("Length ");
236
      break;
237
 
238
    case SEQ_LAYER_ControlType_CC:
239
      MIOS32_LCD_PrintFormattedString("CC#%3d ", layer_event.midi_package.cc_number);
240
      break;
241
 
242
    default:
243
      MIOS32_LCD_PrintString("???    ");
244
      break;
245
  }
246
 
168 tk 247
  MIOS32_LCD_PrintFormattedString("Chn%2d", SEQ_CC_Get(visible_track, SEQ_CC_MIDI_CHANNEL)+1);
167 tk 248
  MIOS32_LCD_PrintChar('/');
168 tk 249
  SEQ_LCD_PrintMIDIPort(SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT));
167 tk 250
  SEQ_LCD_PrintSpaces(1);
251
 
180 tk 252
  MIOS32_LCD_PrintFormattedString("%c:%s", 'A' + ui_selected_par_layer, SEQ_TRG_AssignedTypeStr(visible_track, ui_selected_trg_layer));
253
  MIOS32_LCD_PrintChar(' ');
167 tk 254
 
255
  SEQ_LCD_PrintStepView(ui_selected_step_view);
256
 
257
 
258
  ///////////////////////////////////////////////////////////////////////////
259
  MIOS32_LCD_DeviceSet(1);
260
  MIOS32_LCD_CursorSet(0, 0);
261
 
262
  MIOS32_LCD_PrintFormattedString("Step");
263
  SEQ_LCD_PrintSelectedStep(ui_selected_step, 15);
264
  MIOS32_LCD_PrintChar(':');
265
 
176 tk 266
  if( layer_event.midi_package.event == CC ) {
267
    MIOS32_LCD_PrintFormattedString("CC#%3d %3d",
268
                    layer_event.midi_package.cc_number,
269
                    layer_event.midi_package.value);
270
    SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
271
  } else {
178 tk 272
    if( layer_event.midi_package.note && layer_event.midi_package.velocity && (layer_event.len >= 0) ) {
176 tk 273
      SEQ_LCD_PrintNote(layer_event.midi_package.note);
274
      SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
275
    }
276
    else {
277
      MIOS32_LCD_PrintString("....");
278
    }
279
    MIOS32_LCD_PrintFormattedString(" Vel:%3d", layer_event.midi_package.velocity);
280
  }
167 tk 281
 
176 tk 282
  MIOS32_LCD_PrintString(" Len:");
283
  SEQ_LCD_PrintGatelength(layer_event.len);
167 tk 284
  SEQ_LCD_PrintSpaces(1);
285
 
180 tk 286
  int i;
287
  const char trg_chars[8] = "gsagrgv";
288
  for(i=0; i<7; ++i) {
289
    u8 trg_layer;
290
    if( !(trg_layer=SEQ_TRG_AssignmentGet(visible_track, i)) )
291
      MIOS32_LCD_PrintChar('-');
292
    else
293
      MIOS32_LCD_PrintChar(SEQ_TRG_Get(visible_track, ui_selected_step, trg_layer-1) ? (trg_chars[i]-32) : trg_chars[i]);
294
  }
167 tk 295
 
180 tk 296
 
167 tk 297
  ///////////////////////////////////////////////////////////////////////////
176 tk 298
  seq_layer_ctrl_type_t layer_ctrl_type = SEQ_LAYER_GetVControlType(visible_track, ui_selected_par_layer);
167 tk 299
 
176 tk 300
  // extra handling for gatelength (shows vertical bars)
301
  if( layer_ctrl_type == SEQ_LAYER_ControlType_Length ) {
167 tk 302
 
176 tk 303
    // we want to show horizontal bars
304
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
167 tk 305
 
176 tk 306
    // initial cursor position
307
    MIOS32_LCD_DeviceSet(0);
308
    MIOS32_LCD_CursorSet(0, 1);
167 tk 309
 
176 tk 310
    // determine length of previous step (depends on selected view and track length)
311
    int previous_step = 16*ui_selected_step_view - 1;
312
    if( previous_step < 0 )
313
      previous_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
314
 
315
    seq_layer_evnt_t layer_event;
316
    SEQ_LAYER_GetEvntOfParLayer(visible_track, previous_step, ui_selected_par_layer, &layer_event);
317
    u16 previous_length = layer_event.len;
318
    u8 previous_step_was_long_multi = 0; // hard to determine here... TODO
319
 
320
    // show length of 16 steps
180 tk 321
    u8 step;
176 tk 322
    for(step=0; step<16; ++step) {
323
      // 9th step reached: switch to second LCD
324
      if( step == 8 ) {
325
    MIOS32_LCD_DeviceSet(1);
326
    MIOS32_LCD_CursorSet(0, 1);
327
      }
328
 
329
      u8 visible_step = step + 16*ui_selected_step_view;
330
      SEQ_LAYER_GetEvntOfParLayer(visible_track, visible_step, ui_selected_par_layer, &layer_event);
331
 
178 tk 332
      if( previous_step_was_long_multi || layer_event.len >= 32 ) { // multi note trigger?
176 tk 333
    if( !previous_step_was_long_multi ) {
178 tk 334
      if( previous_length <= 24 && !layer_event.midi_package.velocity ) {
176 tk 335
        SEQ_LCD_PrintSpaces(5);
336
        previous_length = 0;
337
      } else {
338
        SEQ_LCD_PrintGatelength(layer_event.len);
339
        MIOS32_LCD_PrintChar(layer_event.midi_package.velocity ? ' ' : '?'); // notify about multi-triggered events 
340
        // with gate=0 and previous length >= 24 - we don't know how the core will react here
341
 
342
        // calculate total length of events -> previous_length
178 tk 343
        previous_length = (layer_event.len>>5) * (layer_event.len & 0x1f);
344
        // long event if >= 24
345
        previous_step_was_long_multi = previous_length >= 24;
176 tk 346
      }
167 tk 347
    } else {
176 tk 348
      // continued long event
349
      // previous step took 24 steps
350
      previous_length -= 24;
178 tk 351
      // print warning (!!!) if current step activated and overlapped by long multi trigger
176 tk 352
      if( previous_step_was_long_multi && !layer_event.midi_package.velocity )
178 tk 353
        MIOS32_LCD_PrintString(">>>> ");
354
      else
176 tk 355
        MIOS32_LCD_PrintString("!!!! ");
178 tk 356
      // still long event if >= 24
357
      previous_step_was_long_multi = previous_length >= 24;
167 tk 358
    }
176 tk 359
      } else {
360
    previous_step_was_long_multi = 0;
178 tk 361
    // muted step? if previous gatelength <= 24, print spaces
362
    if( !layer_event.midi_package.velocity && previous_length <= 24 ) {
176 tk 363
      SEQ_LCD_PrintSpaces(5);
364
    } else {
178 tk 365
      if( layer_event.len >= 24 )
176 tk 366
        SEQ_LCD_PrintHBar(15); // glide
367
      else
368
        SEQ_LCD_PrintHBar((layer_event.len-1) >> 1);
369
    }
178 tk 370
    previous_length = (layer_event.midi_package.velocity || (previous_length > 24 && layer_event.len > 24)) ? layer_event.len : 0;
176 tk 371
      }
167 tk 372
    }
373
 
176 tk 374
  } else {
375
 
376
    // we want to show vertical bars
377
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
378
 
379
    // initial cursor position
380
    MIOS32_LCD_DeviceSet(0);
381
    MIOS32_LCD_CursorSet(0, 1);
382
 
180 tk 383
    u8 step;
176 tk 384
    for(step=0; step<16; ++step) {
385
      // 9th step reached: switch to second LCD
386
      if( step == 8 ) {
387
    MIOS32_LCD_DeviceSet(1);
388
    MIOS32_LCD_CursorSet(0, 1);
389
      }
390
 
391
      u8 visible_step = step + 16*ui_selected_step_view;
392
      seq_layer_evnt_t layer_event;
393
      SEQ_LAYER_GetEvntOfParLayer(visible_track, visible_step, ui_selected_par_layer, &layer_event);
394
 
395
      switch( layer_ctrl_type ) {
396
        case SEQ_LAYER_ControlType_Note:
397
        case SEQ_LAYER_ControlType_Velocity:
398
      if( layer_event.midi_package.note && layer_event.midi_package.velocity ) {
399
        SEQ_LCD_PrintNote(layer_event.midi_package.note);
400
        SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
401
      } else {
402
        MIOS32_LCD_PrintString("----");
403
      }
404
      break;
405
 
406
        case SEQ_LAYER_ControlType_Chord1:
178 tk 407
        case SEQ_LAYER_ControlType_Chord1_Velocity:
176 tk 408
      if( layer_event.midi_package.velocity ) {
178 tk 409
        MIOS32_LCD_PrintFormattedString("S%2d", (SEQ_PAR_Get(visible_track, step, 0) % SEQ_CORE_NUM_STEPS) + 1);
176 tk 410
        SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
411
      } else {
412
        MIOS32_LCD_PrintString("----");
413
      }
414
      break;
415
 
416
        case SEQ_LAYER_ControlType_Chord2:
178 tk 417
        case SEQ_LAYER_ControlType_Chord2_Velocity:
176 tk 418
      if( layer_event.midi_package.note && layer_event.midi_package.velocity ) {
419
        u8 par_value = SEQ_PAR_Get(visible_track, step, 0);
420
        u8 chord_ix = par_value & 0x0f;
421
        u8 chord_oct = par_value >> 4;
422
        MIOS32_LCD_PrintFormattedString("%d/%d", chord_ix, chord_oct);
423
        SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
424
      } else {
425
        MIOS32_LCD_PrintString("----");
426
      }
427
      break;
428
 
429
    //case SEQ_LAYER_ControlType_Lenght:
430
    //break;
431
    // extra handling -- see code above
432
 
433
        case SEQ_LAYER_ControlType_CC:
434
      MIOS32_LCD_PrintFormattedString("%3d", layer_event.midi_package.value);
435
      SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
436
      break;
437
 
438
        default:
439
      MIOS32_LCD_PrintString("????");
440
      break;
441
      }
442
 
443
      MIOS32_LCD_PrintChar(
167 tk 444
        (visible_step == ui_selected_step) ? '<'
445
    : ((visible_step == ui_selected_step-1) ? '>' : ' '));
176 tk 446
    }
167 tk 447
  }
448
 
449
  return 0; // no error
450
}
451
 
452
 
453
/////////////////////////////////////////////////////////////////////////////
454
// Initialisation
455
/////////////////////////////////////////////////////////////////////////////
456
s32 SEQ_UI_EDIT_Init(u32 mode)
457
{
458
  // install callback routines
168 tk 459
  SEQ_UI_InstallButtonCallback(Button_Handler);
460
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
461
  SEQ_UI_InstallLEDCallback(LED_Handler);
462
  SEQ_UI_InstallLCDCallback(LCD_Handler);
167 tk 463
 
464
  return 0; // no error
465
}
178 tk 466
 
467
 
468
 
469
/////////////////////////////////////////////////////////////////////////////
470
// help function to change/set a single encoder value
471
// if forced_value >= 0: new value will be set to the given value
472
// if forced_value < 0: new value will be changed via incrementer
473
// returns >= 0 if new value has been set (value change)
474
// returns < 0 if no change
475
/////////////////////////////////////////////////////////////////////////////
476
static s32 ChangeSingleEncValue(u8 track, u8 step, s32 incrementer, s32 forced_value, u8 change_gate)
477
{
478
  seq_layer_ctrl_type_t layer_ctrl_type = SEQ_LAYER_GetVControlType(track, ui_selected_par_layer);
479
 
480
  // if not length or CC parameter: only change gate if requested
481
  if( layer_ctrl_type != SEQ_LAYER_ControlType_Length &&
482
      layer_ctrl_type != SEQ_LAYER_ControlType_CC &&
483
      !change_gate &&
484
      !SEQ_TRG_GateGet(track, step) )
485
    return -1;
486
 
487
  s32 old_value = SEQ_PAR_Get(track, step, ui_selected_par_layer);
488
  s32 new_value = (forced_value >= 0) ? forced_value : (old_value + incrementer);
489
  if( new_value < 0 )
490
    new_value = 0;
491
  else if( new_value >= 128 )
492
    new_value = 127;
493
 
494
  // take over if changed
495
  if( new_value == old_value )
496
    return -1;
497
 
498
  SEQ_PAR_Set(track, step, ui_selected_par_layer, (u8)new_value);
499
 
500
  if( layer_ctrl_type != SEQ_LAYER_ControlType_Length ) {
501
    // (de)activate gate depending on value
502
    if( new_value )
503
      SEQ_TRG_GateSet(track, step, 1);
504
    else
505
      SEQ_TRG_GateSet(track, step, 0);
506
  }
507
 
508
  return new_value;
509
}