Subversion Repositories svn.mios32

Rev

Rev 1322 | Rev 1422 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
262 tk 1
// $Id: seq_core.c 1421 2012-02-11 23:44:23Z tk $
2
/*
3
 * Sequencer Core Routines
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 <string.h>
20
#include <seq_bpm.h>
21
#include <seq_midi_out.h>
22
 
23
#include "seq_core.h"
1316 tk 24
#include "seq_song.h"
262 tk 25
#include "seq_random.h"
26
#include "seq_cc.h"
27
#include "seq_layer.h"
337 tk 28
#include "seq_scale.h"
339 tk 29
#include "seq_groove.h"
345 tk 30
#include "seq_humanize.h"
690 tk 31
#include "seq_morph.h"
599 tk 32
#include "seq_lfo.h"
690 tk 33
#include "seq_midi_port.h"
262 tk 34
#include "seq_midi_in.h"
406 tk 35
#include "seq_midi_router.h"
262 tk 36
#include "seq_par.h"
37
#include "seq_trg.h"
38
#include "seq_pattern.h"
39
#include "seq_random.h"
416 tk 40
#include "seq_record.h"
1219 tk 41
#include "seq_live.h"
754 tk 42
#include "seq_midply.h"
758 tk 43
#include "seq_midexp.h"
44
#include "seq_midimp.h"
1083 tk 45
#include "seq_cv.h"
944 tk 46
#include "seq_statistics.h"
262 tk 47
#include "seq_ui.h"
48
 
49
 
1316 tk 50
 
262 tk 51
/////////////////////////////////////////////////////////////////////////////
52
// Local definitions
53
/////////////////////////////////////////////////////////////////////////////
54
 
55
// set this to 1 if performance of clock handler should be measured with a scope
56
// (LED toggling in APP_Background() has to be disabled!)
57
// set this to 2 to visualize forward delay during pattern changes
286 tk 58
#define LED_PERFORMANCE_MEASURING 0
262 tk 59
 
286 tk 60
// same for measuring with the stopwatch
61
// value is visible in menu (-> press exit button)
747 tk 62
// value is visible in INFO->System page (-> press exit button, go to last item)
961 tk 63
#define STOPWATCH_PERFORMANCE_MEASURING 1
262 tk 64
 
286 tk 65
 
262 tk 66
/////////////////////////////////////////////////////////////////////////////
67
// Local prototypes
68
/////////////////////////////////////////////////////////////////////////////
69
 
599 tk 70
static s32 SEQ_CORE_ResetTrkPos(u8 track, seq_core_trk_t *t, seq_cc_trk_t *tcc);
593 tk 71
static s32 SEQ_CORE_NextStep(seq_core_trk_t *t, seq_cc_trk_t *tcc, u8 no_progression, u8 reverse);
262 tk 72
 
73
 
74
/////////////////////////////////////////////////////////////////////////////
75
// Global variables
76
/////////////////////////////////////////////////////////////////////////////
77
 
1313 tk 78
u32 seq_core_timestamp_ms;
79
 
262 tk 80
seq_core_options_t seq_core_options;
81
u8 seq_core_steps_per_measure;
758 tk 82
u8 seq_core_steps_per_pattern;
262 tk 83
 
1015 tk 84
u16 seq_core_trk_muted;
1261 tk 85
u16 seq_core_trk_synched_mute;
86
u16 seq_core_trk_synched_unmute;
1206 tk 87
seq_core_slaveclk_mute_t seq_core_slaveclk_mute;
1015 tk 88
 
751 tk 89
u8 seq_core_step_update_req;
90
 
262 tk 91
u8 seq_core_global_scale;
92
u8 seq_core_global_scale_ctrl;
93
u8 seq_core_global_scale_root;
94
u8 seq_core_global_scale_root_selection;
95
u8 seq_core_keyb_scale_root;
96
 
1320 tk 97
u8 seq_core_global_transpose_enabled;
98
 
491 tk 99
u8 seq_core_bpm_preset_num;
100
float seq_core_bpm_preset_tempo[SEQ_CORE_NUM_BPM_PRESETS];
101
float seq_core_bpm_preset_ramp[SEQ_CORE_NUM_BPM_PRESETS];
102
 
718 tk 103
u8 seq_core_din_sync_pulse_ctr;
262 tk 104
 
524 tk 105
mios32_midi_port_t seq_core_metronome_port;
106
u8 seq_core_metronome_chn;
107
u8 seq_core_metronome_note_m;
108
u8 seq_core_metronome_note_b;
109
 
262 tk 110
seq_core_state_t seq_core_state;
111
seq_core_trk_t seq_core_trk[SEQ_CORE_NUM_TRACKS];
112
 
596 tk 113
seq_core_loop_mode_t seq_core_glb_loop_mode;
114
u8 seq_core_glb_loop_offset;
115
u8 seq_core_glb_loop_steps;
262 tk 116
 
491 tk 117
 
262 tk 118
/////////////////////////////////////////////////////////////////////////////
119
// Local variables
120
/////////////////////////////////////////////////////////////////////////////
121
 
122
static u32 bpm_tick_prefetch_req;
123
static u32 bpm_tick_prefetched_ctr;
124
 
491 tk 125
static float seq_core_bpm_target;
126
static float seq_core_bpm_sweep_inc;
262 tk 127
 
491 tk 128
 
262 tk 129
/////////////////////////////////////////////////////////////////////////////
130
// Initialisation
131
/////////////////////////////////////////////////////////////////////////////
132
s32 SEQ_CORE_Init(u32 mode)
133
{
491 tk 134
  int i;
135
 
1313 tk 136
  seq_core_timestamp_ms = 0;
1015 tk 137
  seq_core_trk_muted = 0;
1206 tk 138
  seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
262 tk 139
  seq_core_options.ALL = 0;
1313 tk 140
  seq_core_options.PASTE_CLR_ALL = 1;
325 tk 141
  seq_core_steps_per_measure = 16-1;
758 tk 142
  seq_core_steps_per_pattern = 16-1;
262 tk 143
  seq_core_global_scale = 0;
144
  seq_core_global_scale_ctrl = 0; // global
145
  seq_core_global_scale_root_selection = 0; // from keyboard
146
  seq_core_keyb_scale_root = 0; // taken if enabled in OPT menu
1320 tk 147
  seq_core_global_transpose_enabled = 0;
718 tk 148
  seq_core_din_sync_pulse_ctr = 0; // used to generate a 1 mS pulse
262 tk 149
 
524 tk 150
  seq_core_metronome_port = DEFAULT;
151
  seq_core_metronome_chn = 10;
152
  seq_core_metronome_note_m = 0x25; // C#1
153
  seq_core_metronome_note_b = 0x25; // C#1
154
 
491 tk 155
  seq_core_bpm_preset_num = 13; // 140.0
156
  for(i=0; i<SEQ_CORE_NUM_BPM_PRESETS; ++i) {
157
    seq_core_bpm_preset_tempo[i] = 75.0 + 5.0*i;
158
    seq_core_bpm_preset_ramp[i] = 0.0;
159
  }
160
  seq_core_bpm_sweep_inc = 0.0;
161
 
262 tk 162
  seq_core_state.ALL = 0;
163
 
596 tk 164
  seq_core_glb_loop_mode = SEQ_CORE_LOOP_MODE_ALL_TRACKS_VIEW;
165
  seq_core_glb_loop_offset = 0;
166
  seq_core_glb_loop_steps = 16-1;
167
 
751 tk 168
  seq_core_step_update_req = 0;
169
 
262 tk 170
  // set initial seed of random generator
171
  SEQ_RANDOM_Gen(0xdeadbabe);
172
 
173
  // reset layers
174
  SEQ_LAYER_Init(0);
175
 
176
  // reset patterns
177
  SEQ_PATTERN_Init(0);
178
 
179
  // reset force-to-scale module
180
  SEQ_SCALE_Init(0);
181
 
339 tk 182
  // reset groove module
183
  SEQ_GROOVE_Init(0);
184
 
473 tk 185
  // reset morph module
186
  SEQ_MORPH_Init(0);
187
 
345 tk 188
  // reset humanizer module
189
  SEQ_HUMANIZE_Init(0);
190
 
599 tk 191
  // reset LFO module
192
  SEQ_LFO_Init(0);
193
 
399 tk 194
  // reset song module
195
  SEQ_SONG_Init(0);
196
 
1219 tk 197
  // reset live play module
198
  SEQ_LIVE_Init(0);
199
 
419 tk 200
  // reset record module
201
  SEQ_RECORD_Init(0);
202
 
758 tk 203
  // init MIDI file player/exporter/importer
754 tk 204
  SEQ_MIDPLY_Init(0);
758 tk 205
  SEQ_MIDEXP_Init(0);
206
  SEQ_MIDIMP_Init(0);
754 tk 207
 
262 tk 208
  // clear registers which are not reset by SEQ_CORE_Reset()
209
  u8 track;
600 tk 210
  seq_core_trk_t *t = &seq_core_trk[0];
211
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t) {
262 tk 212
 
213
    // if track name only contains spaces, the UI will print 
214
    // the track number instead of an empty message
215
    // this ensures highest flexibility (e.g. any track can 
216
    // play patterns normaly assigned for other tracks w/o inconsistent messages)
217
    // -> see SEQ_LCD_PrintTrackName()
218
    int i;
316 tk 219
    for(i=0; i<80; ++i)
717 tk 220
      t->name[i] = ' ';
221
    t->name[80] = 0;
222
 
223
    // clear glide note storage
224
    for(i=0; i<4; ++i)
225
      t->glide_notes[i] = 0;
826 tk 226
 
227
    // don't select sections
828 tk 228
    t->play_section = 0;
262 tk 229
  }
230
 
231
  // reset sequencer
1145 tk 232
  SEQ_CORE_Reset(0);
262 tk 233
 
755 tk 234
  // reset MIDI player
235
  SEQ_MIDPLY_Reset();
236
 
262 tk 237
  // init BPM generator
238
  SEQ_BPM_Init(0);
239
 
240
  SEQ_BPM_PPQN_Set(384);
491 tk 241
  SEQ_CORE_BPM_Update(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num], 0.0);
262 tk 242
 
286 tk 243
#if STOPWATCH_PERFORMANCE_MEASURING
944 tk 244
  SEQ_STATISTICS_StopwatchInit();
286 tk 245
#endif
246
 
262 tk 247
  return 0; // no error
248
}
249
 
250
 
251
/////////////////////////////////////////////////////////////////////////////
252
// this sequencer handler is called periodically to check for new requests
253
// from BPM generator
254
/////////////////////////////////////////////////////////////////////////////
255
s32 SEQ_CORE_Handler(void)
256
{
257
  // handle requests
258
 
1313 tk 259
  ++seq_core_timestamp_ms; // mS accurate timestamp
260
 
262 tk 261
  u8 num_loops = 0;
262
  u8 again = 0;
263
  do {
264
    ++num_loops;
265
 
266
    // note: don't remove any request check - clocks won't be propagated
1044 tk 267
    // as long as any Stop/Cont/Start/SongPos event hasn't been flagged to the sequencer
262 tk 268
    if( SEQ_BPM_ChkReqStop() ) {
653 tk 269
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfc, 0);
262 tk 270
      SEQ_CORE_PlayOffEvents();
754 tk 271
      SEQ_MIDPLY_PlayOffEvents();
262 tk 272
    }
273
 
274
    if( SEQ_BPM_ChkReqCont() ) {
1206 tk 275
      // release slave mute
276
      seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
277
 
653 tk 278
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfb, 0);
1206 tk 279
 
262 tk 280
      // release pause mode
281
      ui_seq_pause = 0;
282
    }
283
 
284
    if( SEQ_BPM_ChkReqStart() ) {
1206 tk 285
      // release slave mute
286
      seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
287
 
653 tk 288
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfa, 0);
1145 tk 289
      SEQ_SONG_Reset(0);
290
      SEQ_CORE_Reset(0);
755 tk 291
      SEQ_MIDPLY_Reset();
1421 tk 292
 
293
      // song page: start song at current edit position
294
      if( ui_page == SEQ_UI_PAGE_SONG ) {
295
    SEQ_SONG_PosSet(ui_song_edit_pos);
296
      }
262 tk 297
    }
298
 
299
    u16 new_song_pos;
300
    if( SEQ_BPM_ChkReqSongPos(&new_song_pos) ) {
1206 tk 301
      // release slave mute
302
      seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
303
 
1145 tk 304
      u32 new_tick = new_song_pos * (SEQ_BPM_PPQN_Get() / 4);
305
      SEQ_CORE_Reset(new_tick);
306
      SEQ_SONG_Reset(new_tick);
338 tk 307
 
1145 tk 308
#if 0
309
      // fast forward to new song position
310
      if( new_tick ) {
311
    u32 bpm_tick;
312
    for(bpm_tick=0; bpm_tick<=new_tick; bpm_tick+=24) {
313
      SEQ_BPM_TickSet(bpm_tick);
314
      SEQ_CORE_Tick(bpm_tick, -1, 1); // mute all non-loopback tracks
315
    }
316
    SEQ_BPM_TickSet(new_tick);
317
      }
318
#endif
757 tk 319
      SEQ_MIDPLY_SongPos(new_song_pos, 1);
262 tk 320
    }
321
 
322
    u32 bpm_tick;
323
    if( SEQ_BPM_ChkReqClk(&bpm_tick) > 0 ) {
762 tk 324
      // check all requests again after execution of this part
325
      again = 1;
326
 
262 tk 327
      if( bpm_tick_prefetched_ctr ) {
328
    // ticks already generated due to prefetching - wait until we catch up
329
    --bpm_tick_prefetched_ctr;
762 tk 330
      } else {
331
    // it's possible to forward the sequencer on pattern changes
332
    // in this case bpm_tick_prefetch_req is > bpm_tick
333
    // in all other cases, we only generate a single tick (realtime play)
262 tk 334
 
762 tk 335
    u32 bpm_tick_target = bpm_tick;
336
    u8 is_prefetch = 0;
337
    if( bpm_tick_prefetch_req > bpm_tick ) {
338
      is_prefetch = 1;
339
      bpm_tick_target = bpm_tick_prefetch_req;
340
      bpm_tick_prefetched_ctr = bpm_tick_target - bpm_tick;
341
#if 0
342
      DEBUG_MSG("[SEQ_CORE:%u] bpm_tick:%u  bpm_tick_target:%u  bpm_tick_prefetched_ctr:%u\n",
343
            SEQ_BPM_TickGet(), bpm_tick, bpm_tick_target, bpm_tick_prefetched_ctr);
286 tk 344
#endif
262 tk 345
    }
762 tk 346
 
347
    // invalidate request before a new one will be generated (e.g. via SEQ_SONG_NextPos())
262 tk 348
    bpm_tick_prefetch_req = 0;
762 tk 349
 
350
    for(; bpm_tick<=bpm_tick_target; ++bpm_tick) {
262 tk 351
#if LED_PERFORMANCE_MEASURING == 1
762 tk 352
      MIOS32_BOARD_LED_Set(0xffffffff, 1);
262 tk 353
#endif
286 tk 354
#if STOPWATCH_PERFORMANCE_MEASURING == 1
944 tk 355
      SEQ_STATISTICS_StopwatchReset();
286 tk 356
#endif
762 tk 357
 
358
      // generate MIDI events
1145 tk 359
      SEQ_CORE_Tick(bpm_tick, -1, 0);
762 tk 360
      SEQ_MIDPLY_Tick(bpm_tick);
361
 
262 tk 362
#if LED_PERFORMANCE_MEASURING == 1
762 tk 363
      MIOS32_BOARD_LED_Set(0xffffffff, 0);
262 tk 364
#endif
286 tk 365
#if STOPWATCH_PERFORMANCE_MEASURING == 1
944 tk 366
      SEQ_STATISTICS_StopwatchCapture();
286 tk 367
#endif
762 tk 368
 
369
      // load new pattern/song step if reference step reached measure
370
      // (this code is outside SEQ_CORE_Tick() to save stack space!)
371
      if( seq_core_state.ref_step == seq_core_steps_per_pattern && (bpm_tick % 96) == 20 ) {
372
        if( SEQ_SONG_ActiveGet() ) {
373
          SEQ_SONG_NextPos();
1319 tk 374
        } else if( seq_core_options.SYNCHED_PATTERN_CHANGE ) {
762 tk 375
          SEQ_PATTERN_Handler();
376
        }
1316 tk 377
 
762 tk 378
      }
379
    }
380
 
381
#if 0
382
    if( is_prefetch )
383
      DEBUG_MSG("[SEQ_CORE:%u] prefetching finished, saved %d ticks\n", SEQ_BPM_TickGet(), bpm_tick_target-SEQ_BPM_TickGet());
384
#endif
262 tk 385
      }
386
    }
387
  } while( again && num_loops < 10 );
388
 
389
  return 0; // no error
390
}
391
 
392
 
393
/////////////////////////////////////////////////////////////////////////////
394
// This function plays all "off" events
395
// Should be called on sequencer reset/restart/pause to avoid hanging notes
396
/////////////////////////////////////////////////////////////////////////////
759 tk 397
s32 SEQ_CORE_PlayOffEvents(void)
262 tk 398
{
399
  // play "off events"
400
  SEQ_MIDI_OUT_FlushQueue();
401
 
332 tk 402
  // clear sustain/stretch flags
262 tk 403
  u8 track;
600 tk 404
  seq_core_trk_t *t = &seq_core_trk[0];
405
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t) {
717 tk 406
    int i;
407
 
332 tk 408
    t->state.SUSTAINED = 0;
409
    t->state.STRETCHED_GL = 0;
717 tk 410
    for(i=0; i<4; ++i)
411
      t->glide_notes[i] = 0;
262 tk 412
  }
413
 
414
  return 0; // no error
415
}
416
 
417
 
418
/////////////////////////////////////////////////////////////////////////////
419
// Resets song position of sequencer
420
/////////////////////////////////////////////////////////////////////////////
1145 tk 421
s32 SEQ_CORE_Reset(u32 bpm_start)
262 tk 422
{
423
  ui_seq_pause = 0;
424
  seq_core_state.FIRST_CLK = 1;
425
 
1313 tk 426
  // reset latched PB/CC values
427
  SEQ_LAYER_ResetLatchedValues();
428
 
262 tk 429
  int track;
600 tk 430
  seq_core_trk_t *t = &seq_core_trk[0];
431
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
432
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc) {
262 tk 433
    t->state.ALL = 0;
599 tk 434
    SEQ_CORE_ResetTrkPos(track, t, tcc);
1145 tk 435
 
436
    // add track offset depending on start position
437
    if( bpm_start ) {
438
#if 0
439
      u32 step_length = ((tcc->clkdiv.value+1) * (tcc->clkdiv.TRIPLETS ? 4 : 6));
440
#else
441
      // leads to bad result with Logic Audio: it starts one step earlier and assumes 16th steps!
442
      u32 step_length = 96;
443
#endif
444
      u8 pos_step = (u8)((bpm_start / step_length) % ((u32)tcc->length+1));
445
 
446
      // next part depends on forward/backward direction
447
      if( tcc->dir_mode == SEQ_CORE_TRKDIR_Backward ) {
448
    t->step = tcc->length - pos_step;
449
      } else {
450
    t->step = pos_step;
451
      }
452
    }
453
 
419 tk 454
    SEQ_RECORD_Reset(track);
262 tk 455
  }
456
 
457
  // since timebase has been changed, ensure that Off-Events are played 
458
  // (otherwise they will be played much later...)
459
  SEQ_CORE_PlayOffEvents();
460
 
1145 tk 461
  // set BPM tick
462
  SEQ_BPM_TickSet(bpm_start);
262 tk 463
 
464
  // cancel prefetch requests/counter
465
  bpm_tick_prefetch_req = 0;
466
  bpm_tick_prefetched_ctr = 0;
467
 
1205 tk 468
  // cancel stop and set step request
600 tk 469
  seq_core_state.MANUAL_TRIGGER_STOP_REQ = 0;
470
 
1145 tk 471
  // reset reference step
472
  seq_core_state.ref_step = (u8)((bpm_start / 96) % ((u32)seq_core_steps_per_measure+1));
473
 
262 tk 474
  return 0; // no error
475
}
476
 
477
 
478
/////////////////////////////////////////////////////////////////////////////
479
// performs a single ppqn tick
761 tk 480
// if "export_track" is -1, all tracks will be played
481
// if "export_track" is between 0 and 15, only the given track + all loopback
759 tk 482
//   tracks will be played (for MIDI file export)
1145 tk 483
// if "mute_nonloopback_tracks" is set, the "normal" tracks won't be played
484
// this option is used for the "fast forward" function on song position changes
262 tk 485
/////////////////////////////////////////////////////////////////////////////
1145 tk 486
s32 SEQ_CORE_Tick(u32 bpm_tick, s8 export_track, u8 mute_nonloopback_tracks)
262 tk 487
{
757 tk 488
  // get MIDI File play mode (if set to SEQ_MIDPLY_MODE_Exclusive, all tracks will be muted)
1316 tk 489
  u8 midply_solo = SEQ_MIDPLY_RunModeGet() != 0 && SEQ_MIDPLY_ModeGet() == SEQ_MIDPLY_MODE_Exclusive;
757 tk 490
 
262 tk 491
  // increment reference step on each 16th note
492
  // set request flag on overrun (tracks can synch to measure)
493
  u8 synch_to_measure_req = 0;
524 tk 494
  if( (bpm_tick % (384/4)) == 0 &&
495
      (seq_core_state.FIRST_CLK || ++seq_core_state.ref_step > seq_core_steps_per_measure) ) {
1145 tk 496
    if( !seq_core_state.FIRST_CLK )
497
      seq_core_state.ref_step = 0;
524 tk 498
    synch_to_measure_req = 1;
262 tk 499
  }
500
 
1206 tk 501
  // disable slave clock mute if not in slave mode anymore
502
  // or start of if measure is reached and OffOnNextMeasure has been requested
1209 tk 503
  u8 is_master = SEQ_BPM_IsMaster();
504
  if( is_master ||
1206 tk 505
      (synch_to_measure_req && (seq_core_slaveclk_mute == SEQ_CORE_SLAVECLK_MUTE_OffOnNextMeasure)) ) {
506
    // enable ports
507
    seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
1209 tk 508
    if( !is_master ) {
509
      // release pause mode
510
      ui_seq_pause = 0;
511
      // TK: this makes sense! Request synch-to-measure for all tracks so that they restart properly
1315 tk 512
      SEQ_CORE_ManualSynchToMeasure(0xffff);
1209 tk 513
    }
1206 tk 514
  }
515
 
1145 tk 516
  // if no export and no mute:
517
  if( export_track == -1 && !mute_nonloopback_tracks ) {
1048 tk 518
    // send FA if external restart has been requested
519
    if( seq_core_state.EXT_RESTART_REQ && synch_to_measure_req ) {
520
      seq_core_state.EXT_RESTART_REQ = 0; // remove request
521
      seq_ui_display_update_req = 1; // request display update
522
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfa, bpm_tick);
523
    }
524
 
761 tk 525
    // send MIDI clock on each 16th tick (since we are working at 384ppqn)
526
    if( (bpm_tick % 16) == 0 )
527
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xf8, bpm_tick);
262 tk 528
 
761 tk 529
    // trigger DIN Sync clock with a special event (0xf9 normaly used for "MIDI tick")
530
    // SEQ_MIDI_PORT_NotifyMIDITx filters it before it will be forwarded to physical ports
1083 tk 531
    if( (bpm_tick % SEQ_CV_ClkDividerGet()) == 0 ) {
761 tk 532
      mios32_midi_package_t p;
533
      p.ALL = 0;
534
      p.type = 0x5; // Single-byte system common message
535
      p.evnt0 = 0xf9;
536
      SEQ_MIDI_OUT_Send(0xff, p, SEQ_MIDI_OUT_ClkEvent, bpm_tick, 0);
537
    }
718 tk 538
 
761 tk 539
    // send metronome tick on each beat if enabled
1145 tk 540
    if( seq_core_state.METRONOME && seq_core_metronome_chn && (bpm_tick % 96) == 0 && (seq_core_state.ref_step % 4) == 0 ) {
761 tk 541
      mios32_midi_package_t p;
262 tk 542
 
761 tk 543
      p.type     = NoteOn;
544
      p.cable    = 15; // use tag of track #16 - unfortunately more than 16 tags are not supported
545
      p.event    = NoteOn;
546
      p.chn      = seq_core_metronome_chn-1;
547
      p.note     = seq_core_metronome_note_b;
548
      p.velocity = 96;
549
      u16 len = 20; // ca. 25% of a 16th
524 tk 550
 
1145 tk 551
      if( seq_core_state.ref_step == 0 ) {
761 tk 552
    if( seq_core_metronome_note_m )
553
      p.note = seq_core_metronome_note_m; // if this note isn't defined, use B note instead
554
    p.velocity = 127;
555
      }
556
 
557
      if( p.note )
558
    SEQ_MIDI_OUT_Send(seq_core_metronome_port, p, SEQ_MIDI_OUT_OnOffEvent, bpm_tick, len);
524 tk 559
    }
560
  }
561
 
1261 tk 562
  // delayed mute
563
  if( synch_to_measure_req ) {
564
    // the priority handling for each individual track ensures
565
    // that mute/unmute will be done depending on the current mute state
566
    // unmute has higher priority than mute
567
    seq_core_trk_muted |= (seq_core_trk_synched_mute & ~seq_core_trk_muted);
568
    seq_core_trk_synched_mute = 0;
524 tk 569
 
1261 tk 570
    seq_core_trk_muted &= ~(seq_core_trk_synched_unmute & seq_core_trk_muted);
571
    seq_core_trk_synched_unmute = 0;
572
  }
573
 
574
 
262 tk 575
  // process all tracks
718 tk 576
  // first the loopback port Bus1, thereafter parameters sent to common MIDI ports
302 tk 577
  int round;
578
  for(round=0; round<2; ++round) {
579
    seq_core_trk_t *t = &seq_core_trk[0];
580
    seq_cc_trk_t *tcc = &seq_cc_trk[0];
581
    int track;
582
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++t, ++tcc, ++track) {
262 tk 583
 
718 tk 584
      // round 0: loopback port Bus1, round 1: remaining ports
1023 tk 585
      u8 loopback_port = (tcc->midi_port & 0xf0) == 0xf0;
302 tk 586
      if( (!round && !loopback_port) || (round && loopback_port) )
262 tk 587
    continue;
306 tk 588
 
761 tk 589
      // for MIDI file export: (export_track != -1): only given track + all loopback tracks will be played
590
      if( round && export_track != -1 && export_track != track )
759 tk 591
    continue;
592
 
599 tk 593
      // handle LFO effect
594
      SEQ_LFO_HandleTrk(track, bpm_tick);
595
 
596
      // send LFO CC (if enabled)
1206 tk 597
      if( !(seq_core_trk_muted & (1 << track)) && !seq_core_slaveclk_mute ) {
599 tk 598
    mios32_midi_package_t p;
741 tk 599
    if( SEQ_LFO_FastCC_Event(track, bpm_tick, &p) > 0 ) {
600
      if( loopback_port )
1023 tk 601
        SEQ_MIDI_IN_BusReceive(tcc->midi_port, p, 1); // forward to MIDI IN handler immediately
741 tk 602
      else
603
        SEQ_MIDI_OUT_Send(tcc->midi_port, p, SEQ_MIDI_OUT_CCEvent, bpm_tick, 0);
604
    }
599 tk 605
      }
606
 
330 tk 607
      // sustained note: play off event if sustain mode has been disabled and no stretched gatelength
473 tk 608
      if( t->state.SUSTAINED && !tcc->mode.SUSTAIN && !t->state.STRETCHED_GL ) {
717 tk 609
    int i;
610
 
611
    // important: play Note Off before new Note On to avoid that glide is triggered on the synth
1319 tk 612
    SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, bpm_tick ? (bpm_tick-1) : 0,
613
                seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 614
    // clear state flag and note storage
332 tk 615
    t->state.SUSTAINED = 0;
717 tk 616
    for(i=0; i<4; ++i)
617
      t->glide_notes[i] = 0;
306 tk 618
      }
338 tk 619
 
302 tk 620
      // if "synch to measure" flag set: reset track if master has reached the selected number of steps
621
      // MEMO: we could also provide the option to synch to another track
600 tk 622
      if( synch_to_measure_req && (tcc->clkdiv.SYNCH_TO_MEASURE || t->state.SYNC_MEASURE) )
599 tk 623
        SEQ_CORE_ResetTrkPos(track, t, tcc);
1211 tk 624
 
1121 tk 625
      u8 skip_this_step = 0;
1211 tk 626
      u8 next_step_event = t->state.FIRST_CLK || bpm_tick >= t->timestamp_next_step;
1316 tk 627
      if( next_step_event ) {
338 tk 628
 
1211 tk 629
    if( next_step_event ) {
630
      // calculate step length
631
      u16 step_length_pre = ((tcc->clkdiv.value+1) * (tcc->clkdiv.TRIPLETS ? 4 : 6));
632
      t->step_length = step_length_pre;
344 tk 633
 
1211 tk 634
      // set timestamp of next step w/o groove delay (reference timestamp)
635
      if( t->state.FIRST_CLK )
636
        t->timestamp_next_step_ref = bpm_tick + t->step_length;
637
      else
638
        t->timestamp_next_step_ref += t->step_length;
828 tk 639
 
1211 tk 640
      // increment step if not in arpeggiator mode or arp position == 0
641
      if( tcc->mode.playmode != SEQ_CORE_TRKMODE_Arpeggiator || !t->arp_pos ) {
642
        // wrap step position around length - especially required for "section selection" later,
643
        // which can set t->step beyond tcc->length+1
644
        u8 prev_step = (u8)((int)t->step % ((int)tcc->length + 1));
645
        t->step = prev_step; // store back wrapped step position
646
 
647
        u8 skip_ctr = 0;
648
        do {
649
          if( t->state.MANUAL_STEP_REQ ) {
650
        // manual step requested
651
        t->state.MANUAL_STEP_REQ = 0;
652
        t->step = t->manual_step;
653
        t->step_saved = t->manual_step;
654
          } else {
655
        // determine next step depending on direction mode
656
        if( !t->state.FIRST_CLK )
657
          SEQ_CORE_NextStep(t, tcc, 0, 0); // 0, 0=with progression, not reverse
1219 tk 658
        else {
659
          // ensure that position reset request is cleared
660
          t->state.POS_RESET = 0;
661
        }
1211 tk 662
          }
302 tk 663
 
1211 tk 664
          // clear "first clock" flag (on following clock ticks we can continue as usual)
665
          t->state.FIRST_CLK = 0;
302 tk 666
 
1211 tk 667
          // if skip flag set for this flag: try again
668
          if( SEQ_TRG_SkipGet(track, t->step, 0) )
669
        ++skip_ctr;
670
          else
671
        break;
344 tk 672
 
1211 tk 673
        } while( skip_ctr < 32 ); // try 32 times maximum
828 tk 674
 
1211 tk 675
        // Section selection
676
        // Approach:
677
        // o enabled with t->play_section > 0
678
        // o section width matches with the Track length, which means that the sequencer will
679
        //   play steps beyond the "last step" with t->play_section > 0
680
        // o section controlled via UI, MIDI Keyboard or BLM
681
        // o lower priority than global loop mode
682
        if( t->play_section > 0 ) {
683
          // note: SEQ_TRG_Get() will return 0 if t->step beyond total track size - no need to consider this here
684
          int step_offset = t->play_section * ((int)tcc->length+1);
685
          t->step += step_offset;
686
        }
596 tk 687
 
1211 tk 688
        // global loop mode handling
689
        // requirements:
690
        // o loop all or only select tracks
691
        // o allow to loop the step view (16 step window) or a definable number of steps
692
        // o wrap step position properly when loop mode is activated so that this
693
        //   doesn't "dirsturb" the sequence output (ensure that the track doesn't get out of sync)
694
        if( seq_core_state.LOOP ) {
695
          u8 loop_active = 0;
696
          int step_offset = 0;
697
 
698
          switch( seq_core_glb_loop_mode ) {
596 tk 699
          case SEQ_CORE_LOOP_MODE_ALL_TRACKS_STATIC:
700
        loop_active = 1;
701
        break;
702
 
703
          case SEQ_CORE_LOOP_MODE_SELECTED_TRACK_STATIC:
704
        if( SEQ_UI_IsSelectedTrack(track) )
705
          loop_active = 1;
706
        break;
707
 
708
          case SEQ_CORE_LOOP_MODE_ALL_TRACKS_VIEW:
709
        loop_active = 1;
710
        // no break!
711
 
712
          case SEQ_CORE_LOOP_MODE_SELECTED_TRACK_VIEW:
713
        if( SEQ_UI_IsSelectedTrack(track) )
714
          loop_active = 1;
715
 
716
        step_offset = 16 * ui_selected_step_view;
717
        break;
1211 tk 718
          }
596 tk 719
 
1211 tk 720
          if( loop_active ) {
721
        // wrap step position within given boundaries if required
722
        step_offset += seq_core_glb_loop_offset;
723
        step_offset %= ((int)tcc->length+1);
596 tk 724
 
1211 tk 725
        int loop_steps = seq_core_glb_loop_steps + 1;
726
        int max_steps = (int)tcc->length + 1;
727
        if( loop_steps > max_steps )
728
          loop_steps = max_steps;
596 tk 729
 
1211 tk 730
        int new_step = (int)t->step;
731
        new_step = step_offset + ((new_step-step_offset) % loop_steps);
596 tk 732
 
1211 tk 733
        if( new_step > tcc->length )
734
          new_step = step_offset;
735
        t->step = new_step;
736
          }
596 tk 737
        }
738
 
1211 tk 739
        // calculate number of cycles to next step
599 tk 740
#if 0
1211 tk 741
        t->timestamp_next_step = t->timestamp_next_step_ref + SEQ_GROOVE_DelayGet(track, t->step + 1);
599 tk 742
#else
1211 tk 743
        t->timestamp_next_step = t->timestamp_next_step_ref + SEQ_GROOVE_DelayGet(track, seq_core_state.ref_step + 1);
599 tk 744
#endif
419 tk 745
 
1211 tk 746
        skip_this_step = !seq_record_options.FWD_MIDI && t->state.REC_DONT_OVERWRITE_NEXT_STEP;
747
        // forward new step to recording function (only used in live recording mode)
748
        SEQ_RECORD_NewStep(track, prev_step, t->step, bpm_tick);
751 tk 749
 
1211 tk 750
        // inform UI about a new step (UI will clear this variable)
751
        seq_core_step_update_req = 1;
752
      }
753
    }
338 tk 754
 
302 tk 755
        // solo function: don't play MIDI event if track not selected
756
        // mute function
330 tk 757
        // track disabled
1145 tk 758
    // mute for non-loopback tracks activated
757 tk 759
    // MIDI player in exclusive mode
1121 tk 760
    // Record Mode, new step and FWD_MIDI off
338 tk 761
        if( (seq_ui_button_state.SOLO && !SEQ_UI_IsSelectedTrack(track)) ||
1015 tk 762
        (seq_core_trk_muted & (1 << track)) || // Track Mute function
1206 tk 763
        seq_core_slaveclk_mute || // Slave Clock Mute Function
607 tk 764
        SEQ_MIDI_PORT_OutMuteGet(tcc->midi_port) || // Port Mute Function
757 tk 765
        tcc->mode.playmode == SEQ_CORE_TRKMODE_Off || // track disabled
1145 tk 766
        (round && mute_nonloopback_tracks) || // all non-loopback tracks should be muted
1121 tk 767
        midply_solo || // MIDI player in exclusive mode
768
        skip_this_step ) { // Record Mode, new step and FWD_MIDI off
419 tk 769
 
338 tk 770
      if( t->state.STRETCHED_GL || t->state.SUSTAINED ) {
717 tk 771
        int i;
772
 
773
        if( !t->state.STRETCHED_GL ) // important: play Note Off before new Note On to avoid that glide is triggered on the synth
1319 tk 774
          SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, bpm_tick ? (bpm_tick-1) : 0,
775
                      seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 776
        else // Glide
1319 tk 777
          SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, bpm_tick,
778
                      seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 779
 
780
        // clear state flags and note storage
338 tk 781
        t->state.STRETCHED_GL = 0;
782
        t->state.SUSTAINED = 0;
717 tk 783
        for(i=0; i<4; ++i)
784
          t->glide_notes[i] = 0;
338 tk 785
      }
419 tk 786
 
330 tk 787
      continue;
338 tk 788
    }
1211 tk 789
 
302 tk 790
        // if random gate trigger set: play step with 1:1 probability
328 tk 791
        if( SEQ_TRG_RandomGateGet(track, t->step, 0) && (SEQ_RANDOM_Gen(0) & 1) )
302 tk 792
      continue;
334 tk 793
 
1219 tk 794
    // parameter layer mute flags (only if not in drum mode)
795
    u16 layer_muted = (tcc->event_mode != SEQ_EVENT_MODE_Drum) ? t->layer_muted : 0;
796
 
473 tk 797
    // check probability if not in drum mode
334 tk 798
    // if probability < 100: play step with given probability
473 tk 799
    // in drum mode, the probability is checked for each individual instrument inside the layer event loop
334 tk 800
    if( tcc->event_mode != SEQ_EVENT_MODE_Drum ) {
801
      u8 rnd_probability;
1219 tk 802
      if( (rnd_probability=SEQ_PAR_ProbabilityGet(track, t->step, 0, layer_muted)) < 100 &&
334 tk 803
          SEQ_RANDOM_Gen_Range(0, 99) >= rnd_probability )
804
        continue;
805
    }
419 tk 806
 
717 tk 807
    // store last glide notes before they will be cleared
808
    u32 last_glide_notes[4];
809
    memcpy(last_glide_notes, t->glide_notes, 4*4);
419 tk 810
 
323 tk 811
        seq_layer_evnt_t layer_events[16];
1211 tk 812
        s32 number_of_events = 0;
813
 
1316 tk 814
    number_of_events = SEQ_LAYER_GetEvents(track, t->step, layer_events, 0);
1211 tk 815
    if( number_of_events > 0 ) {
328 tk 816
      int i;
419 tk 817
 
818
      //////////////////////////////////////////////////////////////////////////////////////////
819
      // First pass: handle length and apply functions which modify the MIDI events
820
      //////////////////////////////////////////////////////////////////////////////////////////
821
      u16 prev_bpm_tick_delay = t->bpm_tick_delay;
822
      u8 gen_on_events = 0; // new On Events will be generated
823
      u8 gen_sustained_events = 0; // new sustained On Events will be generated
608 tk 824
      u8 gen_off_events = 0; // Off Events of previous step will be generated, the variable contains the remaining gatelength
419 tk 825
 
323 tk 826
          seq_layer_evnt_t *e = &layer_events[0];
827
          for(i=0; i<number_of_events; ++e, ++i) {
828
            mios32_midi_package_t *p = &e->midi_package;
328 tk 829
 
332 tk 830
        // instrument layers only used for drum tracks
686 tk 831
        u8 instrument = (tcc->event_mode == SEQ_EVENT_MODE_Drum) ? e->layer_tag : 0;
330 tk 832
 
334 tk 833
        // individual for each instrument in drum mode:
834
        // if probability < 100: play step with given probability
835
        if( tcc->event_mode == SEQ_EVENT_MODE_Drum ) {
836
          u8 rnd_probability;
1219 tk 837
          if( (rnd_probability=SEQ_PAR_ProbabilityGet(track, t->step, instrument, layer_muted)) < 100 &&
334 tk 838
          SEQ_RANDOM_Gen_Range(0, 99) >= rnd_probability )
839
        continue;
840
        }
841
 
323 tk 842
            // transpose notes/CCs
843
            SEQ_CORE_Transpose(t, tcc, p);
330 tk 844
 
1142 tk 845
            // glide trigger
846
            if( e->len > 0 && tcc->event_mode != SEQ_EVENT_MODE_Drum ) {
847
          if( SEQ_TRG_GlideGet(track, t->step, instrument) )
848
        e->len = 96; // Glide
849
            }
850
 
851
        // if glided note already played: omit new note event by setting velocity to 0
852
        if( t->state.STRETCHED_GL && (last_glide_notes[p->note / 32] & (1 << (p->note % 32))) ) {
853
          p->velocity = 0;
854
        }
855
 
856
            // skip if velocity has been cleared by transpose or glide function
323 tk 857
            // (e.g. no key pressed in transpose mode)
330 tk 858
            if( p->type == NoteOn && !p->velocity ) {
859
          // stretched note, length < 96: queue off event
419 tk 860
          if( t->state.STRETCHED_GL && t->state.SUSTAINED && (e->len < 96) )
608 tk 861
        gen_off_events = (t->step_length * e->len) / 96;
323 tk 862
          continue;
330 tk 863
        }
306 tk 864
 
338 tk 865
        // get delay of step (0..95)
866
        // note: negative delays stored in step parameters would require to pre-generate bpm_ticks, 
867
        // which would reduce the immediate response on value/trigger changes
868
        // therefore negative delays are only supported for groove patterns, and they are
869
        // applied over the whole track (e.g. drum mode: all instruments of the appr. track)
1219 tk 870
        t->bpm_tick_delay = SEQ_PAR_StepDelayGet(track, t->step, instrument, layer_muted);
338 tk 871
 
339 tk 872
        // scale delay (0..95) over next clock counter to consider the selected clock divider
873
        if( t->bpm_tick_delay )
344 tk 874
          t->bpm_tick_delay = (t->bpm_tick_delay * t->step_length) / 96;
339 tk 875
 
876
 
419 tk 877
            if( p->type != NoteOn ) {
1024 tk 878
          // apply Pre-FX
879
          if( !SEQ_TRG_NoFxGet(track, t->step, instrument) ) {
880
        SEQ_LFO_Event(track, e);
881
          }
882
 
330 tk 883
            } else if( p->note && p->velocity && (e->len >= 0) ) {
419 tk 884
          // Note Event
330 tk 885
 
339 tk 886
          // groove it
599 tk 887
#if 0
339 tk 888
          SEQ_GROOVE_Event(track, t->step, e);
599 tk 889
#else
890
          SEQ_GROOVE_Event(track, seq_core_state.ref_step, e);
891
#endif
339 tk 892
 
608 tk 893
          // apply Pre-FX before force-to-scale
599 tk 894
          if( !SEQ_TRG_NoFxGet(track, t->step, instrument) ) {
473 tk 895
        SEQ_HUMANIZE_Event(track, t->step, e);
599 tk 896
        SEQ_LFO_Event(track, e);
608 tk 897
          }
898
 
899
          // force to scale
900
          if( tcc->mode.FORCE_SCALE ) {
901
        u8 scale, root_selection, root;
902
        SEQ_CORE_FTS_GetScaleAndRoot(&scale, &root_selection, &root);
903
        SEQ_SCALE_Note(p, scale, root);
904
          }
905
 
906
          // apply Pre-FX after force-to-scale
907
          if( !SEQ_TRG_NoFxGet(track, t->step, instrument) ) {
600 tk 908
        SEQ_CORE_Limit(t, tcc, e); // should be the last Fx in the chain!
599 tk 909
          }
345 tk 910
 
1117 tk 911
          // force velocity to 0x7f (drum mode: selectable value) if accent flag set
912
          if( SEQ_TRG_AccentGet(track, t->step, instrument) ) {
913
        if( tcc->event_mode == SEQ_EVENT_MODE_Drum )
914
          p->velocity = tcc->lay_const[2*16 + i];
915
        else
916
          p->velocity = 0x7f;
917
          }
918
 
330 tk 919
          // sustained or stretched note: play off event of previous step
419 tk 920
          if( t->state.SUSTAINED )
921
        gen_off_events = 1;
330 tk 922
 
717 tk 923
          if( tcc->mode.SUSTAIN || e->len >= 96 )
419 tk 924
        gen_sustained_events = 1;
717 tk 925
          else {
419 tk 926
        // generate common On event with given length
927
        gen_on_events = 1;
928
          }
717 tk 929
        } else if( t->state.STRETCHED_GL && t->state.SUSTAINED && (e->len < 96) ) {
419 tk 930
          // stretched note, length < 96: queue off events
608 tk 931
          gen_off_events = (t->step_length * e->len) / 96;
419 tk 932
        }
933
      }
328 tk 934
 
419 tk 935
      // should Note Off events be played before new events are queued?
936
      if( gen_off_events ) {
717 tk 937
        int i;
938
 
939
        u32 rescheduled_tick = bpm_tick + prev_bpm_tick_delay + gen_off_events;
940
        if( !t->state.STRETCHED_GL ) // important: play Note Off before new Note On to avoid that glide is triggered on the synth
941
          rescheduled_tick -= 1;
1319 tk 942
        SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, rescheduled_tick,
943
                    seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 944
 
945
        // clear state flag and note storage
419 tk 946
        t->state.SUSTAINED = 0;
947
        t->state.STRETCHED_GL = 0;
717 tk 948
        for(i=0; i<4; ++i)
949
          t->glide_notes[i] = 0;
419 tk 950
      }
951
 
952
 
953
      //////////////////////////////////////////////////////////////////////////////////////////
954
      // Second pass: schedule new events
955
      //////////////////////////////////////////////////////////////////////////////////////////
956
          e = &layer_events[0];
957
          for(i=0; i<number_of_events; ++e, ++i) {
958
            mios32_midi_package_t *p = &e->midi_package;
959
 
960
        // instrument layers only used for drum tracks
686 tk 961
        u8 instrument = (tcc->event_mode == SEQ_EVENT_MODE_Drum) ? e->layer_tag : 0;
419 tk 962
 
963
        if( p->type != NoteOn ) {
964
          // e.g. CC or PitchBend
600 tk 965
          if( loopback_port )
1023 tk 966
        SEQ_MIDI_IN_BusReceive(tcc->midi_port, *p, 1); // forward to MIDI IN handler immediately
600 tk 967
          else
968
        SEQ_MIDI_OUT_Send(tcc->midi_port, *p, SEQ_MIDI_OUT_CCEvent, bpm_tick + t->bpm_tick_delay, 0);
419 tk 969
          t->vu_meter = 0x7f; // for visualisation in mute menu
970
        } else {
1319 tk 971
          // skip in record mode if the same note is already played
972
          if( seq_record_state.ENABLED &&
973
          (seq_record_played_notes[p->note>>5] & (1 << (p->note&0x1f))) )
974
        continue;
975
 
717 tk 976
          // sustained/glided note: play note at timestamp, and queue off event at 0xffffffff (so that it can be re-scheduled)      
419 tk 977
          if( gen_sustained_events ) {
717 tk 978
        u32 scheduled_tick = bpm_tick + t->bpm_tick_delay;
979
 
980
        // glide: if same note already played, play the new one a tick later for 
981
        // proper handling of "fingered portamento" function on some synths
982
        if( last_glide_notes[p->note / 32] & (1 << (p->note % 32)) )
983
          scheduled_tick += 1;
984
 
761 tk 985
        // for visualisation in mute menu
986
        t->vu_meter = p->velocity;
987
 
717 tk 988
        SEQ_MIDI_OUT_Send(tcc->midi_port, *p, SEQ_MIDI_OUT_OnEvent, scheduled_tick, 0);
984 tk 989
 
990
        // apply Post-FX
991
        if( !SEQ_TRG_NoFxGet(track, t->step, instrument) ) {
1219 tk 992
          u8 local_gatelength = 95; // echo only with reduced gatelength to avoid killed notes
993
          SEQ_CORE_Echo(t, tcc, *p, bpm_tick + t->bpm_tick_delay, local_gatelength);
984 tk 994
        }
995
 
996
        // Note Off
419 tk 997
        p->velocity = 0;
998
        SEQ_MIDI_OUT_Send(tcc->midi_port, *p, SEQ_MIDI_OUT_OffEvent, 0xffffffff, 0);
999
 
1000
        // notify stretched gatelength if not in sustain mode
1001
        t->state.SUSTAINED = 1;
717 tk 1002
        if( !tcc->mode.SUSTAIN ) {
419 tk 1003
          t->state.STRETCHED_GL = 1;
717 tk 1004
          // store glide note number in 128 bit array for later checks
1005
          t->glide_notes[p->note / 32] |= (1 << (p->note % 32));
1006
        }
984 tk 1007
 
419 tk 1008
          } else if( gen_on_events ) {
1009
        // for visualisation in mute menu
1010
        t->vu_meter = p->velocity;
1011
 
323 tk 1012
        if( loopback_port ) {
1013
          // forward to MIDI IN handler immediately
1023 tk 1014
          SEQ_MIDI_IN_BusReceive(tcc->midi_port, *p, 1);
323 tk 1015
          // multi triggers, but also echo not possible on loopback ports
273 tk 1016
        } else {
419 tk 1017
          u16 gatelength = e->len;
1018
          u8 triggers = 1;
1019
 
1020
          // roll/flam?
1021
          // get roll mode from parameter layer
1219 tk 1022
          u8 roll_mode = SEQ_PAR_RollModeGet(track, t->step, instrument, layer_muted);
1024 tk 1023
          u8 roll2_mode = 0; // taken if roll1 not assigned
419 tk 1024
          // with less priority (parameter == 0): force roll mode if Roll trigger is set
1025
          if( !roll_mode && SEQ_TRG_RollGet(track, t->step, instrument) )
1023 tk 1026
            roll_mode = 0x0a; // 2D10
419 tk 1027
          // if roll mode != 0: increase number of triggers
1024 tk 1028
          if( roll_mode ) {
419 tk 1029
            triggers = ((roll_mode & 0x30)>>4) + 2;
1024 tk 1030
          } else {
1219 tk 1031
            roll2_mode = SEQ_PAR_Roll2ModeGet(track, t->step, instrument, layer_muted);
1024 tk 1032
            if( roll2_mode )
1033
              triggers = (roll2_mode >> 5) + 2;
1034
          }
419 tk 1035
 
1024 tk 1036
 
323 tk 1037
          if( triggers > 1 ) {
1024 tk 1038
            if( roll2_mode ) {
1039
              // force gatelength depending on roll2 value
1040
              gatelength = (8 - 2*(roll2_mode >> 5)) * ((roll2_mode&0x1f)+1);
339 tk 1041
 
1024 tk 1042
              // scale length (0..95) over next clock counter to consider the selected clock divider
1043
              int gatelength = (4 - (roll2_mode >> 5)) * ((roll2_mode&0x1f)+1);
337 tk 1044
 
1024 tk 1045
              u32 half_gatelength = gatelength/2;
1046
              if( !half_gatelength )
1047
            half_gatelength = 1;
323 tk 1048
 
1024 tk 1049
              int i;
1050
              for(i=triggers-1; i>=0; --i)
1051
            SEQ_MIDI_OUT_Send(tcc->midi_port, *p, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay + i*gatelength, half_gatelength);
1052
            } else {
1053
              // force gatelength depending on number of triggers
1054
              if( triggers < 6 ) {
1055
            //       number of triggers:    2   3   4   5
1056
            const u8 gatelength_tab[4] = { 48, 32, 36, 32 };
1057
            // strategy:
1058
            // 2 triggers: played within 1 step at 0 and 48
1059
            // 3 triggers: played within 1 step at 0, 32 and 64
1060
            // 4 triggers: played within 1.5 steps at 0, 36, 72 and 108
1061
            // 5 triggers: played within 1.5 steps at 0, 32, 64, 96 and 128
1062
 
1063
            // in addition, scale length (0..95) over next clock counter to consider the selected clock divider
1064
            gatelength = (gatelength_tab[triggers-2] * t->step_length) / 96;
334 tk 1065
              }
1024 tk 1066
 
1067
              u32 half_gatelength = gatelength/2;
1068
              if( !half_gatelength )
1069
            half_gatelength = 1;
1070
 
1071
              mios32_midi_package_t p_multi = *p;
1072
              u16 roll_attenuation = 256 - (2 * triggers * (16 - (roll_mode & 0x0f))); // magic formula for nice effects
1073
              if( roll_mode & 0x40 ) { // upwards
1074
            int i;
1075
            for(i=triggers-1; i>=0; --i) {
1076
              SEQ_MIDI_OUT_Send(tcc->midi_port, p_multi, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay + i*gatelength, half_gatelength);
334 tk 1077
              u16 velocity = roll_attenuation * p_multi.velocity;
1078
              p_multi.velocity = velocity >> 8;
1079
            }
1024 tk 1080
              } else { // downwards
1081
            int i;
1082
            for(i=0; i<triggers; ++i) {
1083
              SEQ_MIDI_OUT_Send(tcc->midi_port, p_multi, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay + i*gatelength, half_gatelength);
1084
              if( roll_mode ) {
1085
                u16 velocity = roll_attenuation * p_multi.velocity;
1086
                p_multi.velocity = velocity >> 8;
1087
              }
1088
            }
334 tk 1089
              }
1090
            }
302 tk 1091
          } else {
323 tk 1092
            if( !gatelength )
1093
              gatelength = 1;
339 tk 1094
            else // scale length (0..95) over next clock counter to consider the selected clock divider
344 tk 1095
              gatelength = (gatelength * t->step_length) / 96;
338 tk 1096
            SEQ_MIDI_OUT_Send(tcc->midi_port, *p, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay, gatelength);
419 tk 1097
          }
323 tk 1098
 
600 tk 1099
          // apply Post-FX
419 tk 1100
          if( !SEQ_TRG_NoFxGet(track, t->step, instrument) ) {
1101
            if( tcc->echo_repeats && gatelength )
1102
              SEQ_CORE_Echo(t, tcc, *p, bpm_tick + t->bpm_tick_delay, gatelength);
1103
          }
323 tk 1104
        }
262 tk 1105
          }
323 tk 1106
            }
1107
          }
302 tk 1108
        }
262 tk 1109
      }
1110
    }
1111
  }
761 tk 1112
 
262 tk 1113
  // clear "first clock" flag if it was set before
1114
  seq_core_state.FIRST_CLK = 0;
1115
 
600 tk 1116
  // if manual trigger function requested stop: stop sequencer at end of reference step
1117
  if( seq_core_state.MANUAL_TRIGGER_STOP_REQ && (bpm_tick % 96) == 95 )
1118
    SEQ_BPM_Stop();
1119
 
262 tk 1120
  return 0; // no error
1121
}
1122
 
1123
 
1124
/////////////////////////////////////////////////////////////////////////////
1125
// Resets the step position variables of a track
1126
/////////////////////////////////////////////////////////////////////////////
599 tk 1127
static s32 SEQ_CORE_ResetTrkPos(u8 track, seq_core_trk_t *t, seq_cc_trk_t *tcc)
262 tk 1128
{
600 tk 1129
  // synch to measure done
1130
  t->state.SYNC_MEASURE = 0;
1131
 
262 tk 1132
  // don't increment on first clock event
1133
  t->state.FIRST_CLK = 1;
1134
 
338 tk 1135
  // clear delay
1136
  t->bpm_tick_delay = 0;
1137
 
593 tk 1138
  // reset step progression counters
262 tk 1139
  t->step_replay_ctr = 0;
1140
  t->step_fwd_ctr = 0;
593 tk 1141
  t->step_interval_ctr = 0;
1142
  t->step_repeat_ctr = 0;
1143
  t->step_skip_ctr = 0;
262 tk 1144
 
1145
  // next part depends on forward/backward direction
1146
  if( tcc->dir_mode == SEQ_CORE_TRKDIR_Backward ) {
1147
    // only for Backward mode
1148
    t->state.BACKWARD = 1;
1149
    t->step = tcc->length;
1150
  } else {
1151
    // for Forward/PingPong/Pendulum/Random/...
1152
    t->state.BACKWARD = 0;
1153
    t->step = 0;
1154
  }
1155
 
1156
  // save position (for repeat function)
1157
  t->step_saved = t->step;
1158
 
1159
  t->arp_pos = 0;
1160
 
599 tk 1161
  // reset LFO
1162
  SEQ_LFO_ResetTrk(track);
1163
 
262 tk 1164
  return 0; // no error
1165
}
1166
 
1167
 
1168
/////////////////////////////////////////////////////////////////////////////
1205 tk 1169
// Resets the step position variables of all tracks
1170
/////////////////////////////////////////////////////////////////////////////
1171
s32 SEQ_CORE_ResetTrkPosAll(void)
1172
{
1173
  seq_core_trk_t *t = &seq_core_trk[0];
1174
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
1175
  u8 track;
1176
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc)
1177
    SEQ_CORE_ResetTrkPos(track, t, tcc);
1178
 
1179
  return 0; // no error
1180
}
1181
 
1182
/////////////////////////////////////////////////////////////////////////////
262 tk 1183
// Determine next step depending on direction mode
1184
/////////////////////////////////////////////////////////////////////////////
593 tk 1185
static s32 SEQ_CORE_NextStep(seq_core_trk_t *t, seq_cc_trk_t *tcc, u8 no_progression, u8 reverse)
262 tk 1186
{
1187
  int i;
1188
  u8 save_step = 0;
1189
  u8 new_step = 1;
1190
 
1191
  // handle progression parameters if position shouldn't be reset
593 tk 1192
  if( !no_progression && !t->state.POS_RESET ) {
262 tk 1193
    if( ++t->step_fwd_ctr > tcc->steps_forward ) {
1194
      t->step_fwd_ctr = 0;
1195
      if( tcc->steps_jump_back ) {
593 tk 1196
    for(i=0; i<tcc->steps_jump_back; ++i)
1197
      SEQ_CORE_NextStep(t, tcc, 1, 1); // 1=no progression, 1=reverse
262 tk 1198
      }
1199
      if( ++t->step_replay_ctr > tcc->steps_replay ) {
1200
    t->step_replay_ctr = 0;
1201
    save_step = 1; // request to save the step in t->step_saved at the end of this routine
1202
      } else {
1203
    t->step = t->step_saved;
1204
    new_step = 0; // don't calculate new step
1205
      }
1206
    }
593 tk 1207
 
1208
    if( ++t->step_interval_ctr > tcc->steps_rs_interval ) {
1209
      t->step_interval_ctr = 0;
1210
      t->step_repeat_ctr = tcc->steps_repeat;
1211
      t->step_skip_ctr = tcc->steps_skip;
1212
    }
1213
 
1214
    if( t->step_repeat_ctr ) {
1215
      --t->step_repeat_ctr;
1216
      new_step = 0; // repeat step until counter reached zero
1217
    } else {
1218
      while( t->step_skip_ctr ) {
1219
    SEQ_CORE_NextStep(t, tcc, 1, 0); // 1=no progression, 0=not reverse
1220
    --t->step_skip_ctr;
1221
      }
1222
    }
262 tk 1223
  }
1224
 
1225
  if( new_step ) {
1226
    // special cases:
1227
    switch( tcc->dir_mode ) {
1228
      case SEQ_CORE_TRKDIR_Forward:
1229
    t->state.BACKWARD = 0; // force backward flag
1230
    break;
1231
 
1232
      case SEQ_CORE_TRKDIR_Backward:
1233
    t->state.BACKWARD = 1; // force backward flag
1234
    break;
1235
 
1236
      case SEQ_CORE_TRKDIR_PingPong:
1237
      case SEQ_CORE_TRKDIR_Pendulum:
1238
    // nothing else to do...
1239
    break;
1240
 
1241
      case SEQ_CORE_TRKDIR_Random_Dir:
1242
    // set forward/backward direction with 1:1 probability
1243
    t->state.BACKWARD = SEQ_RANDOM_Gen(0) & 1;
1244
        break;
1245
 
1246
      case SEQ_CORE_TRKDIR_Random_Step:
1247
    t->step = SEQ_RANDOM_Gen_Range(tcc->loop, tcc->length);
1248
    new_step = 0; // no new step calculation required anymore
1249
        break;
1250
 
1251
      case SEQ_CORE_TRKDIR_Random_D_S:
1252
    {
1253
      // we continue with a probability of 50%
1254
      // we change the direction with a probability of 25%
1255
      // we jump to a new step with a probability of 25%
1256
      u32 rnd;
1257
      if( ((rnd=SEQ_RANDOM_Gen(0)) & 0xff) < 0x80 ) {
1258
        if( rnd < 0x40 ) {
1259
          // set forward/backward direction with 1:1 probability
1260
          t->state.BACKWARD = SEQ_RANDOM_Gen(0) & 1;
1261
        } else {
1262
          t->step = SEQ_RANDOM_Gen_Range(tcc->loop, tcc->length);
1263
          new_step = 0; // no new step calculation required anymore
1264
        }
1265
      }
1266
    }
1267
    break;
1268
    }
1269
  }
1270
 
1271
  if( new_step ) { // note: new_step will be cleared in SEQ_CORE_TRKDIR_Random_Step mode
1272
    // branch depending on forward/backward mode, take reverse flag into account
1273
    if( t->state.BACKWARD ^ reverse ) {
1274
      // jump to last step if first loop step has been reached or a position reset has been requested
1275
      // in pendulum mode: switch to forward direction
1276
      if( t->state.POS_RESET || t->step <= tcc->loop ) {
1277
    if( tcc->dir_mode == SEQ_CORE_TRKDIR_Pendulum ) {
1278
      t->state.BACKWARD = 0;
1279
    } else {
1280
      t->step = tcc->length;
1281
    }
1282
    // reset arp position as well
1283
    t->arp_pos = 0;
1284
      } else {
1285
    // no reset required; decrement step
1286
    --t->step;
1287
 
1288
    // in pingpong mode: turn direction if loop step has been reached after this decrement
1289
    if( t->step <= tcc->loop && tcc->dir_mode == SEQ_CORE_TRKDIR_PingPong )
1290
      t->state.BACKWARD = 0;
1291
      }
1292
    } else {
1293
      // jump to first (loop) step if last step has been reached or a position reset has been requested
1294
      // in pendulum mode: switch to backward direction
1295
      if( t->state.POS_RESET || t->step >= tcc->length ) {
1296
    if( tcc->dir_mode == SEQ_CORE_TRKDIR_Pendulum ) {
1297
      t->state.BACKWARD = 1;
1298
    } else {
1299
      t->step = tcc->loop;
1300
    }
1301
    // reset arp position as well
1302
    t->arp_pos = 0;
1303
      } else {
1304
    // no reset required; increment step
1305
    ++t->step;
1306
 
1307
    // in pingpong mode: turn direction if last step has been reached after this increment
1308
    if( t->step >= tcc->length && tcc->dir_mode == SEQ_CORE_TRKDIR_PingPong )
1309
      t->state.BACKWARD = 1;
1310
      }
1311
    }
1312
  }
1313
 
1314
  if( !reverse ) {
1315
    // requested by progression handler
1316
    if( save_step )
1317
      t->step_saved = t->step;
1318
 
1319
    t->state.POS_RESET = 0;
1320
  }
1321
 
1322
  return 0; // no error
1323
}
1324
 
1325
 
1326
/////////////////////////////////////////////////////////////////////////////
1327
// Transposes if midi_package contains a Note Event
1328
/////////////////////////////////////////////////////////////////////////////
1219 tk 1329
s32 SEQ_CORE_Transpose(seq_core_trk_t *t, seq_cc_trk_t *tcc, mios32_midi_package_t *p)
262 tk 1330
{
1024 tk 1331
  u8 is_cc = p->type != NoteOn && p->type != NoteOff; // CC or Pitchbender
262 tk 1332
 
1024 tk 1333
  if( is_cc && tcc->event_mode != SEQ_EVENT_MODE_CC ) // only transpose CC/Pitchbender in CC mode
1334
    return -1;
1335
 
1336
  int note = is_cc ? p->value : p->note;
1337
 
262 tk 1338
  int inc_oct = tcc->transpose_oct;
1339
  if( inc_oct >= 8 )
1340
    inc_oct -= 16;
1341
 
1342
  int inc_semi = tcc->transpose_semi;
1343
  if( inc_semi >= 8 )
1344
    inc_semi -= 16;
1345
 
1346
  // in transpose or arp playmode we allow to transpose notes and CCs
1320 tk 1347
  if( tcc->mode.playmode == SEQ_CORE_TRKMODE_Transpose ||
1348
      (!is_cc && seq_core_global_transpose_enabled) ) {
1023 tk 1349
    int tr_note = SEQ_MIDI_IN_TransposerNoteGet(tcc->busasg.bus, tcc->mode.HOLD);
262 tk 1350
 
1351
    if( tr_note < 0 ) {
1352
      p->velocity = 0; // disable note and exit
1353
      return -1; // note has been disabled
1354
    }
1355
 
1322 tk 1356
    inc_semi += tr_note - 0x3c; // C-3 is the base note
262 tk 1357
  }
1358
  else if( tcc->mode.playmode == SEQ_CORE_TRKMODE_Arpeggiator ) {
1359
    int key_num = (note >> 2) & 0x3;
1360
    int arp_oct = (note >> 4) & 0x7;
1361
 
1362
    if( arp_oct < 2 ) { // Multi Arp Event
1363
      inc_oct += ((note >> 2) & 7) - 4;
1364
      key_num = t->arp_pos;
1365
    } else {
1366
      inc_oct += arp_oct - 4;
1367
    }
1368
 
1023 tk 1369
    int arp_note = SEQ_MIDI_IN_ArpNoteGet(tcc->busasg.bus, tcc->mode.HOLD, !tcc->mode.UNSORTED, key_num);
262 tk 1370
 
1371
    if( arp_note & 0x80 ) {
1372
      t->arp_pos = 0;
1373
    } else {
1374
      if( arp_oct < 2 ) { // Multi Arp Event
1375
    // play next key, step will be incremented once t->arp_pos reaches 0 again
1376
    if( ++t->arp_pos >= 4 )
1377
      t->arp_pos = 0;
1378
      }
1379
    }
1380
 
1381
    note = arp_note & 0x7f;
1382
 
1383
    if( !note ) { // disable note and exit
1384
      p->velocity = 0;
1385
      return -1; // note has been disabled
1386
    }
1387
  }
1388
 
1389
  // apply transpose octave/semitones parameter
1390
  if( inc_oct ) {
1391
    note += 12 * inc_oct;
1392
    if( inc_oct < 0 ) {
1393
      while( note < 0 )
1394
    note += 12;
1395
    } else {
1396
      while( note >= 128 )
1397
    note -= 12;
1398
    }
1399
  }
1400
 
1401
  if( inc_semi ) {
1402
    note += inc_semi;
1403
    if( inc_semi < 0 ) {
1404
      while( note < 0 )
1405
    note += 12;
1406
    } else {
1407
      while( note >= 128 )
1408
    note -= 12;
1409
    }
1410
  }
1411
 
1024 tk 1412
  if( is_cc ) // if CC and Pitchbender
1413
    p->value = note;
1414
  else
1415
    p->note = note;
262 tk 1416
 
1417
  return 0; // no error
1418
}
1419
 
1420
 
1421
/////////////////////////////////////////////////////////////////////////////
1422
// Returns the selected scale and root note selection depending on
1423
// global/group specific settings
1424
// scale and root note are for interest while playing the sequence -> SEQ_CORE
1425
// scale and root selection are for interest when editing the settings -> SEQ_UI_OPT
1320 tk 1426
// Both modules are calling this function to ensure consistency
262 tk 1427
/////////////////////////////////////////////////////////////////////////////
1428
s32 SEQ_CORE_FTS_GetScaleAndRoot(u8 *scale, u8 *root_selection, u8 *root)
1429
{
1430
  if( seq_core_global_scale_ctrl > 0 ) {
1431
    // scale/root selection from a specific pattern group
1432
    u8 group = seq_core_global_scale_ctrl-1;
1433
    *scale = seq_cc_trk[(group*SEQ_CORE_NUM_TRACKS_PER_GROUP)+2].shared.scale;
1434
    *root_selection = seq_cc_trk[(group*SEQ_CORE_NUM_TRACKS_PER_GROUP)+3].shared.scale_root;
1435
  } else {
1436
    // global scale/root selection
1437
    *scale = seq_core_global_scale;
1438
    *root_selection = seq_core_global_scale_root_selection;
1439
  }
1440
  *root = (*root_selection == 0) ? seq_core_keyb_scale_root : (*root_selection-1);
1441
 
1442
  return 0; // no error
1443
}
1444
 
1445
 
1446
/////////////////////////////////////////////////////////////////////////////
600 tk 1447
// Limit Fx
1448
/////////////////////////////////////////////////////////////////////////////
1219 tk 1449
s32 SEQ_CORE_Limit(seq_core_trk_t *t, seq_cc_trk_t *tcc, seq_layer_evnt_t *e)
600 tk 1450
{
1451
  u8 lower = tcc->limit_lower;
1452
  u8 upper = tcc->limit_upper;
1453
 
1454
  // check if any limit defined
1455
  if( !lower && !upper )
1456
    return 0; // no limit
1457
 
1458
  // exit if no note event
1459
  mios32_midi_package_t *p = &e->midi_package;
1460
  if( p->type != NoteOn )
1461
    return 0; // no Note
1462
 
1463
  // swap if lower value is greater than upper
1464
  if( lower > upper ) {
1465
    u8 tmp = upper;
1466
    upper=lower;
1467
    lower=tmp;
1468
  }
1469
 
1470
  // apply limit
1471
  s32 note = p->note; // we need a signed value
1472
  if( tcc->limit_lower )
1044 tk 1473
    while( (note-12) < lower )
600 tk 1474
      note += 12;
1475
 
1476
  if( tcc->limit_upper )
1044 tk 1477
    while( (note+12) > upper )
600 tk 1478
      note -= 12;
1479
 
1480
  p->note = note;
1481
 
1482
  return 0; // no error
1483
}
1484
 
1485
 
747 tk 1486
 
600 tk 1487
/////////////////////////////////////////////////////////////////////////////
747 tk 1488
// Name of Delay mode (we should outsource the echo function to seq_echo.c later)
1489
/////////////////////////////////////////////////////////////////////////////
774 tk 1490
// Note: newer gcc versions don't allow to return a "const" parameter, therefore
1491
// this array is declared outside the SEQ_CORE_Echo_GetDelayModeName() function
1121 tk 1492
 
1219 tk 1493
#define NUM_DELAY_VALUES 23
1121 tk 1494
static const char delay_str[NUM_DELAY_VALUES+1][5] = {
747 tk 1495
    " 64T",
1496
    " 64 ",
1497
    " 32T",
1498
    " 32 ",
1499
    " 16T",
1500
    " 16 ",
1501
    "  8T",
1502
    "  8 ",
1503
    "  4T",
1504
    "  4 ",
1505
    "  2T",
1506
    "  2 ",
1507
    "  1T",
1508
    "  1 ",
1509
    "Rnd1",
1510
    "Rnd2",
1121 tk 1511
    " 64d", // new with Beta30
1512
    " 32d", // new with Beta30
1513
    " 16d", // new with Beta30
1514
    "  8d", // new with Beta30
1515
    "  4d", // new with Beta30
1516
    "  2d", // new with Beta30
1219 tk 1517
    "  0 ", // new with Beta42
747 tk 1518
    "????",
1519
  };
1520
 
774 tk 1521
const char *SEQ_CORE_Echo_GetDelayModeName(u8 delay_mode)
1522
{
1121 tk 1523
  if( delay_mode < NUM_DELAY_VALUES )
747 tk 1524
    return delay_str[delay_mode];
1525
 
1121 tk 1526
  return delay_str[NUM_DELAY_VALUES];
747 tk 1527
}
1528
 
1529
 
1530
/////////////////////////////////////////////////////////////////////////////
1121 tk 1531
// Maps delay values from old to new format
1532
// Used to keep pattern binaries compatible to enhanced delay entries
1533
/////////////////////////////////////////////////////////////////////////////
1534
static const u8 delay_value_map[NUM_DELAY_VALUES] = {
1219 tk 1535
  22, //"  0 ",
1121 tk 1536
  0,  //" 64T",
1537
  1,  //" 64 ",
1538
  2,  //" 32T",
1539
  16, //" 64d",
1540
  3,  //" 32 ",
1541
  4,  //" 16T",
1542
  17, //" 32d",
1543
  5,  //" 16 ",
1544
  6,  //"  8T",
1545
  18, //" 16d",
1546
  7,  //"  8 ",
1547
  8,  //"  4T",
1548
  19, //"  8d",
1549
  9,  //"  4 ",
1550
  10, //"  2T",
1551
  20, //"  4d",
1552
  11, //"  2 ",
1553
  12, //"  1T",
1554
  21, //"  2d",
1555
  13, //"  1 ",
1556
  14, //"Rnd1",
1557
  15, //"Rnd2",
1558
};
1559
 
1560
u8 SEQ_CORE_Echo_MapUserToInternal(u8 user_value)
1561
{
1562
  if( user_value < NUM_DELAY_VALUES )
1563
    return delay_value_map[user_value];
1564
 
1565
  return 0;
1566
}
1567
 
1568
u8 SEQ_CORE_Echo_MapInternalToUser(u8 internal_value)
1569
{
1570
  int i;
1571
  for(i=0; i<NUM_DELAY_VALUES; ++i)
1572
    if( delay_value_map[i] == internal_value )
1573
      return i;
1574
 
1575
  return 0;
1576
}
1577
 
1578
 
1579
/////////////////////////////////////////////////////////////////////////////
262 tk 1580
// Echo Fx
1581
/////////////////////////////////////////////////////////////////////////////
1219 tk 1582
s32 SEQ_CORE_Echo(seq_core_trk_t *t, seq_cc_trk_t *tcc, mios32_midi_package_t p, u32 bpm_tick, u32 gatelength)
262 tk 1583
{
1584
  // thanks to MIDI queuing mechanism, this is a no-brainer :)
1585
 
1219 tk 1586
  // 64T, 64, 32T, 32, 16T, 16, ... 1, Rnd1 and Rnd2, 64d..2d (new), 0 (supernew)
1121 tk 1587
  s32 fb_ticks;
742 tk 1588
  s32 echo_delay = tcc->echo_delay;
1219 tk 1589
  if( echo_delay >= 22 ) // new zero delay
1590
    fb_ticks = 0;
1591
  else if ( echo_delay >= 16 ) // new dotted delays
1121 tk 1592
    fb_ticks = 36 * (1 << (echo_delay-16));
1593
  else {
1594
    if( echo_delay >= 14 ) // Rnd1 and Rnd2
1595
      echo_delay = SEQ_RANDOM_Gen_Range(3, 7); // between 32 and 8
1596
    fb_ticks = ((tcc->echo_delay & 1) ? 24 : 16) * (1 << (echo_delay>>1));
1597
  }
262 tk 1598
 
1599
  s32 fb_note = p.note;
1600
  s32 fb_note_base = fb_note; // for random function
1601
 
1602
  // TODO: echo port and MIDI channel
1603
 
1604
  // the initial velocity value allows to start with a low velocity,
1605
  // and to increase it with each step via FB velocity value
1606
  s32 fb_velocity = p.velocity;
1607
  if( tcc->echo_velocity != 20 ) { // 20 == 100% -> no change
1608
    fb_velocity = (fb_velocity * 5*tcc->echo_velocity) / 100;
1609
    if( fb_velocity > 127 )
1610
      fb_velocity = 127;
1611
    p.velocity = (u8)fb_velocity;
1612
  }
1613
 
273 tk 1614
  seq_midi_out_event_type_t event_type = SEQ_MIDI_OUT_OnOffEvent;
333 tk 1615
  if( (p.type == CC || p.type == PitchBend) && !gatelength )
273 tk 1616
    event_type = SEQ_MIDI_OUT_CCEvent;
262 tk 1617
 
276 tk 1618
  // for the case that force-to-scale is activated
1619
  u8 scale, root_selection, root;
1620
  SEQ_CORE_FTS_GetScaleAndRoot(&scale, &root_selection, &root);
1621
 
262 tk 1622
  u32 echo_offset = fb_ticks;
1623
  int i;
1624
  for(i=0; i<tcc->echo_repeats; ++i) {
1625
    if( i ) { // no feedback of velocity or echo ticks on first step
1626
      if( tcc->echo_fb_velocity != 20 ) { // 20 == 100% -> no change
1627
    fb_velocity = (fb_velocity * 5*tcc->echo_fb_velocity) / 100;
1628
    if( fb_velocity > 127 )
1629
      fb_velocity = 127;
1630
    p.velocity = (u8)fb_velocity;
1631
      }
1632
 
1633
      if( tcc->echo_fb_ticks != 20 ) { // 20 == 100% -> no change
1634
    fb_ticks = (fb_ticks * 5*tcc->echo_fb_ticks) / 100;
1635
      }
1636
      echo_offset += fb_ticks;
1637
    }
1638
 
1639
    if( tcc->echo_fb_note != 24 ) { // 24 == 0 -> no change
1640
      if( tcc->echo_fb_note == 49 ) // random
1641
    fb_note = fb_note_base + ((s32)SEQ_RANDOM_Gen_Range(0, 48) - 24);
1642
      else
1643
    fb_note = fb_note + ((s32)tcc->echo_fb_note-24);
1644
      while( fb_note < 0 )
1645
    fb_note += 12;
1646
      while( fb_note > 127 )
1647
    fb_note -= 12;
1648
 
1649
      p.note = (u8)fb_note;
1650
    }
1651
 
1652
    if( gatelength && tcc->echo_fb_gatelength != 20 ) { // 20 == 100% -> no change
1653
      gatelength = (gatelength * 5*tcc->echo_fb_gatelength) / 100;
1654
      if( !gatelength )
1655
    gatelength = 1;
1656
    }
1657
 
276 tk 1658
    // force to scale
1659
    if( tcc->mode.FORCE_SCALE ) {
1660
      SEQ_SCALE_Note(&p, scale, root);
1661
    }
1662
 
273 tk 1663
    SEQ_MIDI_OUT_Send(tcc->midi_port, p, event_type, bpm_tick + echo_offset, gatelength);
262 tk 1664
  }
1665
 
1666
  return 0; // no error
1667
}
1668
 
1669
 
1670
/////////////////////////////////////////////////////////////////////////////
600 tk 1671
// Manually triggers a step of all selected tracks
1672
/////////////////////////////////////////////////////////////////////////////
1673
s32 SEQ_CORE_ManualTrigger(u8 step)
1674
{
1675
  MIOS32_IRQ_Disable();
1676
 
1677
  u8 track;
1678
  seq_core_trk_t *t = &seq_core_trk[0];
1679
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
1680
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc) {
1681
    if( SEQ_UI_IsSelectedTrack(track) ) {
1205 tk 1682
      if( !SEQ_BPM_IsRunning() ) {
1683
    // reset track position
1684
    SEQ_CORE_ResetTrkPos(track, t, tcc);
600 tk 1685
 
1205 tk 1686
    // change step
1687
    t->step = step;
1688
    t->step_saved = t->step;
1689
      } else {
1690
    // request next step
1691
    t->manual_step = step;
1692
    t->state.MANUAL_STEP_REQ = 1;
1693
      }
600 tk 1694
    }
1695
  }
1696
 
1697
  if( !SEQ_BPM_IsRunning() ) {
1205 tk 1698
    // start sequencer if not running, but only for one step
600 tk 1699
    SEQ_BPM_Cont();
1700
    seq_core_state.MANUAL_TRIGGER_STOP_REQ = 1;
1701
  }
1702
 
1703
  MIOS32_IRQ_Enable();
1704
 
1705
  return 0; // no error
1706
}
1707
 
1708
 
1709
/////////////////////////////////////////////////////////////////////////////
1315 tk 1710
// Manually requests synch to measure for given tracks
600 tk 1711
/////////////////////////////////////////////////////////////////////////////
1315 tk 1712
s32 SEQ_CORE_ManualSynchToMeasure(u16 tracks)
600 tk 1713
{
1714
  MIOS32_IRQ_Disable();
1715
 
1716
  u8 track;
1717
  seq_core_trk_t *t = &seq_core_trk[0];
1718
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t)
1315 tk 1719
    if( tracks & (1 << track) )
600 tk 1720
      t->state.SYNC_MEASURE = 1;
1721
 
1722
  MIOS32_IRQ_Enable();
1723
 
1724
  return 0; // no error
1725
}
1726
 
1727
 
1728
/////////////////////////////////////////////////////////////////////////////
262 tk 1729
// This function requests to pre-generate sequencer ticks for a given time
1730
// It returns -1 if the previously requested delay hasn't passed yet
1731
/////////////////////////////////////////////////////////////////////////////
1732
s32 SEQ_CORE_AddForwardDelay(u16 delay_ms)
1733
{
1734
  if( bpm_tick_prefetch_req )
1735
    return -1; // ongoing request
1736
 
1737
  // calculate how many BPM ticks have to be forwarded
1738
  bpm_tick_prefetch_req = SEQ_BPM_TickGet() + SEQ_BPM_TicksFor_mS(delay_ms);
1739
 
1740
  return 0; // no error
1741
}
491 tk 1742
 
1743
 
1744
/////////////////////////////////////////////////////////////////////////////
1745
// This function updates the BPM rate in a given sweep time
1746
/////////////////////////////////////////////////////////////////////////////
1747
s32 SEQ_CORE_BPM_Update(float bpm, float sweep_ramp)
1748
{
1749
  if( sweep_ramp <= 0.0 ) {
1750
    seq_core_bpm_target = bpm;
1751
    SEQ_BPM_Set(seq_core_bpm_target);
1752
    seq_core_bpm_sweep_inc = 0.0;
1753
  } else {
1754
    seq_core_bpm_target = bpm;
1755
    seq_core_bpm_sweep_inc = (seq_core_bpm_target - SEQ_BPM_Get()) / (10.0 * sweep_ramp);
1756
  }
1757
 
1758
  return 0; // no error
1759
}
1760
 
1761
/////////////////////////////////////////////////////////////////////////////
1762
// This function should be called each mS to update the BPM
1763
/////////////////////////////////////////////////////////////////////////////
1764
s32 SEQ_CORE_BPM_SweepHandler(void)
1765
{
1766
  static u8 prescaler = 0;
1767
 
1768
  // next step each 100 mS
1769
  if( ++prescaler < 100 )
1770
    return 0;
1771
  prescaler = 0;
1772
 
1773
  if( seq_core_bpm_sweep_inc != 0.0 ) {
1774
    float current_bpm = SEQ_BPM_Get();
1775
    float tolerance = 0.1;
1776
 
1777
    if( (seq_core_bpm_sweep_inc > 0.0 && current_bpm >= (seq_core_bpm_target-tolerance)) ||
1778
    (seq_core_bpm_sweep_inc < 0.0 && current_bpm <= (seq_core_bpm_target+tolerance)) ) {
1779
      seq_core_bpm_sweep_inc = 0.0; // final value reached
1780
      SEQ_BPM_Set(seq_core_bpm_target);
1781
    } else {
1782
      SEQ_BPM_Set(current_bpm + seq_core_bpm_sweep_inc);
1783
    }
1784
  }
1785
 
1786
  return 0; // no error
1787
}
1788
 
607 tk 1789
 
1790
/////////////////////////////////////////////////////////////////////////////
1791
// Scrub function called from UI when SCRUB button pressed and Datawheel
1792
// is moved
1793
/////////////////////////////////////////////////////////////////////////////
1794
s32 SEQ_CORE_Scrub(s32 incrementer)
1795
{
1796
  // simple but useful: increment/decrement the step of each track
1797
  // (in MBSEQ V3 we only generated some additional clocks, which had
1798
  // the disadvantage, that sequences couldn't be scrubbed back)
1799
 
1800
  // this simplified method currently has following disadvantages:
1801
  // - clock dividers not taken into account (difficult, needs some code restructuring in SEQ_CORE_Tick())
1802
  // - ...and?
1803
  // advantage:
1804
  // - sequencer stays in sync with outgoing/incoming MIDI clock!
1805
  // - reverse scrubbing for some interesting effects while played live (MB-808 has a similar function: nudge)
1806
 
1807
  u8 track;
1808
  seq_core_trk_t *t = &seq_core_trk[0];
1809
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
1810
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc) {
1811
    SEQ_CORE_NextStep(t, tcc, 0, incrementer >= 0 ? 0 : 1);
1812
  }
1813
 
1814
#if 0
1815
  // disabled so that we stay in Sync with MIDI clock!
1816
  // increment/decrement reference step
1817
  if( incrementer >= 0 ) {
1818
    if( ++seq_core_state.ref_step > seq_core_steps_per_measure )
1819
      seq_core_state.ref_step = 0;
1820
  } else {
1821
    if( seq_core_state.ref_step )
1822
      --seq_core_state.ref_step;
1823
    else
1824
      seq_core_state.ref_step = seq_core_steps_per_measure;
1825
  }
1826
#endif
1827
 
1828
  return 0; // no error
1829
}