Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
168 tk 1
// $Id: seq_cc.c 1794 2013-05-31 19:25:43Z tk $
2
/*
248 tk 3
 * CC layer
168 tk 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>
318 tk 19
#include <string.h>
20
#include "tasks.h"
21
 
741 tk 22
#include "seq_ui.h"
168 tk 23
#include "seq_core.h"
24
#include "seq_cc.h"
333 tk 25
#include "seq_par.h"
174 tk 26
#include "seq_layer.h"
741 tk 27
#include "seq_morph.h"
168 tk 28
 
29
 
30
/////////////////////////////////////////////////////////////////////////////
31
// global variables
32
/////////////////////////////////////////////////////////////////////////////
33
seq_cc_trk_t seq_cc_trk[SEQ_CORE_NUM_TRACKS];
34
 
35
 
36
/////////////////////////////////////////////////////////////////////////////
37
// Initialisation
38
/////////////////////////////////////////////////////////////////////////////
39
s32 SEQ_CC_Init(u32 mode)
40
{
41
  // initialize all CC parameters
42
  int track;
43
  for(track=0; track<SEQ_CORE_NUM_TRACKS; ++track) {
44
    seq_cc_trk_t *tcc = &seq_cc_trk[track];
45
 
318 tk 46
    // clear all CCs
325 tk 47
    memset((u8 *)tcc, 0, sizeof(seq_cc_trk_t));
168 tk 48
 
1316 tk 49
#ifndef MBSEQV4L
318 tk 50
    // set parameters which are not changed by SEQ_LAYER_CopyPreset() function
168 tk 51
    tcc->midi_chn = track % 16;
52
    tcc->midi_port = DEFAULT;
1313 tk 53
    tcc->event_mode = SEQ_EVENT_MODE_Note;
1316 tk 54
#else
55
    // extra for MBSEQ V4L: use same channel by default
56
    tcc->midi_chn = 0;
57
    tcc->midi_port = DEFAULT;
58
 
59
    // set combined mode for first 3 tracks of a sequence
60
    // set all other tracks to CC
61
    if( (track >= 0 && track <= 2) || (track >= 8 && track <= 10) ) {
62
      tcc->event_mode = SEQ_EVENT_MODE_Combined;
63
    } else {
64
      tcc->event_mode = SEQ_EVENT_MODE_CC;
65
    }
66
#endif
168 tk 67
  }
68
 
69
  return 0; // no error
70
}
71
 
72
 
73
/////////////////////////////////////////////////////////////////////////////
74
// Set CCs
75
/////////////////////////////////////////////////////////////////////////////
248 tk 76
s32 SEQ_CC_Set(u8 track, u8 cc, u8 value)
168 tk 77
{
78
  if( track >= SEQ_CORE_NUM_TRACKS )
79
    return -1; // invalid track
80
 
81
  seq_cc_trk_t *tcc = &seq_cc_trk[track];
82
 
83
  // since CCs can be modified from other tasks at different priority we should do this operation atomic
318 tk 84
  portENTER_CRITICAL();
168 tk 85
 
596 tk 86
  if( cc < 0x30 ) {
318 tk 87
    tcc->lay_const[cc] = value;
333 tk 88
    if( tcc->event_mode != SEQ_EVENT_MODE_Drum )
769 tk 89
      SEQ_CC_LinkUpdate(track);
318 tk 90
  } else {
91
    switch( cc ) {
92
      case SEQ_CC_MODE: tcc->mode.playmode = value; break;
93
      case SEQ_CC_MODE_FLAGS: tcc->mode.flags = value; break;
168 tk 94
 
333 tk 95
      case SEQ_CC_MIDI_EVENT_MODE:
96
    tcc->event_mode = value;
769 tk 97
    SEQ_CC_LinkUpdate(track);
333 tk 98
    break;
99
 
318 tk 100
      case SEQ_CC_MIDI_CHANNEL: tcc->midi_chn = value; break;
101
      case SEQ_CC_MIDI_PORT: tcc->midi_port = value; break;
600 tk 102
 
1023 tk 103
      case SEQ_CC_BUSASG: tcc->busasg.bus = value; break;
104
 
600 tk 105
      case SEQ_CC_LIMIT_LOWER: tcc->limit_lower = value; break;
106
      case SEQ_CC_LIMIT_UPPER: tcc->limit_upper = value; break;
318 tk 107
 
108
      case SEQ_CC_DIRECTION: tcc->dir_mode = value; break;
109
      case SEQ_CC_STEPS_REPLAY: tcc->steps_replay = value; break;
110
      case SEQ_CC_STEPS_FORWARD: tcc->steps_forward = value; break;
111
      case SEQ_CC_STEPS_JMPBCK: tcc->steps_jump_back = value; break;
112
      case SEQ_CC_CLK_DIVIDER: tcc->clkdiv.value = value; break;
337 tk 113
 
114
      case SEQ_CC_LENGTH:
115
    // ensure that step position pointer matches with the new track length
116
    tcc->length = value;
117
    seq_core_trk[track].step %= ((u16)value+1);
118
    break;
119
 
318 tk 120
      case SEQ_CC_LOOP: tcc->loop = value; break;
121
      case SEQ_CC_CLKDIV_FLAGS: tcc->clkdiv.flags = value; break;
122
 
123
      case SEQ_CC_TRANSPOSE_SEMI: tcc->transpose_semi = value; break;
124
      case SEQ_CC_TRANSPOSE_OCT: tcc->transpose_oct = value; break;
125
      case SEQ_CC_GROOVE_VALUE: tcc->groove_value = value; break;
126
      case SEQ_CC_GROOVE_STYLE: tcc->groove_style = value; break;
127
      case SEQ_CC_MORPH_MODE: tcc->morph_mode = value; break;
607 tk 128
      case SEQ_CC_MORPH_DST: tcc->morph_dst = value; break;
318 tk 129
      case SEQ_CC_HUMANIZE_VALUE: tcc->humanize_value = value; break;
130
      case SEQ_CC_HUMANIZE_MODE: tcc->humanize_mode = value; break;
131
 
132
      case SEQ_CC_ASG_GATE: tcc->trg_assignments.gate = value; break;
133
      case SEQ_CC_ASG_ACCENT: tcc->trg_assignments.accent = value; break;
134
      case SEQ_CC_ASG_ROLL: tcc->trg_assignments.roll = value; break;
135
      case SEQ_CC_ASG_GLIDE: tcc->trg_assignments.glide = value; break;
136
      case SEQ_CC_ASG_SKIP: tcc->trg_assignments.skip = value; break;
137
      case SEQ_CC_ASG_RANDOM_GATE: tcc->trg_assignments.random_gate = value; break;
138
      case SEQ_CC_ASG_RANDOM_VALUE: tcc->trg_assignments.random_value = value; break;
139
      case SEQ_CC_ASG_NO_FX: tcc->trg_assignments.no_fx = value; break;
333 tk 140
 
141
      case SEQ_CC_PAR_ASG_DRUM_LAYER_A:
142
    tcc->par_assignment_drum[0] = value;
769 tk 143
    SEQ_CC_LinkUpdate(track);
333 tk 144
    break;
145
      case SEQ_CC_PAR_ASG_DRUM_LAYER_B:
146
    tcc->par_assignment_drum[1] = value;
769 tk 147
    SEQ_CC_LinkUpdate(track);
333 tk 148
    break;
149
 
593 tk 150
      case SEQ_CC_STEPS_REPEAT: tcc->steps_repeat = value; break;
151
      case SEQ_CC_STEPS_SKIP: tcc->steps_skip = value; break;
152
      case SEQ_CC_STEPS_RS_INTERVAL: tcc->steps_rs_interval = value; break;
153
 
318 tk 154
#if 0  
155
      case SEQ_CC_CHANGE_STEP: break; // TODO
156
#endif
157
 
158
      case SEQ_CC_ECHO_REPEATS: tcc->echo_repeats = value; break;
159
      case SEQ_CC_ECHO_DELAY: tcc->echo_delay = value; break;
160
      case SEQ_CC_ECHO_VELOCITY: tcc->echo_velocity = value; break;
161
      case SEQ_CC_ECHO_FB_VELOCITY: tcc->echo_fb_velocity = value; break;
162
      case SEQ_CC_ECHO_FB_NOTE: tcc->echo_fb_note = value; break;
163
      case SEQ_CC_ECHO_FB_GATELENGTH: tcc->echo_fb_gatelength = value; break;
164
      case SEQ_CC_ECHO_FB_TICKS: tcc->echo_fb_ticks = value; break;
599 tk 165
 
166
      case SEQ_CC_LFO_WAVEFORM: tcc->lfo_waveform = value; break;
167
      case SEQ_CC_LFO_AMPLITUDE: tcc->lfo_amplitude = value; break;
168
      case SEQ_CC_LFO_PHASE: tcc->lfo_phase = value; break;
169
      case SEQ_CC_LFO_STEPS: tcc->lfo_steps = value; break;
170
      case SEQ_CC_LFO_STEPS_RST: tcc->lfo_steps_rst = value; break;
171
      case SEQ_CC_LFO_ENABLE_FLAGS: tcc->lfo_enable_flags.ALL = value; break;
172
      case SEQ_CC_LFO_CC: tcc->lfo_cc = value; break;
173
      case SEQ_CC_LFO_CC_OFFSET: tcc->lfo_cc_offset = value; break;
174
      case SEQ_CC_LFO_CC_PPQN: tcc->lfo_cc_ppqn = value; break;
168 tk 175
 
318 tk 176
      default:
177
    portEXIT_CRITICAL();
178
        return -2; // invalid CC
179
    }
168 tk 180
  }
181
 
318 tk 182
  portEXIT_CRITICAL();
168 tk 183
 
184
  return 0; // no error
185
}
186
 
187
 
188
/////////////////////////////////////////////////////////////////////////////
741 tk 189
// Set CCs via MIDI (different mapping, especially used by Loopback Feature)
190
// see also doc/mbseqv4_cc_implementation.txt
191
/////////////////////////////////////////////////////////////////////////////
192
s32 SEQ_CC_MIDI_Set(u8 track, u8 cc, u8 value)
193
{
194
  if( cc == 0x01 ) { // ModWheel -> Morph Value
1316 tk 195
#ifndef MBSEQV4L
741 tk 196
    // update screen immediately if in morph page
197
    if( ui_page == SEQ_UI_PAGE_TRKMORPH )
198
      seq_ui_display_update_req = 1;
1316 tk 199
#endif
741 tk 200
    // forward morph value
201
    return SEQ_MORPH_ValueSet(value);
202
  } else if( cc == 0x03 ) {
203
    seq_core_global_scale = value;
204
    return 1;
205
  } else if( cc >= 0x10 && cc <= 0x5f ) {
742 tk 206
    u8 mapped_cc = cc+0x20;
207
 
208
    switch( mapped_cc ) {
209
      case SEQ_CC_LFO_AMPLITUDE:
210
    value *= 2; // 7bit -> 8bit
211
    break;
212
      case SEQ_CC_MIDI_PORT:
213
    if( value >= 0x70 )
214
      value = 0xf0 | (value & 0x0f); // map to Bus
215
    else if( value >= 0x60 )
216
      value = 0x80 | (value & 0x0f); // map to AOUT
217
    break;
218
    }
219
 
220
    return SEQ_CC_Set(track, mapped_cc, value); // 0x10..0x5f -> 0x30..0x7f
741 tk 221
  }
222
 
223
  return -1; // CC not mapped
224
}
225
 
226
 
227
/////////////////////////////////////////////////////////////////////////////
1794 tk 228
// Returns the CC value for MIDI (different mapping, especially used by Loopback Feature)
229
// see also doc/mbseqv4_cc_implementation.txt
230
// Returns < 0 if CC value not mapped
231
/////////////////////////////////////////////////////////////////////////////
232
s32 SEQ_CC_MIDI_Get(u8 track, u8 cc, u8 *mapped_cc)
233
{
234
  if( cc >= 0x30 && cc <= 0x7f ) {
235
    *mapped_cc = cc - 0x20;
236
 
237
    u8 value = SEQ_CC_Get(track, cc);
238
    switch( cc ) {
239
      case SEQ_CC_LFO_AMPLITUDE:
240
    value /= 2; // 8bit -> 7bit
241
    break;
242
      case SEQ_CC_MIDI_PORT:
243
    if( value >= 0xf0 )
244
      value = 0x70 | (value & 0x0f); // map to Bus
245
    else if( value >= 0x80 )
246
      value = 0x60 | (value & 0x0f); // map to AOUT
247
    break;
248
    }
249
 
250
    return value;
251
  }
252
 
253
  return -1; // CC not mapped
254
}
255
 
256
 
257
/////////////////////////////////////////////////////////////////////////////
168 tk 258
// Get CCs
259
/////////////////////////////////////////////////////////////////////////////
260
s32 SEQ_CC_Get(u8 track, u8 cc)
261
{
262
  if( track >= SEQ_CORE_NUM_TRACKS )
263
    return -1; // invalid track
264
 
265
  seq_cc_trk_t *tcc = &seq_cc_trk[track];
266
 
596 tk 267
  if( cc < 0x30 ) {
318 tk 268
    return tcc->lay_const[cc];
269
  }
270
 
168 tk 271
  switch( cc ) {
272
    case SEQ_CC_MODE: return tcc->mode.playmode;
273
    case SEQ_CC_MODE_FLAGS: return tcc->mode.flags;
323 tk 274
    case SEQ_CC_MIDI_EVENT_MODE: return tcc->event_mode;
168 tk 275
    case SEQ_CC_MIDI_CHANNEL: return tcc->midi_chn;
276
    case SEQ_CC_MIDI_PORT: return tcc->midi_port;
1023 tk 277
    case SEQ_CC_BUSASG: return tcc->busasg.bus;
600 tk 278
 
279
    case SEQ_CC_LIMIT_LOWER: return tcc->limit_lower;
280
    case SEQ_CC_LIMIT_UPPER: return tcc->limit_upper;
168 tk 281
 
282
    case SEQ_CC_DIRECTION: return tcc->dir_mode;
283
    case SEQ_CC_STEPS_REPLAY: return tcc->steps_replay;
284
    case SEQ_CC_STEPS_FORWARD: return tcc->steps_forward;
285
    case SEQ_CC_STEPS_JMPBCK: return tcc->steps_jump_back;
286
    case SEQ_CC_CLK_DIVIDER: return tcc->clkdiv.value;
287
    case SEQ_CC_LENGTH: return tcc->length;
288
    case SEQ_CC_LOOP: return tcc->loop;
289
    case SEQ_CC_CLKDIV_FLAGS: return tcc->clkdiv.flags;
290
 
291
    case SEQ_CC_TRANSPOSE_SEMI: return tcc->transpose_semi;
292
    case SEQ_CC_TRANSPOSE_OCT: return tcc->transpose_oct;
293
    case SEQ_CC_GROOVE_VALUE: return tcc->groove_value;
294
    case SEQ_CC_GROOVE_STYLE: return tcc->groove_style;
295
    case SEQ_CC_MORPH_MODE: return tcc->morph_mode;
607 tk 296
    case SEQ_CC_MORPH_DST: return tcc->morph_dst;
168 tk 297
    case SEQ_CC_HUMANIZE_VALUE: return tcc->humanize_value;
298
    case SEQ_CC_HUMANIZE_MODE: return tcc->humanize_mode;
299
 
300
    case SEQ_CC_ASG_GATE: return tcc->trg_assignments.gate;
301
    case SEQ_CC_ASG_ACCENT: return tcc->trg_assignments.accent;
318 tk 302
    case SEQ_CC_ASG_ROLL: return tcc->trg_assignments.roll;
168 tk 303
    case SEQ_CC_ASG_GLIDE: return tcc->trg_assignments.glide;
318 tk 304
    case SEQ_CC_ASG_SKIP: return tcc->trg_assignments.skip;
168 tk 305
    case SEQ_CC_ASG_RANDOM_GATE: return tcc->trg_assignments.random_gate;
306
    case SEQ_CC_ASG_RANDOM_VALUE: return tcc->trg_assignments.random_value;
294 tk 307
    case SEQ_CC_ASG_NO_FX: return tcc->trg_assignments.no_fx;
318 tk 308
 
333 tk 309
    case SEQ_CC_PAR_ASG_DRUM_LAYER_A: return tcc->par_assignment_drum[0];
310
    case SEQ_CC_PAR_ASG_DRUM_LAYER_B: return tcc->par_assignment_drum[1];
311
 
593 tk 312
    case SEQ_CC_STEPS_REPEAT: return tcc->steps_repeat;
313
    case SEQ_CC_STEPS_SKIP: return tcc->steps_skip;
314
    case SEQ_CC_STEPS_RS_INTERVAL: return tcc->steps_rs_interval;
315
 
318 tk 316
#if 0  
235 tk 317
    case SEQ_CC_CHANGE_STEP: return 0; // TODO
318 tk 318
#endif
235 tk 319
 
320
    case SEQ_CC_ECHO_REPEATS: return tcc->echo_repeats; break;
321
    case SEQ_CC_ECHO_DELAY: return tcc->echo_delay; break;
322
    case SEQ_CC_ECHO_VELOCITY: return tcc->echo_velocity; break;
323
    case SEQ_CC_ECHO_FB_VELOCITY: return tcc->echo_fb_velocity; break;
324
    case SEQ_CC_ECHO_FB_NOTE: return tcc->echo_fb_note; break;
325
    case SEQ_CC_ECHO_FB_GATELENGTH: return tcc->echo_fb_gatelength; break;
326
    case SEQ_CC_ECHO_FB_TICKS: return tcc->echo_fb_ticks; break;
599 tk 327
 
328
    case SEQ_CC_LFO_WAVEFORM: return tcc->lfo_waveform;
329
    case SEQ_CC_LFO_AMPLITUDE: return tcc->lfo_amplitude;
330
    case SEQ_CC_LFO_PHASE: return tcc->lfo_phase;
331
    case SEQ_CC_LFO_STEPS: return tcc->lfo_steps;
332
    case SEQ_CC_LFO_STEPS_RST: return tcc->lfo_steps_rst;
333
    case SEQ_CC_LFO_ENABLE_FLAGS: return tcc->lfo_enable_flags.ALL;
334
    case SEQ_CC_LFO_CC: return tcc->lfo_cc;
335
    case SEQ_CC_LFO_CC_OFFSET: return tcc->lfo_cc_offset;
336
    case SEQ_CC_LFO_CC_PPQN: return tcc->lfo_cc_ppqn;
168 tk 337
  }
338
 
339
  return -2; // invalid CC
340
}
333 tk 341
 
342
 
343
 
344
/////////////////////////////////////////////////////////////////////////////
769 tk 345
// Should be called whenever the event mode or par layer assignments have
346
// been changed
333 tk 347
/////////////////////////////////////////////////////////////////////////////
769 tk 348
s32 SEQ_CC_LinkUpdate(u8 track)
333 tk 349
{
350
  seq_cc_trk_t *tcc = &seq_cc_trk[track];
351
 
343 tk 352
  u8 *par_asg = (tcc->event_mode == SEQ_EVENT_MODE_Drum)
353
    ? (u8 *)&seq_cc_trk[track].par_assignment_drum[0]
354
    : (u8 *)&seq_cc_trk[track].lay_const[0*16];
333 tk 355
 
769 tk 356
  // since CCs can be modified from other tasks at different priority we should do this operation atomic
357
  portENTER_CRITICAL();
358
 
333 tk 359
  tcc->link_par_layer_note = -1;
360
  tcc->link_par_layer_chord = -1;
361
  tcc->link_par_layer_velocity = -1;
362
  tcc->link_par_layer_length = -1;
363
  tcc->link_par_layer_probability = -1;
364
  tcc->link_par_layer_delay = -1;
365
  tcc->link_par_layer_roll = -1;
1024 tk 366
  tcc->link_par_layer_roll2 = -1;
333 tk 367
 
368
  u8 num_layers = SEQ_PAR_NumLayersGet(track);
369
  if( num_layers ) {
370
    // search backwards to ensure that first assignments will be taken
371
    int layer;
372
    for(layer=num_layers-1; layer>=0; --layer) {
343 tk 373
      switch( (seq_par_layer_type_t)par_asg[layer] ) {
333 tk 374
        case SEQ_PAR_Type_Note: tcc->link_par_layer_note = layer; break;
375
        case SEQ_PAR_Type_Chord: tcc->link_par_layer_chord = layer; break;
376
        case SEQ_PAR_Type_Velocity: tcc->link_par_layer_velocity = layer; break;
377
        case SEQ_PAR_Type_Length: tcc->link_par_layer_length = layer; break;
378
        case SEQ_PAR_Type_Probability: tcc->link_par_layer_probability = layer; break;
379
        case SEQ_PAR_Type_Delay: tcc->link_par_layer_delay = layer; break;
380
        case SEQ_PAR_Type_Roll: tcc->link_par_layer_roll = layer; break;
1024 tk 381
        case SEQ_PAR_Type_Roll2: tcc->link_par_layer_roll2 = layer; break;
333 tk 382
      }
383
    }
384
  }
385
 
769 tk 386
  portEXIT_CRITICAL();
387
 
333 tk 388
  return 0; // no error
389
}