Subversion Repositories svn.mios32

Rev

Rev 2294 | Rev 2322 | 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 2308 2016-02-14 19:30:07Z 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
 
1806 tk 23
#include "tasks.h"
24
 
262 tk 25
#include "seq_core.h"
1316 tk 26
#include "seq_song.h"
262 tk 27
#include "seq_random.h"
28
#include "seq_cc.h"
29
#include "seq_layer.h"
337 tk 30
#include "seq_scale.h"
339 tk 31
#include "seq_groove.h"
345 tk 32
#include "seq_humanize.h"
2118 tk 33
#include "seq_robotize.h"
690 tk 34
#include "seq_morph.h"
599 tk 35
#include "seq_lfo.h"
690 tk 36
#include "seq_midi_port.h"
262 tk 37
#include "seq_midi_in.h"
406 tk 38
#include "seq_midi_router.h"
262 tk 39
#include "seq_par.h"
40
#include "seq_trg.h"
41
#include "seq_pattern.h"
42
#include "seq_random.h"
416 tk 43
#include "seq_record.h"
1219 tk 44
#include "seq_live.h"
754 tk 45
#include "seq_midply.h"
758 tk 46
#include "seq_midexp.h"
47
#include "seq_midimp.h"
1083 tk 48
#include "seq_cv.h"
944 tk 49
#include "seq_statistics.h"
262 tk 50
#include "seq_ui.h"
51
 
52
 
1316 tk 53
 
262 tk 54
/////////////////////////////////////////////////////////////////////////////
55
// Local definitions
56
/////////////////////////////////////////////////////////////////////////////
57
 
58
// set this to 1 if performance of clock handler should be measured with a scope
59
// (LED toggling in APP_Background() has to be disabled!)
60
// set this to 2 to visualize forward delay during pattern changes
286 tk 61
#define LED_PERFORMANCE_MEASURING 0
262 tk 62
 
286 tk 63
// same for measuring with the stopwatch
64
// value is visible in menu (-> press exit button)
747 tk 65
// value is visible in INFO->System page (-> press exit button, go to last item)
961 tk 66
#define STOPWATCH_PERFORMANCE_MEASURING 1
262 tk 67
 
286 tk 68
 
262 tk 69
/////////////////////////////////////////////////////////////////////////////
70
// Local prototypes
71
/////////////////////////////////////////////////////////////////////////////
72
 
599 tk 73
static s32 SEQ_CORE_ResetTrkPos(u8 track, seq_core_trk_t *t, seq_cc_trk_t *tcc);
593 tk 74
static s32 SEQ_CORE_NextStep(seq_core_trk_t *t, seq_cc_trk_t *tcc, u8 no_progression, u8 reverse);
262 tk 75
 
76
 
77
/////////////////////////////////////////////////////////////////////////////
78
// Global variables
79
/////////////////////////////////////////////////////////////////////////////
80
 
81
seq_core_options_t seq_core_options;
82
u8 seq_core_steps_per_measure;
758 tk 83
u8 seq_core_steps_per_pattern;
262 tk 84
 
1015 tk 85
u16 seq_core_trk_muted;
1261 tk 86
u16 seq_core_trk_synched_mute;
87
u16 seq_core_trk_synched_unmute;
1206 tk 88
seq_core_slaveclk_mute_t seq_core_slaveclk_mute;
2110 tk 89
u16 seq_core_trk_soloed;
1015 tk 90
 
751 tk 91
u8 seq_core_step_update_req;
92
 
262 tk 93
u8 seq_core_global_scale;
94
u8 seq_core_global_scale_ctrl;
95
u8 seq_core_global_scale_root;
96
u8 seq_core_global_scale_root_selection;
97
u8 seq_core_keyb_scale_root;
98
 
1320 tk 99
u8 seq_core_global_transpose_enabled;
100
 
491 tk 101
u8 seq_core_bpm_preset_num;
102
float seq_core_bpm_preset_tempo[SEQ_CORE_NUM_BPM_PRESETS];
103
float seq_core_bpm_preset_ramp[SEQ_CORE_NUM_BPM_PRESETS];
104
 
718 tk 105
u8 seq_core_din_sync_pulse_ctr;
262 tk 106
 
524 tk 107
mios32_midi_port_t seq_core_metronome_port;
108
u8 seq_core_metronome_chn;
109
u8 seq_core_metronome_note_m;
110
u8 seq_core_metronome_note_b;
111
 
262 tk 112
seq_core_state_t seq_core_state;
113
seq_core_trk_t seq_core_trk[SEQ_CORE_NUM_TRACKS];
114
 
596 tk 115
seq_core_loop_mode_t seq_core_glb_loop_mode;
116
u8 seq_core_glb_loop_offset;
117
u8 seq_core_glb_loop_steps;
262 tk 118
 
491 tk 119
 
262 tk 120
/////////////////////////////////////////////////////////////////////////////
121
// Local variables
122
/////////////////////////////////////////////////////////////////////////////
123
 
124
static u32 bpm_tick_prefetch_req;
2206 tk 125
static u32 bpm_tick_prefetched;
262 tk 126
 
491 tk 127
static float seq_core_bpm_target;
128
static float seq_core_bpm_sweep_inc;
262 tk 129
 
491 tk 130
 
262 tk 131
/////////////////////////////////////////////////////////////////////////////
132
// Initialisation
1794 tk 133
// \param mode if 0: clear all parameters, if 1: don't clear global parameters which are stored in the MBSEQ_GC.V4 file
262 tk 134
/////////////////////////////////////////////////////////////////////////////
135
s32 SEQ_CORE_Init(u32 mode)
136
{
491 tk 137
  int i;
138
 
1015 tk 139
  seq_core_trk_muted = 0;
1206 tk 140
  seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
2110 tk 141
  seq_core_trk_soloed = 0;
262 tk 142
  seq_core_options.ALL = 0;
1794 tk 143
  if( mode == 0 ) {
144
    seq_core_options.INIT_CC = 64;
2294 tk 145
    seq_core_options.INIT_WITH_TRIGGERS = 1;
1794 tk 146
    seq_core_options.PASTE_CLR_ALL = 1;
147
    seq_core_options.PATTERN_MIXER_MAP_COUPLING = 0;
2101 tk 148
    seq_core_options.MIXER_LIVE_SEND = 1;
1794 tk 149
  }
325 tk 150
  seq_core_steps_per_measure = 16-1;
758 tk 151
  seq_core_steps_per_pattern = 16-1;
262 tk 152
  seq_core_global_scale = 0;
153
  seq_core_global_scale_ctrl = 0; // global
154
  seq_core_global_scale_root_selection = 0; // from keyboard
155
  seq_core_keyb_scale_root = 0; // taken if enabled in OPT menu
1320 tk 156
  seq_core_global_transpose_enabled = 0;
718 tk 157
  seq_core_din_sync_pulse_ctr = 0; // used to generate a 1 mS pulse
262 tk 158
 
1794 tk 159
  if( mode == 0 ) {
160
    seq_core_metronome_port = DEFAULT;
161
    seq_core_metronome_chn = 10;
162
    seq_core_metronome_note_m = 0x25; // C#1
163
    seq_core_metronome_note_b = 0x25; // C#1
164
  }
524 tk 165
 
491 tk 166
  seq_core_bpm_preset_num = 13; // 140.0
167
  for(i=0; i<SEQ_CORE_NUM_BPM_PRESETS; ++i) {
168
    seq_core_bpm_preset_tempo[i] = 75.0 + 5.0*i;
169
    seq_core_bpm_preset_ramp[i] = 0.0;
170
  }
171
  seq_core_bpm_sweep_inc = 0.0;
172
 
262 tk 173
  seq_core_state.ALL = 0;
174
 
596 tk 175
  seq_core_glb_loop_mode = SEQ_CORE_LOOP_MODE_ALL_TRACKS_VIEW;
176
  seq_core_glb_loop_offset = 0;
177
  seq_core_glb_loop_steps = 16-1;
178
 
751 tk 179
  seq_core_step_update_req = 0;
180
 
262 tk 181
  // set initial seed of random generator
182
  SEQ_RANDOM_Gen(0xdeadbabe);
183
 
184
  // reset layers
185
  SEQ_LAYER_Init(0);
186
 
187
  // reset patterns
188
  SEQ_PATTERN_Init(0);
189
 
190
  // reset force-to-scale module
191
  SEQ_SCALE_Init(0);
192
 
339 tk 193
  // reset groove module
194
  SEQ_GROOVE_Init(0);
195
 
473 tk 196
  // reset morph module
197
  SEQ_MORPH_Init(0);
198
 
345 tk 199
  // reset humanizer module
200
  SEQ_HUMANIZE_Init(0);
201
 
2118 tk 202
 
203
  // reset robotizer module
204
  SEQ_ROBOTIZE_Init(0);
205
 
599 tk 206
  // reset LFO module
207
  SEQ_LFO_Init(0);
208
 
399 tk 209
  // reset song module
210
  SEQ_SONG_Init(0);
211
 
1219 tk 212
  // reset live play module
213
  SEQ_LIVE_Init(0);
214
 
419 tk 215
  // reset record module
216
  SEQ_RECORD_Init(0);
217
 
758 tk 218
  // init MIDI file player/exporter/importer
754 tk 219
  SEQ_MIDPLY_Init(0);
758 tk 220
  SEQ_MIDEXP_Init(0);
221
  SEQ_MIDIMP_Init(0);
754 tk 222
 
262 tk 223
  // clear registers which are not reset by SEQ_CORE_Reset()
224
  u8 track;
600 tk 225
  seq_core_trk_t *t = &seq_core_trk[0];
226
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t) {
262 tk 227
 
228
    // if track name only contains spaces, the UI will print 
229
    // the track number instead of an empty message
230
    // this ensures highest flexibility (e.g. any track can 
231
    // play patterns normaly assigned for other tracks w/o inconsistent messages)
232
    // -> see SEQ_LCD_PrintTrackName()
233
    int i;
316 tk 234
    for(i=0; i<80; ++i)
717 tk 235
      t->name[i] = ' ';
236
    t->name[80] = 0;
237
 
238
    // clear glide note storage
239
    for(i=0; i<4; ++i)
240
      t->glide_notes[i] = 0;
826 tk 241
 
242
    // don't select sections
828 tk 243
    t->play_section = 0;
262 tk 244
  }
245
 
246
  // reset sequencer
1145 tk 247
  SEQ_CORE_Reset(0);
262 tk 248
 
755 tk 249
  // reset MIDI player
250
  SEQ_MIDPLY_Reset();
251
 
262 tk 252
  // init BPM generator
253
  SEQ_BPM_Init(0);
254
 
255
  SEQ_BPM_PPQN_Set(384);
491 tk 256
  SEQ_CORE_BPM_Update(seq_core_bpm_preset_tempo[seq_core_bpm_preset_num], 0.0);
262 tk 257
 
286 tk 258
#if STOPWATCH_PERFORMANCE_MEASURING
944 tk 259
  SEQ_STATISTICS_StopwatchInit();
286 tk 260
#endif
261
 
262 tk 262
  return 0; // no error
263
}
264
 
265
 
266
/////////////////////////////////////////////////////////////////////////////
1859 tk 267
// This function schedules a MIDI event by considering the "normal" and "Fx"
268
// MIDI port
269
/////////////////////////////////////////////////////////////////////////////
2145 tk 270
s32 SEQ_CORE_ScheduleEvent(seq_core_trk_t *t, seq_cc_trk_t *tcc, mios32_midi_package_t midi_package, seq_midi_out_event_type_t event_type, u32 timestamp, u32 len, u8 is_echo, seq_robotize_flags_t robotize_flags)
1859 tk 271
{
272
  s32 status = 0;
1860 tk 273
  mios32_midi_port_t fx_midi_port = tcc->fx_midi_port ? tcc->fx_midi_port : tcc->midi_port;
1859 tk 274
 
2128 borfo 275
  //check that there are more than 0 additional channels, that it's not just one channel and FX starting on current channel, check disable flag, check for robotizer
276
  if( ! ( tcc->fx_midi_num_chn & 0x3f ) || ( ( tcc->fx_midi_num_chn & 0x3f ) == 1 && tcc->fx_midi_chn == midi_package.chn  ) || ( ( tcc->fx_midi_num_chn & 0x40 ) && ! robotize_flags.DUPLICATE ) ) {
1859 tk 277
    status |= SEQ_MIDI_OUT_Send(tcc->midi_port, midi_package, event_type, timestamp, len);
1862 tk 278
 
279
    if( event_type == SEQ_MIDI_OUT_OnEvent ) { // schedule off event at same port
280
      midi_package.velocity = 0;
281
      status |= SEQ_MIDI_OUT_Send(tcc->midi_port, midi_package, SEQ_MIDI_OUT_OffEvent, 0xffffffff, 0);
282
    }
1859 tk 283
  } else {
1862 tk 284
    if( event_type == SEQ_MIDI_OUT_OnEvent || event_type == SEQ_MIDI_OUT_OnOffEvent ) {
1859 tk 285
      switch( tcc->fx_midi_mode.beh ) {
286
      case SEQ_CORE_FX_MIDI_MODE_BEH_Alternate:
287
      case SEQ_CORE_FX_MIDI_MODE_BEH_AlternateSynchedEcho: {
288
    // forward to next channel
1863 tk 289
    if( (tcc->fx_midi_mode.beh == SEQ_CORE_FX_MIDI_MODE_BEH_AlternateSynchedEcho && !is_echo) ||
2128 borfo 290
      ++t->fx_midi_ctr > ( tcc->fx_midi_num_chn & 0x3f ) )
1859 tk 291
      t->fx_midi_ctr = 0;
292
 
1862 tk 293
    mios32_midi_port_t midi_port;
1859 tk 294
    if( t->fx_midi_ctr == 0 ) {
1862 tk 295
      midi_port = tcc->midi_port;
1859 tk 296
    } else {
1862 tk 297
      midi_port = fx_midi_port;
2128 borfo 298
      midi_package.chn = (( tcc->fx_midi_num_chn & 0x3f ) + (t->fx_midi_ctr-1)) % 16;
1859 tk 299
    }
1862 tk 300
 
301
    status |= SEQ_MIDI_OUT_Send(midi_port, midi_package, event_type, timestamp, len);
302
 
303
    if( event_type == SEQ_MIDI_OUT_OnEvent ) { // schedule off event at same port
304
      midi_package.velocity = 0;
305
      status |= SEQ_MIDI_OUT_Send(midi_port, midi_package, SEQ_MIDI_OUT_OffEvent, 0xffffffff, 0);
306
    }
1859 tk 307
      } break;
308
 
309
      case SEQ_CORE_FX_MIDI_MODE_BEH_Random: {
310
    // select random channel
2128 borfo 311
    int ix = SEQ_RANDOM_Gen_Range(0, ( tcc->fx_midi_num_chn & 0x3f ));
1862 tk 312
    mios32_midi_port_t midi_port;
1859 tk 313
    if( ix == 0 ) {
1862 tk 314
      midi_port = tcc->midi_port;
1859 tk 315
    } else {
1862 tk 316
      midi_port = fx_midi_port;
2128 borfo 317
      midi_package.chn = (( tcc->fx_midi_num_chn & 0x3f ) + ix-1) % 16;
1859 tk 318
    }
1862 tk 319
 
320
    status |= SEQ_MIDI_OUT_Send(midi_port, midi_package, event_type, timestamp, len);
321
 
322
    if( event_type == SEQ_MIDI_OUT_OnEvent ) { // schedule off event at same port
323
      midi_package.velocity = 0;
324
      status |= SEQ_MIDI_OUT_Send(midi_port, midi_package, SEQ_MIDI_OUT_OffEvent, 0xffffffff, 0);
325
    }
1859 tk 326
      } break;
327
 
328
      default: { // && SEQ_CORE_FX_MIDI_MODE_BEH_Forward
329
    // forward to all channels
330
 
331
    // original channel
332
    status |= SEQ_MIDI_OUT_Send(tcc->midi_port, midi_package, event_type, timestamp, len);
333
 
334
    // all other channels
335
    int ix;
2128 borfo 336
    for(ix=0; ix < ( tcc->fx_midi_num_chn & 0x3f ); ++ix) {
1859 tk 337
      midi_package.chn = (tcc->fx_midi_chn + ix) % 16;
1860 tk 338
      status |= SEQ_MIDI_OUT_Send(fx_midi_port, midi_package, event_type, timestamp, len);
1859 tk 339
    }
1862 tk 340
 
341
    if( event_type == SEQ_MIDI_OUT_OnEvent ) { // schedule off event at same port
342
      midi_package.velocity = 0;
343
 
344
      midi_package.chn = tcc->midi_chn % 16;
345
      status |= SEQ_MIDI_OUT_Send(tcc->midi_port, midi_package, SEQ_MIDI_OUT_OffEvent, 0xffffffff, 0);
346
 
2128 borfo 347
      for(ix=0; ix< ( tcc->fx_midi_num_chn & 0x3f ); ++ix) {
1862 tk 348
        midi_package.chn = (tcc->fx_midi_chn + ix) % 16;
349
        status |= SEQ_MIDI_OUT_Send(fx_midi_port, midi_package, SEQ_MIDI_OUT_OffEvent, 0xffffffff, 0);
350
      }
351
    }
1859 tk 352
      } break;
353
 
354
 
355
      }
356
    } else {
357
      // original channel
358
      status |= SEQ_MIDI_OUT_Send(tcc->midi_port, midi_package, event_type, timestamp, len);
359
 
360
      if( tcc->fx_midi_mode.fwd_non_notes ) {
361
    // all other channels
362
    int ix;
2128 borfo 363
    for(ix=0; ix < ( tcc->fx_midi_num_chn & 0x3f ); ++ix) {
1859 tk 364
      midi_package.chn = (tcc->fx_midi_chn + ix) % 16;
1860 tk 365
      status |= SEQ_MIDI_OUT_Send(fx_midi_port, midi_package, event_type, timestamp, len);
1859 tk 366
    }
367
      }
368
    }
369
  }
370
 
371
  return status;
372
}
373
 
374
 
375
/////////////////////////////////////////////////////////////////////////////
262 tk 376
// this sequencer handler is called periodically to check for new requests
377
// from BPM generator
378
/////////////////////////////////////////////////////////////////////////////
379
s32 SEQ_CORE_Handler(void)
380
{
381
  // handle requests
382
 
383
  u8 num_loops = 0;
384
  u8 again = 0;
385
  do {
386
    ++num_loops;
387
 
388
    // note: don't remove any request check - clocks won't be propagated
1044 tk 389
    // as long as any Stop/Cont/Start/SongPos event hasn't been flagged to the sequencer
262 tk 390
    if( SEQ_BPM_ChkReqStop() ) {
653 tk 391
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfc, 0);
262 tk 392
      SEQ_CORE_PlayOffEvents();
754 tk 393
      SEQ_MIDPLY_PlayOffEvents();
2308 tk 394
 
395
      int track;
396
      for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
397
    SEQ_RECORD_Reset(track);
398
      }
262 tk 399
    }
400
 
401
    if( SEQ_BPM_ChkReqCont() ) {
1206 tk 402
      // release slave mute
403
      seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
404
 
2206 tk 405
      // update delays
406
      SEQ_MIDI_PORT_ClkDelayUpdateAll();
407
 
408
      // send continue event
653 tk 409
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfb, 0);
1206 tk 410
 
262 tk 411
      // release pause mode
412
      ui_seq_pause = 0;
413
    }
414
 
415
    if( SEQ_BPM_ChkReqStart() ) {
1206 tk 416
      // release slave mute
417
      seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
418
 
2206 tk 419
      // update delays
420
      SEQ_MIDI_PORT_ClkDelayUpdateAll();
421
 
422
      // send start event and reset sequencer
653 tk 423
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfa, 0);
1145 tk 424
      SEQ_SONG_Reset(0);
425
      SEQ_CORE_Reset(0);
755 tk 426
      SEQ_MIDPLY_Reset();
1421 tk 427
 
428
      // song page: start song at current edit position
429
      if( ui_page == SEQ_UI_PAGE_SONG ) {
430
    SEQ_SONG_PosSet(ui_song_edit_pos);
431
      }
262 tk 432
    }
433
 
434
    u16 new_song_pos;
435
    if( SEQ_BPM_ChkReqSongPos(&new_song_pos) ) {
1206 tk 436
      // release slave mute
437
      seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
438
 
2206 tk 439
      // update delays
440
      SEQ_MIDI_PORT_ClkDelayUpdateAll();
441
 
442
      // new position
1145 tk 443
      u32 new_tick = new_song_pos * (SEQ_BPM_PPQN_Get() / 4);
444
      SEQ_CORE_Reset(new_tick);
445
      SEQ_SONG_Reset(new_tick);
338 tk 446
 
1145 tk 447
#if 0
448
      // fast forward to new song position
449
      if( new_tick ) {
450
    u32 bpm_tick;
451
    for(bpm_tick=0; bpm_tick<=new_tick; bpm_tick+=24) {
452
      SEQ_BPM_TickSet(bpm_tick);
453
      SEQ_CORE_Tick(bpm_tick, -1, 1); // mute all non-loopback tracks
454
    }
455
    SEQ_BPM_TickSet(new_tick);
456
      }
457
#endif
757 tk 458
      SEQ_MIDPLY_SongPos(new_song_pos, 1);
262 tk 459
    }
460
 
461
    u32 bpm_tick;
462
    if( SEQ_BPM_ChkReqClk(&bpm_tick) > 0 ) {
762 tk 463
      // check all requests again after execution of this part
464
      again = 1;
465
 
2206 tk 466
      // it's possible to forward the sequencer on pattern changes
467
      // in this case bpm_tick_prefetch_req is > bpm_tick
468
      // in all other cases, we only generate a single tick (realtime play)
469
      u32 add_bpm_ticks = 0;
470
      if( bpm_tick_prefetch_req > bpm_tick ) {
471
    add_bpm_ticks = bpm_tick_prefetch_req - bpm_tick;
472
      }
473
      // invalidate request before a new one will be generated (e.g. via SEQ_SONG_NextPos())
474
      bpm_tick_prefetch_req = 0;
262 tk 475
 
2206 tk 476
      // consider negative delay offsets: preload the appr. number of ticks
477
      s8 max_negative_offset = SEQ_MIDI_PORT_TickDelayMaxNegativeOffset(); 
478
      if( max_negative_offset < 0 ) {
479
    s32 offset = -max_negative_offset + 3; // +3 margin
480
    add_bpm_ticks += offset;
481
      }
762 tk 482
 
2206 tk 483
      // remove ticks which have already been processed before
484
      u32 bpm_tick_target = bpm_tick + add_bpm_ticks;
485
      if( !seq_core_state.FIRST_CLK && bpm_tick <= bpm_tick_prefetched ) {
486
    bpm_tick = bpm_tick_prefetched + 1;
487
      }
762 tk 488
 
2206 tk 489
      // processing remaining ticks
490
      for(; bpm_tick<=bpm_tick_target; ++bpm_tick) {
491
    bpm_tick_prefetched = bpm_tick;
492
 
262 tk 493
#if LED_PERFORMANCE_MEASURING == 1
2206 tk 494
    MIOS32_BOARD_LED_Set(0xffffffff, 1);
262 tk 495
#endif
286 tk 496
#if STOPWATCH_PERFORMANCE_MEASURING == 1
2206 tk 497
    SEQ_STATISTICS_StopwatchReset();
286 tk 498
#endif
762 tk 499
 
2206 tk 500
    // generate MIDI events
501
    SEQ_CORE_Tick(bpm_tick, -1, 0);
502
    SEQ_MIDPLY_Tick(bpm_tick);
762 tk 503
 
262 tk 504
#if LED_PERFORMANCE_MEASURING == 1
2206 tk 505
    MIOS32_BOARD_LED_Set(0xffffffff, 0);
262 tk 506
#endif
286 tk 507
#if STOPWATCH_PERFORMANCE_MEASURING == 1
2206 tk 508
    SEQ_STATISTICS_StopwatchCapture();
286 tk 509
#endif
762 tk 510
 
2206 tk 511
    // load new pattern/song step if reference step reached measure
512
    // (this code is outside SEQ_CORE_Tick() to save stack space!)
513
    if( (bpm_tick % 96) == 20 ) {
514
      if( SEQ_SONG_ActiveGet() ) {
2250 tk 515
        // to handle the case as described under http://midibox.org/forums/topic/19774-question-about-expected-behaviour-in-song-mode/
516
        // seq_core_steps_per_measure was lower than seq_core_steps_per_pattern
517
        u32 song_switch_step = (seq_core_steps_per_measure < seq_core_steps_per_pattern) ? seq_core_steps_per_measure : seq_core_steps_per_pattern;
2206 tk 518
        if( ( seq_song_guide_track && seq_song_guide_track <= SEQ_CORE_NUM_TRACKS &&
519
          seq_core_state.ref_step_song == seq_cc_trk[seq_song_guide_track-1].length) ||
2250 tk 520
        (!seq_song_guide_track && seq_core_state.ref_step_song == song_switch_step) ) {
2206 tk 521
 
522
          if( seq_song_guide_track ) {
523
        // request synch-to-measure for all tracks
524
        SEQ_CORE_ManualSynchToMeasure(0xffff);
525
 
526
        // corner case: we will load new tracks and the length of the guide track could change
527
        // in order to ensure that the reference step jumps back to 0, we've to force this here:
528
        seq_core_state.FORCE_REF_STEP_RESET = 1;
1493 tk 529
          }
2206 tk 530
 
531
          SEQ_SONG_NextPos();
762 tk 532
        }
2206 tk 533
      } else {
534
        if( seq_core_options.SYNCHED_PATTERN_CHANGE &&
535
        seq_core_state.ref_step == seq_core_steps_per_pattern ) {
536
          SEQ_PATTERN_Handler();
537
        }
762 tk 538
      }
539
    }
262 tk 540
      }
541
    }
542
  } while( again && num_loops < 10 );
543
 
544
  return 0; // no error
545
}
546
 
547
 
548
/////////////////////////////////////////////////////////////////////////////
549
// This function plays all "off" events
550
// Should be called on sequencer reset/restart/pause to avoid hanging notes
551
/////////////////////////////////////////////////////////////////////////////
759 tk 552
s32 SEQ_CORE_PlayOffEvents(void)
262 tk 553
{
554
  // play "off events"
555
  SEQ_MIDI_OUT_FlushQueue();
556
 
332 tk 557
  // clear sustain/stretch flags
262 tk 558
  u8 track;
600 tk 559
  seq_core_trk_t *t = &seq_core_trk[0];
560
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t) {
717 tk 561
    int i;
562
 
332 tk 563
    t->state.SUSTAINED = 0;
564
    t->state.STRETCHED_GL = 0;
717 tk 565
    for(i=0; i<4; ++i)
566
      t->glide_notes[i] = 0;
262 tk 567
  }
568
 
569
  return 0; // no error
570
}
571
 
572
 
573
/////////////////////////////////////////////////////////////////////////////
574
// Resets song position of sequencer
575
/////////////////////////////////////////////////////////////////////////////
1145 tk 576
s32 SEQ_CORE_Reset(u32 bpm_start)
262 tk 577
{
578
  ui_seq_pause = 0;
579
  seq_core_state.FIRST_CLK = 1;
580
 
1313 tk 581
  // reset latched PB/CC values
582
  SEQ_LAYER_ResetLatchedValues();
583
 
262 tk 584
  int track;
600 tk 585
  seq_core_trk_t *t = &seq_core_trk[0];
586
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
587
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc) {
2308 tk 588
    // clear all states (except for recording)
589
    {
590
      u8 rec_dont_overwrite_next_step = t->state.REC_DONT_OVERWRITE_NEXT_STEP;
591
      t->state.ALL = 0;
592
      t->state.REC_DONT_OVERWRITE_NEXT_STEP = rec_dont_overwrite_next_step;
593
    }
599 tk 594
    SEQ_CORE_ResetTrkPos(track, t, tcc);
1145 tk 595
 
2159 tk 596
    t->bar = 0;
1806 tk 597
    t->layer_muted_from_midi = 0;
598
    t->layer_muted_from_midi_next = 0;
1809 tk 599
    t->lfo_cc_muted_from_midi = 0;
600
    t->lfo_cc_muted_from_midi_next = 0;
1806 tk 601
 
1145 tk 602
    // add track offset depending on start position
603
    if( bpm_start ) {
604
#if 0
605
      u32 step_length = ((tcc->clkdiv.value+1) * (tcc->clkdiv.TRIPLETS ? 4 : 6));
606
#else
607
      // leads to bad result with Logic Audio: it starts one step earlier and assumes 16th steps!
608
      u32 step_length = 96;
609
#endif
2162 tk 610
      u32 pos_step = (u8)((bpm_start / step_length) % ((u32)tcc->length+1));
611
      u32 pos_bar  = (u8)((bpm_start / step_length) / ((u32)tcc->length+1));
1145 tk 612
 
613
      // next part depends on forward/backward direction
614
      if( tcc->dir_mode == SEQ_CORE_TRKDIR_Backward ) {
615
    t->step = tcc->length - pos_step;
616
      } else {
617
    t->step = pos_step;
618
      }
2162 tk 619
 
620
      t->bar = pos_bar;
1145 tk 621
    }
262 tk 622
  }
623
 
624
  // since timebase has been changed, ensure that Off-Events are played 
625
  // (otherwise they will be played much later...)
626
  SEQ_CORE_PlayOffEvents();
627
 
1145 tk 628
  // set BPM tick
629
  SEQ_BPM_TickSet(bpm_start);
262 tk 630
 
631
  // cancel prefetch requests/counter
632
  bpm_tick_prefetch_req = 0;
2206 tk 633
  bpm_tick_prefetched = bpm_start;
262 tk 634
 
1205 tk 635
  // cancel stop and set step request
600 tk 636
  seq_core_state.MANUAL_TRIGGER_STOP_REQ = 0;
637
 
1145 tk 638
  // reset reference step
1513 tk 639
  seq_core_state.ref_step = (u16)((bpm_start / 96) % ((u32)seq_core_steps_per_measure+1));
640
  if( seq_song_guide_track ) {
641
    seq_core_state.ref_step_song = (u16)((bpm_start / 96) % ((u32)seq_cc_trk[seq_song_guide_track-1].length+1));
642
  } else {
643
    seq_core_state.ref_step_song = seq_core_state.ref_step;
644
  }
1145 tk 645
 
262 tk 646
  return 0; // no error
647
}
648
 
649
 
650
/////////////////////////////////////////////////////////////////////////////
651
// performs a single ppqn tick
761 tk 652
// if "export_track" is -1, all tracks will be played
653
// if "export_track" is between 0 and 15, only the given track + all loopback
759 tk 654
//   tracks will be played (for MIDI file export)
1145 tk 655
// if "mute_nonloopback_tracks" is set, the "normal" tracks won't be played
656
// this option is used for the "fast forward" function on song position changes
262 tk 657
/////////////////////////////////////////////////////////////////////////////
1145 tk 658
s32 SEQ_CORE_Tick(u32 bpm_tick, s8 export_track, u8 mute_nonloopback_tracks)
262 tk 659
{
757 tk 660
  // get MIDI File play mode (if set to SEQ_MIDPLY_MODE_Exclusive, all tracks will be muted)
1316 tk 661
  u8 midply_solo = SEQ_MIDPLY_RunModeGet() != 0 && SEQ_MIDPLY_ModeGet() == SEQ_MIDPLY_MODE_Exclusive;
757 tk 662
 
262 tk 663
  // increment reference step on each 16th note
664
  // set request flag on overrun (tracks can synch to measure)
665
  u8 synch_to_measure_req = 0;
1513 tk 666
  if( (bpm_tick % (384/4)) == 0 ) {
1518 tk 667
    seq_core_trk_t *t = &seq_core_trk[0];
668
    seq_cc_trk_t *tcc = &seq_cc_trk[0];
669
    u8 track;
670
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc) {
671
      if( seq_core_state.reset_trkpos_req & (1 << track) ) {
672
    SEQ_CORE_ResetTrkPos(track, t, tcc);
2159 tk 673
    ++t->bar;
1518 tk 674
      }
1806 tk 675
 
676
      // NEW: temporary layer mutes on incoming MIDI
677
      // take over _next mutes
1810 tk 678
      int num_steps = (seq_core_options.LIVE_LAYER_MUTE_STEPS < 2) ? 1 : (seq_core_options.LIVE_LAYER_MUTE_STEPS-2+1);
679
      if( (bpm_tick % (num_steps*(384/4))) == 0 ) {
1809 tk 680
    // layer mutes
681
    t->layer_muted_from_midi = t->layer_muted_from_midi_next;
682
    t->layer_muted_from_midi_next = 0;
683
 
684
    // the same for the LFO CC
685
    t->lfo_cc_muted_from_midi = t->lfo_cc_muted_from_midi_next;
686
    t->lfo_cc_muted_from_midi_next = 0;
687
      }
1515 tk 688
    }
1518 tk 689
    seq_core_state.reset_trkpos_req = 0;
1515 tk 690
 
1513 tk 691
    if( seq_core_state.FIRST_CLK || seq_core_state.FORCE_REF_STEP_RESET ) {
692
      seq_core_state.FORCE_REF_STEP_RESET = 0;
693
      synch_to_measure_req = 1;
1145 tk 694
      seq_core_state.ref_step = 0;
1513 tk 695
      seq_core_state.ref_step_song = 0;
696
    } else {
697
      if( ++seq_core_state.ref_step > seq_core_steps_per_measure ) {
698
    seq_core_state.ref_step = 0;
699
      }
700
 
701
      if( seq_song_guide_track ) {
702
    if( ++seq_core_state.ref_step_song > seq_cc_trk[seq_song_guide_track-1].length ) {
703
      seq_core_state.ref_step_song = 0;
704
    }
705
      } else {
706
    seq_core_state.ref_step_song = seq_core_state.ref_step;
707
      }
708
 
709
      if( SEQ_SONG_ActiveGet() ) {
710
    if( seq_core_state.ref_step_song == 0 )
711
      synch_to_measure_req = 1;
712
      } else {
713
    if( seq_core_state.ref_step == 0 )
714
      synch_to_measure_req = 1;
715
      }
716
    }
262 tk 717
  }
718
 
1206 tk 719
  // disable slave clock mute if not in slave mode anymore
720
  // or start of if measure is reached and OffOnNextMeasure has been requested
1209 tk 721
  u8 is_master = SEQ_BPM_IsMaster();
722
  if( is_master ||
1206 tk 723
      (synch_to_measure_req && (seq_core_slaveclk_mute == SEQ_CORE_SLAVECLK_MUTE_OffOnNextMeasure)) ) {
724
    // enable ports
725
    seq_core_slaveclk_mute = SEQ_CORE_SLAVECLK_MUTE_Off;
1209 tk 726
    if( !is_master ) {
727
      // release pause mode
728
      ui_seq_pause = 0;
729
      // TK: this makes sense! Request synch-to-measure for all tracks so that they restart properly
1315 tk 730
      SEQ_CORE_ManualSynchToMeasure(0xffff);
1209 tk 731
    }
1206 tk 732
  }
733
 
1145 tk 734
  // if no export and no mute:
735
  if( export_track == -1 && !mute_nonloopback_tracks ) {
1048 tk 736
    // send FA if external restart has been requested
737
    if( seq_core_state.EXT_RESTART_REQ && synch_to_measure_req ) {
738
      seq_core_state.EXT_RESTART_REQ = 0; // remove request
739
      seq_ui_display_update_req = 1; // request display update
740
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xfa, bpm_tick);
741
    }
742
 
761 tk 743
    // send MIDI clock on each 16th tick (since we are working at 384ppqn)
744
    if( (bpm_tick % 16) == 0 )
745
      SEQ_MIDI_ROUTER_SendMIDIClockEvent(0xf8, bpm_tick);
262 tk 746
 
761 tk 747
    // trigger DIN Sync clock with a special event (0xf9 normaly used for "MIDI tick")
748
    // SEQ_MIDI_PORT_NotifyMIDITx filters it before it will be forwarded to physical ports
2098 tk 749
 
750
    {
751
      int clkout;
752
 
761 tk 753
      mios32_midi_package_t p;
754
      p.ALL = 0;
755
      p.type = 0x5; // Single-byte system common message
756
      p.evnt0 = 0xf9;
2098 tk 757
 
758
      u16 *clk_divider = (u16 *)&seq_cv_clkout_divider[0];
759
      for(clkout=0; clkout<SEQ_CV_NUM_CLKOUT; ++clkout, ++clk_divider) {
760
    if( *clk_divider && (bpm_tick % *clk_divider) == 0 ) {
761
      p.evnt1 = clkout; // Transfers the Clock Output
762
      SEQ_MIDI_OUT_Send(0xff, p, SEQ_MIDI_OUT_ClkEvent, bpm_tick, 0);
763
    }
764
      }
761 tk 765
    }
718 tk 766
 
761 tk 767
    // send metronome tick on each beat if enabled
1145 tk 768
    if( seq_core_state.METRONOME && seq_core_metronome_chn && (bpm_tick % 96) == 0 && (seq_core_state.ref_step % 4) == 0 ) {
761 tk 769
      mios32_midi_package_t p;
262 tk 770
 
761 tk 771
      p.type     = NoteOn;
772
      p.cable    = 15; // use tag of track #16 - unfortunately more than 16 tags are not supported
773
      p.event    = NoteOn;
774
      p.chn      = seq_core_metronome_chn-1;
775
      p.note     = seq_core_metronome_note_b;
776
      p.velocity = 96;
777
      u16 len = 20; // ca. 25% of a 16th
524 tk 778
 
1145 tk 779
      if( seq_core_state.ref_step == 0 ) {
761 tk 780
    if( seq_core_metronome_note_m )
781
      p.note = seq_core_metronome_note_m; // if this note isn't defined, use B note instead
782
    p.velocity = 127;
783
      }
784
 
785
      if( p.note )
786
    SEQ_MIDI_OUT_Send(seq_core_metronome_port, p, SEQ_MIDI_OUT_OnOffEvent, bpm_tick, len);
524 tk 787
    }
788
  }
789
 
1261 tk 790
  // delayed mute
791
  if( synch_to_measure_req ) {
792
    // the priority handling for each individual track ensures
793
    // that mute/unmute will be done depending on the current mute state
794
    // unmute has higher priority than mute
795
    seq_core_trk_muted |= (seq_core_trk_synched_mute & ~seq_core_trk_muted);
796
    seq_core_trk_synched_mute = 0;
524 tk 797
 
1261 tk 798
    seq_core_trk_muted &= ~(seq_core_trk_synched_unmute & seq_core_trk_muted);
799
    seq_core_trk_synched_unmute = 0;
800
  }
801
 
262 tk 802
  // process all tracks
718 tk 803
  // first the loopback port Bus1, thereafter parameters sent to common MIDI ports
302 tk 804
  int round;
805
  for(round=0; round<2; ++round) {
806
    seq_core_trk_t *t = &seq_core_trk[0];
807
    seq_cc_trk_t *tcc = &seq_cc_trk[0];
808
    int track;
809
    for(track=0; track<SEQ_CORE_NUM_TRACKS; ++t, ++tcc, ++track) {
262 tk 810
 
2118 tk 811
      seq_robotize_flags_t robotize_flags;
812
      robotize_flags.ALL = 0;
813
 
718 tk 814
      // round 0: loopback port Bus1, round 1: remaining ports
1023 tk 815
      u8 loopback_port = (tcc->midi_port & 0xf0) == 0xf0;
302 tk 816
      if( (!round && !loopback_port) || (round && loopback_port) )
262 tk 817
    continue;
306 tk 818
 
761 tk 819
      // for MIDI file export: (export_track != -1): only given track + all loopback tracks will be played
820
      if( round && export_track != -1 && export_track != track )
759 tk 821
    continue;
822
 
599 tk 823
      // handle LFO effect
824
      SEQ_LFO_HandleTrk(track, bpm_tick);
825
 
1809 tk 826
      // send LFO CC (if enabled and not muted)
827
      if( !(seq_core_trk_muted & (1 << track)) && !seq_core_slaveclk_mute && !t->lfo_cc_muted_from_midi ) {
599 tk 828
    mios32_midi_package_t p;
1787 tk 829
    if( SEQ_LFO_FastCC_Event(track, bpm_tick, &p, 0) > 0 ) {
741 tk 830
      if( loopback_port )
1675 tk 831
        SEQ_MIDI_IN_BusReceive(tcc->midi_port & 0x0f, p, 1); // forward to MIDI IN handler immediately
741 tk 832
      else
2128 borfo 833
        SEQ_CORE_ScheduleEvent(t, tcc, p, SEQ_MIDI_OUT_CCEvent, bpm_tick, 0, 0, robotize_flags);
741 tk 834
    }
599 tk 835
      }
836
 
330 tk 837
      // sustained note: play off event if sustain mode has been disabled and no stretched gatelength
2233 tk 838
      if( t->state.SUSTAINED && (t->state.CANCEL_SUSTAIN_REQ || (!tcc->mode.SUSTAIN && !tcc->mode.ROBOSUSTAIN && !t->state.STRETCHED_GL)) ) {
717 tk 839
    int i;
840
 
841
    // important: play Note Off before new Note On to avoid that glide is triggered on the synth
1319 tk 842
    SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, bpm_tick ? (bpm_tick-1) : 0,
843
                seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 844
    // clear state flag and note storage
332 tk 845
    t->state.SUSTAINED = 0;
717 tk 846
    for(i=0; i<4; ++i)
847
      t->glide_notes[i] = 0;
306 tk 848
      }
2230 tk 849
      t->state.CANCEL_SUSTAIN_REQ = 0;
338 tk 850
 
302 tk 851
      // if "synch to measure" flag set: reset track if master has reached the selected number of steps
852
      // MEMO: we could also provide the option to synch to another track
2159 tk 853
      if( synch_to_measure_req && (tcc->clkdiv.SYNCH_TO_MEASURE || t->state.SYNC_MEASURE) ) {
599 tk 854
        SEQ_CORE_ResetTrkPos(track, t, tcc);
2159 tk 855
    ++t->bar;
856
      }
1211 tk 857
 
2159 tk 858
      u8 mute_this_step = 0;
1211 tk 859
      u8 next_step_event = t->state.FIRST_CLK || bpm_tick >= t->timestamp_next_step;
1883 tk 860
 
1316 tk 861
      if( next_step_event ) {
338 tk 862
 
1639 tk 863
    {
1211 tk 864
      // calculate step length
865
      u16 step_length_pre = ((tcc->clkdiv.value+1) * (tcc->clkdiv.TRIPLETS ? 4 : 6));
866
      t->step_length = step_length_pre;
344 tk 867
 
1211 tk 868
      // set timestamp of next step w/o groove delay (reference timestamp)
869
      if( t->state.FIRST_CLK )
870
        t->timestamp_next_step_ref = bpm_tick + t->step_length;
871
      else
872
        t->timestamp_next_step_ref += t->step_length;
828 tk 873
 
1211 tk 874
      // increment step if not in arpeggiator mode or arp position == 0
1788 tk 875
      u8 inc_step = tcc->mode.playmode != SEQ_CORE_TRKMODE_Arpeggiator || !t->arp_pos;
1211 tk 876
 
1788 tk 877
      // wrap step position around length - especially required for "section selection" later,
878
      // which can set t->step beyond tcc->length+1
879
      u8 prev_step = (u8)((int)t->step % ((int)tcc->length + 1));
880
      t->step = prev_step; // store back wrapped step position
881
 
882
      u8 skip_ctr = 0;
883
      do {
884
        if( t->state.MANUAL_STEP_REQ ) {
885
          // manual step requested
886
          t->state.MANUAL_STEP_REQ = 0;
887
          t->step = t->manual_step;
888
          t->step_saved = t->manual_step;
889
          t->arp_pos = 0;
1883 tk 890
        } else if( tcc->clkdiv.MANUAL ) {
891
          // if clkdiv MANUAL mode: step was not requested, skip it!
2159 tk 892
          mute_this_step = 1;
1788 tk 893
        } else {
894
          // determine next step depending on direction mode
895
          if( !t->state.FIRST_CLK && inc_step )
896
        SEQ_CORE_NextStep(t, tcc, 0, 0); // 0, 0=with progression, not reverse
897
          else {
898
        // ensure that position reset request is cleared
899
        t->state.POS_RESET = 0;
1211 tk 900
          }
1788 tk 901
        }
302 tk 902
 
1788 tk 903
        // clear "first clock" flag (on following clock ticks we can continue as usual)
904
        t->state.FIRST_CLK = 0;
302 tk 905
 
1788 tk 906
        // if skip flag set for this flag: try again
907
        if( SEQ_TRG_SkipGet(track, t->step, 0) )
908
          ++skip_ctr;
909
        else
910
          break;
911
 
912
      } while( skip_ctr < 32 ); // try 32 times maximum
344 tk 913
 
1788 tk 914
      // Section selection
915
      // Approach:
916
      // o enabled with t->play_section > 0
917
      // o section width matches with the Track length, which means that the sequencer will
918
      //   play steps beyond the "last step" with t->play_section > 0
919
      // o section controlled via UI, MIDI Keyboard or BLM
920
      // o lower priority than global loop mode
921
      if( t->play_section > 0 ) {
922
        // note: SEQ_TRG_Get() will return 0 if t->step beyond total track size - no need to consider this here
923
        int step_offset = t->play_section * ((int)tcc->length+1);
924
        t->step += step_offset;
925
      }
828 tk 926
 
1788 tk 927
      // global loop mode handling
928
      // requirements:
929
      // o loop all or only select tracks
930
      // o allow to loop the step view (16 step window) or a definable number of steps
931
      // o wrap step position properly when loop mode is activated so that this
932
      //   doesn't "dirsturb" the sequence output (ensure that the track doesn't get out of sync)
933
      if( seq_core_state.LOOP ) {
934
        u8 loop_active = 0;
935
        int step_offset = 0;
936
 
937
        switch( seq_core_glb_loop_mode ) {
938
        case SEQ_CORE_LOOP_MODE_ALL_TRACKS_STATIC:
939
          loop_active = 1;
940
          break;
596 tk 941
 
1788 tk 942
        case SEQ_CORE_LOOP_MODE_SELECTED_TRACK_STATIC:
943
          if( SEQ_UI_IsSelectedTrack(track) )
596 tk 944
        loop_active = 1;
1788 tk 945
          break;
596 tk 946
 
1788 tk 947
        case SEQ_CORE_LOOP_MODE_ALL_TRACKS_VIEW:
948
          loop_active = 1;
949
          // no break!
596 tk 950
 
1788 tk 951
        case SEQ_CORE_LOOP_MODE_SELECTED_TRACK_VIEW:
952
          if( SEQ_UI_IsSelectedTrack(track) )
596 tk 953
        loop_active = 1;
954
 
1788 tk 955
          step_offset = 16 * ui_selected_step_view;
956
          break;
957
        }
596 tk 958
 
1788 tk 959
        if( loop_active ) {
960
          // wrap step position within given boundaries if required
961
          step_offset += seq_core_glb_loop_offset;
962
          step_offset %= ((int)tcc->length+1);
596 tk 963
 
1788 tk 964
          int loop_steps = seq_core_glb_loop_steps + 1;
965
          int max_steps = (int)tcc->length + 1;
966
          if( loop_steps > max_steps )
967
        loop_steps = max_steps;
596 tk 968
 
1788 tk 969
          int new_step = (int)t->step;
970
          new_step = step_offset + ((new_step-step_offset) % loop_steps);
596 tk 971
 
1788 tk 972
          if( new_step > tcc->length )
973
        new_step = step_offset;
974
          t->step = new_step;
596 tk 975
        }
1788 tk 976
      }
596 tk 977
 
1788 tk 978
      // calculate number of cycles to next step
599 tk 979
#if 0
1788 tk 980
      t->timestamp_next_step = t->timestamp_next_step_ref + SEQ_GROOVE_DelayGet(track, t->step + 1);
599 tk 981
#else
1788 tk 982
      t->timestamp_next_step = t->timestamp_next_step_ref + SEQ_GROOVE_DelayGet(track, seq_core_state.ref_step + 1);
599 tk 983
#endif
419 tk 984
 
2308 tk 985
      if( !mute_this_step && !seq_record_options.FWD_MIDI ) { // if not already skipped (e.g. MANUAL mode)
986
        mute_this_step = t->state.REC_DONT_OVERWRITE_NEXT_STEP;
987
 
988
        if( seq_core_state.FIRST_CLK && seq_record_options.AUTO_START )
989
          mute_this_step = 1; // mute initial step which is going to be recorded
1883 tk 990
      }
2308 tk 991
 
1788 tk 992
      // forward new step to recording function (only used in live recording mode)
993
      SEQ_RECORD_NewStep(track, prev_step, t->step, bpm_tick);
751 tk 994
 
2145 tk 995
      // forward to live function (for repeats)
996
      // if it returns 1, the step won't be played
997
      if( SEQ_LIVE_NewStep(track, prev_step, t->step, bpm_tick) == 1 )
2159 tk 998
        mute_this_step = 1;
2145 tk 999
 
1788 tk 1000
      // inform UI about a new step (UI will clear this variable)
1001
      seq_core_step_update_req = 1;
1211 tk 1002
    }
338 tk 1003
 
302 tk 1004
        // solo function: don't play MIDI event if track not selected
1005
        // mute function
330 tk 1006
        // track disabled
1145 tk 1007
    // mute for non-loopback tracks activated
757 tk 1008
    // MIDI player in exclusive mode
1121 tk 1009
    // Record Mode, new step and FWD_MIDI off
2110 tk 1010
    u8 track_soloed = seq_core_trk_soloed && (seq_core_trk_soloed & (1 << track));
1011
        if( (!seq_core_trk_soloed && seq_ui_button_state.SOLO && !SEQ_UI_IsSelectedTrack(track)) ||
1012
        (seq_core_trk_soloed && !track_soloed) ||
1013
        (!track_soloed && (seq_core_trk_muted & (1 << track))) || // Track Mute function
1206 tk 1014
        seq_core_slaveclk_mute || // Slave Clock Mute Function
607 tk 1015
        SEQ_MIDI_PORT_OutMuteGet(tcc->midi_port) || // Port Mute Function
757 tk 1016
        tcc->mode.playmode == SEQ_CORE_TRKMODE_Off || // track disabled
1145 tk 1017
        (round && mute_nonloopback_tracks) || // all non-loopback tracks should be muted
1121 tk 1018
        midply_solo || // MIDI player in exclusive mode
2159 tk 1019
        mute_this_step ) { // Record Mode, new step and FWD_MIDI off
419 tk 1020
 
338 tk 1021
      if( t->state.STRETCHED_GL || t->state.SUSTAINED ) {
717 tk 1022
        int i;
1023
 
1024
        if( !t->state.STRETCHED_GL ) // important: play Note Off before new Note On to avoid that glide is triggered on the synth
1319 tk 1025
          SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, bpm_tick ? (bpm_tick-1) : 0,
1026
                      seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 1027
        else // Glide
1319 tk 1028
          SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, bpm_tick,
1029
                      seq_record_state.ENABLED ? seq_record_played_notes : NULL);
717 tk 1030
 
1031
        // clear state flags and note storage
338 tk 1032
        t->state.STRETCHED_GL = 0;
1033
        t->state.SUSTAINED = 0;
717 tk 1034
        for(i=0; i<4; ++i)
1035
          t->glide_notes[i] = 0;
338 tk 1036
      }
419 tk 1037
 
330 tk 1038
      continue;
338 tk 1039
    }
1211 tk 1040
 
2159 tk 1041
    // parameter layer mute flags (only if not in drum mode)
1042
    u16 layer_muted = (tcc->event_mode != SEQ_EVENT_MODE_Drum) ? (t->layer_muted | t->layer_muted_from_midi) : 0;
1043
 
302 tk 1044
        // if random gate trigger set: play step with 1:1 probability
328 tk 1045
        if( SEQ_TRG_RandomGateGet(track, t->step, 0) && (SEQ_RANDOM_Gen(0) & 1) )
302 tk 1046
      continue;
334 tk 1047
 
473 tk 1048
    // check probability if not in drum mode
334 tk 1049
    // if probability < 100: play step with given probability
473 tk 1050
    // in drum mode, the probability is checked for each individual instrument inside the layer event loop
334 tk 1051
    if( tcc->event_mode != SEQ_EVENT_MODE_Drum ) {
1052
      u8 rnd_probability;
1219 tk 1053
      if( (rnd_probability=SEQ_PAR_ProbabilityGet(track, t->step, 0, layer_muted)) < 100 &&
334 tk 1054
          SEQ_RANDOM_Gen_Range(0, 99) >= rnd_probability )
1055
        continue;
1056
    }
419 tk 1057
 
717 tk 1058
    // store last glide notes before they will be cleared
2104 tk 1059
    //memcpy(last_glide_notes, t->glide_notes, 4*4);
1060
    // this will be a bit faster (memcpy copies bytes, by copying words we save some time)
1061
    u32 prev_glide_notes[4];
1062
    u32 next_glide_notes[4];
1063
    {
1064
      u32 *src_ptr = (u32 *)&t->glide_notes[0];
1065
      u32 *dst_ptr = (u32 *)&prev_glide_notes[0];
1066
      u32 *next_ptr = (u32 *)&next_glide_notes[0];
1067
      int i;
1068
      for(i=0; i<4; ++i) {
1069
        *dst_ptr++ = *src_ptr++;
1070
        *next_ptr++ = 0;
1071
      }
1072
    }
419 tk 1073
 
323 tk 1074
        seq_layer_evnt_t layer_events[16];
1211 tk 1075
        s32 number_of_events = 0;
1076
 
1316 tk 1077
    number_of_events = SEQ_LAYER_GetEvents(track, t->step, layer_events, 0);
1211 tk 1078
    if( number_of_events > 0 ) {
328 tk 1079
      int i;
419 tk 1080
 
1081
      //////////////////////////////////////////////////////////////////////////////////////////
1082
      // First pass: handle length and apply functions which modify the MIDI events
1083
      //////////////////////////////////////////////////////////////////////////////////////////
1084
      u16 prev_bpm_tick_delay = t->bpm_tick_delay;
1085
      u8 gen_on_events = 0; // new On Events will be generated
1086
      u8 gen_sustained_events = 0; // new sustained On Events will be generated
608 tk 1087
      u8 gen_off_events = 0; // Off Events of previous step will be generated, the variable contains the remaining gatelength
419 tk 1088
 
323 tk 1089
          seq_layer_evnt_t *e = &layer_events[0];
1090
          for(i=0; i<number_of_events; ++e, ++i) {
1091
            mios32_midi_package_t *p = &e->midi_package;
328 tk 1092
 
332 tk 1093
        // instrument layers only used for drum tracks
686 tk 1094
        u8 instrument = (tcc->event_mode == SEQ_EVENT_MODE_Drum) ? e->layer_tag : 0;
330 tk 1095
 
334 tk 1096
        // individual for each instrument in drum mode:
1097
        // if probability < 100: play step with given probability
1098
        if( tcc->event_mode == SEQ_EVENT_MODE_Drum ) {
1099
          u8 rnd_probability;
1219 tk 1100
          if( (rnd_probability=SEQ_PAR_ProbabilityGet(track, t->step, instrument, layer_muted)) < 100 &&
334 tk 1101
          SEQ_RANDOM_Gen_Range(0, 99) >= rnd_probability )
1102
        continue;
1103
        }
2159 tk 1104
 
1105
        // get nofx flag
1106
        robotize_flags = SEQ_ROBOTIZE_Event(track, t->step, e);
1107
        u8 no_fx = SEQ_TRG_NoFxGet(track, t->step, instrument);
1108
 
1109
        // get nth trigger flag
1110
        // note: this check will be done again during the second pass for some triggers which are not handled during first pass
1111
        u8 nth_trigger = 0;
1112
        {
2162 tk 1113
          u8 nth_variant = 0; // Nth1 or Nth2
1114
          u8 nth_value = SEQ_PAR_Nth1ValueGet(track, t->step, instrument, layer_muted);
1115
          if( !nth_value ) {
1116
        nth_variant = 1;
1117
        nth_value = SEQ_PAR_Nth2ValueGet(track, t->step, instrument, layer_muted);
1118
          }
2159 tk 1119
 
1120
          if( nth_value ) {
1121
        int bar = nth_value & 0xf;
2162 tk 1122
        int trigger = nth_variant ? ((t->bar % (bar+1)) == bar) : ((t->bar % (bar+1)) == 0);
2159 tk 1123
 
1124
        int mode = (nth_value >> 4) & 0x7;
1125
        if( mode == SEQ_PAR_TYPE_NTH_PLAY ) {
1126
          if( !trigger )
1127
            continue; // step not played
1128
        } else if( mode == SEQ_PAR_TYPE_NTH_MUTE ) {
1129
          if( trigger )
1130
            continue; // step not played
1131
        } else if( mode == SEQ_PAR_TYPE_NTH_FX ) {
1132
          if( !trigger )
1133
            no_fx = 1;
2170 tk 1134
        } else if( mode == SEQ_PAR_TYPE_NTH_NO_FX ) {        
2159 tk 1135
          if( trigger )
1136
            no_fx = 1;
1137
        } else {
1138
          if( trigger )
1139
            nth_trigger = mode;
1140
        }
1141
          }
1142
        }
1143
 
323 tk 1144
            // transpose notes/CCs
1145
            SEQ_CORE_Transpose(t, tcc, p);
330 tk 1146
 
1142 tk 1147
            // glide trigger
1148
            if( e->len > 0 && tcc->event_mode != SEQ_EVENT_MODE_Drum ) {
1149
          if( SEQ_TRG_GlideGet(track, t->step, instrument) )
1150
        e->len = 96; // Glide
1151
            }
1152
 
1153
        // if glided note already played: omit new note event by setting velocity to 0
2104 tk 1154
        if( t->state.STRETCHED_GL ) {
1155
          u32 ix = p->note / 32;
1156
          u32 mask = (1 << (p->note % 32));
1157
          if( prev_glide_notes[ix] & mask ) {
2139 tk 1158
        if( e->len >= 96 ) {
1159
          next_glide_notes[ix] |= mask;
1160
        }
2104 tk 1161
        p->velocity = 0;
1162
          }
1142 tk 1163
        }
1164
 
1165
            // skip if velocity has been cleared by transpose or glide function
323 tk 1166
            // (e.g. no key pressed in transpose mode)
330 tk 1167
            if( p->type == NoteOn && !p->velocity ) {
1168
          // stretched note, length < 96: queue off event
419 tk 1169
          if( t->state.STRETCHED_GL && t->state.SUSTAINED && (e->len < 96) )
608 tk 1170
        gen_off_events = (t->step_length * e->len) / 96;
323 tk 1171
          continue;
330 tk 1172
        }
306 tk 1173
 
338 tk 1174
        // get delay of step (0..95)
1175
        // note: negative delays stored in step parameters would require to pre-generate bpm_ticks, 
1176
        // which would reduce the immediate response on value/trigger changes
1177
        // therefore negative delays are only supported for groove patterns, and they are
1178
        // applied over the whole track (e.g. drum mode: all instruments of the appr. track)
1219 tk 1179
        t->bpm_tick_delay = SEQ_PAR_StepDelayGet(track, t->step, instrument, layer_muted);
338 tk 1180
 
339 tk 1181
        // scale delay (0..95) over next clock counter to consider the selected clock divider
1182
        if( t->bpm_tick_delay )
344 tk 1183
          t->bpm_tick_delay = (t->bpm_tick_delay * t->step_length) / 96;
339 tk 1184
 
1185
 
419 tk 1186
            if( p->type != NoteOn ) {
1024 tk 1187
          // apply Pre-FX
2159 tk 1188
          if( !no_fx ) {
1024 tk 1189
        SEQ_LFO_Event(track, e);
1190
          }
1191
 
330 tk 1192
            } else if( p->note && p->velocity && (e->len >= 0) ) {
419 tk 1193
          // Note Event
330 tk 1194
 
339 tk 1195
          // groove it
599 tk 1196
#if 0
339 tk 1197
          SEQ_GROOVE_Event(track, t->step, e);
599 tk 1198
#else
1199
          SEQ_GROOVE_Event(track, seq_core_state.ref_step, e);
1200
#endif
339 tk 1201
 
608 tk 1202
          // apply Pre-FX before force-to-scale
2159 tk 1203
          if( !no_fx ) {
1204
        SEQ_HUMANIZE_Event(track, t->step, e);
2118 tk 1205
 
2159 tk 1206
        if( !robotize_flags.NOFX ) {
1207
          SEQ_LFO_Event(track, e);
1208
        }
1209
          }
2118 tk 1210
 
2139 tk 1211
          tcc->mode.ROBOSUSTAIN = ( robotize_flags.SUSTAIN ) ? 1 : 0 ;// set robosustain flag
608 tk 1212
 
1213
          // force to scale
1214
          if( tcc->mode.FORCE_SCALE ) {
2159 tk 1215
        u8 scale, root_selection, root;
1216
        SEQ_CORE_FTS_GetScaleAndRoot(&scale, &root_selection, &root);
1217
        SEQ_SCALE_Note(p, scale, root);
608 tk 1218
          }
1219
 
1220
          // apply Pre-FX after force-to-scale
2159 tk 1221
          if( !no_fx ) {
1222
        SEQ_CORE_Limit(t, tcc, e); // should be the last Fx in the chain!
599 tk 1223
          }
345 tk 1224
 
1117 tk 1225
          // force velocity to 0x7f (drum mode: selectable value) if accent flag set
2159 tk 1226
          if( nth_trigger == SEQ_PAR_TYPE_NTH_ACCENT || SEQ_TRG_AccentGet(track, t->step, instrument) ) {
1117 tk 1227
        if( tcc->event_mode == SEQ_EVENT_MODE_Drum )
1228
          p->velocity = tcc->lay_const[2*16 + i];
1229
        else
1230
          p->velocity = 0x7f;
1231
          }
1232
 
330 tk 1233
          // sustained or stretched note: play off event of previous step
419 tk 1234
          if( t->state.SUSTAINED )
1235
        gen_off_events = 1;
330 tk 1236
 
2124 borfo 1237
          if( tcc->mode.SUSTAIN || tcc->mode.ROBOSUSTAIN || e->len >= 96 )
419 tk 1238
        gen_sustained_events = 1;
717 tk 1239
          else {
419 tk 1240
        // generate common On event with given length
1241
        gen_on_events = 1;
1242
          }
717 tk 1243
        } else if( t->state.STRETCHED_GL && t->state.SUSTAINED && (e->len < 96) ) {
419 tk 1244
          // stretched note, length < 96: queue off events
608 tk 1245
          gen_off_events = (t->step_length * e->len) / 96;
419 tk 1246
        }
1247
      }
328 tk 1248
 
419 tk 1249
      // should Note Off events be played before new events are queued?
1250
      if( gen_off_events ) {
717 tk 1251
        u32 rescheduled_tick = bpm_tick + prev_bpm_tick_delay + gen_off_events;
1252
        if( !t->state.STRETCHED_GL ) // important: play Note Off before new Note On to avoid that glide is triggered on the synth
1253
          rescheduled_tick -= 1;
2104 tk 1254
 
1319 tk 1255
        SEQ_MIDI_OUT_ReSchedule(track, SEQ_MIDI_OUT_OffEvent, rescheduled_tick,
2104 tk 1256
                    seq_record_state.ENABLED ? seq_record_played_notes : (t->state.STRETCHED_GL ? next_glide_notes : NULL));
717 tk 1257
 
1258
        // clear state flag and note storage
419 tk 1259
        t->state.SUSTAINED = 0;
2104 tk 1260
        if( seq_record_state.ENABLED || !t->state.STRETCHED_GL ) {
1261
          t->state.STRETCHED_GL = 0;
1262
 
1263
          u32 *dst_ptr = (u32 *)&t->glide_notes[0];
1264
          int i;
1265
          for(i=0; i<4; ++i) {
1266
        *dst_ptr++ = 0;
1267
          }
1268
        } else if( t->state.STRETCHED_GL ) {
1269
          // improved glide handling for polyphonic steps
1270
          u8 any_glide = 0;
1271
          u32 *src_ptr = (u32 *)&next_glide_notes[0];
1272
          u32 *dst_ptr = (u32 *)&t->glide_notes[0];
1273
          int i;
1274
          for(i=0; i<4; ++i) {
1275
        if( *src_ptr )
1276
          any_glide |= 1;
1277
 
1278
        *dst_ptr++ = *src_ptr++;
1279
          }
1280
 
1281
          if( !any_glide )
1282
        t->state.STRETCHED_GL = 0;
1283
        }
419 tk 1284
      }
1285
 
1286
 
1287
      //////////////////////////////////////////////////////////////////////////////////////////
1288
      // Second pass: schedule new events
1289
      //////////////////////////////////////////////////////////////////////////////////////////
1290
          e = &layer_events[0];
1675 tk 1291
      u8 reset_stacks_done = 0;
419 tk 1292
          for(i=0; i<number_of_events; ++e, ++i) {
1293
            mios32_midi_package_t *p = &e->midi_package;
1294
 
1295
        // instrument layers only used for drum tracks
686 tk 1296
        u8 instrument = (tcc->event_mode == SEQ_EVENT_MODE_Drum) ? e->layer_tag : 0;
419 tk 1297
 
2159 tk 1298
        robotize_flags = SEQ_ROBOTIZE_Event(track, t->step, e);
1299
        u8 no_fx = SEQ_TRG_NoFxGet(track, t->step, instrument);
1300
 
1301
        // get nth trigger flag
1302
        // note: this check was already done during first pass, do it here again for triggers which are handled in the second pass
1303
        u8 nth_trigger = 0;
1304
        {
2162 tk 1305
          u8 nth_variant = 0; // Nth1 or Nth2
1306
          u8 nth_value = SEQ_PAR_Nth1ValueGet(track, t->step, instrument, layer_muted);
1307
          if( !nth_value ) {
1308
        nth_variant = 1;
1309
        nth_value = SEQ_PAR_Nth2ValueGet(track, t->step, instrument, layer_muted);
1310
          }
1311
 
2159 tk 1312
          if( nth_value ) {
1313
        int bar = nth_value & 0xf;
2162 tk 1314
        int trigger = nth_variant ? ((t->bar % (bar+1)) == bar) : ((t->bar % (bar+1)) == 0);
2159 tk 1315
 
1316
        int mode = (nth_value >> 4) & 0x7;
2170 tk 1317
        if( mode == SEQ_PAR_TYPE_NTH_PLAY ) {
2159 tk 1318
          if( !trigger )
2170 tk 1319
            continue; // step not played
1320
        } else if( mode == SEQ_PAR_TYPE_NTH_MUTE ) {
1321
          if( trigger )
1322
            continue; // step not played
1323
        } else if( mode == SEQ_PAR_TYPE_NTH_FX ) {
1324
          if( !trigger )
2159 tk 1325
            no_fx = 1;
1326
        } else if( mode == SEQ_PAR_TYPE_NTH_NO_FX ) {        
1327
          if( trigger )
1328
            no_fx = 1;
1329
        } else {
1330
          if( trigger )
1331
            nth_trigger = mode;
1332
        }
1333
          }
1334
        }
1335
 
419 tk 1336
        if( p->type != NoteOn ) {
1422 tk 1337
          // e.g. CC, PitchBend, ProgramChange
600 tk 1338
          if( loopback_port )
1675 tk 1339
        SEQ_MIDI_IN_BusReceive(tcc->midi_port & 0x0f, *p, 1); // forward to MIDI IN handler immediately
600 tk 1340
          else
2128 borfo 1341
        SEQ_CORE_ScheduleEvent(t, tcc, *p, SEQ_MIDI_OUT_CCEvent, bpm_tick + t->bpm_tick_delay, 0, 0, robotize_flags);
419 tk 1342
          t->vu_meter = 0x7f; // for visualisation in mute menu
1343
        } else {
1319 tk 1344
          // skip in record mode if the same note is already played
2149 tk 1345
          if( seq_record_state.ENABLED && t->state.STRETCHED_GL &&
1319 tk 1346
          (seq_record_played_notes[p->note>>5] & (1 << (p->note&0x1f))) )
1347
        continue;
1348
 
2104 tk 1349
          // skip in glide mode if note stretched
1350
          if( t->state.STRETCHED_GL &&
1351
          (next_glide_notes[p->note>>5] & (1 << (p->note&0x1f))) )
1352
        continue;
1353
 
717 tk 1354
          // sustained/glided note: play note at timestamp, and queue off event at 0xffffffff (so that it can be re-scheduled)      
419 tk 1355
          if( gen_sustained_events ) {
761 tk 1356
        // for visualisation in mute menu
1357
        t->vu_meter = p->velocity;
1358
 
1638 tk 1359
        if( loopback_port ) {
1675 tk 1360
          if( !reset_stacks_done ) {
1361
            // reset current stack
1362
            SEQ_MIDI_IN_ResetSingleTransArpStacks(tcc->midi_port & 0x0f);
1363
            reset_stacks_done = 1;
1364
          }
1638 tk 1365
          // forward to MIDI IN handler immediately
1675 tk 1366
          SEQ_MIDI_IN_BusReceive(tcc->midi_port & 0x0f, *p, 1);
1638 tk 1367
        } else {
1368
          u32 scheduled_tick = bpm_tick + t->bpm_tick_delay;
984 tk 1369
 
1638 tk 1370
          // glide: if same note already played, play the new one a tick later for 
1371
          // proper handling of "fingered portamento" function on some synths
2104 tk 1372
          if( prev_glide_notes[p->note / 32] & (1 << (p->note % 32)) )
1638 tk 1373
            scheduled_tick += 1;
1374
 
1862 tk 1375
          // Note On (the Note Off will be prepared as well in SEQ_CORE_ScheduleEvent)
2128 borfo 1376
          SEQ_CORE_ScheduleEvent(t, tcc, *p, SEQ_MIDI_OUT_OnEvent, scheduled_tick, 0, 0, robotize_flags);
1638 tk 1377
 
1378
          // apply Post-FX
2159 tk 1379
          if( !no_fx && !robotize_flags.NOFX ) {
1638 tk 1380
            u8 local_gatelength = 95; // echo only with reduced gatelength to avoid killed notes
2125 borfo 1381
 
1382
            SEQ_CORE_Echo(t, tcc, *p, bpm_tick + t->bpm_tick_delay, local_gatelength, robotize_flags);
1638 tk 1383
          }
984 tk 1384
        }
1385
 
419 tk 1386
        // notify stretched gatelength if not in sustain mode
1387
        t->state.SUSTAINED = 1;
2124 borfo 1388
        if( !tcc->mode.SUSTAIN && !tcc->mode.ROBOSUSTAIN ) {
419 tk 1389
          t->state.STRETCHED_GL = 1;
717 tk 1390
          // store glide note number in 128 bit array for later checks
1391
          t->glide_notes[p->note / 32] |= (1 << (p->note % 32));
1392
        }
984 tk 1393
 
419 tk 1394
          } else if( gen_on_events ) {
1395
        // for visualisation in mute menu
1396
        t->vu_meter = p->velocity;
1397
 
323 tk 1398
        if( loopback_port ) {
1675 tk 1399
          if( !reset_stacks_done ) {
1400
            reset_stacks_done = 1;
1401
            // reset current stack
1402
            SEQ_MIDI_IN_ResetSingleTransArpStacks(tcc->midi_port & 0x0f);
1403
          }
323 tk 1404
          // forward to MIDI IN handler immediately
1675 tk 1405
          SEQ_MIDI_IN_BusReceive(tcc->midi_port & 0x0f, *p, 1);
323 tk 1406
          // multi triggers, but also echo not possible on loopback ports
273 tk 1407
        } else {
419 tk 1408
          u16 gatelength = e->len;
1409
          u8 triggers = 1;
1410
 
1411
          // roll/flam?
1412
          // get roll mode from parameter layer
2188 tk 1413
          u8 roll_mode = 0;
1024 tk 1414
          u8 roll2_mode = 0; // taken if roll1 not assigned
2188 tk 1415
          if( SEQ_TRG_RollGateGet(track, t->step, instrument) ) { // optional roll gate
1416
            roll_mode = SEQ_PAR_RollModeGet(track, t->step, instrument, layer_muted);
1417
            // with less priority (parameter == 0): force roll mode if Roll trigger is set
1418
            if( nth_trigger == SEQ_PAR_TYPE_NTH_ROLL || (!roll_mode && SEQ_TRG_RollGet(track, t->step, instrument)) )
1419
              roll_mode = 0x0a; // 2D10
1420
            // if roll mode != 0: increase number of triggers
1421
            if( roll_mode ) {
1422
              triggers = ((roll_mode & 0x30)>>4) + 2;
1423
            } else {
1424
              roll2_mode = SEQ_PAR_Roll2ModeGet(track, t->step, instrument, layer_muted);
1425
              if( roll2_mode )
1426
            triggers = (roll2_mode >> 5) + 2;
1427
            }
1024 tk 1428
          }
419 tk 1429
 
323 tk 1430
          if( triggers > 1 ) {
1024 tk 1431
            if( roll2_mode ) {
1432
              // force gatelength depending on roll2 value
1433
              gatelength = (8 - 2*(roll2_mode >> 5)) * ((roll2_mode&0x1f)+1);
339 tk 1434
 
1024 tk 1435
              // scale length (0..95) over next clock counter to consider the selected clock divider
1436
              int gatelength = (4 - (roll2_mode >> 5)) * ((roll2_mode&0x1f)+1);
337 tk 1437
 
1024 tk 1438
              u32 half_gatelength = gatelength/2;
1439
              if( !half_gatelength )
1440
            half_gatelength = 1;
323 tk 1441
 
1024 tk 1442
              int i;
1443
              for(i=triggers-1; i>=0; --i)
2145 tk 1444
            SEQ_CORE_ScheduleEvent(t, tcc, *p, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay + i*gatelength, half_gatelength, 0, robotize_flags);
1024 tk 1445
            } else {
1446
              // force gatelength depending on number of triggers
1447
              if( triggers < 6 ) {
1448
            //       number of triggers:    2   3   4   5
1449
            const u8 gatelength_tab[4] = { 48, 32, 36, 32 };
1450
            // strategy:
1451
            // 2 triggers: played within 1 step at 0 and 48
1452
            // 3 triggers: played within 1 step at 0, 32 and 64
1453
            // 4 triggers: played within 1.5 steps at 0, 36, 72 and 108
1454
            // 5 triggers: played within 1.5 steps at 0, 32, 64, 96 and 128
1455
 
1456
            // in addition, scale length (0..95) over next clock counter to consider the selected clock divider
1457
            gatelength = (gatelength_tab[triggers-2] * t->step_length) / 96;
334 tk 1458
              }
1024 tk 1459
 
1460
              u32 half_gatelength = gatelength/2;
1461
              if( !half_gatelength )
1462
            half_gatelength = 1;
1463
 
1464
              mios32_midi_package_t p_multi = *p;
1465
              u16 roll_attenuation = 256 - (2 * triggers * (16 - (roll_mode & 0x0f))); // magic formula for nice effects
1466
              if( roll_mode & 0x40 ) { // upwards
1467
            int i;
1468
            for(i=triggers-1; i>=0; --i) {
2145 tk 1469
              SEQ_CORE_ScheduleEvent(t, tcc, p_multi, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay + i*gatelength, half_gatelength ,0, robotize_flags);
334 tk 1470
              u16 velocity = roll_attenuation * p_multi.velocity;
1471
              p_multi.velocity = velocity >> 8;
1472
            }
1024 tk 1473
              } else { // downwards
1474
            int i;
1475
            for(i=0; i<triggers; ++i) {
2145 tk 1476
              SEQ_CORE_ScheduleEvent(t, tcc, p_multi, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay + i*gatelength, half_gatelength, 0, robotize_flags);
1024 tk 1477
              if( roll_mode ) {
1478
                u16 velocity = roll_attenuation * p_multi.velocity;
1479
                p_multi.velocity = velocity >> 8;
1480
              }
1481
            }
334 tk 1482
              }
1483
            }
302 tk 1484
          } else {
323 tk 1485
            if( !gatelength )
1486
              gatelength = 1;
339 tk 1487
            else // scale length (0..95) over next clock counter to consider the selected clock divider
344 tk 1488
              gatelength = (gatelength * t->step_length) / 96;
2145 tk 1489
            SEQ_CORE_ScheduleEvent(t, tcc, *p, SEQ_MIDI_OUT_OnOffEvent, bpm_tick + t->bpm_tick_delay, gatelength, 0, robotize_flags);
419 tk 1490
          }
323 tk 1491
 
600 tk 1492
          // apply Post-FX
2159 tk 1493
          if( !no_fx && !robotize_flags.NOFX) {
2125 borfo 1494
            if( ( (tcc->echo_repeats & 0x3f) && ( !(tcc->echo_repeats & 0x40) || robotize_flags.ECHO ) && gatelength ) )
1495
              SEQ_CORE_Echo(t, tcc, *p, bpm_tick + t->bpm_tick_delay, gatelength, robotize_flags);
419 tk 1496
          }
323 tk 1497
        }
262 tk 1498
          }
323 tk 1499
            }
1500
          }
302 tk 1501
        }
262 tk 1502
      }
1503
    }
1504
  }
761 tk 1505
 
262 tk 1506
  // clear "first clock" flag if it was set before
1507
  seq_core_state.FIRST_CLK = 0;
1508
 
600 tk 1509
  // if manual trigger function requested stop: stop sequencer at end of reference step
1510
  if( seq_core_state.MANUAL_TRIGGER_STOP_REQ && (bpm_tick % 96) == 95 )
1511
    SEQ_BPM_Stop();
1512
 
262 tk 1513
  return 0; // no error
1514
}
1515
 
1516
 
1517
/////////////////////////////////////////////////////////////////////////////
1518
// Resets the step position variables of a track
1519
/////////////////////////////////////////////////////////////////////////////
599 tk 1520
static s32 SEQ_CORE_ResetTrkPos(u8 track, seq_core_trk_t *t, seq_cc_trk_t *tcc)
262 tk 1521
{
600 tk 1522
  // synch to measure done
1523
  t->state.SYNC_MEASURE = 0;
1524
 
262 tk 1525
  // don't increment on first clock event
1526
  t->state.FIRST_CLK = 1;
1527
 
338 tk 1528
  // clear delay
1529
  t->bpm_tick_delay = 0;
1530
 
593 tk 1531
  // reset step progression counters
262 tk 1532
  t->step_replay_ctr = 0;
1533
  t->step_fwd_ctr = 0;
593 tk 1534
  t->step_interval_ctr = 0;
1535
  t->step_repeat_ctr = 0;
1536
  t->step_skip_ctr = 0;
262 tk 1537
 
1859 tk 1538
  // and MIDI Fx channel counter
1539
  t->fx_midi_ctr = 0xff; // start with original channel
1540
 
262 tk 1541
  // next part depends on forward/backward direction
1542
  if( tcc->dir_mode == SEQ_CORE_TRKDIR_Backward ) {
1543
    // only for Backward mode
1544
    t->state.BACKWARD = 1;
1545
    t->step = tcc->length;
1546
  } else {
1547
    // for Forward/PingPong/Pendulum/Random/...
1548
    t->state.BACKWARD = 0;
1549
    t->step = 0;
1550
  }
1551
 
1552
  // save position (for repeat function)
1553
  t->step_saved = t->step;
1554
 
1555
  t->arp_pos = 0;
1556
 
599 tk 1557
  // reset LFO
1558
  SEQ_LFO_ResetTrk(track);
1559
 
262 tk 1560
  return 0; // no error
1561
}
1562
 
1563
 
1564
/////////////////////////////////////////////////////////////////////////////
1205 tk 1565
// Resets the step position variables of all tracks
1566
/////////////////////////////////////////////////////////////////////////////
1567
s32 SEQ_CORE_ResetTrkPosAll(void)
1568
{
1569
  seq_core_trk_t *t = &seq_core_trk[0];
1570
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
1571
  u8 track;
1572
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc)
1573
    SEQ_CORE_ResetTrkPos(track, t, tcc);
1574
 
1575
  return 0; // no error
1576
}
1577
 
1578
/////////////////////////////////////////////////////////////////////////////
1883 tk 1579
// Sets the track position for the given track (optionally scaled over 7bit)
1580
// the manual flag will set the step immediately, and play it
1581
/////////////////////////////////////////////////////////////////////////////
1582
extern s32 SEQ_CORE_SetTrkPos(u8 track, u8 value, u8 scale_value)
1583
{
1584
  if( track >= SEQ_CORE_NUM_TRACKS )
1585
    return -1; // invalid track
1586
 
1587
  seq_core_trk_t *t = &seq_core_trk[track];
1588
  seq_cc_trk_t *tcc = &seq_cc_trk[track];
1589
 
1590
  // scale CC value over track length
1591
  // selectable steps: 128 maximum
1592
  int step = value;
1593
  if( scale_value ) {
1594
    int length = (int)tcc->length + 1;
1595
    if( length > 128 )
1596
      length = 128;
1597
    step = ((step * length) / 128);
1598
  }
1599
 
1600
  if( !SEQ_BPM_IsRunning() ) {
1601
    // reset track position
1602
    SEQ_CORE_ResetTrkPos(track, t, tcc);
1603
 
1604
    // change step
1605
    t->step = step;
1606
    t->step_saved = t->step;
1607
  } else {
1608
    // request next step
1609
    t->manual_step = step;
1610
    t->state.MANUAL_STEP_REQ = 1;
1611
 
1612
    if( tcc->clkdiv.MANUAL )
1613
      t->state.FIRST_CLK = 1; // change to step immediately (not synchronized)
1614
  }
1615
 
1616
  return 0; // no error
1617
}
1618
 
1619
/////////////////////////////////////////////////////////////////////////////
262 tk 1620
// Determine next step depending on direction mode
1621
/////////////////////////////////////////////////////////////////////////////
593 tk 1622
static s32 SEQ_CORE_NextStep(seq_core_trk_t *t, seq_cc_trk_t *tcc, u8 no_progression, u8 reverse)
262 tk 1623
{
1624
  int i;
1625
  u8 save_step = 0;
1626
  u8 new_step = 1;
1627
 
1628
  // handle progression parameters if position shouldn't be reset
593 tk 1629
  if( !no_progression && !t->state.POS_RESET ) {
262 tk 1630
    if( ++t->step_fwd_ctr > tcc->steps_forward ) {
1631
      t->step_fwd_ctr = 0;
1632
      if( tcc->steps_jump_back ) {
593 tk 1633
    for(i=0; i<tcc->steps_jump_back; ++i)
1634
      SEQ_CORE_NextStep(t, tcc, 1, 1); // 1=no progression, 1=reverse
262 tk 1635
      }
1636
      if( ++t->step_replay_ctr > tcc->steps_replay ) {
1637
    t->step_replay_ctr = 0;
1638
    save_step = 1; // request to save the step in t->step_saved at the end of this routine
1639
      } else {
1640
    t->step = t->step_saved;
1641
    new_step = 0; // don't calculate new step
1642
      }
1643
    }
593 tk 1644
 
1645
    if( ++t->step_interval_ctr > tcc->steps_rs_interval ) {
1646
      t->step_interval_ctr = 0;
1647
      t->step_repeat_ctr = tcc->steps_repeat;
1648
      t->step_skip_ctr = tcc->steps_skip;
1649
    }
1650
 
1651
    if( t->step_repeat_ctr ) {
1652
      --t->step_repeat_ctr;
1653
      new_step = 0; // repeat step until counter reached zero
1654
    } else {
1655
      while( t->step_skip_ctr ) {
1656
    SEQ_CORE_NextStep(t, tcc, 1, 0); // 1=no progression, 0=not reverse
1657
    --t->step_skip_ctr;
1658
      }
1659
    }
262 tk 1660
  }
1661
 
1662
  if( new_step ) {
1663
    // special cases:
1664
    switch( tcc->dir_mode ) {
1665
      case SEQ_CORE_TRKDIR_Forward:
1666
    t->state.BACKWARD = 0; // force backward flag
1667
    break;
1668
 
1669
      case SEQ_CORE_TRKDIR_Backward:
1670
    t->state.BACKWARD = 1; // force backward flag
1671
    break;
1672
 
1673
      case SEQ_CORE_TRKDIR_PingPong:
1674
      case SEQ_CORE_TRKDIR_Pendulum:
1675
    // nothing else to do...
1676
    break;
1677
 
1678
      case SEQ_CORE_TRKDIR_Random_Dir:
1679
    // set forward/backward direction with 1:1 probability
1680
    t->state.BACKWARD = SEQ_RANDOM_Gen(0) & 1;
1681
        break;
1682
 
1683
      case SEQ_CORE_TRKDIR_Random_Step:
1684
    t->step = SEQ_RANDOM_Gen_Range(tcc->loop, tcc->length);
1685
    new_step = 0; // no new step calculation required anymore
1686
        break;
1687
 
1688
      case SEQ_CORE_TRKDIR_Random_D_S:
1689
    {
1690
      // we continue with a probability of 50%
1691
      // we change the direction with a probability of 25%
1692
      // we jump to a new step with a probability of 25%
1693
      u32 rnd;
1694
      if( ((rnd=SEQ_RANDOM_Gen(0)) & 0xff) < 0x80 ) {
1695
        if( rnd < 0x40 ) {
1696
          // set forward/backward direction with 1:1 probability
1697
          t->state.BACKWARD = SEQ_RANDOM_Gen(0) & 1;
1698
        } else {
1699
          t->step = SEQ_RANDOM_Gen_Range(tcc->loop, tcc->length);
1700
          new_step = 0; // no new step calculation required anymore
1701
        }
1702
      }
1703
    }
1704
    break;
1705
    }
1706
  }
1707
 
1708
  if( new_step ) { // note: new_step will be cleared in SEQ_CORE_TRKDIR_Random_Step mode
1709
    // branch depending on forward/backward mode, take reverse flag into account
1710
    if( t->state.BACKWARD ^ reverse ) {
1711
      // jump to last step if first loop step has been reached or a position reset has been requested
1712
      // in pendulum mode: switch to forward direction
1713
      if( t->state.POS_RESET || t->step <= tcc->loop ) {
2159 tk 1714
    ++t->bar;
1715
 
262 tk 1716
    if( tcc->dir_mode == SEQ_CORE_TRKDIR_Pendulum ) {
1717
      t->state.BACKWARD = 0;
1718
    } else {
1719
      t->step = tcc->length;
1720
    }
1721
    // reset arp position as well
1722
    t->arp_pos = 0;
1723
      } else {
1724
    // no reset required; decrement step
1725
    --t->step;
1726
 
1727
    // in pingpong mode: turn direction if loop step has been reached after this decrement
1728
    if( t->step <= tcc->loop && tcc->dir_mode == SEQ_CORE_TRKDIR_PingPong )
1729
      t->state.BACKWARD = 0;
1730
      }
1731
    } else {
1732
      // jump to first (loop) step if last step has been reached or a position reset has been requested
1733
      // in pendulum mode: switch to backward direction
1734
      if( t->state.POS_RESET || t->step >= tcc->length ) {
2159 tk 1735
    ++t->bar;
1736
 
262 tk 1737
    if( tcc->dir_mode == SEQ_CORE_TRKDIR_Pendulum ) {
1738
      t->state.BACKWARD = 1;
1739
    } else {
1740
      t->step = tcc->loop;
1741
    }
1742
    // reset arp position as well
1743
    t->arp_pos = 0;
1744
      } else {
1745
    // no reset required; increment step
1746
    ++t->step;
1747
 
1748
    // in pingpong mode: turn direction if last step has been reached after this increment
1749
    if( t->step >= tcc->length && tcc->dir_mode == SEQ_CORE_TRKDIR_PingPong )
1750
      t->state.BACKWARD = 1;
1751
      }
1752
    }
1753
  }
1754
 
1755
  if( !reverse ) {
1756
    // requested by progression handler
1757
    if( save_step )
1758
      t->step_saved = t->step;
1759
 
1760
    t->state.POS_RESET = 0;
1761
  }
1762
 
1763
  return 0; // no error
1764
}
1765
 
1766
 
1767
/////////////////////////////////////////////////////////////////////////////
1768
// Transposes if midi_package contains a Note Event
1769
/////////////////////////////////////////////////////////////////////////////
1219 tk 1770
s32 SEQ_CORE_Transpose(seq_core_trk_t *t, seq_cc_trk_t *tcc, mios32_midi_package_t *p)
262 tk 1771
{
1422 tk 1772
  u8 is_cc = p->type != NoteOn && p->type != NoteOff; // CC, Pitchbender, Programchange
262 tk 1773
 
1422 tk 1774
  if( is_cc && tcc->event_mode != SEQ_EVENT_MODE_CC ) // only transpose CC/Pitchbender/Program Change in CC mode
1024 tk 1775
    return -1;
1776
 
1777
  int note = is_cc ? p->value : p->note;
1778
 
262 tk 1779
  int inc_oct = tcc->transpose_oct;
1780
  if( inc_oct >= 8 )
1781
    inc_oct -= 16;
1782
 
1783
  int inc_semi = tcc->transpose_semi;
1784
  if( inc_semi >= 8 )
1785
    inc_semi -= 16;
1786
 
1787
  // in transpose or arp playmode we allow to transpose notes and CCs
1320 tk 1788
  if( tcc->mode.playmode == SEQ_CORE_TRKMODE_Transpose ||
1789
      (!is_cc && seq_core_global_transpose_enabled) ) {
1023 tk 1790
    int tr_note = SEQ_MIDI_IN_TransposerNoteGet(tcc->busasg.bus, tcc->mode.HOLD);
262 tk 1791
 
1792
    if( tr_note < 0 ) {
1793
      p->velocity = 0; // disable note and exit
1794
      return -1; // note has been disabled
1795
    }
1796
 
1322 tk 1797
    inc_semi += tr_note - 0x3c; // C-3 is the base note
262 tk 1798
  }
1799
  else if( tcc->mode.playmode == SEQ_CORE_TRKMODE_Arpeggiator ) {
1800
    int key_num = (note >> 2) & 0x3;
1801
    int arp_oct = (note >> 4) & 0x7;
1802
 
1803
    if( arp_oct < 2 ) { // Multi Arp Event
1804
      inc_oct += ((note >> 2) & 7) - 4;
1805
      key_num = t->arp_pos;
1806
    } else {
1807
      inc_oct += arp_oct - 4;
1808
    }
1809
 
1023 tk 1810
    int arp_note = SEQ_MIDI_IN_ArpNoteGet(tcc->busasg.bus, tcc->mode.HOLD, !tcc->mode.UNSORTED, key_num);
262 tk 1811
 
1812
    if( arp_note & 0x80 ) {
1813
      t->arp_pos = 0;
1814
    } else {
1815
      if( arp_oct < 2 ) { // Multi Arp Event
1816
    // play next key, step will be incremented once t->arp_pos reaches 0 again
1817
    if( ++t->arp_pos >= 4 )
1818
      t->arp_pos = 0;
1819
      }
1820
    }
1821
 
1822
    note = arp_note & 0x7f;
1823
 
1824
    if( !note ) { // disable note and exit
1825
      p->velocity = 0;
1826
      return -1; // note has been disabled
1827
    }
1828
  }
1829
 
1830
  // apply transpose octave/semitones parameter
1831
  if( inc_oct ) {
1832
    note += 12 * inc_oct;
1833
  }
1834
 
1835
  if( inc_semi ) {
1836
    note += inc_semi;
1837
  }
1838
 
1746 tk 1839
  // ensure that note is in the 0..127 range
1840
  note = SEQ_CORE_TrimNote(note, 0, 127);
1841
 
1422 tk 1842
  if( is_cc ) // if CC, Pitchbender, ProgramChange
1024 tk 1843
    p->value = note;
1844
  else
1845
    p->note = note;
262 tk 1846
 
1847
  return 0; // no error
1848
}
1849
 
1850
 
1851
/////////////////////////////////////////////////////////////////////////////
1852
// Returns the selected scale and root note selection depending on
1853
// global/group specific settings
1854
// scale and root note are for interest while playing the sequence -> SEQ_CORE
1855
// scale and root selection are for interest when editing the settings -> SEQ_UI_OPT
1320 tk 1856
// Both modules are calling this function to ensure consistency
262 tk 1857
/////////////////////////////////////////////////////////////////////////////
1858
s32 SEQ_CORE_FTS_GetScaleAndRoot(u8 *scale, u8 *root_selection, u8 *root)
1859
{
1860
  if( seq_core_global_scale_ctrl > 0 ) {
1861
    // scale/root selection from a specific pattern group
1862
    u8 group = seq_core_global_scale_ctrl-1;
1863
    *scale = seq_cc_trk[(group*SEQ_CORE_NUM_TRACKS_PER_GROUP)+2].shared.scale;
1864
    *root_selection = seq_cc_trk[(group*SEQ_CORE_NUM_TRACKS_PER_GROUP)+3].shared.scale_root;
1865
  } else {
1866
    // global scale/root selection
1867
    *scale = seq_core_global_scale;
1868
    *root_selection = seq_core_global_scale_root_selection;
1869
  }
1870
  *root = (*root_selection == 0) ? seq_core_keyb_scale_root : (*root_selection-1);
1871
 
1872
  return 0; // no error
1873
}
1874
 
1875
 
1876
/////////////////////////////////////////////////////////////////////////////
600 tk 1877
// Limit Fx
1878
/////////////////////////////////////////////////////////////////////////////
1219 tk 1879
s32 SEQ_CORE_Limit(seq_core_trk_t *t, seq_cc_trk_t *tcc, seq_layer_evnt_t *e)
600 tk 1880
{
1881
  u8 lower = tcc->limit_lower;
1882
  u8 upper = tcc->limit_upper;
1883
 
1884
  // check if any limit defined
1885
  if( !lower && !upper )
1886
    return 0; // no limit
1887
 
1888
  // exit if no note event
1889
  mios32_midi_package_t *p = &e->midi_package;
1890
  if( p->type != NoteOn )
1891
    return 0; // no Note
1892
 
1746 tk 1893
  // if not set: allow full range
1894
  if( !upper )
1895
    upper = 127;
1896
 
600 tk 1897
  // swap if lower value is greater than upper
1898
  if( lower > upper ) {
1899
    u8 tmp = upper;
1900
    upper=lower;
1901
    lower=tmp;
1902
  }
1903
 
1904
  // apply limit
1746 tk 1905
  p->note = SEQ_CORE_TrimNote(p->note, lower, upper);
600 tk 1906
 
1907
  return 0; // no error
1908
}
1909
 
1910
 
747 tk 1911
 
600 tk 1912
/////////////////////////////////////////////////////////////////////////////
747 tk 1913
// Name of Delay mode (we should outsource the echo function to seq_echo.c later)
1914
/////////////////////////////////////////////////////////////////////////////
774 tk 1915
// Note: newer gcc versions don't allow to return a "const" parameter, therefore
1916
// this array is declared outside the SEQ_CORE_Echo_GetDelayModeName() function
1121 tk 1917
 
1219 tk 1918
#define NUM_DELAY_VALUES 23
1121 tk 1919
static const char delay_str[NUM_DELAY_VALUES+1][5] = {
747 tk 1920
    " 64T",
1921
    " 64 ",
1922
    " 32T",
1923
    " 32 ",
1924
    " 16T",
1925
    " 16 ",
1926
    "  8T",
1927
    "  8 ",
1928
    "  4T",
1929
    "  4 ",
1930
    "  2T",
1931
    "  2 ",
1932
    "  1T",
1933
    "  1 ",
1934
    "Rnd1",
1935
    "Rnd2",
1121 tk 1936
    " 64d", // new with Beta30
1937
    " 32d", // new with Beta30
1938
    " 16d", // new with Beta30
1939
    "  8d", // new with Beta30
1940
    "  4d", // new with Beta30
1941
    "  2d", // new with Beta30
1219 tk 1942
    "  0 ", // new with Beta42
747 tk 1943
    "????",
1944
  };
1945
 
774 tk 1946
const char *SEQ_CORE_Echo_GetDelayModeName(u8 delay_mode)
1947
{
1121 tk 1948
  if( delay_mode < NUM_DELAY_VALUES )
747 tk 1949
    return delay_str[delay_mode];
1950
 
1121 tk 1951
  return delay_str[NUM_DELAY_VALUES];
747 tk 1952
}
1953
 
1954
 
1955
/////////////////////////////////////////////////////////////////////////////
1121 tk 1956
// Maps delay values from old to new format
1957
// Used to keep pattern binaries compatible to enhanced delay entries
1958
/////////////////////////////////////////////////////////////////////////////
1959
static const u8 delay_value_map[NUM_DELAY_VALUES] = {
1219 tk 1960
  22, //"  0 ",
1121 tk 1961
  0,  //" 64T",
1962
  1,  //" 64 ",
1963
  2,  //" 32T",
1964
  16, //" 64d",
1965
  3,  //" 32 ",
1966
  4,  //" 16T",
1967
  17, //" 32d",
1968
  5,  //" 16 ",
1969
  6,  //"  8T",
1970
  18, //" 16d",
1971
  7,  //"  8 ",
1972
  8,  //"  4T",
1973
  19, //"  8d",
1974
  9,  //"  4 ",
1975
  10, //"  2T",
1976
  20, //"  4d",
1977
  11, //"  2 ",
1978
  12, //"  1T",
1979
  21, //"  2d",
1980
  13, //"  1 ",
1981
  14, //"Rnd1",
1982
  15, //"Rnd2",
1983
};
1984
 
1985
u8 SEQ_CORE_Echo_MapUserToInternal(u8 user_value)
1986
{
1987
  if( user_value < NUM_DELAY_VALUES )
1988
    return delay_value_map[user_value];
1989
 
1990
  return 0;
1991
}
1992
 
1993
u8 SEQ_CORE_Echo_MapInternalToUser(u8 internal_value)
1994
{
1995
  int i;
1996
  for(i=0; i<NUM_DELAY_VALUES; ++i)
1997
    if( delay_value_map[i] == internal_value )
1998
      return i;
1999
 
2000
  return 0;
2001
}
2002
 
2003
 
2004
/////////////////////////////////////////////////////////////////////////////
262 tk 2005
// Echo Fx
2006
/////////////////////////////////////////////////////////////////////////////
2125 borfo 2007
s32 SEQ_CORE_Echo(seq_core_trk_t *t, seq_cc_trk_t *tcc, mios32_midi_package_t p, u32 bpm_tick, u32 gatelength, seq_robotize_flags_t robotize_flags)
262 tk 2008
{
2009
  // thanks to MIDI queuing mechanism, this is a no-brainer :)
2010
 
1219 tk 2011
  // 64T, 64, 32T, 32, 16T, 16, ... 1, Rnd1 and Rnd2, 64d..2d (new), 0 (supernew)
1121 tk 2012
  s32 fb_ticks;
742 tk 2013
  s32 echo_delay = tcc->echo_delay;
1219 tk 2014
  if( echo_delay >= 22 ) // new zero delay
2015
    fb_ticks = 0;
2016
  else if ( echo_delay >= 16 ) // new dotted delays
1121 tk 2017
    fb_ticks = 36 * (1 << (echo_delay-16));
2018
  else {
2019
    if( echo_delay >= 14 ) // Rnd1 and Rnd2
2020
      echo_delay = SEQ_RANDOM_Gen_Range(3, 7); // between 32 and 8
2021
    fb_ticks = ((tcc->echo_delay & 1) ? 24 : 16) * (1 << (echo_delay>>1));
2022
  }
262 tk 2023
 
2024
  s32 fb_note = p.note;
2025
  s32 fb_note_base = fb_note; // for random function
2026
 
2027
  // the initial velocity value allows to start with a low velocity,
2028
  // and to increase it with each step via FB velocity value
2029
  s32 fb_velocity = p.velocity;
2030
  if( tcc->echo_velocity != 20 ) { // 20 == 100% -> no change
2031
    fb_velocity = (fb_velocity * 5*tcc->echo_velocity) / 100;
2032
    if( fb_velocity > 127 )
2033
      fb_velocity = 127;
2034
    p.velocity = (u8)fb_velocity;
2035
  }
2036
 
273 tk 2037
  seq_midi_out_event_type_t event_type = SEQ_MIDI_OUT_OnOffEvent;
1422 tk 2038
  if( (p.type == CC || p.type == PitchBend || p.type == ProgramChange) && !gatelength )
273 tk 2039
    event_type = SEQ_MIDI_OUT_CCEvent;
262 tk 2040
 
276 tk 2041
  // for the case that force-to-scale is activated
2042
  u8 scale, root_selection, root;
2043
  SEQ_CORE_FTS_GetScaleAndRoot(&scale, &root_selection, &root);
2044
 
262 tk 2045
  u32 echo_offset = fb_ticks;
2050 tk 2046
  u8 echo_repeats = tcc->echo_repeats;
2125 borfo 2047
 
2048
  if( robotize_flags.ECHO ) {
2049
    // remove 0x40 flag indicating that echo is active (it's reversed, so 1 indicates echo is set to off)
2050
    // have to strip this flag out or the MSB flag makes a huge # of echo_repeats.
2051
    echo_repeats = echo_repeats & 0x0F;
2052
  }
2053
 
2054
  if( echo_repeats & 0x40 && !robotize_flags.ECHO) // disable flag
2050 tk 2055
    echo_repeats = 0;
2125 borfo 2056
 
2057
 
262 tk 2058
  int i;
2050 tk 2059
  for(i=0; i<echo_repeats; ++i) {
262 tk 2060
    if( i ) { // no feedback of velocity or echo ticks on first step
2061
      if( tcc->echo_fb_velocity != 20 ) { // 20 == 100% -> no change
2062
    fb_velocity = (fb_velocity * 5*tcc->echo_fb_velocity) / 100;
2063
    if( fb_velocity > 127 )
2064
      fb_velocity = 127;
2065
    p.velocity = (u8)fb_velocity;
2066
      }
2067
 
2068
      if( tcc->echo_fb_ticks != 20 ) { // 20 == 100% -> no change
2069
    fb_ticks = (fb_ticks * 5*tcc->echo_fb_ticks) / 100;
2070
      }
2071
      echo_offset += fb_ticks;
2072
    }
2073
 
2074
    if( tcc->echo_fb_note != 24 ) { // 24 == 0 -> no change
2075
      if( tcc->echo_fb_note == 49 ) // random
2076
    fb_note = fb_note_base + ((s32)SEQ_RANDOM_Gen_Range(0, 48) - 24);
2077
      else
2078
    fb_note = fb_note + ((s32)tcc->echo_fb_note-24);
2079
 
1746 tk 2080
      // ensure that note is in the 0..127 range
2081
      fb_note = SEQ_CORE_TrimNote(fb_note, 0, 127);
2082
 
262 tk 2083
      p.note = (u8)fb_note;
2084
    }
2085
 
2086
    if( gatelength && tcc->echo_fb_gatelength != 20 ) { // 20 == 100% -> no change
2087
      gatelength = (gatelength * 5*tcc->echo_fb_gatelength) / 100;
2088
      if( !gatelength )
2089
    gatelength = 1;
2090
    }
2091
 
276 tk 2092
    // force to scale
2093
    if( tcc->mode.FORCE_SCALE ) {
2094
      SEQ_SCALE_Note(&p, scale, root);
2095
    }
2096
 
2145 tk 2097
    SEQ_CORE_ScheduleEvent(t, tcc, p, event_type, bpm_tick + echo_offset, gatelength, 1, robotize_flags);
262 tk 2098
  }
2099
 
2100
  return 0; // no error
2101
}
2102
 
2103
 
2104
/////////////////////////////////////////////////////////////////////////////
600 tk 2105
// Manually triggers a step of all selected tracks
2106
/////////////////////////////////////////////////////////////////////////////
2107
s32 SEQ_CORE_ManualTrigger(u8 step)
2108
{
2109
  MIOS32_IRQ_Disable();
2110
 
2111
  u8 track;
1883 tk 2112
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
600 tk 2113
    if( SEQ_UI_IsSelectedTrack(track) ) {
1883 tk 2114
      SEQ_CORE_SetTrkPos(track, step, 0);
600 tk 2115
    }
2116
  }
2117
 
2118
  if( !SEQ_BPM_IsRunning() ) {
1205 tk 2119
    // start sequencer if not running, but only for one step
600 tk 2120
    SEQ_BPM_Cont();
2121
    seq_core_state.MANUAL_TRIGGER_STOP_REQ = 1;
2122
  }
2123
 
2124
  MIOS32_IRQ_Enable();
2125
 
2126
  return 0; // no error
2127
}
2128
 
2129
 
2130
/////////////////////////////////////////////////////////////////////////////
1315 tk 2131
// Manually requests synch to measure for given tracks
600 tk 2132
/////////////////////////////////////////////////////////////////////////////
1315 tk 2133
s32 SEQ_CORE_ManualSynchToMeasure(u16 tracks)
600 tk 2134
{
2135
  MIOS32_IRQ_Disable();
2136
 
2137
  u8 track;
2138
  seq_core_trk_t *t = &seq_core_trk[0];
2139
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t)
1315 tk 2140
    if( tracks & (1 << track) )
600 tk 2141
      t->state.SYNC_MEASURE = 1;
2142
 
2143
  MIOS32_IRQ_Enable();
2144
 
2145
  return 0; // no error
2146
}
2147
 
2148
 
2149
/////////////////////////////////////////////////////////////////////////////
1806 tk 2150
// This function is called by the "Live" function on incoming MIDI events,
2151
// currently we use it to control the temporary layer mutes.
2152
/////////////////////////////////////////////////////////////////////////////
2153
s32 SEQ_CORE_NotifyIncomingMIDIEvent(u8 track, mios32_midi_package_t p)
2154
{
2155
  if( track >= SEQ_CORE_NUM_TRACKS )
2156
    return -1; // invalid track
2157
 
1810 tk 2158
  if( !seq_core_options.LIVE_LAYER_MUTE_STEPS )
2159
    return 0; // disabled
2160
 
1806 tk 2161
  seq_core_trk_t *t = &seq_core_trk[track];
2162
  seq_cc_trk_t *tcc = &seq_cc_trk[track];
2163
 
2164
  if( tcc->event_mode == SEQ_EVENT_MODE_Drum )
2165
    return 0; // (currently) not relevant in drum mode
2166
 
2167
  switch( p.event ) {
2168
  //case NoteOff:
2169
  case NoteOn: {
2170
    if( p.velocity == 0 ) // ignore Note Offs
2171
      break;
2172
 
2173
    // temporary mute layers which are assigned to notes or chords
2174
    u8 *layer_type_ptr = (u8 *)&tcc->lay_const[0*16];
2175
    int par_layer;
2176
    int num_p_layers = SEQ_PAR_NumLayersGet(track);
2177
    u16 mask = 1;
2178
    for(par_layer=0; par_layer<num_p_layers; ++par_layer, ++layer_type_ptr, mask <<= 1) {
2274 tk 2179
      if( *layer_type_ptr == SEQ_PAR_Type_Note || *layer_type_ptr == SEQ_PAR_Type_Chord1 || *layer_type_ptr == SEQ_PAR_Type_Chord2 ) {
1806 tk 2180
    // hm... should we also play a note off for active notes?
2181
    // and should we mute the sequencer notes as long as no Note Off has been played?
2182
    // problem: we would have to track all actively played MIDI notes, this consumes a lot of memory
2183
 
2184
    portENTER_CRITICAL();
1810 tk 2185
    if( seq_core_options.LIVE_LAYER_MUTE_STEPS == 1 ) {
2186
      t->layer_muted |= mask;      // mute layer immediately
2187
    } else {
2188
      t->layer_muted_from_midi |= mask;      // mute layer immediately
2189
      t->layer_muted_from_midi_next |= mask; // and for the next step
2190
    }
1806 tk 2191
    portEXIT_CRITICAL();
2192
      }
2193
    }
2194
  } break;
2195
 
2196
  //case PolyPressure:
2197
  case CC:
2198
  case ProgramChange:
2199
  //case Aftertouch:
2200
  case PitchBend: {
2201
    // temporary mute layers which are assigned to the corresponding event
2202
    u8 *layer_type_ptr = (u8 *)&tcc->lay_const[0*16];
2203
    int par_layer;
2204
    int num_p_layers = SEQ_PAR_NumLayersGet(track);
2205
    u16 mask = 1;
2206
    for(par_layer=0; par_layer<num_p_layers; ++par_layer, ++layer_type_ptr, mask <<= 1) {
1813 tk 2207
      u8 apply_mask = 0;
1806 tk 2208
      switch( *layer_type_ptr ) {
2209
      case SEQ_PAR_Type_CC: {
2210
    if( p.event == CC && p.cc_number == tcc->lay_const[1*16 + par_layer] ) {
1810 tk 2211
      apply_mask = 1;
1806 tk 2212
    }
2213
      } break;
2214
 
2215
      case SEQ_PAR_Type_PitchBend: {
2216
    if( p.event == PitchBend ) {
1810 tk 2217
      apply_mask = 1;
1806 tk 2218
    }
2219
      } break;
2220
 
2221
      case SEQ_PAR_Type_ProgramChange: {
2222
    if( p.event == ProgramChange ) {
1810 tk 2223
      apply_mask = 1;
2224
    }
2225
      } break;
2226
      }
2227
 
2228
      if( apply_mask ) {
2229
    portENTER_CRITICAL();
2230
    if( seq_core_options.LIVE_LAYER_MUTE_STEPS == 1 ) {
2231
      t->layer_muted |= mask;      // mute layer immediately
2232
    } else {
1806 tk 2233
      t->layer_muted_from_midi |= mask;      // mute layer immediately
2234
      t->layer_muted_from_midi_next |= mask; // and for the next step
2235
    }
1810 tk 2236
    portEXIT_CRITICAL();
1806 tk 2237
      }
2238
    }
1809 tk 2239
 
1810 tk 2240
    // check also LFO CC (note: only handled as temporary change)
1809 tk 2241
    if( p.event == CC && p.cc_number == tcc->lfo_cc ) {
2242
      portENTER_CRITICAL();
2243
      t->lfo_cc_muted_from_midi = 1;
2244
      t->lfo_cc_muted_from_midi_next = 1;
2245
      portEXIT_CRITICAL();
2246
    }
2247
 
1806 tk 2248
  } break;
2249
  }
2250
 
2251
  return 0; // no error
2252
}
2253
 
2254
 
2255
/////////////////////////////////////////////////////////////////////////////
262 tk 2256
// This function requests to pre-generate sequencer ticks for a given time
2257
// It returns -1 if the previously requested delay hasn't passed yet
2258
/////////////////////////////////////////////////////////////////////////////
2259
s32 SEQ_CORE_AddForwardDelay(u16 delay_ms)
2260
{
2261
  if( bpm_tick_prefetch_req )
2262
    return -1; // ongoing request
2263
 
2264
  // calculate how many BPM ticks have to be forwarded
1983 tk 2265
  u32 delay_ticks = SEQ_BPM_TicksFor_mS(delay_ms);
2266
  bpm_tick_prefetch_req = SEQ_BPM_TickGet() + delay_ticks;
262 tk 2267
 
1983 tk 2268
  return delay_ticks; // no error
262 tk 2269
}
491 tk 2270
 
2271
 
2272
/////////////////////////////////////////////////////////////////////////////
2273
// This function updates the BPM rate in a given sweep time
2274
/////////////////////////////////////////////////////////////////////////////
2275
s32 SEQ_CORE_BPM_Update(float bpm, float sweep_ramp)
2276
{
2277
  if( sweep_ramp <= 0.0 ) {
2278
    seq_core_bpm_target = bpm;
2279
    SEQ_BPM_Set(seq_core_bpm_target);
2206 tk 2280
    SEQ_MIDI_PORT_ClkDelayUpdateAll();
491 tk 2281
    seq_core_bpm_sweep_inc = 0.0;
2282
  } else {
2283
    seq_core_bpm_target = bpm;
2284
    seq_core_bpm_sweep_inc = (seq_core_bpm_target - SEQ_BPM_Get()) / (10.0 * sweep_ramp);
2285
  }
2286
 
2287
  return 0; // no error
2288
}
2289
 
2290
/////////////////////////////////////////////////////////////////////////////
2291
// This function should be called each mS to update the BPM
2292
/////////////////////////////////////////////////////////////////////////////
2293
s32 SEQ_CORE_BPM_SweepHandler(void)
2294
{
2295
  static u8 prescaler = 0;
2296
 
2297
  // next step each 100 mS
2298
  if( ++prescaler < 100 )
2299
    return 0;
2300
  prescaler = 0;
2301
 
2302
  if( seq_core_bpm_sweep_inc != 0.0 ) {
2303
    float current_bpm = SEQ_BPM_Get();
2304
    float tolerance = 0.1;
2305
 
2306
    if( (seq_core_bpm_sweep_inc > 0.0 && current_bpm >= (seq_core_bpm_target-tolerance)) ||
2307
    (seq_core_bpm_sweep_inc < 0.0 && current_bpm <= (seq_core_bpm_target+tolerance)) ) {
2308
      seq_core_bpm_sweep_inc = 0.0; // final value reached
2309
      SEQ_BPM_Set(seq_core_bpm_target);
2206 tk 2310
      SEQ_MIDI_PORT_ClkDelayUpdateAll();
491 tk 2311
    } else {
2312
      SEQ_BPM_Set(current_bpm + seq_core_bpm_sweep_inc);
2206 tk 2313
      SEQ_MIDI_PORT_ClkDelayUpdateAll();
491 tk 2314
    }
2315
  }
2316
 
2317
  return 0; // no error
2318
}
2319
 
607 tk 2320
 
2321
/////////////////////////////////////////////////////////////////////////////
2322
// Scrub function called from UI when SCRUB button pressed and Datawheel
2323
// is moved
2324
/////////////////////////////////////////////////////////////////////////////
2325
s32 SEQ_CORE_Scrub(s32 incrementer)
2326
{
2327
  // simple but useful: increment/decrement the step of each track
2328
  // (in MBSEQ V3 we only generated some additional clocks, which had
2329
  // the disadvantage, that sequences couldn't be scrubbed back)
2330
 
2331
  // this simplified method currently has following disadvantages:
2332
  // - clock dividers not taken into account (difficult, needs some code restructuring in SEQ_CORE_Tick())
2333
  // - ...and?
2334
  // advantage:
2335
  // - sequencer stays in sync with outgoing/incoming MIDI clock!
2336
  // - reverse scrubbing for some interesting effects while played live (MB-808 has a similar function: nudge)
2337
 
2338
  u8 track;
2339
  seq_core_trk_t *t = &seq_core_trk[0];
2340
  seq_cc_trk_t *tcc = &seq_cc_trk[0];
2341
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track, ++t, ++tcc) {
2342
    SEQ_CORE_NextStep(t, tcc, 0, incrementer >= 0 ? 0 : 1);
2343
  }
2344
 
2345
#if 0
2346
  // disabled so that we stay in Sync with MIDI clock!
2347
  // increment/decrement reference step
2348
  if( incrementer >= 0 ) {
2349
    if( ++seq_core_state.ref_step > seq_core_steps_per_measure )
2350
      seq_core_state.ref_step = 0;
2351
  } else {
2352
    if( seq_core_state.ref_step )
2353
      --seq_core_state.ref_step;
2354
    else
2355
      seq_core_state.ref_step = seq_core_steps_per_measure;
2356
  }
2357
#endif
2358
 
2359
  return 0; // no error
2360
}
1746 tk 2361
 
2362
 
2363
/////////////////////////////////////////////////////////////////////////////
2230 tk 2364
// This function has to be called from the UI whenever notes have been
2365
// updated to ensure that an ongoing sustained note is cancled if
2366
// there is no step played by the track anymore.
2367
/////////////////////////////////////////////////////////////////////////////
2368
s32 SEQ_CORE_CancelSustainedNotes(u8 track)
2369
{
2370
  if( track >= SEQ_CORE_NUM_TRACKS )
2371
    return -1; // invalid track
2372
 
2373
  seq_core_trk_t *t = &seq_core_trk[track];
2374
  seq_cc_trk_t *tcc = &seq_cc_trk[track];
2375
 
2376
  if( t->state.SUSTAINED && tcc->event_mode != SEQ_EVENT_MODE_Drum ) {
2377
    u8 gate_trg_assignment = tcc->trg_assignments.gate;
2378
 
2379
    if( gate_trg_assignment ) {
2380
      u8 any_gate_set = 0;
2381
      u8 trg_instrument = 0;
2234 tk 2382
      int trk_len = (int)tcc->length + 1;
2230 tk 2383
      int i;
2384
 
2234 tk 2385
      for(i=0; i<trk_len; ++i) {
2386
    if( SEQ_TRG_Get(track, i, gate_trg_assignment-1, trg_instrument) ) {
2230 tk 2387
      any_gate_set = 1;
2388
      break;
2389
    }
2390
      }
2391
 
2392
      if( !any_gate_set ) {
2393
    t->state.CANCEL_SUSTAIN_REQ = 1;
2394
      }
2395
    }
2396
  }
2397
 
2398
  return 0; // no error
2399
}
2400
 
2401
 
2402
/////////////////////////////////////////////////////////////////////////////
1746 tk 2403
// This function ensures, that a (transposed) note is within
2404
// the <lower>..<upper> range.
2405
//
2406
// If the note is outside the range, it will be "trimmed" in the semitone
2407
// range, and the octave will be kept.
2408
/////////////////////////////////////////////////////////////////////////////
2409
u8 SEQ_CORE_TrimNote(s32 note, u8 lower, u8 upper)
2410
{
2411
  // negative note (e.g. after transpose?)
2412
  // shift it to the positive range
2413
  if( note < 0 )
2414
    note = 11 - ((-note - 1) % 12);
2415
 
2416
  // check for lower boundary
2417
  if( note < (s32)lower ) {
2418
    note = 12*(lower/12) + (note % 12);
2419
  }
2420
 
2421
  // check for upper boundary
2422
  if( note > (s32)upper ) {
2423
    note = 12*(upper/12) + (note % 12);
2424
 
2425
    // if note still > upper value (e.g. upper is set to >= 120)
2426
    // an if (instead of while) should work in all cases, because note will be (12*int(127/12)) + 11 = 131 in worst case!
2427
    if( note > upper )
2428
      note -= 12;
2429
  }
2430
 
2431
  return note;
2432
}