Subversion Repositories svn.mios32

Rev

Rev 2524 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1454 midilab 1
/*
2
 * Pattern Remix page
3
 *
4
 * ==========================================================================
5
 *
6
 *  Copyright (C) 2012 Romulo Silva (contato@romulosilva.org)
7
 *  Licensed for personal non-commercial use only.
8
 *  All other rights reserved.
9
 *
10
 * ==========================================================================
11
 */
12
 
13
/////////////////////////////////////////////////////////////////////////////
14
// Include files
15
/////////////////////////////////////////////////////////////////////////////
16
 
17
#include <mios32.h>
18
#include <string.h>
19
#include <seq_bpm.h>
20
#include "seq_lcd.h"
21
#include "seq_ui.h"
22
#include "seq_mixer.h"
23
 
24
#include "tasks.h"
25
#include "file.h"
26
#include "seq_file_t.h"
27
#include "seq_file.h"
28
#include "seq_file_b.h"
29
#include "seq_core.h"
30
 
31
/////////////////////////////////////////////////////////////////////////////
32
// Local definitions
33
/////////////////////////////////////////////////////////////////////////////
34
 
35
#define PAGE_MAIN        0
36
#define PAGE_REMIX       1
37
#define PAGE_OPTION      2
38
#define PAGE_NAME_EDIT   3
39
#define PAGE_TRK_DELAY   4
40
 
41
/////////////////////////////////////////////////////////////////////////////
42
// Local variables
43
/////////////////////////////////////////////////////////////////////////////
44
 
45
static u8 selected_page = PAGE_MAIN;
46
 
47
static seq_pattern_t selected_pattern[SEQ_CORE_NUM_GROUPS];
48
 
1475 midilab 49
// default ableton api port insi
50
// TODO: put this inside options page to be selected by the user
51
static mios32_midi_port_t ableton_port = USB0;
52
 
1454 midilab 53
// preview function
1475 midilab 54
static u8 preview_mode = 0;
55
static u8 remix_mode = 0;
1454 midilab 56
static u8 preview_bank;
57
static u8 preview_num;
58
static char preview_name[21];
59
static char pattern_name[21];
60
static char pattern_name_copypaste[21];
1475 midilab 61
static u16 seq_pattern_demix_map = 0;
1454 midilab 62
 
63
// option parameters
1475 midilab 64
static u8 auto_save = 0;
65
//static u8 auto_reset = 0;
66
static u8 ableton_api = 1;
1454 midilab 67
 
68
// static variables (only used here, therefore local)
69
static u32 pc_time_control = 0; // timestamp of last operation
70
 
1475 midilab 71
//static mios32_sys_time_t pattern_timer;
1454 midilab 72
static mios32_sys_time_t pattern_remix_timer;
73
 
74
/////////////////////////////////////////////////////////////////////////////
75
// Local LED handler function
76
/////////////////////////////////////////////////////////////////////////////
77
static s32 LED_Handler(u16 *gp_leds)
78
{
79
 
80
  if( SEQ_FILE_FormattingRequired() )
81
    return 0; // no LED action as long as files not available
82
 
83
  switch( selected_page ) {
84
 
85
    ///////////////////////////////////////////////////////////////////////////
86
    // REMIX PAGE
87
    case PAGE_REMIX: {
88
 
89
            *gp_leds = seq_pattern_remix_map;
90
 
91
    } break;
92
 
93
    ///////////////////////////////////////////////////////////////////////////
94
    // OPTION PAGE
95
    case PAGE_OPTION: {
96
 
97
    } break;
98
 
99
    ///////////////////////////////////////////////////////////////////////////
100
    // PATTERN NAME EDIT PAGE
101
    case PAGE_NAME_EDIT: {
102
 
103
    } break;
104
 
105
    ///////////////////////////////////////////////////////////////////////////
106
    // TRACK DELAY PAGE
107
    case PAGE_TRK_DELAY: {
108
 
109
    } break;
110
 
111
    ///////////////////////////////////////////////////////////////////////////
112
    // MAIN PAGE
113
    case PAGE_MAIN: {
114
 
115
      seq_pattern_t pattern = (ui_selected_item == (ui_selected_group) && ui_cursor_flash)
116
 
117
        ? seq_pattern[ui_selected_group] : selected_pattern[ui_selected_group];
118
 
119
      *gp_leds = (1 << pattern.group) | (1 << (pattern.num+8));
120
 
121
    } break;
122
 
123
    ///////////////////////////////////////////////////////////////////////////
124
    // Page do not exist
125
    default: {
126
 
127
        } break;
128
 
129
  }
130
 
131
    return 0; // no error
132
 
133
}
134
 
135
 
136
/////////////////////////////////////////////////////////////////////////////
137
// Local encoder callback function
138
// Should return:
139
//   1 if value has been changed
140
//   0 if value hasn't been changed
141
//  -1 if invalid or unsupported encoder
142
/////////////////////////////////////////////////////////////////////////////
143
static s32 Encoder_Handler(seq_ui_encoder_t encoder, s32 incrementer)
144
{
145
  if( SEQ_FILE_FormattingRequired() )
146
    return 0; // no encoder action as long as files not available
147
 
148
  switch( selected_page ) {
149
 
150
    ///////////////////////////////////////////////////////////////////////////
151
    // REMIX PAGE
152
    case PAGE_REMIX: {
153
 
154
      // TODO: finish the incrementer helper for gp encoders
155
      if( encoder <= SEQ_UI_ENCODER_GP16 ) {
156
 
157
                if ( preview_mode ) { // the remix state
158
 
159
                    if( ((1 << encoder) | seq_pattern_remix_map) == seq_pattern_remix_map ) { // if we already got the requested bit setup
160
                        // unset him inside remix map
161
                        seq_pattern_remix_map &= ~(1 << encoder);
162
                    } else { // else setup it!
163
                        // set him inside remix map
164
                        seq_pattern_remix_map |= (1 << encoder);
165
                    }
166
 
167
                } else { // the demix state
168
 
169
                    // in this state we can not mix, just turn mixed states track into demixed state
170
                    if( ((1 << encoder) | seq_pattern_remix_map) == seq_pattern_remix_map ) { // if we already got the requested bit setup inside remix map
171
                        // unset him inside remix map
172
                        seq_pattern_remix_map &= ~(1 << encoder);
173
                    } else if ( ((1 << encoder) | seq_pattern_demix_map) == seq_pattern_demix_map ) { // if we already got the requested bit setup demix map
174
                        // set him inside remix map
175
                        seq_pattern_remix_map |= (1 << encoder);
176
                    }
177
 
178
              }
179
 
1475 midilab 180
                if ( !preview_mode && ableton_api) {
1454 midilab 181
                    // send slot play envet to ableton cc (111 + track) with value 127 to channel 16
1475 midilab 182
                    MIOS32_MIDI_SendCC(ableton_port, 15, (111 + encoder), 127);
1454 midilab 183
                }
184
 
185
      }        
186
 
187
    } break;
188
 
189
    ///////////////////////////////////////////////////////////////////////////
190
    // OPTION PAGE
191
    case PAGE_OPTION: {
192
 
193
    } break;
194
 
195
    ///////////////////////////////////////////////////////////////////////////
196
    // PATTERN NAME EDIT PAGE
197
    case PAGE_NAME_EDIT: {
198
 
199
      u8 group;
200
      s32 status;
201
 
202
      // if we got a OK button pressed
203
      if (encoder==SEQ_UI_ENCODER_GP16) {
204
        // Get back to main page
205
        selected_page = PAGE_MAIN;
206
        return 1;
207
      }
208
 
209
      if( (status=SEQ_UI_KeyPad_Handler(encoder, incrementer, (char *)&seq_pattern_name[0], 20)) < 0 ) {
210
        // error
211
        return 0;
212
      } else {
213
        // copy the name of group 1 pattern to all other pattern groups
214
        for(group=1; group<SEQ_CORE_NUM_GROUPS; ++group) {
215
                    //SEQ_LABEL_CopyPresetCategory(seq_pattern[0].num, (char *)&seq_pattern_name[group][0]);
216
                    sprintf(seq_pattern_name[group], seq_pattern_name[0]);
217
        }
218
 
219
                // copy the pattern name
220
                sprintf(pattern_name, seq_pattern_name[0]);
221
 
222
      }
223
 
224
      return 1;
225
 
226
    } break;
227
 
228
    ///////////////////////////////////////////////////////////////////////////
229
    // TRACK DELAY PAGE
230
    case PAGE_TRK_DELAY: {
231
 
232
    } break;
233
 
234
    ///////////////////////////////////////////////////////////////////////////
235
    // MAIN PAGE
236
    case PAGE_MAIN: {
237
 
238
      switch( encoder ) {
239
 
240
        case SEQ_UI_ENCODER_Datawheel:
241
          incrementer = incrementer;
242
 
243
          u16 value = (u16)(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num]*10);
244
          if( SEQ_UI_Var16_Inc(&value, 25, 3000, incrementer) ) { // at 384ppqn, the minimum BPM rate is ca. 2.5
245
            // set new BPM
246
            seq_core_bpm_preset_tempo[seq_core_bpm_preset_num] = (float)value/10.0;
247
            SEQ_CORE_BPM_Update(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num], seq_core_bpm_preset_ramp[seq_core_bpm_preset_num]);
248
            return 1; // value has been changed
249
          } else {
250
            return 0; // value hasn't been changed
251
          }
252
 
253
        default:
254
          return -1; // invalid or unsupported encoder
255
      }
256
 
257
    } break;
258
 
259
    ///////////////////////////////////////////////////////////////////////////
260
    // Page do not exist
261
    default:
262
      break;
263
 
264
  }
265
 
266
    return 0;
267
 
268
}
269
 
270
 
271
/////////////////////////////////////////////////////////////////////////////
272
// Local button callback function
273
// Should return:
274
//   1 if value has been changed
275
//   0 if value hasn't been changed
276
//  -1 if invalid or unsupported button
277
/////////////////////////////////////////////////////////////////////////////
278
static s32 Button_Handler(seq_ui_button_t button, s32 depressed)
279
{
280
 
281
  if( SEQ_FILE_FormattingRequired() )
282
    return 0; // no button action as long as files not available
283
 
284
    u8 group;
285
    s32 status;
286
 
287
  switch( button ) {
288
 
289
        case SEQ_UI_BUTTON_Edit: {
290
 
291
 
292
            if ( depressed && (selected_page == PAGE_REMIX) ) {
293
 
294
                // we want to show vertical VU meters normal mode
295
                SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
296
 
297
                selected_page = PAGE_MAIN;     
298
 
299
                //
300
                // here we run the commands for remix states
301
                //
302
                u16 remix_map_tmp;
303
 
304
                // if we are in no preview_mode them call the demix procedment in case we got some request
305
                if ( (seq_pattern_remix_map != seq_pattern_demix_map) && ( remix_mode ) ) {
306
                    remix_map_tmp = seq_pattern_remix_map;
307
                    seq_pattern_remix_map = ~(seq_pattern_remix_map ^ seq_pattern_demix_map);
308
 
309
          if (ableton_api) {
310
 
311
            // TODO: implements a ableton remotescript to the clip control functionality
312
 
313
                        u8 track;
314
                        for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
315
 
316
                         // if we got the track bit setup inside our remix_map, them do not send mixer data for that track channel, let it be mixed down
317
                         if ( ((1 << track) | seq_pattern_remix_map) == seq_pattern_remix_map ) {
318
                             // do nothing...
319
                         } else {
2161 tk 320
#ifndef MIOS32_FAMILY_EMULATION
1454 midilab 321
                             // delay our task for ableton get a breath before change the pattern line
1475 midilab 322
                             vTaskDelay(50);
2161 tk 323
#endif
1475 midilab 324
                             // send slot play envet to ableton: cc (111 + track) with value 127 to channel 16
325
                             MIOS32_MIDI_SendCC(ableton_port, 15, (111 + track), 127);
1454 midilab 326
                         }
327
 
328
                        }          
329
 
330
          }
331
 
332
                    // if we are in remix mode lets start the process
333
                    if (remix_map_tmp == 0) {
334
 
335
                        //pattern_name = pattern_name_remix;
336
                        preview_mode = 0;
337
                        remix_mode = 0;
338
                        // set the pattern_remix_timer reference
339
                        pattern_remix_timer = MIOS32_SYS_TimeGet();
340
 
341
                    }
342
 
343
                    // Change Pattern
344
                    u8 group;
345
                    for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
346
                        // change pattern
347
                        SEQ_PATTERN_Change(group, seq_pattern[group], 0);
348
                    }
349
 
350
                    // copy the pattern name for future reference
351
                    sprintf(pattern_name, seq_pattern_name[0]);
352
 
353
                    // getting back
354
                    seq_pattern_remix_map = remix_map_tmp;
355
                    seq_pattern_demix_map = seq_pattern_remix_map;
356
 
357
                }
358
 
359
            } else if ( !depressed ) {     
360
 
361
                // we want to show horizontal VU meters in remix mode
362
                SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_HBars);
363
 
364
                selected_page = PAGE_REMIX;
365
            }
366
 
367
            return 1;  
368
 
369
        } break;               
370
 
371
    case SEQ_UI_BUTTON_Select: {
372
 
373
      if(!depressed) {
374
        selected_page = PAGE_OPTION;
375
        return 1;
376
      }
377
 
378
      if( (depressed) && (selected_page == PAGE_OPTION) ) {
379
        selected_page = PAGE_MAIN;
380
      }
381
 
382
        } break;
383
 
384
        default:
385
            break;
386
 
387
 
388
  }
389
 
1475 midilab 390
  if( depressed ) return 0; // ignore when button depressed if its not SEQ_UI_BUTTON_Select or SEQ_UI_BUTTON_Edit
1454 midilab 391
 
392
  switch( selected_page ) {
393
 
394
    ///////////////////////////////////////////////////////////////////////////
395
    // REMIX PAGE
396
    case PAGE_REMIX: {
397
 
398
      if( button <= SEQ_UI_BUTTON_GP16 ) {
399
        // re-using encoder routine
400
        return Encoder_Handler(button, 0);
401
      }        
402
 
403
    } break;
404
 
405
    ///////////////////////////////////////////////////////////////////////////
406
    // OPTION PAGE
407
    case PAGE_OPTION: {
408
 
409
      switch( button ) {
410
 
411
        case SEQ_UI_BUTTON_GP1:
1475 midilab 412
          // Save Pattern(all 4 groups at once)
1454 midilab 413
          for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
414
 
415
            if( (status=SEQ_PATTERN_Save(group, seq_pattern[group])) < 0 ) {
416
              SEQ_UI_SDCardErrMsg(2000, status);
417
              return 0;
418
            }
419
 
420
          }
421
 
422
          // Save the pattern mixer
423
          SEQ_MIXER_Save(SEQ_MIXER_NumGet());
424
 
425
          break;
426
 
427
        case SEQ_UI_BUTTON_GP2:
428
          // Edit Pattern Name
429
                    //SEQ_LCD_Clear();
430
          selected_page = PAGE_NAME_EDIT;
431
          break;
432
 
433
        case SEQ_UI_BUTTON_GP3:
434
          // Copy Pattern
435
 
2524 tk 436
      // copy the pattern name
437
      if (remix_mode == 1) {
438
        sprintf(pattern_name_copypaste, pattern_name);
439
      } else {
440
        sprintf(pattern_name_copypaste, seq_pattern_name[0]);
441
      }
1454 midilab 442
 
2524 tk 443
 
444
      // We are going to use the multicopy procedure
445
      SEQ_UI_PATTERN_MultiCopy(0);
446
 
447
      // coping mixer
448
      SEQ_UI_MIXER_Copy();
449
 
1454 midilab 450
          break;
451
 
452
        case SEQ_UI_BUTTON_GP4:
453
          // Paste Pattern
454
 
2524 tk 455
      // We are going to use the multicopy procedure
456
      SEQ_UI_PATTERN_MultiPaste(0);
457
 
458
      // paste the pattern name
459
      sprintf(seq_pattern_name[0], pattern_name_copypaste);
460
 
461
      // paste mixer
462
      SEQ_UI_MIXER_Paste();
1454 midilab 463
 
464
          break;
465
 
466
        case SEQ_UI_BUTTON_GP5:
467
        case SEQ_UI_BUTTON_GP6:
468
          return -1; // not mapped
469
 
470
        case SEQ_UI_BUTTON_GP7:
471
        case SEQ_UI_BUTTON_GP8:
472
          // Track Delay Page
473
                    //SEQ_LCD_Clear();
474
          //selected_page = PAGE_TRK_DELAY;
475
          //break;
476
                    return -1; // not mapped
477
 
478
        case SEQ_UI_BUTTON_GP9:
479
        case SEQ_UI_BUTTON_GP10:
480
                    return -1; // not mapped
481
 
482
        case SEQ_UI_BUTTON_GP11:
483
        case SEQ_UI_BUTTON_GP12:
484
                    return -1; // not mapped
485
 
486
        case SEQ_UI_BUTTON_GP13:
487
        case SEQ_UI_BUTTON_GP14:
488
          // Auto Save switch
489
          auto_save ^= 1;
490
          break;
491
          break;
492
 
493
        case SEQ_UI_BUTTON_GP15:
494
        case SEQ_UI_BUTTON_GP16:
495
                    // Ableton API switch
496
          ableton_api ^= 1;
497
          return -1; // not mapped
498
      }
499
 
500
      return 0;
501
 
502
    } break;
503
 
504
    ///////////////////////////////////////////////////////////////////////////
505
    // PATTERN NAME EDIT PAGE
506
    case PAGE_NAME_EDIT: {
507
 
508
      return Encoder_Handler((seq_ui_encoder_t)button, 0);
509
 
510
    } break;
511
 
512
    ///////////////////////////////////////////////////////////////////////////
513
    // TRACK DELAY PAGE
514
    case PAGE_TRK_DELAY: {
515
 
516
    } break;
517
 
518
    ///////////////////////////////////////////////////////////////////////////
519
    // MAIN PAGE
520
    case PAGE_MAIN: {
521
 
522
      // Pattern Change Group Requests
523
      if( button <= SEQ_UI_BUTTON_GP8 ) {
524
 
525
        u8 group;
526
 
527
        for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
528
          if( selected_pattern[group].group == button ) {
529
            if( SEQ_FILE_B_NumPatterns(selected_pattern[group].bank) > 64 ) {
530
              selected_pattern[group].lower ^= 1;
531
            } else {
532
              selected_pattern[group].lower = 0; // toggling not required
533
            }
534
          } else {
535
            selected_pattern[group].group = button;
536
            preview_bank = button;
537
            //preview_mode = 0;
538
          }
539
        }
540
 
541
                SEQ_PATTERN_PeekName(selected_pattern[0], preview_name);
542
                preview_mode = 1;
543
 
544
        return 1; // value always changed
545
      }
546
 
547
      // Pattern Change Request
548
      if( button >= SEQ_UI_BUTTON_GP9 && button <= SEQ_UI_BUTTON_GP16 ) {
549
 
550
        //u8 group;
551
 
552
        s32 status = 0;
553
 
554
        // setting save patterns for later autosave procedure
555
        //for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group)
556
        //  save_pattern[group] = seq_pattern[group];
557
 
558
        // change preview pattern
559
        selected_pattern[0].num = button-8;
560
        selected_pattern[1].num = button-8;
561
        selected_pattern[2].num = button-8;
562
        selected_pattern[3].num = button-8;
563
 
564
        if ( !preview_mode )
565
        {
566
          preview_num = button-8;
567
          SEQ_PATTERN_PeekName(selected_pattern[0], preview_name);
568
          preview_mode = 1;
569
 
1475 midilab 570
                    // for security reasons in live environment, we can not accept rapid 2x press of pattern button.
1454 midilab 571
                    // if the buttons are not good quality they can send a 2x rapid signal os pressing in just one physical pressing
572
                    // the time we need is bassicly the human time to read the name of patterns requested
573
                // start time in count
1911 tk 574
                                    pc_time_control = MIOS32_TIMESTAMP_Get() + 200;
1454 midilab 575
                    // vTaksDelay(200);
576
        } else {
577
 
578
                    // 
579
                    if ( remix_mode == 0 ) {
580
 
1475 midilab 581
                        //char str[30];
582
                        //sprintf(str, "%d = %d %d = %d", selected_pattern[0].num, preview_num, selected_pattern[0].group, preview_bank);
583
                        //SEQ_UI_Msg(SEQ_UI_MSG_USER, 2000, str, "debug");
584
 
1454 midilab 585
                        // Check for remix state
586
                        if ( (selected_pattern[0].num == preview_num) &&  (selected_pattern[0].group == preview_bank) ) {
587
 
1911 tk 588
                            //if ( pc_time_control >= MIOS32_TIMESTAMP_Get() )
1475 midilab 589
                            //  return 0; // do nothing, just to be shure we are not handle acidental double clicks, it happens!                    
590
 
1454 midilab 591
                            // if we got some remix bit setup, enter in remix mode
592
                            if (seq_pattern_remix_map != 0) {
593
                                // set the remix mode
594
                                remix_mode = 1;
595
                            }
596
 
597
                        }
598
 
599
                    }
600
 
601
          // Change Pattern
602
          if ( (selected_pattern[0].num == preview_num) &&  (selected_pattern[0].group == preview_bank) ) {
603
 
1911 tk 604
            if ( pc_time_control >= MIOS32_TIMESTAMP_Get() )
1475 midilab 605
                return 0; // do nothing, just to be shure we are not handle acidental double clicks
1454 midilab 606
 
607
                        if (ableton_api) {
608
 
609
                            u8 ableton_pattern_number = 0;
610
 
611
                            //
612
                            // ABLETON API PATTERN CHANGE HANDLE
613
                            //
614
                            // send ableton event to change the line clips
615
                            if (selected_pattern[0].lower) {
616
                            ableton_pattern_number = ((selected_pattern[0].group - 1) * 8) + button;
617
                            } else {
618
                            ableton_pattern_number = (((selected_pattern[0].group - 1) + 8) * 8) + button;
619
                            }
620
 
621
                            // midi_cc to send = 110
622
                            // midi_chn = 16
1475 midilab 623
                            // midi_port = ableton_port
1454 midilab 624
                            // here we need to send a clip line change request
1475 midilab 625
                            MIOS32_MIDI_SendCC(ableton_port, 15, 110, ableton_pattern_number);
1454 midilab 626
 
2161 tk 627
#ifndef MIOS32_FAMILY_EMULATION
1454 midilab 628
                            // delay our task for ableton get a breath before change the pattern line
629
                            vTaskDelay(50);
2161 tk 630
#endif
1475 midilab 631
 
632
                            // clip triggering
1454 midilab 633
                            u8 track;
634
                for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
635
 
636
                // if we got the track bit setup inside our remix_map, them do not send mixer data for that track channel, let it be mixed down
637
                if ( ((1 << track) | seq_pattern_remix_map) == seq_pattern_remix_map ) {
638
                    // do nothing...
639
                } else {
2161 tk 640
#ifndef MIOS32_FAMILY_EMULATION
1475 midilab 641
                                    // delay our task for ableton get a breath before change the pattern line
642
                                    vTaskDelay(50);                                
2161 tk 643
#endif
1475 midilab 644
                                    // send clip slot play envet to ableton cc (111 + track) with value 127 to channel 16
645
                    MIOS32_MIDI_SendCC(ableton_port, 15, (111 + track), 127);
1454 midilab 646
                }
647
 
648
                }          
649
 
650
                            // send a global clip change(all clips in the clip line)    
651
                            // send play envet to ableton cc 20 with value 127 to channel 16
1475 midilab 652
                            //MIOS32_MIDI_SendCC(ableton_port, 15, 20, 127);
1454 midilab 653
 
654
                        }
655
 
656
                        //
657
                        // Autosave Pattern
658
                        //
659
                        if (auto_save) {
660
 
1475 midilab 661
                            // Autosave all 4 group of patterns
1454 midilab 662
                            for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
663
 
1475 midilab 664
                                // Save to SD Card
1454 midilab 665
                                if( (status=SEQ_PATTERN_Save(group, seq_pattern[group])) < 0 ) {
666
                                    SEQ_UI_SDCardErrMsg(2000, status);
667
                                }
668
 
669
                            }
670
 
671
                            // Autosave Mixer Map
672
                            SEQ_MIXER_Save(SEQ_MIXER_NumGet());
673
 
674
                        }                          
675
 
676
                        // if we are not in remix mode 
677
                        if (seq_pattern_remix_map == 0) {
678
 
679
                            // keep the name of old pattern(because we still got 1 or more tracks belongs to this pattern)
680
                            //pattern_name = seq_pattern_name;
681
                            // set timer for mixed pattern
682
                            pattern_remix_timer = MIOS32_SYS_TimeGet();
683
                        }                              
684
 
685
                        //
686
                        // Pattern change request
687
                        //
688
            for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group) {
689
 
690
              // change pattern
691
              //selected_pattern[group].num = button-8;
692
              SEQ_PATTERN_Change(group, selected_pattern[group], 0);
693
 
694
                            //if ( remix_mode ) {
695
                                // keep the pattern name...
696
                                //sprintf(seq_pattern_name[group], pattern_name);
697
                            //}
698
 
699
            }
700
 
701
                        if ( !remix_mode ) {
702
                            // copy the pattern name for future reference
703
                            //sprintf(pattern_name, seq_pattern_name[0]);   
704
                            SEQ_PATTERN_PeekName(selected_pattern[0], pattern_name);
705
                            // TODO: sync this with the pattern change handled by SEQ_PATTERN_Handler()
706
                            //pattern_timer.seconds = 0;        
707
                            preview_mode = 0;
708
                        }
709
 
710
                        // support for demix
711
            seq_pattern_demix_map = seq_pattern_remix_map;
712
 
713
            //preview_mode = 0;
714
 
715
          // Request a Pattern Preview
716
          } else {
717
            preview_num = button-8;
718
            SEQ_PATTERN_PeekName(selected_pattern[0], preview_name);
719
 
1475 midilab 720
              // for security reasons in live environment, we can not accept 2x rapid press of pattern button.
1454 midilab 721
            // if the buttons are not good quality they can send a 2x rapid signal os pressing in just one physical pressing
722
              // the time we need is bassicly the human time to read the name of patterns requested
723
            // start time in count
1911 tk 724
              pc_time_control = MIOS32_TIMESTAMP_Get() + 200;
1454 midilab 725
 
726
          }
727
 
728
        }          
729
 
730
        return 1; // value always changed
731
      }
732
 
733
      u8 visible_track = SEQ_UI_VisibleTrackGet();
734
 
735
      switch( button ) {
736
 
737
        case SEQ_UI_BUTTON_Right:
738
          // switch to next track
739
          if( visible_track < (SEQ_CORE_NUM_TRACKS - 1) )
740
            visible_track++;
741
 
742
          ui_selected_tracks = (1 << visible_track);
743
          ui_selected_group = visible_track / 4;
744
 
745
          return 1; // value always changed
746
 
747
        case SEQ_UI_BUTTON_Left:
748
          // switch to previous track
749
          if( visible_track >= 1 )
750
            visible_track--;
751
 
752
          ui_selected_tracks = (1 << visible_track);
753
          ui_selected_group = visible_track / 4;
754
 
755
          return 1; // value always changed
756
 
757
        case SEQ_UI_BUTTON_Up:
758
          return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, 1);
759
 
760
        case SEQ_UI_BUTTON_Down:
761
          return Encoder_Handler(SEQ_UI_ENCODER_Datawheel, -1);
762
      }
763
 
764
      return -1; // invalid or unsupported button
765
 
766
    } break;
767
 
768
    ///////////////////////////////////////////////////////////////////////////
769
    // Page do not exist
770
    default:
771
      break;
772
 
773
  }
774
 
775
    return 0;
776
 
777
}
778
 
779
/////////////////////////////////////////////////////////////////////////////
780
// Local Display Handler function
781
// IN: <high_prio>: if set, a high-priority LCD update is requested
782
/////////////////////////////////////////////////////////////////////////////
783
static s32 LCD_Handler(u8 high_prio)
784
{
785
  // layout:
786
  // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
787
  // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
788
  // <--------------------------------------> <-------------------------------------->
789
  //     No Patterns available as long as the Session hasn't been created!
790
  //                   Please press EXIT and  create a new Session!
791
 
792
  // Main Page
793
  // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
794
  // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
795
  // <--------------------------------------> <-------------------------------------->
796
  // A1: Breakbeats 2                   16.16 A4: Breakbeat full              10:10:10
797
  // ____ ____ ____ ____ T01: Track Name      x__x __x_ ____ ____              126 BPM
798
 
799
  // Remix Page
800
  // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
801
  // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
802
  // <--------------------------------------> <-------------------------------------->
803
  //  1    2    3    4    5    6    7    8     9    10   11   12   13   14   15   16
804
  // MIX  .... UMIX .... UMIX .... .... MIX   .... .... .... .... .... .... .... ....
805
 
806
  // In preview_mode we can state tracks to Mix state only(on/off), on normal mode
807
  // we can state track do DMix state only(on/off)
808
 
809
  // Options Page
810
  // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
811
  // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
812
  // <--------------------------------------> <-------------------------------------->
813
  // A1: Breakbeats 2                         Auto save Auto rset Abtn. Api
814
  // Save Name Copy Paste          Trk Delay     Off       On        On
815
 
816
  // Edit Name Page
817
  // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
818
  // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
819
  // <--------------------------------------> <-------------------------------------->
820
  // A1: <xxxxxxxxxxxxxxxxxxxx>
821
  // .,!1 ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7 TUV8 WXYZ9 -_ 0  Char <>  Del Ins        OK  
822
 
823
  // Track Delay Page
824
  // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
825
  // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
826
  // <--------------------------------------> <-------------------------------------->
827
  //   1    2    3    4    5    6    7    8     9    10   11   12   13   14   15   16
828
  //  -10 +230  -45  -22  +23  -43 +221  -32  -210 +230  -45 -322 +323  -43 +221  -32
829
  // for this we could use t->bpm_tick_delay, but we need a way to saving
830
  // this values inside the track pattern
831
 
832
  if( SEQ_FILE_FormattingRequired() ) {
833
    if( high_prio )
834
      return 0;
835
 
836
    SEQ_LCD_CursorSet(0, 0);
837
    SEQ_LCD_PrintString("    No Patterns available as long as theSession hasn't been created!            ");
838
    SEQ_LCD_CursorSet(0, 1);
839
    SEQ_LCD_PrintString("                  Please press EXIT and create a new Session!                   ");
840
    return 0;
841
  }
842
 
843
  switch( selected_page ) {
844
 
845
    ///////////////////////////////////////////////////////////////////////////
846
    // REMIX PAGE
847
    case PAGE_REMIX: {
848
 
849
      // Remix Page
850
      // 00000000001111111111222222222233333333330000000000111111111122222222223333333333
851
      // 01234567890123456789012345678901234567890123456789012345678901234567890123456789
852
      // <--------------------------------------><-------------------------------------->
853
      //  1M   2    3M   4    5    6    7    8    9    10   11   12   13   14   15   16
854
      // ...  .... .... .... .... .... .... .... .... .... .... .... .... .... .... ....
855
 
856
      // <--------------------------------------><-------------------------------------->
857
      //  1D    2   3D    4   5    6    7    8    9    10   11   12   13   14   15   16
858
      //  .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ....
859
 
860
      if( high_prio ) {
861
 
862
        ///////////////////////////////////////////////////////////////////////////
863
        // frequently update VU meters and step position counter
864
        u8 track;
865
        //u8 spacer = 0;
866
 
867
        SEQ_LCD_CursorSet(0, 1);
868
 
869
        seq_core_trk_t *t = &seq_core_trk[0];
870
        for(track=0; track<16; ++t, ++track) {
871
 
872
          //if( !(track % 4) && (track!=0) )
873
          //  spacer++;
874
 
875
          //SEQ_LCD_CursorSet(track+spacer, 1);
876
 
877
 
878
                    //SEQ_LCD_PrintVBar(t->vu_meter >> 4);
879
                    SEQ_LCD_PrintHBar(t->vu_meter >> 3);
880
 
881
        }
882
 
883
      } else { // not high_prio
884
 
885
        u8 track;
886
 
887
        SEQ_LCD_CursorSet(0, 0);
888
                SEQ_LCD_PrintSpaces(1);
889
 
890
        for(track=0; track<16; ++track) {
891
 
892
                    // print the mixed state info
893
                    if( seq_pattern_remix_map & (1 << track) ) {
894
 
895
                        SEQ_LCD_PrintFormattedString("%dM", track+1);
896
            if (track < 9) {
897
              SEQ_LCD_PrintSpaces(3);
898
            } else {
899
              SEQ_LCD_PrintSpaces(2);
900
            }
901
 
902
                    // print the demixed state info 
903
                    } else if ( ( seq_pattern_remix_map ^ seq_pattern_demix_map ) & (1 << track) ) {
904
 
905
                        SEQ_LCD_PrintFormattedString("%dD", track+1);
906
            if (track < 9) {
907
              SEQ_LCD_PrintSpaces(3);
908
            } else {
909
              SEQ_LCD_PrintSpaces(2);
910
            }
911
 
912
                  }else {
913
 
914
            SEQ_LCD_PrintFormattedString("%d", track+1);
915
            if (track < 9) {
916
              SEQ_LCD_PrintSpaces(4);
917
            } else {
918
              SEQ_LCD_PrintSpaces(3);
919
            }
920
 
921
                    }
922
 
923
        }
924
 
925
                SEQ_LCD_PrintSpaces(1);
926
 
927
      }
928
 
929
    } break;
930
 
931
    ///////////////////////////////////////////////////////////////////////////
932
    // OPTION PAGE
933
    case PAGE_OPTION: {
934
 
935
      // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
936
      // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
937
      // <--------------------------------------> <-------------------------------------->
938
      // A1: Breakbeats 2                                              Auto save Abtn. Api
939
      // Save Name Copy Paste                                             Off        On
940
 
941
      ///////////////////////////////////////////////////////////////////////////
942
      // Current Pattern Name
943
            SEQ_LCD_Clear();
944
      SEQ_LCD_CursorSet(0, 0);
945
      SEQ_LCD_PrintPattern(seq_pattern[0]);
946
      SEQ_LCD_PrintFormattedString(": %s", seq_pattern_name[0]);
947
 
948
      ///////////////////////////////////////////////////////////////////////////
949
      // Options Labels Left Side
950
      SEQ_LCD_CursorSet(0, 1);
951
      SEQ_LCD_PrintString("Save ");
952
      SEQ_LCD_PrintString("Name ");
953
      SEQ_LCD_PrintString("Copy ");
954
      SEQ_LCD_PrintString("Paste");
955
 
956
      //SEQ_LCD_CursorSet(30, 1);
957
      //SEQ_LCD_PrintString("Trk Delay ");
958
 
959
      ///////////////////////////////////////////////////////////////////////////
960
      // Options Labels Right Side
961
      SEQ_LCD_CursorSet(61, 0);
962
      SEQ_LCD_PrintString("Auto save ");
963
      //SEQ_LCD_PrintString("Auto rset ");
964
      SEQ_LCD_PrintString("Abtn. Api ");
965
 
966
      SEQ_LCD_CursorSet(61, 1);
967
      if (auto_save) {
968
        SEQ_LCD_PrintString("   On     ");
969
      } else {
970
        SEQ_LCD_PrintString("   Off    ");
971
      }
972
 
973
      //if (auto_reset) {
974
      //  SEQ_LCD_PrintString("   On     ");
975
      //} else {
976
      //  SEQ_LCD_PrintString("   Off    ");
977
      //}
978
 
979
      if (ableton_api) {
980
        SEQ_LCD_PrintString("   On     ");
981
      } else {
982
        SEQ_LCD_PrintString("   Off    ");
983
      }
984
 
985
    } break;
986
 
987
    ///////////////////////////////////////////////////////////////////////////
988
    // PATTERN NAME EDIT PAGE
989
    case PAGE_NAME_EDIT: {
990
 
991
      u8 i;
992
 
993
            SEQ_LCD_Clear();
994
 
1475 midilab 995
            SEQ_UI_KeyPad_LCD_Msg();
996
      SEQ_LCD_CursorSet(76, 1);
997
      SEQ_LCD_PrintString("Back");
998
 
999
            // Print the pattern name
1454 midilab 1000
      SEQ_LCD_CursorSet(0, 0);
1001
      SEQ_LCD_PrintPattern(seq_pattern[0]);
1002
      SEQ_LCD_PrintString(": ");
1003
 
1004
      for(i=0; i<20; ++i)
1005
        SEQ_LCD_PrintChar(seq_pattern_name[ui_selected_group][i]);
1006
 
1007
      // insert flashing cursor
1008
      if( ui_cursor_flash ) {
1009
        SEQ_LCD_CursorSet(3 + ((ui_edit_name_cursor < 5) ? 1 : 2) + ui_edit_name_cursor, 0);
1010
        SEQ_LCD_PrintChar('*');
1011
      }
1012
 
1013
      //return 0;
1014
 
1015
    } break;
1016
 
1017
    ///////////////////////////////////////////////////////////////////////////
1018
    // TRACK DELAY PAGE
1019
    case PAGE_TRK_DELAY: {
1020
 
1021
      // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
1022
      // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
1023
      // <--------------------------------------> <-------------------------------------->
1024
      //   1    2    3    4    5    6    7    8     9    10   11   12   13   14   15   16
1025
      //  -10 +230  -45  -22  +23  -43 +221  -32  -210 +230  -45 -322 +323  -43 +221  -32
1026
 
1027
      u8 track;
1028
 
1029
      SEQ_LCD_CursorSet(0, 2);
1030
      for(track=0; track<16; ++track) {
1031
 
1032
          SEQ_LCD_PrintFormattedString("%d", track);
1033
          if (track < 11) {
1034
            SEQ_LCD_PrintSpaces(4);
1035
          } else {
1036
            SEQ_LCD_PrintSpaces(3);
1037
          }
1038
 
1039
      }
1040
 
1041
      SEQ_LCD_CursorSet(1, 2);
1042
      for(track=0; track<16; ++track) {
1043
 
1044
          SEQ_LCD_PrintFormattedString("%d", track);
1045
          //SEQ_LCD_PrintFormattedString("%d", 0);
1046
          if (track < 11) {
1047
            SEQ_LCD_PrintSpaces(4);
1048
          } else {
1049
            SEQ_LCD_PrintSpaces(3);
1050
          }
1051
 
1052
      }
1053
 
1054
    } break;
1055
 
1056
    ///////////////////////////////////////////////////////////////////////////
1057
    // MAIN PAGE
1058
    case PAGE_MAIN: {
1059
 
1060
      // 0000000000111111111122222222223333333333 0000000000111111111122222222223333333333
1061
      // 0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
1062
      // <--------------------------------------> <-------------------------------------->
1063
      // A1: Breakbeats 2                   16.16 A4: Breakbeat full              10:10:10
1064
      // ____ ____ ____ ____ T01: Track Name      x__x __x_ ____ ____              126 BPM
1065
 
1066
            //SEQ_LCD_CursorSet(0, 0);
1067
            //SEQ_LCD_PrintSpaces();
1068
 
1069
      if( high_prio ) {
1070
 
1071
        ///////////////////////////////////////////////////////////////////////////
1072
        // Frequently update VU meters
1073
        u8 track;
1074
        u8 spacer = 0;
1075
        seq_core_trk_t *t = &seq_core_trk[0];
1076
        for(track=0; track<16; ++t, ++track) {
1077
 
1078
          if( !(track % 4) && (track!=0) )
1079
            spacer++;
1080
 
1081
          SEQ_LCD_CursorSet(track+spacer, 1);
1082
 
1083
          //if( seq_core_trk_muted & (1 << track) )
1084
          //  SEQ_LCD_PrintVBar('M');
1085
          //else
1086
            SEQ_LCD_PrintVBar(t->vu_meter >> 4);
1087
 
1088
                }
1089
 
1090
                if ( remix_mode && preview_mode ) {
1091
 
1092
                    spacer = 0;
1093
                    seq_core_trk_t *t = &seq_core_trk[0];
1094
          for(track=0; track<16; ++t, ++track) {
1095
 
1096
            if( !(track % 4) && (track!=0) )
1097
              spacer++;
1098
 
1099
            SEQ_LCD_CursorSet((track+spacer)+40, 1);
1100
 
1101
                        if( !( seq_pattern_remix_map & (1 << track) ) )
1102
                            SEQ_LCD_PrintVBar(t->vu_meter >> 4);
1103
 
1104
          }
1105
 
1106
                }
1107
 
1108
                ///////////////////////////////////////////////////////////////////////////
1109
                // Print Pattern Relative Sequencer Position
1110
                // SEQ_LCD_CursorSet(28, 0);
1111
                // u32 tick = SEQ_BPM_TickGet();
1112
                // tick = tick - seq_pattern_start_tick;
1113
                // u32 ticks_per_step = SEQ_BPM_PPQN_Get() / 4;
1114
                // u32 ticks_per_measure = ticks_per_step * (seq_core_steps_per_measure+1);
1115
                // u32 measure = (tick / ticks_per_measure) + 1;
1116
                // u32 step = ((tick % ticks_per_measure) / ticks_per_step) + 1;
1117
                //u32 microstep = tick % ticks_per_step;
1118
                //SEQ_LCD_PrintFormattedString("%8u.%3d.%3d", measure, step, microstep);
1119
                // SEQ_LCD_PrintFormattedString("%8u.%3d", measure, step);
1120
 
1121
      } else { // not high_prio
1122
 
1123
                SEQ_LCD_Clear();
1124
 
1125
        ///////////////////////////////////////////////////////////////////////////
1126
        // Current Pattern Name
1127
        SEQ_LCD_CursorSet(0, 0);
1128
        SEQ_LCD_PrintPattern(seq_pattern[0]);
1129
                if (remix_mode == 1) {
1130
                    SEQ_LCD_PrintFormattedString(": %s", pattern_name);
1131
                } else {
1132
                    SEQ_LCD_PrintFormattedString(": %s", seq_pattern_name[0]);
1133
                }
1134
 
1135
                //
1136
 
1137
        ///////////////////////////////////////////////////////////////////////////
1138
        // Print Selected Track Name
1139
        SEQ_LCD_CursorSet(20, 1);
1140
        u8 visible_track = SEQ_UI_VisibleTrackGet();
1141
        if ( visible_track < 9 ) {
1142
          SEQ_LCD_PrintFormattedString("T0%d: ", visible_track+1);
1143
        } else {
1144
          SEQ_LCD_PrintFormattedString("T%d: ", visible_track+1);
1145
        }
1146
        SEQ_LCD_PrintTrackLabel(visible_track, (char *)seq_core_trk[visible_track].name);
1147
        //SEQ_LCD_PrintString((char *)seq_core_trk[visible_track].name);
1148
                //SEQ_LCD_PrintSpaces();
1149
 
1150
 
1151
        ///////////////////////////////////////////////////////////////////////////
1152
        // Print Total Play Time
1153
        SEQ_LCD_CursorSet(72, 0);
1154
                if ( seq_play_timer.seconds == 0 ) {
1155
                    SEQ_LCD_PrintFormattedString("00:00:00");
1156
                } else {
1157
                    mios32_sys_time_t play_time = MIOS32_SYS_TimeGet();
1158
                    play_time.seconds = play_time.seconds - seq_play_timer.seconds;
1159
                    int hours = (play_time.seconds / 3600) % 24;
1160
                    int minutes = (play_time.seconds % 3600) / 60;
1161
                    int seconds = (play_time.seconds % 3600) % 60;
1162
                    SEQ_LCD_PrintFormattedString("%02d:%02d:%02d", hours, minutes, seconds);
1163
                }
1164
 
1165
                ///////////////////////////////////////////////////////////////////////////
1166
                // Print Total Play Time of Pattern
1167
                SEQ_LCD_CursorSet(35, 0);
1168
 
1169
                if ( seq_play_timer.seconds == 0 ) {
1170
                    SEQ_LCD_PrintFormattedString("00:00");
1171
                    pattern_remix_timer = MIOS32_SYS_TimeGet();
1172
                } else {
1173
                    mios32_sys_time_t play_time = MIOS32_SYS_TimeGet();
1174
                    play_time.seconds = play_time.seconds - pattern_remix_timer.seconds;
1175
                    int minutes = (play_time.seconds % 3600) / 60;
1176
                    int seconds = (play_time.seconds % 3600) % 60;
1177
                    SEQ_LCD_PrintFormattedString("%02d:%02d", minutes, seconds);   
1178
                }
1179
 
1180
        ///////////////////////////////////////////////////////////////////////////
1181
        // Print BPM
1182
        SEQ_LCD_CursorSet(71, 1);
1183
        float bpm = seq_core_bpm_preset_tempo[seq_core_bpm_preset_num];
1184
        SEQ_LCD_PrintFormattedString("%3d.%d BPM", (int)bpm, (int)(10*bpm)%10);
1185
 
1186
        ///////////////////////////////////////////////////////////////////////////
1187
        // Print Total Sequencer Position
1188
        //SEQ_LCD_CursorSet(64, 1);
1189
        //u32 tick = SEQ_BPM_TickGet();
1190
        //u32 ticks_per_step = SEQ_BPM_PPQN_Get() / 4;
1191
        //u32 ticks_per_measure = ticks_per_step * (seq_core_steps_per_measure+1);
1192
        //u32 measure = (tick / ticks_per_measure) + 1;
1193
        //u32 step = ((tick % ticks_per_measure) / ticks_per_step) + 1;
1194
        //u32 microstep = tick % ticks_per_step;
1195
        //SEQ_LCD_PrintFormattedString("%8u.%3d.%3d", measure, step, microstep);
1196
 
1197
        ///////////////////////////////////////////////////////////////////////////
1198
        // Requested Pattern Name
1199
        if ( preview_mode ) {
1200
 
1201
          SEQ_LCD_CursorSet(40, 0);
1202
          //SEQ_LCD_PrintPatternLabel(preview_pattern, preview_pattern.name);
1203
          //SEQ_LCD_PrintString(">>>");
1204
          //SEQ_LCD_PrintFormattedString("Pattern N: %d, B: %d", preview_name, preview_bank);
1205
          SEQ_LCD_PrintPattern(selected_pattern[0]);
1206
          SEQ_LCD_PrintFormattedString(": %s", preview_name);
1207
 
1208
                    if ( remix_mode ) {
1209
                        ///////////////////////////////////////////////////////////////////////////
1210
                        // Print Total Play Time of Pattern remixed
1211
                        SEQ_LCD_CursorSet(65, 0);
1212
                        mios32_sys_time_t play_time = MIOS32_SYS_TimeGet();
1213
                        play_time.seconds = play_time.seconds - seq_pattern_start_time.seconds;
1214
                        int minutes = (play_time.seconds % 3600) / 60;
1215
                        int seconds = (play_time.seconds % 3600) % 60;
1216
                        SEQ_LCD_PrintFormattedString("%02d:%02d", minutes, seconds);
1217
 
1218
                        /*
1219
 
1220
                        if ( seq_play_timer.seconds == 0 ) {
1221
                            SEQ_LCD_PrintFormattedString("00:00");
1222
                            pattern_remix_timer = MIOS32_SYS_TimeGet();
1223
                        } else {
1224
                            mios32_sys_time_t play_time = MIOS32_SYS_TimeGet();
1225
                            play_time.seconds = play_time.seconds - pattern_remix_timer.seconds;
1226
                            int minutes = (play_time.seconds % 3600) / 60;
1227
                            int seconds = (play_time.seconds % 3600) % 60;
1228
                            SEQ_LCD_PrintFormattedString("%02d:%02d", minutes, seconds);
1229
                        }
1230
 
1231
                         */
1232
                    }
1233
 
1234
        }
1235
 
1236
                if ( remix_mode ) {
1237
 
1238
                    SEQ_LCD_CursorSet(29, 0);
1239
                    SEQ_LCD_PrintFormattedString("REMIX");
1240
                }
1241
 
1242
        ///////////////////////////////////////////////////////////////////////////
1243
        // Remix matrix
1244
        if (seq_pattern_remix_map != 0) {
1245
 
1246
                    u8 track;  
1247
                    u8 spacer = 0;
1248
 
1249
          for(track=0; track<16; ++track) {
1250
 
1251
            if( !(track % 4) && (track!=0) )
1252
              spacer++;
1253
 
1254
            SEQ_LCD_CursorSet((track+spacer)+40, 1);
1255
 
1256
            // print who is in remix or deremix state
1257
            if( seq_pattern_remix_map & (1 << track) )
1258
              SEQ_LCD_PrintVBar('X');
1259
            else
1260
              SEQ_LCD_PrintVBar('_');
1261
 
1262
          }
1263
 
1264
        }
1265
 
1266
      }
1267
 
1268
    } break;
1269
 
1270
    ///////////////////////////////////////////////////////////////////////////
1271
    // Page do not exist
1272
    default:
1273
      break;
1274
 
1275
  }
1276
 
1277
  return 0; // no error
1278
}
1279
 
1280
 
1281
/////////////////////////////////////////////////////////////////////////////
1282
// Initialisation
1283
/////////////////////////////////////////////////////////////////////////////
1284
s32 SEQ_UI_PATTERN_RMX_Init(u32 mode)
1285
{
1286
 
1475 midilab 1287
    // init with our preview reference with the actucal pattern values
1288
    preview_num = seq_pattern[0].num;
1289
    preview_bank = seq_pattern[0].group;
1290
    //pattern_timer.seconds = 0;
1454 midilab 1291
 
1292
    // clean our string memory space
1475 midilab 1293
    //sprintf(pattern_name_copypaste, "");
1454 midilab 1294
 
1295
  // install callback routines
1296
  SEQ_UI_InstallButtonCallback(Button_Handler);
1297
  SEQ_UI_InstallEncoderCallback(Encoder_Handler);
1298
  SEQ_UI_InstallLEDCallback(LED_Handler);
1299
  SEQ_UI_InstallLCDCallback(LCD_Handler);
1300
 
1301
  // we want to show vertical VU meters
1302
  SEQ_LCD_InitSpecialChars(SEQ_LCD_CHARSET_VBars);
1303
 
1304
  // init selection patterns
1305
  u8 group;
1306
  for(group=0; group<SEQ_CORE_NUM_GROUPS; ++group)
1307
    selected_pattern[group] = seq_pattern[group];
1308
 
1309
  return 0; // no error
1310
}