Subversion Repositories svn.mios32

Rev

Rev 174 | Rev 178 | 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 176 2008-12-13 02:16: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
/////////////////////////////////////////////////////////////////////////////
168 tk 32
// Local LED handler function
167 tk 33
/////////////////////////////////////////////////////////////////////////////
173 tk 34
static s32 LED_Handler(u16 *gp_leds)
167 tk 35
{
36
  u8 visible_track = SEQ_UI_VisibleTrackGet();
37
 
38
  *gp_leds =
39
    (trg_layer_value[visible_track][ui_selected_trg_layer][2*ui_selected_step_view+1] << 8) |
40
    trg_layer_value[visible_track][ui_selected_trg_layer][2*ui_selected_step_view+0];
41
 
42
  return 0; // no error
43
}
44
 
45
 
46
/////////////////////////////////////////////////////////////////////////////
168 tk 47
// Local encoder callback function
48
// Should return:
49
//   1 if value has been changed
50
//   0 if value hasn't been changed
51
//  -1 if invalid or unsupported encoder
167 tk 52
/////////////////////////////////////////////////////////////////////////////
168 tk 53
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
167 tk 54
{
168 tk 55
#if 0
56
  // leads to: comparison is always true due to limited range of data type
57
  if( (encoder >= SEQ_UI_ENCODER_GP1 && encoder <= SEQ_UI_ENCODER_GP16) || encoder == SEQ_UI_ENCODER_Datawheel ) {
58
#else
59
  if( encoder <= SEQ_UI_ENCODER_GP16 || encoder == SEQ_UI_ENCODER_Datawheel ) {
60
#endif
61
    u8 visible_track = SEQ_UI_VisibleTrackGet();
62
    u8 step = ((encoder == SEQ_UI_ENCODER_Datawheel) ? (ui_selected_step%16) : encoder) + ui_selected_step_view*16;
167 tk 63
 
168 tk 64
    // select step
65
    ui_selected_step = step;
66
 
67
    // add to absolute value
174 tk 68
    s32 old_value = SEQ_PAR_Get(visible_track, ui_selected_par_layer, step);
69
    s32 new_value = old_value + incrementer;
70
    if( new_value < 0 )
71
      new_value = 0;
72
    else if( new_value >= 128 )
73
      new_value = 127;
168 tk 74
 
75
    // take over if changed
174 tk 76
    if( new_value == old_value ) {
168 tk 77
      return 0; // value not changed
78
    }
79
 
174 tk 80
    SEQ_PAR_Set(visible_track, ui_selected_par_layer, step, (u8)new_value);
168 tk 81
 
176 tk 82
    if( SEQ_LAYER_GetVControlType(visible_track, ui_selected_par_layer) != SEQ_LAYER_ControlType_Length ) {
83
      // (de)activate gate depending on value
84
      if( new_value )
85
    trg_layer_value[visible_track][0][step>>3] |= (1 << (step&7));
86
      else
87
    trg_layer_value[visible_track][0][step>>3] &= ~(1 << (step&7));
88
    }
168 tk 89
 
90
    return 1; // value changed
91
  }
92
 
93
  return -1; // invalid or unsupported encoder
167 tk 94
}
95
 
96
 
97
/////////////////////////////////////////////////////////////////////////////
168 tk 98
// Local button callback function
99
// Should return:
100
//   1 if value has been changed
101
//   0 if value hasn't been changed
102
//  -1 if invalid or unsupported button
167 tk 103
/////////////////////////////////////////////////////////////////////////////
168 tk 104
static s32 Button_Handler(seq_ui_button_t button, s32 depressed)
167 tk 105
{
168 tk 106
  if( depressed ) return 0; // ignore when button depressed
167 tk 107
 
168 tk 108
#if 0
109
  // leads to: comparison is always true due to limited range of data type
110
  if( button >= SEQ_UI_BUTTON_GP1 && button <= SEQ_UI_BUTTON_GP16 ) {
111
#else
112
  if( button <= SEQ_UI_BUTTON_GP16 ) {
113
#endif
114
    // toggle trigger layer
115
    u8 visible_track = SEQ_UI_VisibleTrackGet();
116
    u8 step = button + ui_selected_step_view*16;
117
    trg_layer_value[visible_track][ui_selected_trg_layer][step>>3] ^= (1 << (step&7));
118
    return 1; // value always changed
119
  } else {
120
    switch( button ) {
121
      case SEQ_UI_BUTTON_Select:
122
      case SEQ_UI_BUTTON_Right:
123
    if( ++ui_selected_step >= SEQ_CORE_NUM_STEPS )
124
      ui_selected_step = 0;
125
    ui_selected_step_view = ui_selected_step / 16;
126
    return 1; // value always changed
167 tk 127
 
168 tk 128
      case SEQ_UI_BUTTON_Left:
129
    if( ui_selected_step == 0 )
130
      ui_selected_step = SEQ_CORE_NUM_STEPS-1;
131
    ui_selected_step_view = ui_selected_step / 16;
132
    return 1; // value always changed
167 tk 133
 
168 tk 134
      case SEQ_UI_BUTTON_Up:
135
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
136
 
137
      case SEQ_UI_BUTTON_Down:
138
    return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
139
    }
167 tk 140
  }
141
 
168 tk 142
  return -1; // invalid or unsupported button
167 tk 143
}
144
 
145
 
146
/////////////////////////////////////////////////////////////////////////////
147
// Local Display Handler function
148
// IN: <high_prio>: if set, a high-priority LCD update is requested
149
/////////////////////////////////////////////////////////////////////////////
150
static s32 LCD_Handler(u8 high_prio)
151
{
152
  if( high_prio )
153
    return 0; // there are no high-priority updates
154
 
155
  u8 visible_track = SEQ_UI_VisibleTrackGet();
176 tk 156
  u8 step = ui_selected_step + ui_selected_step_view*16;
167 tk 157
 
176 tk 158
  seq_layer_evnt_t layer_event;
159
  SEQ_LAYER_GetEvntOfParLayer(visible_track, step, ui_selected_par_layer, &layer_event);
168 tk 160
 
176 tk 161
 
167 tk 162
  ///////////////////////////////////////////////////////////////////////////
163
  MIOS32_LCD_DeviceSet(0);
164
  MIOS32_LCD_CursorSet(0, 0);
165
 
166
  SEQ_LCD_PrintGxTy(ui_selected_group, ui_selected_tracks);
167
  SEQ_LCD_PrintSpaces(2);
168
 
176 tk 169
  MIOS32_LCD_PrintChar('A' + ui_selected_par_layer);
170
  MIOS32_LCD_PrintChar(':');
167 tk 171
 
176 tk 172
  switch( SEQ_LAYER_GetVControlType(visible_track, ui_selected_par_layer) ) {
173
    case SEQ_LAYER_ControlType_Note:
174
      MIOS32_LCD_PrintString("Note   ");
175
      break;
176
 
177
    case SEQ_LAYER_ControlType_Velocity:
178
      MIOS32_LCD_PrintString("Vel.   ");
179
      break;
180
 
181
    case SEQ_LAYER_ControlType_Chord1:
182
      MIOS32_LCD_PrintString("Chord1 ");
183
      break;
184
 
185
    case SEQ_LAYER_ControlType_Chord2:
186
      MIOS32_LCD_PrintString("Chord2 ");
187
      break;
188
 
189
    case SEQ_LAYER_ControlType_Length:
190
      MIOS32_LCD_PrintString("Length ");
191
      break;
192
 
193
    case SEQ_LAYER_ControlType_CC:
194
      MIOS32_LCD_PrintFormattedString("CC#%3d ", layer_event.midi_package.cc_number);
195
      break;
196
 
197
    default:
198
      MIOS32_LCD_PrintString("???    ");
199
      break;
200
  }
201
 
168 tk 202
  MIOS32_LCD_PrintFormattedString("Chn%2d", SEQ_CC_Get(visible_track, SEQ_CC_MIDI_CHANNEL)+1);
167 tk 203
  MIOS32_LCD_PrintChar('/');
168 tk 204
  SEQ_LCD_PrintMIDIPort(SEQ_CC_Get(visible_track, SEQ_CC_MIDI_PORT));
167 tk 205
  SEQ_LCD_PrintSpaces(1);
206
 
207
  SEQ_LCD_PrintTrgLayer(ui_selected_trg_layer);
208
 
209
  SEQ_LCD_PrintStepView(ui_selected_step_view);
210
 
211
 
212
  ///////////////////////////////////////////////////////////////////////////
213
  MIOS32_LCD_DeviceSet(1);
214
  MIOS32_LCD_CursorSet(0, 0);
215
 
216
  MIOS32_LCD_PrintFormattedString("Step");
217
  SEQ_LCD_PrintSelectedStep(ui_selected_step, 15);
218
  MIOS32_LCD_PrintChar(':');
219
 
176 tk 220
  if( layer_event.midi_package.event == CC ) {
221
    MIOS32_LCD_PrintFormattedString("CC#%3d %3d",
222
                    layer_event.midi_package.cc_number,
223
                    layer_event.midi_package.value);
224
    SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
225
  } else {
226
    if( layer_event.midi_package.note && layer_event.midi_package.velocity && layer_event.len ) {
227
      SEQ_LCD_PrintNote(layer_event.midi_package.note);
228
      SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
229
    }
230
    else {
231
      MIOS32_LCD_PrintString("....");
232
    }
233
    MIOS32_LCD_PrintFormattedString(" Vel:%3d", layer_event.midi_package.velocity);
234
  }
167 tk 235
 
176 tk 236
  MIOS32_LCD_PrintString(" Len:");
237
  SEQ_LCD_PrintGatelength(layer_event.len);
167 tk 238
  SEQ_LCD_PrintSpaces(1);
239
 
240
  MIOS32_LCD_PrintFormattedString("G-a-r--");
241
 
242
  ///////////////////////////////////////////////////////////////////////////
176 tk 243
  seq_layer_ctrl_type_t layer_ctrl_type = SEQ_LAYER_GetVControlType(visible_track, ui_selected_par_layer);
167 tk 244
 
176 tk 245
  // extra handling for gatelength (shows vertical bars)
246
  if( layer_ctrl_type == SEQ_LAYER_ControlType_Length ) {
167 tk 247
 
176 tk 248
    // we want to show horizontal bars
249
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
167 tk 250
 
176 tk 251
    // initial cursor position
252
    MIOS32_LCD_DeviceSet(0);
253
    MIOS32_LCD_CursorSet(0, 1);
167 tk 254
 
176 tk 255
    // determine length of previous step (depends on selected view and track length)
256
    int previous_step = 16*ui_selected_step_view - 1;
257
    if( previous_step < 0 )
258
      previous_step = SEQ_CC_Get(visible_track, SEQ_CC_LENGTH);
259
 
260
    seq_layer_evnt_t layer_event;
261
    SEQ_LAYER_GetEvntOfParLayer(visible_track, previous_step, ui_selected_par_layer, &layer_event);
262
    u16 previous_length = layer_event.len;
263
    u8 previous_step_was_long_multi = 0; // hard to determine here... TODO
264
 
265
    // show length of 16 steps
266
    for(step=0; step<16; ++step) {
267
      // 9th step reached: switch to second LCD
268
      if( step == 8 ) {
269
    MIOS32_LCD_DeviceSet(1);
270
    MIOS32_LCD_CursorSet(0, 1);
271
      }
272
 
273
      u8 visible_step = step + 16*ui_selected_step_view;
274
      SEQ_LAYER_GetEvntOfParLayer(visible_track, visible_step, ui_selected_par_layer, &layer_event);
275
 
276
      if( previous_step_was_long_multi || layer_event.len > 32 ) { // multi note trigger? - note: .len always +1 of parameter layer value
277
    if( !previous_step_was_long_multi ) {
278
      if( previous_length < 24 && !layer_event.midi_package.velocity ) {
279
        SEQ_LCD_PrintSpaces(5);
280
        previous_length = 0;
281
      } else {
282
        SEQ_LCD_PrintGatelength(layer_event.len);
283
        MIOS32_LCD_PrintChar(layer_event.midi_package.velocity ? ' ' : '?'); // notify about multi-triggered events 
284
        // with gate=0 and previous length >= 24 - we don't know how the core will react here
285
 
286
        // calculate total length of events -> previous_length
287
        previous_length = ((layer_event.len-1)>>5) * (layer_event.len & 0x1f) + 1;
288
        // long event if > 25
289
        previous_step_was_long_multi = previous_length > 25;
290
      }
167 tk 291
    } else {
176 tk 292
      // continued long event
293
      // previous step took 24 steps
294
      previous_length -= 24;
295
      // print warning (!!!) if current step not activated but should be played due to continued multi trigger
296
      if( previous_step_was_long_multi && !layer_event.midi_package.velocity )
297
        MIOS32_LCD_PrintString("!!!! ");
298
      else
299
        MIOS32_LCD_PrintString(">>>> ");
300
      // still long event if > 25
301
      previous_step_was_long_multi = previous_length > 25;
167 tk 302
    }
176 tk 303
      } else {
304
    previous_step_was_long_multi = 0;
305
    // muted step? if previous gatelength <= 25, print spaces
306
    if( !layer_event.midi_package.velocity && previous_length <= 25 ) {
307
      SEQ_LCD_PrintSpaces(5);
308
    } else {
309
      if( layer_event.len > 24 )
310
        SEQ_LCD_PrintHBar(15); // glide
311
      else
312
        SEQ_LCD_PrintHBar((layer_event.len-1) >> 1);
313
    }
314
    previous_length = (layer_event.midi_package.velocity || (previous_length > 25 && layer_event.len > 25)) ? layer_event.len : 0;
315
      }
167 tk 316
    }
317
 
176 tk 318
  } else {
319
 
320
    // we want to show vertical bars
321
    SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
322
 
323
    // initial cursor position
324
    MIOS32_LCD_DeviceSet(0);
325
    MIOS32_LCD_CursorSet(0, 1);
326
 
327
    for(step=0; step<16; ++step) {
328
      // 9th step reached: switch to second LCD
329
      if( step == 8 ) {
330
    MIOS32_LCD_DeviceSet(1);
331
    MIOS32_LCD_CursorSet(0, 1);
332
      }
333
 
334
      u8 visible_step = step + 16*ui_selected_step_view;
335
      seq_layer_evnt_t layer_event;
336
      SEQ_LAYER_GetEvntOfParLayer(visible_track, visible_step, ui_selected_par_layer, &layer_event);
337
 
338
      switch( layer_ctrl_type ) {
339
        case SEQ_LAYER_ControlType_Note:
340
        case SEQ_LAYER_ControlType_Velocity:
341
      if( layer_event.midi_package.note && layer_event.midi_package.velocity ) {
342
        SEQ_LCD_PrintNote(layer_event.midi_package.note);
343
        SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
344
      } else {
345
        MIOS32_LCD_PrintString("----");
346
      }
347
      break;
348
 
349
        case SEQ_LAYER_ControlType_Chord1:
350
      if( layer_event.midi_package.velocity ) {
351
        MIOS32_LCD_PrintFormattedString("S%2d", (SEQ_PAR_Get(visible_track, 0, step) % SEQ_CORE_NUM_STEPS) + 1);
352
        SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
353
      } else {
354
        MIOS32_LCD_PrintString("----");
355
      }
356
      break;
357
 
358
        case SEQ_LAYER_ControlType_Chord2:
359
      if( layer_event.midi_package.note && layer_event.midi_package.velocity ) {
360
        u8 par_value = SEQ_PAR_Get(visible_track, step, 0);
361
        u8 chord_ix = par_value & 0x0f;
362
        u8 chord_oct = par_value >> 4;
363
        MIOS32_LCD_PrintFormattedString("%d/%d", chord_ix, chord_oct);
364
        SEQ_LCD_PrintVBar(layer_event.midi_package.velocity >> 4);
365
      } else {
366
        MIOS32_LCD_PrintString("----");
367
      }
368
      break;
369
 
370
    //case SEQ_LAYER_ControlType_Lenght:
371
    //break;
372
    // extra handling -- see code above
373
 
374
        case SEQ_LAYER_ControlType_CC:
375
      MIOS32_LCD_PrintFormattedString("%3d", layer_event.midi_package.value);
376
      SEQ_LCD_PrintVBar(layer_event.midi_package.value >> 4);
377
      break;
378
 
379
        default:
380
      MIOS32_LCD_PrintString("????");
381
      break;
382
      }
383
 
384
      MIOS32_LCD_PrintChar(
167 tk 385
        (visible_step == ui_selected_step) ? '<'
386
    : ((visible_step == ui_selected_step-1) ? '>' : ' '));
176 tk 387
    }
167 tk 388
  }
389
 
390
  return 0; // no error
391
}
392
 
393
 
394
/////////////////////////////////////////////////////////////////////////////
395
// Initialisation
396
/////////////////////////////////////////////////////////////////////////////
397
s32 SEQ_UI_EDIT_Init(u32 mode)
398
{
399
  // install callback routines
168 tk 400
  SEQ_UI_InstallButtonCallback(Button_Handler);
401
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
402
  SEQ_UI_InstallLEDCallback(LED_Handler);
403
  SEQ_UI_InstallLCDCallback(LCD_Handler);
167 tk 404
 
405
  return 0; // no error
406
}