Subversion Repositories svn.mios32

Rev

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

Rev Author Line No. Line
1334 tk 1
/* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */
2
// $Id: MbCv.cpp 1960 2014-02-09 20:21:24Z tk $
3
/*
4
 * MIDIbox CV Unit
5
 *
6
 * ==========================================================================
7
 *
8
 *  Copyright (C) 2010 Thorsten Klose (tk@midibox.org)
9
 *  Licensed for personal non-commercial use only.
10
 *  All other rights reserved.
11
 *
12
 * ==========================================================================
13
 */
14
 
15
#include "MbCv.h"
1887 tk 16
#include <app.h>
1903 tk 17
#include <string.h>
18
#include <mbcv_map.h>
1334 tk 19
 
20
/////////////////////////////////////////////////////////////////////////////
21
// Constructor
22
/////////////////////////////////////////////////////////////////////////////
23
MbCv::MbCv()
24
{
25
    u8 cv = 0;
26
    init(cv, NULL);
27
}
28
 
29
 
30
/////////////////////////////////////////////////////////////////////////////
31
// Destructor
32
/////////////////////////////////////////////////////////////////////////////
33
MbCv::~MbCv()
34
{
35
}
36
 
37
 
38
/////////////////////////////////////////////////////////////////////////////
39
// Initializes the sound engines
40
/////////////////////////////////////////////////////////////////////////////
41
void MbCv::init(u8 _cvNum, MbCvClock *_mbCvClockPtr)
42
{
1903 tk 43
    cvNum = _cvNum;
44
 
1334 tk 45
    mbCvClockPtr = _mbCvClockPtr;
46
    mbCvVoice.init(_cvNum, &mbCvMidiVoice);
47
    mbCvMidiVoice.init();
1398 tk 48
    mbCvMod.init(_cvNum);
1960 tk 49
    lastExternalGateValue = 0;
1334 tk 50
 
51
    updatePatch(true);
52
}
53
 
54
 
55
/////////////////////////////////////////////////////////////////////////////
56
// Sound Engine Update Cycle
57
/////////////////////////////////////////////////////////////////////////////
58
bool MbCv::tick(const u8 &updateSpeedFactor)
59
{
1960 tk 60
    // external trigger
61
    {
62
        u16 ainValue = MIOS32_AIN_PinGet(cvNum); // 12bit
63
        u16 threshold = mbCvVoice.voiceExternalGateThreshold << 4; // 8bit -> 12bit
64
        if( threshold ) {
65
            if( lastExternalGateValue < threshold && ainValue >= threshold ) {
66
                mbCvVoice.gateOn();
67
                triggerNoteOn(&mbCvVoice);
68
            } else if( lastExternalGateValue >= threshold && ainValue < threshold ) {
69
                mbCvVoice.gateOff(mbCvVoice.voicePlayedNote);
70
                triggerNoteOff(&mbCvVoice);
71
            }
72
        }
73
        lastExternalGateValue = ainValue;
74
    }
75
 
1408 tk 76
    // clock
77
    if( mbCvClockPtr->eventStart ) {
78
        mbCvSeqBassline.seqRestartReq = true;
79
    }
80
 
81
    if( mbCvClockPtr->eventStop ) {
82
        mbCvSeqBassline.seqStopReq = true;
83
    }
84
 
85
    // clock arp and sequencers
1334 tk 86
    if( mbCvClockPtr->eventClock ) {
87
        mbCvArp.clockReq = true;
1408 tk 88
        mbCvSeqBassline.seqClockReq = true;
1334 tk 89
    }
90
 
91
    // LFOs
1398 tk 92
    {
93
        MbCvLfo *l = mbCvLfo.first();
94
        for(int lfo=0; lfo < mbCvLfo.size; ++lfo, ++l) {
95
            if( mbCvClockPtr->eventClock )
96
                l->syncClockReq = 1;
1338 tk 97
 
1398 tk 98
            l->lfoAmplitudeModulation =  mbCvMod.takeDstValue(MBCV_MOD_DST_LFO1_A + lfo);
99
            l->lfoRateModulation = mbCvMod.takeDstValue(MBCV_MOD_DST_LFO1_R + lfo);
1338 tk 100
 
1398 tk 101
            if( l->tick(updateSpeedFactor) ) {
102
                // trigger[MBCV_TRG_L1P+lfo];
1396 tk 103
            }
104
        }
1334 tk 105
    }
106
 
107
    // ENVs
1396 tk 108
    {
109
        MbCvEnv *e = mbCvEnv1.first();
110
        for(int env=0; env < mbCvEnv1.size; ++env, ++e) {
111
            if( mbCvClockPtr->eventClock )
112
                e->syncClockReq = 1;
1338 tk 113
 
1398 tk 114
            e->envAmplitudeModulation = mbCvMod.takeDstValue(MBCV_MOD_DST_ENV1_A);
115
            e->envRateModulation = mbCvMod.takeDstValue(MBCV_MOD_DST_ENV1_R);
116
 
117
            if( e->tick(updateSpeedFactor) ) {
118
                // trigger[MBCV_TRG_E1S];
1396 tk 119
            }
1338 tk 120
        }
1396 tk 121
    }
1338 tk 122
 
1396 tk 123
    {
124
        MbCvEnvMulti *e = mbCvEnv2.first();
125
        for(int env=0; env < mbCvEnv2.size; ++env, ++e) {
126
            if( mbCvClockPtr->eventClock )
127
                e->syncClockReq = 1;
1334 tk 128
 
1398 tk 129
            e->envAmplitudeModulation = mbCvMod.takeDstValue(MBCV_MOD_DST_ENV2_A);
130
            e->envRateModulation = mbCvMod.takeDstValue(MBCV_MOD_DST_ENV2_R);
131
 
132
            if( e->tick(updateSpeedFactor) ) {
133
                // trigger[MBCV_TRG_E2S];
1396 tk 134
            }
1398 tk 135
        }
136
    }
1396 tk 137
 
1398 tk 138
    // Modulation Matrix
139
    {
140
        // do ModMatrix calculations
141
        mbCvMod.tick();
142
 
143
        // additional direct modulation paths
1960 tk 144
        {
145
            s32 lfo1Value = (s32)mbCvLfo[0].lfoOut;
146
            s32 lfo2Value = (s32)mbCvLfo[1].lfoOut;
147
            s32 env1Value = (s32)mbCvEnv1[0].envOut;
148
            s32 env2Value = (s32)mbCvEnv2[0].envOut;
1398 tk 149
 
1960 tk 150
            { // Pitch
151
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_CV];
152
                mod += (lfo1Value * (s32)mbCvLfo[0].lfoDepthPitch) / 128;
153
                mod += (lfo2Value * (s32)mbCvLfo[1].lfoDepthPitch) / 128;
154
                mod += (env1Value * (s32)mbCvEnv1[0].envDepthPitch) / 128;
155
                mod += (env1Value * (s32)mbCvEnv2[0].envDepthPitch) / 128;
156
                mbCvMod.modDst[MBCV_MOD_DST_CV] = mod;
157
            }
1398 tk 158
 
1960 tk 159
            { // LFO1 Amp
160
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_LFO1_A];
161
                mod += (lfo2Value * (s32)mbCvLfo[1].lfoDepthLfoAmplitude) / 128;
162
                mod += (env1Value * (s32)mbCvEnv1[0].envDepthLfo1Amplitude) / 128;
163
                mod += (env2Value * (s32)mbCvEnv2[0].envDepthLfo1Amplitude) / 128;
164
                mbCvMod.modDst[MBCV_MOD_DST_LFO1_A] = mod;
165
            }
1398 tk 166
 
1960 tk 167
            { // LFO2 Amp
168
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_LFO2_A];
169
                mod += (lfo1Value * (s32)mbCvLfo[0].lfoDepthLfoAmplitude) / 128;
170
                mod += (env1Value * (s32)mbCvEnv1[0].envDepthLfo2Amplitude) / 128;
171
                mod += (env2Value * (s32)mbCvEnv2[0].envDepthLfo2Amplitude) / 128;
172
                mbCvMod.modDst[MBCV_MOD_DST_LFO2_A] = mod;
173
            }
1398 tk 174
 
1960 tk 175
            { // LFO1 Rate
176
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_LFO1_R];
177
                mod += (lfo2Value * (s32)mbCvLfo[1].lfoDepthLfoRate) / 128;
178
                mod += (env1Value * (s32)mbCvEnv1[0].envDepthLfo1Rate) / 128;
179
                mod += (env2Value * (s32)mbCvEnv2[0].envDepthLfo1Rate) / 128;
180
                mbCvMod.modDst[MBCV_MOD_DST_LFO1_R] = mod;
181
            }
1398 tk 182
 
1960 tk 183
            { // LFO2 Rate
184
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_LFO2_R];
185
                mod += (lfo1Value * (s32)mbCvLfo[0].lfoDepthLfoRate) / 128;
186
                mod += (env1Value * (s32)mbCvEnv1[0].envDepthLfo2Rate) / 128;
187
                mod += (env2Value * (s32)mbCvEnv2[0].envDepthLfo2Rate) / 128;
188
                mbCvMod.modDst[MBCV_MOD_DST_LFO2_R] = mod;
189
            }
1398 tk 190
 
1960 tk 191
            { // ENV1 Rate
192
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_ENV1_R];
193
                mod += (lfo1Value * (s32)mbCvLfo[0].lfoDepthEnv1Rate) / 128;
194
                mod += (lfo2Value * (s32)mbCvLfo[1].lfoDepthEnv1Rate) / 128;
195
                mbCvMod.modDst[MBCV_MOD_DST_ENV1_R] = mod;
196
            }
197
 
198
            { // ENV2 Rate
199
                s32 mod = mbCvMod.modDst[MBCV_MOD_DST_ENV2_R];
200
                mod += (lfo1Value * (s32)mbCvLfo[0].lfoDepthEnv2Rate) / 128;
201
                mod += (lfo2Value * (s32)mbCvLfo[1].lfoDepthEnv2Rate) / 128;
202
                mbCvMod.modDst[MBCV_MOD_DST_ENV2_R] = mod;
203
            }
1398 tk 204
        }
1334 tk 205
    }
206
 
1398 tk 207
    {
208
        // Voice handling
209
        MbCvVoice *v = &mbCvVoice; // allows to use multiple voices later
1334 tk 210
 
1960 tk 211
        v->voicePitchModulation = mbCvMod.takeDstValue(MBCV_MOD_DST_CV);
1334 tk 212
 
1408 tk 213
        if( mbCvArp.arpEnabled ) {
1398 tk 214
            mbCvArp.tick(v, this);
1408 tk 215
        } else {
216
            mbCvSeqBassline.tick(v, this);
217
        }
1398 tk 218
 
219
        if( v->gate(updateSpeedFactor) )
220
            v->pitch(updateSpeedFactor);
221
    }
222
 
1334 tk 223
    return true;
224
}
225
 
226
 
227
/////////////////////////////////////////////////////////////////////////////
228
// Receives a MIDI package
229
/////////////////////////////////////////////////////////////////////////////
230
void MbCv::midiReceive(mios32_midi_port_t port, mios32_midi_package_t midi_package)
231
{
232
    if( !mbCvMidiVoice.isAssignedPort(port) )
233
        return;
234
 
235
    switch( midi_package.event ) {
236
    case NoteOff:
237
        midiReceiveNote(midi_package.chn, midi_package.note, 0x00);
238
        break;
239
 
240
    case NoteOn:
241
        midiReceiveNote(midi_package.chn, midi_package.note, midi_package.velocity);
242
        break;
243
 
244
    case PolyPressure:
245
        midiReceiveAftertouch(midi_package.chn, midi_package.evnt2);
246
        break;
247
 
248
    case CC:
249
        midiReceiveCC(midi_package.chn, midi_package.cc_number, midi_package.value);
250
        break;
251
 
252
    case PitchBend: {
253
        u16 pitchbend_value_14bit = (midi_package.evnt2 << 7) | (midi_package.evnt1 & 0x7f);
254
        midiReceivePitchBend(midi_package.chn, pitchbend_value_14bit);
255
    } break;
256
 
257
    case Aftertouch:
258
        midiReceiveAftertouch(midi_package.chn, midi_package.evnt1);
259
        break;
260
  }
261
}
262
 
263
 
264
/////////////////////////////////////////////////////////////////////////////
265
// Receives a MIDI note
266
/////////////////////////////////////////////////////////////////////////////
267
void MbCv::midiReceiveNote(u8 chn, u8 note, u8 velocity)
268
{
1338 tk 269
    // check if MIDI channel and splitzone matches
270
    if( !mbCvMidiVoice.isAssigned(chn, note) )
271
        return; // note filtered
272
 
1334 tk 273
    // operation must be atomic!
274
    MIOS32_IRQ_Disable();
275
 
276
    // set note on/off
1398 tk 277
    if( velocity ) {
1334 tk 278
        noteOn(note, velocity, false);
1398 tk 279
    } else
1334 tk 280
        noteOff(note, false);
281
 
282
    MIOS32_IRQ_Enable();
283
}
284
 
285
 
286
/////////////////////////////////////////////////////////////////////////////
287
// Receives a MIDI CC
288
/////////////////////////////////////////////////////////////////////////////
289
void MbCv::midiReceiveCC(u8 chn, u8 ccNumber, u8 value)
290
{
291
    // take over CC (valid CCs will be checked by MIDI voice)
1398 tk 292
    if( mbCvMidiVoice.isAssigned(chn) ) {
293
        if( ccNumber == 1 )
1960 tk 294
            mbCvMidiVoice.midivoiceModWheel = value;
1398 tk 295
 
1334 tk 296
        mbCvMidiVoice.setCC(ccNumber, value);
1398 tk 297
    }
1334 tk 298
}
299
 
300
 
301
/////////////////////////////////////////////////////////////////////////////
302
// Receives a Pitchbend Event
303
/////////////////////////////////////////////////////////////////////////////
304
void MbCv::midiReceivePitchBend(u8 chn, u16 pitchbendValue14bit)
305
{
306
    if( mbCvMidiVoice.isAssigned(chn) ) {
307
        s16 pitchbendValueSigned = (s16)pitchbendValue14bit - 8192;
1960 tk 308
        mbCvMidiVoice.midivoicePitchBender = pitchbendValueSigned;
1334 tk 309
    }
310
}
311
 
312
 
313
/////////////////////////////////////////////////////////////////////////////
314
// Receives an Aftertouch Event
315
/////////////////////////////////////////////////////////////////////////////
316
void MbCv::midiReceiveAftertouch(u8 chn, u8 value)
317
{
1398 tk 318
    if( mbCvMidiVoice.isAssigned(chn) ) {
1960 tk 319
        mbCvMidiVoice.midivoiceAftertouch = value;
1398 tk 320
    }
1334 tk 321
}
322
 
323
 
324
/////////////////////////////////////////////////////////////////////////////
325
// Should be called whenver the patch has been changed
326
/////////////////////////////////////////////////////////////////////////////
327
void MbCv::updatePatch(bool forceEngineInit)
328
{
329
    // disable interrupts to ensure atomic change
330
    MIOS32_IRQ_Disable();
331
 
332
    mbCvMidiVoice.init();
333
    mbCvVoice.init();
334
    mbCvArp.init();
1408 tk 335
    mbCvSeqBassline.init();
336
 
1334 tk 337
    for(int lfo=0; lfo<mbCvLfo.size; ++lfo)
338
        mbCvLfo[lfo].init();
339
 
1394 tk 340
    for(int env=0; env<mbCvEnv1.size; ++env)
341
        mbCvEnv1[env].init();
1334 tk 342
 
343
    // enable interrupts again
344
    MIOS32_IRQ_Enable();
345
}
346
 
347
 
348
 
349
/////////////////////////////////////////////////////////////////////////////
350
// Play a note independent from channel
351
/////////////////////////////////////////////////////////////////////////////
352
void MbCv::noteOn(u8 note, u8 velocity, bool bypassNotestack)
353
{
354
    MbCvVoice *v = &mbCvVoice;
355
    MbCvMidiVoice *mv = (MbCvMidiVoice *)v->midiVoicePtr;
356
 
357
    // branch depending on normal/arp mode
358
    if( mbCvArp.arpEnabled ) {
359
        mbCvArp.noteOn(v, note, velocity);
360
    } else {
361
        // push note into stack
362
        if( !bypassNotestack )
363
            mv->notestackPush(note, velocity);
364
 
365
        // switch off gate if not in legato or sequencer mode
366
        if( !v->voiceLegato && !v->voiceSequencerOnly )
367
            v->gateOff(note);
368
 
369
        // call Note On Handler
370
        if( v->noteOn(note, velocity) )
371
            triggerNoteOn(v);
372
    }
373
}
374
 
375
 
376
/////////////////////////////////////////////////////////////////////////////
377
// Disable a note independent from channel
378
/////////////////////////////////////////////////////////////////////////////
379
void MbCv::noteOff(u8 note, bool bypassNotestack)
380
{
381
    MbCvVoice *v = &mbCvVoice;
382
    MbCvMidiVoice *mv = (MbCvMidiVoice *)v->midiVoicePtr;
383
 
384
    // TODO: if sustain active: mark note, but don't stop it (will work in normal and arp mode)
385
    // if not in arp mode: sustain only relevant if only one active note in stack
386
 
387
    // branch depending on normal/arp mode
388
    if( mbCvArp.arpEnabled ) {
389
        mbCvArp.noteOff(v, note);
390
    } else {
391
        if( bypassNotestack ) {
392
            v->noteOff(note, 0);
393
            triggerNoteOff(v);
394
        } else {
395
            u8 lastFirstNote = mv->midivoiceNotestack.note_items[0].note;
396
            // pop note from stack
397
            if( mv->notestackPop(note) > 0 ) {
398
                // call Note Off Handler
399
                if( v->noteOff(note, lastFirstNote) > 0 ) { // retrigger requested?
400
                    if( v->noteOn(mv->midivoiceNotestack.note_items[0].note, mv->midivoiceNotestack.note_items[0].tag) ) // new note
401
                        triggerNoteOn(v);
402
                } else {
403
                    triggerNoteOff(v);
404
                }
405
            }
406
        }
407
    }
408
}
409
 
410
 
411
/////////////////////////////////////////////////////////////////////////////
412
// All notes off - independent from channel
413
/////////////////////////////////////////////////////////////////////////////
414
void MbCv::noteAllOff(bool bypassNotestack)
415
{
416
    MbCvVoice *v = &mbCvVoice;
417
 
418
    v->voiceActive = 0;
419
    v->voiceGateClrReq = 1;
420
    v->voiceGateSetReq = 0;
421
    triggerNoteOff(v);
422
 
423
    if( !bypassNotestack ) {
424
        v->midiVoicePtr->notestackReset();
425
    }
426
}
427
 
428
 
429
/////////////////////////////////////////////////////////////////////////////
430
// Note On/Off Triggers
431
/////////////////////////////////////////////////////////////////////////////
432
void MbCv::triggerNoteOn(MbCvVoice *v)
433
{
434
    mbCvVoice.voiceNoteRestartReq = 1;
435
 
436
    MbCvLfo *l = mbCvLfo.first();
437
    for(int lfo=0; lfo < mbCvLfo.size; ++lfo, ++l)
1347 tk 438
        if( l->lfoModeKeySync )
1334 tk 439
            l->restartReq = 1;
440
 
1396 tk 441
    {
442
        MbCvEnv *e = mbCvEnv1.first();
443
        for(int env=0; env < mbCvEnv1.size; ++env, ++e)
444
            if( e->envModeKeySync )
445
                e->restartReq = 1;
446
    }
447
 
448
    {
449
        MbCvEnvMulti *e = mbCvEnv2.first();
450
        for(int env=0; env < mbCvEnv2.size; ++env, ++e)
451
            if( e->envModeKeySync )
452
                e->restartReq = 1;
453
    }
1334 tk 454
}
455
 
456
 
457
void MbCv::triggerNoteOff(MbCvVoice *v)
458
{
1396 tk 459
    {
460
        MbCvEnv *e = mbCvEnv1.first();
461
        for(int env=0; env < mbCvEnv1.size; ++env, ++e)
462
            if( e->envModeKeySync )
463
                e->releaseReq = 1;
464
    }
465
 
466
    {
467
        MbCvEnvMulti *e = mbCvEnv2.first();
468
        for(int env=0; env < mbCvEnv2.size; ++env, ++e)
469
            if( e->envModeKeySync )
470
                e->releaseReq = 1;
471
    }
1334 tk 472
}
1903 tk 473
 
474
 
475
 
476
/////////////////////////////////////////////////////////////////////////////
477
// NRPNs
478
/////////////////////////////////////////////////////////////////////////////
479
 
480
#define CREATE_GROUP(name, str) \
1904 tk 481
    static const char name##String[] = str;
1903 tk 482
 
483
#define CREATE_ACCESS_FUNCTIONS(group, name, str, readCode, writeCode) \
1904 tk 484
    static const char group##name##String[] = str; \
1903 tk 485
    static void get##group##name(MbCv* cv, u32 arg, u16 *value) { readCode; }    \
486
    static void set##group##name(MbCv* cv, u32 arg, u16 value) { writeCode; }
487
 
488
typedef struct {
1904 tk 489
    const char *groupString;
490
    const char *nameString;
1903 tk 491
    void (*getFunct)(MbCv *cv, u32 arg, u16 *value);
492
    void (*setFunct)(MbCv *cv, u32 arg, u16 value);
493
    u32 arg;
494
    u16 min;
495
    u16 max;
496
    u8 is_bidir;
497
} MbCvTableEntry_t;
498
 
499
#define NRPN_TABLE_ITEM(group, name, arg, min, max, is_bidir) \
500
    { group##String, group##name##String, get##group##name, set##group##name, arg, min, max, is_bidir }
501
 
502
#define NRPN_TABLE_ITEM_EMPTY() \
503
    { NULL, NULL, NULL, NULL, 0, 0, 0, 0 }
504
 
505
#define NRPN_TABLE_ITEM_EMPTY8() \
506
    NRPN_TABLE_ITEM_EMPTY(), NRPN_TABLE_ITEM_EMPTY(), NRPN_TABLE_ITEM_EMPTY(), NRPN_TABLE_ITEM_EMPTY(), \
507
    NRPN_TABLE_ITEM_EMPTY(), NRPN_TABLE_ITEM_EMPTY(), NRPN_TABLE_ITEM_EMPTY(), NRPN_TABLE_ITEM_EMPTY()
508
 
509
#define NRPN_TABLE_ITEM_EMPTY16() \
510
    NRPN_TABLE_ITEM_EMPTY8(), \
511
    NRPN_TABLE_ITEM_EMPTY8()
512
 
513
CREATE_GROUP(MidiVoice, "Voice");
514
CREATE_ACCESS_FUNCTIONS(MidiVoice, Port,               "MIDI Port %d",    *value = cv->mbCvMidiVoice.getPortEnabled(arg),          cv->mbCvMidiVoice.setPortEnabled(arg, value));
515
CREATE_ACCESS_FUNCTIONS(MidiVoice, Channel,            "MIDI Channel",    *value = cv->mbCvMidiVoice.midivoiceChannel,             cv->mbCvMidiVoice.midivoiceChannel = value);
516
CREATE_ACCESS_FUNCTIONS(MidiVoice, EventMode,          "Event Mode",      *value = (u16)cv->mbCvVoice.voiceEventMode,              cv->mbCvVoice.voiceEventMode = (mbcv_midi_event_mode_t)value);
517
CREATE_ACCESS_FUNCTIONS(MidiVoice, SplitLower,         "Split Lower",     *value = cv->mbCvMidiVoice.midivoiceSplitLower,          cv->mbCvMidiVoice.midivoiceSplitLower = value);
518
CREATE_ACCESS_FUNCTIONS(MidiVoice, SplitUpper,         "Split Upper",     *value = cv->mbCvMidiVoice.midivoiceSplitUpper,          cv->mbCvMidiVoice.midivoiceSplitUpper = value);
519
CREATE_ACCESS_FUNCTIONS(MidiVoice, CCNumber,           "CC Number",       *value = cv->mbCvMidiVoice.midivoiceCCNumber,            cv->mbCvMidiVoice.midivoiceCCNumber = value);
520
CREATE_ACCESS_FUNCTIONS(MidiVoice, AoutCurve,          "AOUT Curve",      *value = cv->mbCvVoice.getAoutCurve(),                   cv->mbCvVoice.setAoutCurve(value));
521
CREATE_ACCESS_FUNCTIONS(MidiVoice, AoutSlewRate,       "AOUT Slew Rate",  *value = cv->mbCvVoice.getAoutSlewRate(),                cv->mbCvVoice.setAoutSlewRate(value));
522
CREATE_ACCESS_FUNCTIONS(MidiVoice, GateInverted,       "Inv. Gate",       *value = cv->mbCvVoice.voiceGateInverted,                cv->mbCvVoice.voiceGateInverted = value);
523
CREATE_ACCESS_FUNCTIONS(MidiVoice, Legato,             "Legato",          *value = cv->mbCvVoice.voiceLegato,                      cv->mbCvVoice.voiceLegato = value);
524
CREATE_ACCESS_FUNCTIONS(MidiVoice, Poly,               "Poly",            *value = cv->mbCvVoice.voicePoly,                        cv->mbCvVoice.voicePoly = value);
525
CREATE_ACCESS_FUNCTIONS(MidiVoice, SusKey,             "SusKey",          *value = cv->mbCvVoice.voiceSusKey,                      cv->mbCvVoice.voiceSusKey = value);
526
CREATE_ACCESS_FUNCTIONS(MidiVoice, PortamentoMode,     "PortamentoMode",  *value = cv->mbCvVoice.getPortamentoMode(),              cv->mbCvVoice.setPortamentoMode(value));
1960 tk 527
CREATE_ACCESS_FUNCTIONS(MidiVoice, ForceToScale,       "ForceToScale",    *value = cv->mbCvVoice.voiceForceToScale,                cv->mbCvVoice.voiceForceToScale = value);
528
CREATE_ACCESS_FUNCTIONS(MidiVoice, ExtGateThrs,        "ExtGateThrs",     *value = cv->mbCvVoice.voiceExternalGateThreshold,    cv->mbCvVoice.voiceExternalGateThreshold = value);
1903 tk 529
CREATE_ACCESS_FUNCTIONS(MidiVoice, PitchRange,         "Pitch Range",     *value = cv->mbCvVoice.voicePitchrange,                  cv->mbCvVoice.voicePitchrange = value);
530
CREATE_ACCESS_FUNCTIONS(MidiVoice, Ketrack,            "Keytrack",        *value = (int)cv->mbCvVoice.voiceKeytrack + 0x80,        cv->mbCvVoice.voiceKeytrack = (int)value - 0x80);
531
CREATE_ACCESS_FUNCTIONS(MidiVoice, TransposeOctave,    "Transp. Octave",  *value = (int)cv->mbCvVoice.voiceTransposeOctave + 8,    cv->mbCvVoice.voiceTransposeOctave = (int)value - 8);
532
CREATE_ACCESS_FUNCTIONS(MidiVoice, TransposeSemitone,  "Transp. Semi.",   *value = (int)cv->mbCvVoice.voiceTransposeSemitone + 8,  cv->mbCvVoice.voiceTransposeSemitone = (int)value - 8);
533
CREATE_ACCESS_FUNCTIONS(MidiVoice, Finetune,           "Finetune",        *value = (int)cv->mbCvVoice.voiceFinetune + 0x80,        cv->mbCvVoice.voiceFinetune = (int)value - 0x80);
534
CREATE_ACCESS_FUNCTIONS(MidiVoice, PortamentoRate,     "PortamentoRate",  *value = cv->mbCvVoice.voicePortamentoRate,              cv->mbCvVoice.voicePortamentoRate = value);
535
 
536
CREATE_GROUP(Arp, "Arp");
537
CREATE_ACCESS_FUNCTIONS(Arp, Enabled,                  "Enable",          *value = cv->mbCvArp.arpEnabled,                         cv->mbCvArp.arpEnabled = value);
538
CREATE_ACCESS_FUNCTIONS(Arp, Dir,                      "Direction",       *value = cv->mbCvArp.arpDirGet(),                        cv->mbCvArp.arpDirSet(value));
539
CREATE_ACCESS_FUNCTIONS(Arp, HoldMode,                 "Hold",            *value = cv->mbCvArp.arpHoldMode,                        cv->mbCvArp.arpHoldMode = value);
540
CREATE_ACCESS_FUNCTIONS(Arp, SortedNotes,              "Sort",            *value = cv->mbCvArp.arpSortedNotes,                     cv->mbCvArp.arpSortedNotes = value);
541
CREATE_ACCESS_FUNCTIONS(Arp, SyncMode,                 "Sync",            *value = cv->mbCvArp.arpSyncMode,                        cv->mbCvArp.arpSyncMode = value);
542
CREATE_ACCESS_FUNCTIONS(Arp, OneshotMode,              "Oneshot",         *value = cv->mbCvArp.arpOneshotMode,                     cv->mbCvArp.arpOneshotMode = value);
543
CREATE_ACCESS_FUNCTIONS(Arp, ConstantCycle,            "Constant Cycle",  *value = cv->mbCvArp.arpConstantCycle,                   cv->mbCvArp.arpConstantCycle = value);
544
CREATE_ACCESS_FUNCTIONS(Arp, EasyChordMode,            "Easy Chord",      *value = cv->mbCvArp.arpEasyChordMode,                   cv->mbCvArp.arpEasyChordMode = value);
545
CREATE_ACCESS_FUNCTIONS(Arp, Speed,                    "Speed",           *value = cv->mbCvArp.arpSpeed,                           cv->mbCvArp.arpSpeed = value);
546
CREATE_ACCESS_FUNCTIONS(Arp, Gatelength,               "Gatelength",      *value = cv->mbCvArp.arpGatelength,                      cv->mbCvArp.arpGatelength = value);
547
 
548
CREATE_GROUP(Seq, "Seq");
549
CREATE_ACCESS_FUNCTIONS(Seq, Enabled,          "Enable",          *value = cv->mbCvSeqBassline.seqEnabled,                 cv->mbCvSeqBassline.seqEnabled = value);
550
CREATE_ACCESS_FUNCTIONS(Seq, PatternNumber,    "Pattern #",       *value = cv->mbCvSeqBassline.seqPatternNumber,           cv->mbCvSeqBassline.seqPatternNumber = value);
551
CREATE_ACCESS_FUNCTIONS(Seq, PatternLength,    "Length",          *value = cv->mbCvSeqBassline.seqPatternLength,           cv->mbCvSeqBassline.seqPatternLength = value);
552
CREATE_ACCESS_FUNCTIONS(Seq, Resolution,       "Resolution",      *value = cv->mbCvSeqBassline.seqResolution,              cv->mbCvSeqBassline.seqResolution = value);
553
CREATE_ACCESS_FUNCTIONS(Seq, GateLength,       "Gatelength",      *value = cv->mbCvSeqBassline.seqGateLength,              cv->mbCvSeqBassline.seqGateLength = value);
554
CREATE_ACCESS_FUNCTIONS(Seq, EnvMod,           "EnvMod",          *value = cv->mbCvSeqBassline.seqEnvMod,                  cv->mbCvSeqBassline.seqEnvMod = value);
555
CREATE_ACCESS_FUNCTIONS(Seq, Accent,           "Accent",          *value = cv->mbCvSeqBassline.seqAccent,                  cv->mbCvSeqBassline.seqAccent = value);
556
CREATE_ACCESS_FUNCTIONS(Seq, Key,              "Key #%2d",        *value = cv->mbCvSeqBassline.seqBasslineKey[cv->mbCvSeqBassline.seqPatternNumber][arg],      cv->mbCvSeqBassline.seqBasslineKey[cv->mbCvSeqBassline.seqPatternNumber][arg] = value);
1911 tk 557
CREATE_ACCESS_FUNCTIONS(Seq, Args,             "Args #%2d",       *value = cv->mbCvSeqBassline.seqBasslineArgs[cv->mbCvSeqBassline.seqPatternNumber][arg].ALL, cv->mbCvSeqBassline.seqBasslineArgs[cv->mbCvSeqBassline.seqPatternNumber][arg].ALL = value);
1903 tk 558
 
559
CREATE_GROUP(Lfo, "LFO%d");
560
CREATE_ACCESS_FUNCTIONS(Lfo, Amplitude,                "Amplitude",       *value = (int)cv->mbCvLfo[arg].lfoAmplitude + 0x80,         cv->mbCvLfo[arg].lfoAmplitude = (int)value - 0x80);
561
CREATE_ACCESS_FUNCTIONS(Lfo, Rate,                     "Rate",            *value = (int)cv->mbCvLfo[arg].lfoRate,                     cv->mbCvLfo[arg].lfoRate = value);
562
CREATE_ACCESS_FUNCTIONS(Lfo, Delay,                    "Delay",           *value = (int)cv->mbCvLfo[arg].lfoDelay,                    cv->mbCvLfo[arg].lfoDelay = value);
563
CREATE_ACCESS_FUNCTIONS(Lfo, Phase,                    "Phase",           *value = (int)cv->mbCvLfo[arg].lfoPhase,                    cv->mbCvLfo[arg].lfoPhase = value);
564
CREATE_ACCESS_FUNCTIONS(Lfo, Waveform,                 "Waveform",        *value = (int)cv->mbCvLfo[arg].lfoWaveform,                 cv->mbCvLfo[arg].lfoWaveform = value);
565
CREATE_ACCESS_FUNCTIONS(Lfo, ModeClkSync,              "ClkSync",         *value = (int)cv->mbCvLfo[arg].lfoModeClkSync,              cv->mbCvLfo[arg].lfoModeClkSync = value);
566
CREATE_ACCESS_FUNCTIONS(Lfo, ModeKeySync,              "KeySync",         *value = (int)cv->mbCvLfo[arg].lfoModeKeySync,              cv->mbCvLfo[arg].lfoModeKeySync = value);
567
CREATE_ACCESS_FUNCTIONS(Lfo, ModeOneshot,              "Oneshot",         *value = (int)cv->mbCvLfo[arg].lfoModeOneshot,              cv->mbCvLfo[arg].lfoModeOneshot = value);
568
CREATE_ACCESS_FUNCTIONS(Lfo, ModeFast,                 "Fast",            *value = (int)cv->mbCvLfo[arg].lfoModeFast,                 cv->mbCvLfo[arg].lfoModeFast = value);
569
CREATE_ACCESS_FUNCTIONS(Lfo, DepthPitch,               "Depth CV",        *value = (int)cv->mbCvLfo[arg].lfoDepthPitch + 0x80,        cv->mbCvLfo[arg].lfoDepthPitch = (int)value - 0x80);
570
CREATE_ACCESS_FUNCTIONS(Lfo, DepthLfoAmplitude,        "Depth LFO Amp.",  *value = (int)cv->mbCvLfo[arg].lfoDepthLfoAmplitude + 0x80, cv->mbCvLfo[arg].lfoDepthLfoAmplitude = (int)value - 0x80);
571
CREATE_ACCESS_FUNCTIONS(Lfo, DepthLfoRate,             "Depth LFO Rate",  *value = (int)cv->mbCvLfo[arg].lfoDepthLfoRate + 0x80,      cv->mbCvLfo[arg].lfoDepthLfoRate = (int)value - 0x80);
572
CREATE_ACCESS_FUNCTIONS(Lfo, DepthEnv1Rate,            "Depth ENV1 Rate", *value = (int)cv->mbCvLfo[arg].lfoDepthEnv1Rate + 0x80,     cv->mbCvLfo[arg].lfoDepthEnv1Rate = (int)value - 0x80);
573
CREATE_ACCESS_FUNCTIONS(Lfo, DepthEnv2Rate,            "Depth ENV2 Rate", *value = (int)cv->mbCvLfo[arg].lfoDepthEnv2Rate + 0x80,     cv->mbCvLfo[arg].lfoDepthEnv2Rate = (int)value - 0x80);
574
 
575
CREATE_GROUP(Env1, "ENV1");
576
CREATE_ACCESS_FUNCTIONS(Env1, Amplitude,               "Amplitude",       *value = (int)cv->mbCvEnv1[arg].envAmplitude + 0x80,          cv->mbCvEnv1[arg].envAmplitude = (int)value - 0x80);
1960 tk 577
CREATE_ACCESS_FUNCTIONS(Env1, CurvePos,                "CurvePos",        *value = (int)cv->mbCvEnv1[arg].envCurvePos,                  cv->mbCvEnv1[arg].envCurvePos = (int)value);
578
CREATE_ACCESS_FUNCTIONS(Env1, CurveNeg,                "CurveNeg",        *value = (int)cv->mbCvEnv1[arg].envCurveNeg,                  cv->mbCvEnv1[arg].envCurveNeg = (int)value);
1903 tk 579
CREATE_ACCESS_FUNCTIONS(Env1, Delay,                   "Delay",           *value = (int)cv->mbCvEnv1[arg].envDelay,                     cv->mbCvEnv1[arg].envDelay = (int)value);
580
CREATE_ACCESS_FUNCTIONS(Env1, Attack,                  "Attack",          *value = (int)cv->mbCvEnv1[arg].envAttack,                    cv->mbCvEnv1[arg].envAttack = (int)value);
581
CREATE_ACCESS_FUNCTIONS(Env1, Decay,                   "Decay",           *value = (int)cv->mbCvEnv1[arg].envDecay,                     cv->mbCvEnv1[arg].envDecay = (int)value);
582
CREATE_ACCESS_FUNCTIONS(Env1, Sustain,                 "Sustain",         *value = (int)cv->mbCvEnv1[arg].envSustain,                   cv->mbCvEnv1[arg].envSustain = (int)value);
583
CREATE_ACCESS_FUNCTIONS(Env1, Release,                 "Release",         *value = (int)cv->mbCvEnv1[arg].envRelease,                   cv->mbCvEnv1[arg].envRelease = (int)value);
584
CREATE_ACCESS_FUNCTIONS(Env1, ModeClkSync,             "ClkSync",         *value = (int)cv->mbCvEnv1[arg].envModeClkSync,               cv->mbCvEnv1[arg].envModeClkSync = (int)value);
585
CREATE_ACCESS_FUNCTIONS(Env1, ModeKeySync,             "KeySync",         *value = (int)cv->mbCvEnv1[arg].envModeKeySync,               cv->mbCvEnv1[arg].envModeKeySync = (int)value);
586
CREATE_ACCESS_FUNCTIONS(Env1, ModeOneshot,             "Oneshot",         *value = (int)cv->mbCvEnv1[arg].envModeOneshot,               cv->mbCvEnv1[arg].envModeOneshot = (int)value);
587
CREATE_ACCESS_FUNCTIONS(Env1, ModeFast,                "Fast",            *value = (int)cv->mbCvEnv1[arg].envModeFast,                  cv->mbCvEnv1[arg].envModeFast = (int)value);
588
CREATE_ACCESS_FUNCTIONS(Env1, DepthPitch,              "Depth CV",        *value = (int)cv->mbCvEnv1[arg].envDepthPitch + 0x80,         cv->mbCvEnv1[arg].envDepthPitch = (int)value - 0x80);
589
CREATE_ACCESS_FUNCTIONS(Env1, DepthLfo1Amplitude,      "Depth LFO1 Amp.", *value = (int)cv->mbCvEnv1[arg].envDepthLfo1Amplitude + 0x80, cv->mbCvEnv1[arg].envDepthLfo1Amplitude = (int)value - 0x80);
590
CREATE_ACCESS_FUNCTIONS(Env1, DepthLfo1Rate,           "Depth LFO1 Rate", *value = (int)cv->mbCvEnv1[arg].envDepthLfo1Rate + 0x80,      cv->mbCvEnv1[arg].envDepthLfo1Rate = (int)value - 0x80);
591
CREATE_ACCESS_FUNCTIONS(Env1, DepthLfo2Amplitude,      "Depth LFO2 Amp.", *value = (int)cv->mbCvEnv1[arg].envDepthLfo2Amplitude + 0x80, cv->mbCvEnv1[arg].envDepthLfo2Amplitude = (int)value - 0x80);
592
CREATE_ACCESS_FUNCTIONS(Env1, DepthLfo2Rate,           "Depth LFO2 Rate", *value = (int)cv->mbCvEnv1[arg].envDepthLfo2Rate + 0x80,      cv->mbCvEnv1[arg].envDepthLfo2Rate = (int)value - 0x80);
593
 
594
CREATE_GROUP(Env2, "ENV2");
595
CREATE_ACCESS_FUNCTIONS(Env2, Amplitude,               "Amplitude",       *value = (int)cv->mbCvEnv2[arg].envAmplitude + 0x80,          cv->mbCvEnv2[arg].envAmplitude = (int)value - 0x80);
1960 tk 596
CREATE_ACCESS_FUNCTIONS(Env2, CurvePos,                "CurvePos",        *value = (int)cv->mbCvEnv2[arg].envCurvePos,                  cv->mbCvEnv2[arg].envCurvePos = (int)value);
597
CREATE_ACCESS_FUNCTIONS(Env2, CurveNeg,                "CurveNeg",        *value = (int)cv->mbCvEnv2[arg].envCurveNeg,                  cv->mbCvEnv2[arg].envCurveNeg = (int)value);
1903 tk 598
CREATE_ACCESS_FUNCTIONS(Env2, Offset,                  "Offset",          *value = (int)cv->mbCvEnv2[arg].envOffset,                    cv->mbCvEnv2[arg].envOffset = (int)value);
599
CREATE_ACCESS_FUNCTIONS(Env2, Rate,                    "Rate",            *value = (int)cv->mbCvEnv2[arg].envRate,                      cv->mbCvEnv2[arg].envRate = (int)value);
600
CREATE_ACCESS_FUNCTIONS(Env2, LoopAttack,              "Loop Attack",     *value = (int)cv->mbCvEnv2[arg].envLoopAttack,                cv->mbCvEnv2[arg].envLoopAttack = (int)value);
601
CREATE_ACCESS_FUNCTIONS(Env2, SustainStep,             "Sustain Step",    *value = (int)cv->mbCvEnv2[arg].envSustainStep,               cv->mbCvEnv2[arg].envSustainStep = (int)value);
602
CREATE_ACCESS_FUNCTIONS(Env2, LoopRelease,             "Loop Release",    *value = (int)cv->mbCvEnv2[arg].envLoopRelease,               cv->mbCvEnv2[arg].envLoopRelease = (int)value);
603
CREATE_ACCESS_FUNCTIONS(Env2, LastStep,                "Last Step",       *value = (int)cv->mbCvEnv2[arg].envLastStep,                  cv->mbCvEnv2[arg].envLastStep = (int)value);
604
CREATE_ACCESS_FUNCTIONS(Env2, ModeClkSync,             "ClkSync",         *value = (int)cv->mbCvEnv2[arg].envModeClkSync,               cv->mbCvEnv2[arg].envModeClkSync = (int)value);
605
CREATE_ACCESS_FUNCTIONS(Env2, ModeKeySync,             "KeySync",         *value = (int)cv->mbCvEnv2[arg].envModeKeySync,               cv->mbCvEnv2[arg].envModeKeySync = (int)value);
606
CREATE_ACCESS_FUNCTIONS(Env2, ModeOneshot,             "Oneshot",         *value = (int)cv->mbCvEnv2[arg].envModeOneshot,               cv->mbCvEnv2[arg].envModeOneshot = (int)value);
607
CREATE_ACCESS_FUNCTIONS(Env2, ModeFast,                "Fast",            *value = (int)cv->mbCvEnv2[arg].envModeFast,                  cv->mbCvEnv2[arg].envModeFast = (int)value);
608
CREATE_ACCESS_FUNCTIONS(Env2, DepthPitch,              "Depth CV",        *value = (int)cv->mbCvEnv2[arg].envDepthPitch + 0x80,         cv->mbCvEnv2[arg].envDepthPitch = (int)value - 0x80);
609
CREATE_ACCESS_FUNCTIONS(Env2, DepthLfo1Amplitude,      "Depth LFO1 Amp.", *value = (int)cv->mbCvEnv2[arg].envDepthLfo1Amplitude + 0x80, cv->mbCvEnv2[arg].envDepthLfo1Amplitude = (int)value - 0x80);
610
CREATE_ACCESS_FUNCTIONS(Env2, DepthLfo1Rate,           "Depth LFO1 Rate", *value = (int)cv->mbCvEnv2[arg].envDepthLfo1Rate + 0x80,      cv->mbCvEnv2[arg].envDepthLfo1Rate = (int)value - 0x80);
611
CREATE_ACCESS_FUNCTIONS(Env2, DepthLfo2Amplitude,      "Depth LFO2 Amp.", *value = (int)cv->mbCvEnv2[arg].envDepthLfo2Amplitude + 0x80, cv->mbCvEnv2[arg].envDepthLfo2Amplitude = (int)value - 0x80);
612
CREATE_ACCESS_FUNCTIONS(Env2, DepthLfo2Rate,           "Depth LFO2 Rate", *value = (int)cv->mbCvEnv2[arg].envDepthLfo2Rate + 0x80,      cv->mbCvEnv2[arg].envDepthLfo2Rate = (int)value - 0x80);
613
CREATE_ACCESS_FUNCTIONS(Env2, Level,                   "Level Step #%2d", *value = cv->mbCvEnv2[0].envLevel[arg],                       cv->mbCvEnv2[0].envLevel[arg] = value); // TODO: take ENV index into MSBs of arg?
614
 
615
CREATE_GROUP(Mod, "Mod%d");
616
CREATE_ACCESS_FUNCTIONS(Mod, Depth,                    "Depth",           *value = cv->mbCvMod.modPatch[arg].depth + 0x80,              cv->mbCvMod.modPatch[arg].depth = (int)value - 0x80);
1960 tk 617
CREATE_ACCESS_FUNCTIONS(Mod, Offset,                   "Offset",          *value = cv->mbCvMod.modPatch[arg].offset + 0x80,             cv->mbCvMod.modPatch[arg].offset = (int)value - 0x80);
1903 tk 618
CREATE_ACCESS_FUNCTIONS(Mod, Src1,                     "Source1",         *value = cv->mbCvMod.modPatch[arg].src1,                      cv->mbCvMod.modPatch[arg].src1 = value);
619
CREATE_ACCESS_FUNCTIONS(Mod, Src1Chn,                  "Source1 CV",      *value = cv->mbCvMod.modPatch[arg].src1_chn,                  cv->mbCvMod.modPatch[arg].src1_chn = value);
620
CREATE_ACCESS_FUNCTIONS(Mod, Src2,                     "Source2",         *value = cv->mbCvMod.modPatch[arg].src2,                      cv->mbCvMod.modPatch[arg].src2 = value);
621
CREATE_ACCESS_FUNCTIONS(Mod, Src2Chn,                  "Source2 CV",      *value = cv->mbCvMod.modPatch[arg].src2_chn,                  cv->mbCvMod.modPatch[arg].src2_chn = value);
622
CREATE_ACCESS_FUNCTIONS(Mod, Op,                       "Operator",        *value = cv->mbCvMod.modPatch[arg].op & 0x3f,                 cv->mbCvMod.modPatch[arg].op &= 0xc0; cv->mbCvMod.modPatch[arg].op |= (value & 0x3f));
623
CREATE_ACCESS_FUNCTIONS(Mod, Dst1,                     "Destination1",    *value = cv->mbCvMod.modPatch[arg].dst1,                      cv->mbCvMod.modPatch[arg].dst1 = value);
624
CREATE_ACCESS_FUNCTIONS(Mod, Dst1Inv,                  "Dst1 Inverted",   *value = (cv->mbCvMod.modPatch[arg].op & (1 << 6)) ? 1 : 0,   cv->mbCvMod.modPatch[arg].op &= ~(1 << 6); cv->mbCvMod.modPatch[arg].op |= ((value&1) << 6));
625
CREATE_ACCESS_FUNCTIONS(Mod, Dst2,                     "Destination2",    *value = cv->mbCvMod.modPatch[arg].dst2,                      cv->mbCvMod.modPatch[arg].dst2 = value);
626
CREATE_ACCESS_FUNCTIONS(Mod, Dst2Inv,                  "Dst2 Inverted",   *value = (cv->mbCvMod.modPatch[arg].op & (1 << 7)) ? 1 : 0,   cv->mbCvMod.modPatch[arg].op &= ~(1 << 7); cv->mbCvMod.modPatch[arg].op |= ((value&1) << 7));
627
 
628
 
629
#define MBCV_NRPN_TABLE_SIZE 0x380
630
static const MbCvTableEntry_t mbCvNrpnTable[MBCV_NRPN_TABLE_SIZE] = {
631
    // 0x000
632
    NRPN_TABLE_ITEM(  MidiVoice, Port,               0, 0, 1, 0),
633
    NRPN_TABLE_ITEM(  MidiVoice, Port,               1, 0, 1, 0),
634
    NRPN_TABLE_ITEM(  MidiVoice, Port,               2, 0, 1, 0),
635
    NRPN_TABLE_ITEM(  MidiVoice, Port,               3, 0, 1, 0),
636
    NRPN_TABLE_ITEM(  MidiVoice, Port,               4, 0, 1, 0),
637
    NRPN_TABLE_ITEM(  MidiVoice, Port,               5, 0, 1, 0),
638
    NRPN_TABLE_ITEM(  MidiVoice, Port,               6, 0, 1, 0),
639
    NRPN_TABLE_ITEM(  MidiVoice, Port,               7, 0, 1, 0),
640
    NRPN_TABLE_ITEM(  MidiVoice, Port,               8, 0, 1, 0),
641
    NRPN_TABLE_ITEM(  MidiVoice, Port,               9, 0, 1, 0),
642
    NRPN_TABLE_ITEM(  MidiVoice, Port,              10, 0, 1, 0),
643
    NRPN_TABLE_ITEM(  MidiVoice, Port,              11, 0, 1, 0),
644
    NRPN_TABLE_ITEM(  MidiVoice, Port,              12, 0, 1, 0),
645
    NRPN_TABLE_ITEM(  MidiVoice, Port,              13, 0, 1, 0),
646
    NRPN_TABLE_ITEM(  MidiVoice, Port,              14, 0, 1, 0),
647
    NRPN_TABLE_ITEM(  MidiVoice, Port,              15, 0, 1, 0),
648
 
649
    // 0x010
650
    NRPN_TABLE_ITEM(  MidiVoice, Channel,            0, 0, 16, 0),
651
    NRPN_TABLE_ITEM(  MidiVoice, EventMode,          0, 0, MBCV_MIDI_EVENT_MODE_NUM-1, 0),
652
    NRPN_TABLE_ITEM(  MidiVoice, SplitLower,         0, 0, 127, 0),
653
    NRPN_TABLE_ITEM(  MidiVoice, SplitUpper,         0, 0, 127, 0),
654
    NRPN_TABLE_ITEM(  MidiVoice, CCNumber,           0, 0, 127, 0),
655
    NRPN_TABLE_ITEM_EMPTY(),
656
    NRPN_TABLE_ITEM_EMPTY(),
657
    NRPN_TABLE_ITEM_EMPTY(),
658
 
659
    // 0x018
660
    NRPN_TABLE_ITEM(  MidiVoice, AoutCurve,          0, 0, MBCV_MAP_NUM_CURVES-1, 0),
661
    NRPN_TABLE_ITEM(  MidiVoice, AoutSlewRate,       0, 0, 255, 0),
662
    NRPN_TABLE_ITEM(  MidiVoice, GateInverted,       0, 0, 1, 0),
663
    NRPN_TABLE_ITEM_EMPTY(),
664
    NRPN_TABLE_ITEM_EMPTY(),
665
    NRPN_TABLE_ITEM_EMPTY(),
666
    NRPN_TABLE_ITEM_EMPTY(),
667
    NRPN_TABLE_ITEM_EMPTY(),
668
 
669
    // 0x20
670
    NRPN_TABLE_ITEM(  MidiVoice, Legato,             0, 0, 1, 0),
671
    NRPN_TABLE_ITEM(  MidiVoice, Poly,               0, 0, 1, 0),
672
    NRPN_TABLE_ITEM(  MidiVoice, SusKey,             0, 0, 1, 0),
673
    NRPN_TABLE_ITEM(  MidiVoice, PortamentoMode,     0, 0, 2, 0),
1960 tk 674
    NRPN_TABLE_ITEM(  MidiVoice, ForceToScale,       0, 0, 1, 0),
675
    NRPN_TABLE_ITEM(  MidiVoice, ExtGateThrs,        0, 0, 255, 0),
1903 tk 676
    NRPN_TABLE_ITEM_EMPTY(),
677
    NRPN_TABLE_ITEM_EMPTY(),
678
    NRPN_TABLE_ITEM_EMPTY8(),
679
 
680
    // 0x030
681
    NRPN_TABLE_ITEM(  MidiVoice, PitchRange,         0, 0, 24, 0),
682
    NRPN_TABLE_ITEM(  MidiVoice, Ketrack,            0, 0, 255, 1),
683
    NRPN_TABLE_ITEM(  MidiVoice, TransposeOctave,    0, 0, 15, 1),
684
    NRPN_TABLE_ITEM(  MidiVoice, TransposeSemitone,  0, 0, 15, 1),
685
    NRPN_TABLE_ITEM(  MidiVoice, Finetune,           0, 0, 255, 1),
686
    NRPN_TABLE_ITEM(  MidiVoice, PortamentoRate,     0, 0, 255, 0),
687
    NRPN_TABLE_ITEM_EMPTY(),
688
    NRPN_TABLE_ITEM_EMPTY(),
689
    NRPN_TABLE_ITEM_EMPTY8(),
690
 
691
    // 0x040
1917 tk 692
    NRPN_TABLE_ITEM_EMPTY16(),
1903 tk 693
    // 0x050
694
    NRPN_TABLE_ITEM_EMPTY16(),
695
    // 0x060
696
    NRPN_TABLE_ITEM_EMPTY16(),
697
    // 0x070
698
    NRPN_TABLE_ITEM_EMPTY16(),
699
 
700
    // 0x080
701
    NRPN_TABLE_ITEM(  Arp, Enabled,                  0, 0, 1, 0),
702
    NRPN_TABLE_ITEM(  Arp, Dir,                      0, 0, 6, 0),
703
    NRPN_TABLE_ITEM(  Arp, HoldMode,                 0, 0, 1, 0),
704
    NRPN_TABLE_ITEM(  Arp, SortedNotes,              0, 0, 1, 0),
705
    NRPN_TABLE_ITEM(  Arp, SyncMode,                 0, 0, 1, 0),
706
    NRPN_TABLE_ITEM(  Arp, OneshotMode,              0, 0, 1, 0),
707
    NRPN_TABLE_ITEM(  Arp, ConstantCycle,            0, 0, 1, 0),
708
    NRPN_TABLE_ITEM(  Arp, EasyChordMode,            0, 0, 1, 0),
709
    NRPN_TABLE_ITEM_EMPTY(),
710
    NRPN_TABLE_ITEM_EMPTY(),
711
    NRPN_TABLE_ITEM_EMPTY(),
712
    NRPN_TABLE_ITEM_EMPTY(),
713
    NRPN_TABLE_ITEM_EMPTY(),
714
    NRPN_TABLE_ITEM_EMPTY(),
715
    NRPN_TABLE_ITEM_EMPTY(),
716
    NRPN_TABLE_ITEM_EMPTY(),
717
 
718
    // 0x090
719
    NRPN_TABLE_ITEM(  Arp, Speed,                    0, 0, 63, 0),
720
    NRPN_TABLE_ITEM(  Arp, Gatelength,               0, 0, 63, 0),
721
    NRPN_TABLE_ITEM_EMPTY(),
722
    NRPN_TABLE_ITEM_EMPTY(),
723
    NRPN_TABLE_ITEM_EMPTY(),
724
    NRPN_TABLE_ITEM_EMPTY(),
725
    NRPN_TABLE_ITEM_EMPTY(),
726
    NRPN_TABLE_ITEM_EMPTY(),
727
    NRPN_TABLE_ITEM_EMPTY8(),
728
 
729
    // 0x0a0
730
    NRPN_TABLE_ITEM(  Seq, Enabled,          0, 0, 1, 0),
731
    NRPN_TABLE_ITEM(  Seq, PatternNumber,    0, 0, 7, 0),
732
    NRPN_TABLE_ITEM(  Seq, PatternLength,    0, 0, 31, 0),
733
    NRPN_TABLE_ITEM(  Seq, Resolution,       0, 0, 255, 0),
734
    NRPN_TABLE_ITEM(  Seq, GateLength,       0, 0, 100, 0),
735
    NRPN_TABLE_ITEM_EMPTY(),
736
    NRPN_TABLE_ITEM_EMPTY(),
737
    NRPN_TABLE_ITEM_EMPTY(),
738
 
739
    // 0x0a8
740
    NRPN_TABLE_ITEM(  Seq, EnvMod,           0, 0, 255, 0),
741
    NRPN_TABLE_ITEM(  Seq, Accent,           0, 0, 255, 0),
742
    NRPN_TABLE_ITEM_EMPTY(),
743
    NRPN_TABLE_ITEM_EMPTY(),
744
    NRPN_TABLE_ITEM_EMPTY(),
745
    NRPN_TABLE_ITEM_EMPTY(),
746
    NRPN_TABLE_ITEM_EMPTY(),
747
    NRPN_TABLE_ITEM_EMPTY(),
748
 
749
    // 0x0b0
750
    NRPN_TABLE_ITEM_EMPTY16(),
751
 
752
    // 0x0c0
753
    NRPN_TABLE_ITEM(  Seq, Key,              0, 0, 127, 0),
754
    NRPN_TABLE_ITEM(  Seq, Key,              1, 0, 127, 0),
755
    NRPN_TABLE_ITEM(  Seq, Key,              2, 0, 127, 0),
756
    NRPN_TABLE_ITEM(  Seq, Key,              3, 0, 127, 0),
757
    NRPN_TABLE_ITEM(  Seq, Key,              4, 0, 127, 0),
758
    NRPN_TABLE_ITEM(  Seq, Key,              5, 0, 127, 0),
759
    NRPN_TABLE_ITEM(  Seq, Key,              6, 0, 127, 0),
760
    NRPN_TABLE_ITEM(  Seq, Key,              7, 0, 127, 0),
761
    NRPN_TABLE_ITEM(  Seq, Key,              8, 0, 127, 0),
762
    NRPN_TABLE_ITEM(  Seq, Key,              9, 0, 127, 0),
763
    NRPN_TABLE_ITEM(  Seq, Key,             10, 0, 127, 0),
764
    NRPN_TABLE_ITEM(  Seq, Key,             11, 0, 127, 0),
765
    NRPN_TABLE_ITEM(  Seq, Key,             12, 0, 127, 0),
766
    NRPN_TABLE_ITEM(  Seq, Key,             13, 0, 127, 0),
767
    NRPN_TABLE_ITEM(  Seq, Key,             14, 0, 127, 0),
768
    NRPN_TABLE_ITEM(  Seq, Key,             15, 0, 127, 0),
769
    NRPN_TABLE_ITEM(  Seq, Key,             16, 0, 127, 0),
770
    NRPN_TABLE_ITEM(  Seq, Key,             17, 0, 127, 0),
771
    NRPN_TABLE_ITEM(  Seq, Key,             18, 0, 127, 0),
772
    NRPN_TABLE_ITEM(  Seq, Key,             19, 0, 127, 0),
773
    NRPN_TABLE_ITEM(  Seq, Key,             20, 0, 127, 0),
774
    NRPN_TABLE_ITEM(  Seq, Key,             21, 0, 127, 0),
775
    NRPN_TABLE_ITEM(  Seq, Key,             22, 0, 127, 0),
776
    NRPN_TABLE_ITEM(  Seq, Key,             23, 0, 127, 0),
777
    NRPN_TABLE_ITEM(  Seq, Key,             24, 0, 127, 0),
778
    NRPN_TABLE_ITEM(  Seq, Key,             25, 0, 127, 0),
779
    NRPN_TABLE_ITEM(  Seq, Key,             26, 0, 127, 0),
780
    NRPN_TABLE_ITEM(  Seq, Key,             27, 0, 127, 0),
781
    NRPN_TABLE_ITEM(  Seq, Key,             28, 0, 127, 0),
782
    NRPN_TABLE_ITEM(  Seq, Key,             29, 0, 127, 0),
783
    NRPN_TABLE_ITEM(  Seq, Key,             30, 0, 127, 0),
784
    NRPN_TABLE_ITEM(  Seq, Key,             31, 0, 127, 0),
785
 
786
    // 0x0e0
787
    NRPN_TABLE_ITEM(  Seq, Args,             0, 0, 7, 0),
788
    NRPN_TABLE_ITEM(  Seq, Args,             1, 0, 7, 0),
789
    NRPN_TABLE_ITEM(  Seq, Args,             2, 0, 7, 0),
790
    NRPN_TABLE_ITEM(  Seq, Args,             3, 0, 7, 0),
791
    NRPN_TABLE_ITEM(  Seq, Args,             4, 0, 7, 0),
792
    NRPN_TABLE_ITEM(  Seq, Args,             5, 0, 7, 0),
793
    NRPN_TABLE_ITEM(  Seq, Args,             6, 0, 7, 0),
794
    NRPN_TABLE_ITEM(  Seq, Args,             7, 0, 7, 0),
795
    NRPN_TABLE_ITEM(  Seq, Args,             8, 0, 7, 0),
796
    NRPN_TABLE_ITEM(  Seq, Args,             9, 0, 7, 0),
797
    NRPN_TABLE_ITEM(  Seq, Args,            10, 0, 7, 0),
798
    NRPN_TABLE_ITEM(  Seq, Args,            11, 0, 7, 0),
799
    NRPN_TABLE_ITEM(  Seq, Args,            12, 0, 7, 0),
800
    NRPN_TABLE_ITEM(  Seq, Args,            13, 0, 7, 0),
801
    NRPN_TABLE_ITEM(  Seq, Args,            14, 0, 7, 0),
802
    NRPN_TABLE_ITEM(  Seq, Args,            15, 0, 7, 0),
803
    NRPN_TABLE_ITEM(  Seq, Args,            16, 0, 7, 0),
804
    NRPN_TABLE_ITEM(  Seq, Args,            17, 0, 7, 0),
805
    NRPN_TABLE_ITEM(  Seq, Args,            18, 0, 7, 0),
806
    NRPN_TABLE_ITEM(  Seq, Args,            19, 0, 7, 0),
807
    NRPN_TABLE_ITEM(  Seq, Args,            20, 0, 7, 0),
808
    NRPN_TABLE_ITEM(  Seq, Args,            21, 0, 7, 0),
809
    NRPN_TABLE_ITEM(  Seq, Args,            22, 0, 7, 0),
810
    NRPN_TABLE_ITEM(  Seq, Args,            23, 0, 7, 0),
811
    NRPN_TABLE_ITEM(  Seq, Args,            24, 0, 7, 0),
812
    NRPN_TABLE_ITEM(  Seq, Args,            25, 0, 7, 0),
813
    NRPN_TABLE_ITEM(  Seq, Args,            26, 0, 7, 0),
814
    NRPN_TABLE_ITEM(  Seq, Args,            27, 0, 7, 0),
815
    NRPN_TABLE_ITEM(  Seq, Args,            28, 0, 7, 0),
816
    NRPN_TABLE_ITEM(  Seq, Args,            29, 0, 7, 0),
817
    NRPN_TABLE_ITEM(  Seq, Args,            30, 0, 7, 0),
818
    NRPN_TABLE_ITEM(  Seq, Args,            31, 0, 7, 0),
819
 
820
    // 0x100
821
    NRPN_TABLE_ITEM(  Lfo, Amplitude,                0, 0, 255, 1),
822
    NRPN_TABLE_ITEM(  Lfo, Rate,                     0, 0, 255, 0),
823
    NRPN_TABLE_ITEM(  Lfo, Delay,                    0, 0, 255, 0),
824
    NRPN_TABLE_ITEM(  Lfo, Phase,                    0, 0, 255, 0),
825
    NRPN_TABLE_ITEM(  Lfo, Waveform,                 0, 0, 8, 0), // TODO: create enum for waveform
826
    NRPN_TABLE_ITEM_EMPTY(),
827
    NRPN_TABLE_ITEM_EMPTY(),
828
    NRPN_TABLE_ITEM_EMPTY(),
829
    NRPN_TABLE_ITEM_EMPTY8(),
830
 
831
    // 0x110
832
    NRPN_TABLE_ITEM(  Lfo, ModeClkSync,              0, 0, 1, 0),
833
    NRPN_TABLE_ITEM(  Lfo, ModeKeySync,              0, 0, 1, 0),
834
    NRPN_TABLE_ITEM(  Lfo, ModeOneshot,              0, 0, 1, 0),
835
    NRPN_TABLE_ITEM(  Lfo, ModeFast,                 0, 0, 1, 0),
836
    NRPN_TABLE_ITEM_EMPTY(),
837
    NRPN_TABLE_ITEM_EMPTY(),
838
    NRPN_TABLE_ITEM_EMPTY(),
839
    NRPN_TABLE_ITEM_EMPTY(),
840
    NRPN_TABLE_ITEM_EMPTY8(),
841
 
842
    // 0x120
843
    NRPN_TABLE_ITEM(  Lfo, DepthPitch,               0, 0, 255, 1),
844
    NRPN_TABLE_ITEM(  Lfo, DepthLfoAmplitude,        0, 0, 255, 1),
845
    NRPN_TABLE_ITEM(  Lfo, DepthLfoRate,             0, 0, 255, 1),
846
    NRPN_TABLE_ITEM(  Lfo, DepthEnv1Rate,            0, 0, 255, 1),
847
    NRPN_TABLE_ITEM(  Lfo, DepthEnv2Rate,            0, 0, 255, 1),
848
    NRPN_TABLE_ITEM_EMPTY(),
849
    NRPN_TABLE_ITEM_EMPTY(),
850
    NRPN_TABLE_ITEM_EMPTY(),
851
    NRPN_TABLE_ITEM_EMPTY8(),
852
 
853
    // 0x130
854
    NRPN_TABLE_ITEM_EMPTY16(),
855
    // 0x140
856
    NRPN_TABLE_ITEM_EMPTY16(),
857
    // 0x150
858
    NRPN_TABLE_ITEM_EMPTY16(),
859
    // 0x160
860
    NRPN_TABLE_ITEM_EMPTY16(),
861
    // 0x170
862
    NRPN_TABLE_ITEM_EMPTY16(),
863
 
864
    // 0x180
865
    NRPN_TABLE_ITEM(  Lfo, Amplitude,                1, 0, 255, 1),
866
    NRPN_TABLE_ITEM(  Lfo, Rate,                     1, 0, 255, 0),
867
    NRPN_TABLE_ITEM(  Lfo, Delay,                    1, 0, 255, 0),
868
    NRPN_TABLE_ITEM(  Lfo, Phase,                    1, 0, 255, 0),
869
    NRPN_TABLE_ITEM(  Lfo, Waveform,                 1, 0, 8, 0), // TODO: create enum for waveform
870
    NRPN_TABLE_ITEM_EMPTY(),
871
    NRPN_TABLE_ITEM_EMPTY(),
872
    NRPN_TABLE_ITEM_EMPTY(),
873
    NRPN_TABLE_ITEM_EMPTY8(),
874
 
875
    // 0x190
876
    NRPN_TABLE_ITEM(  Lfo, ModeClkSync,              1, 0, 1, 0),
877
    NRPN_TABLE_ITEM(  Lfo, ModeKeySync,              1, 0, 1, 0),
878
    NRPN_TABLE_ITEM(  Lfo, ModeOneshot,              1, 0, 1, 0),
879
    NRPN_TABLE_ITEM(  Lfo, ModeFast,                 1, 0, 1, 0),
880
    NRPN_TABLE_ITEM_EMPTY(),
881
    NRPN_TABLE_ITEM_EMPTY(),
882
    NRPN_TABLE_ITEM_EMPTY(),
883
    NRPN_TABLE_ITEM_EMPTY(),
884
    NRPN_TABLE_ITEM_EMPTY8(),
885
 
886
    // 0x1a0
887
    NRPN_TABLE_ITEM(  Lfo, DepthPitch,               1, 0, 255, 1),
888
    NRPN_TABLE_ITEM(  Lfo, DepthLfoAmplitude,        1, 0, 255, 1),
889
    NRPN_TABLE_ITEM(  Lfo, DepthLfoRate,             1, 0, 255, 1),
890
    NRPN_TABLE_ITEM(  Lfo, DepthEnv1Rate,            1, 0, 255, 1),
891
    NRPN_TABLE_ITEM(  Lfo, DepthEnv2Rate,            1, 0, 255, 1),
892
    NRPN_TABLE_ITEM_EMPTY(),
893
    NRPN_TABLE_ITEM_EMPTY(),
894
    NRPN_TABLE_ITEM_EMPTY(),
895
    NRPN_TABLE_ITEM_EMPTY8(),
896
 
897
    // 0x1b0
898
    NRPN_TABLE_ITEM_EMPTY16(),
899
    // 0x1c0
900
    NRPN_TABLE_ITEM_EMPTY16(),
901
    // 0x1d0
902
    NRPN_TABLE_ITEM_EMPTY16(),
903
    // 0x1e0
904
    NRPN_TABLE_ITEM_EMPTY16(),
905
    // 0x1f0
906
    NRPN_TABLE_ITEM_EMPTY16(),
907
 
908
    // 0x200
909
    NRPN_TABLE_ITEM(  Env1, Amplitude,               0, 0, 255, 1),
1960 tk 910
    NRPN_TABLE_ITEM(  Env1, CurvePos,                0, 0, MBCV_ENV_NUM_CURVES-1, 0),
911
    NRPN_TABLE_ITEM(  Env1, CurveNeg,                0, 0, MBCV_ENV_NUM_CURVES-1, 0),
1903 tk 912
    NRPN_TABLE_ITEM(  Env1, Delay,                   0, 0, 255, 0),
913
    NRPN_TABLE_ITEM(  Env1, Attack,                  0, 0, 255, 0),
914
    NRPN_TABLE_ITEM(  Env1, Decay,                   0, 0, 255, 0),
915
    NRPN_TABLE_ITEM(  Env1, Sustain,                 0, 0, 255, 0),
916
    NRPN_TABLE_ITEM(  Env1, Release,                 0, 0, 255, 0),
917
    NRPN_TABLE_ITEM_EMPTY8(),
918
 
919
    // 0x210
920
    NRPN_TABLE_ITEM(  Env1, ModeClkSync,             0, 0, 1, 0),
921
    NRPN_TABLE_ITEM(  Env1, ModeKeySync,             0, 0, 1, 0),
922
    NRPN_TABLE_ITEM(  Env1, ModeOneshot,             0, 0, 1, 0),
923
    NRPN_TABLE_ITEM(  Env1, ModeFast,                0, 0, 1, 0),
924
    NRPN_TABLE_ITEM_EMPTY(),
925
    NRPN_TABLE_ITEM_EMPTY(),
926
    NRPN_TABLE_ITEM_EMPTY(),
927
    NRPN_TABLE_ITEM_EMPTY(),
928
    NRPN_TABLE_ITEM_EMPTY8(),
929
 
930
    // 0x220
931
    NRPN_TABLE_ITEM(  Env1, DepthPitch,              0, 0, 255, 1),
932
    NRPN_TABLE_ITEM(  Env1, DepthLfo1Amplitude,      0, 0, 255, 1),
933
    NRPN_TABLE_ITEM(  Env1, DepthLfo1Rate,           0, 0, 255, 1),
934
    NRPN_TABLE_ITEM(  Env1, DepthLfo2Amplitude,      0, 0, 255, 1),
935
    NRPN_TABLE_ITEM(  Env1, DepthLfo2Rate,           0, 0, 255, 1),
936
    NRPN_TABLE_ITEM_EMPTY(),
937
    NRPN_TABLE_ITEM_EMPTY(),
938
    NRPN_TABLE_ITEM_EMPTY(),
939
    NRPN_TABLE_ITEM_EMPTY8(),
940
 
941
    // 0x230
942
    NRPN_TABLE_ITEM_EMPTY16(),
943
    // 0x240
944
    NRPN_TABLE_ITEM_EMPTY16(),
945
    // 0x250
946
    NRPN_TABLE_ITEM_EMPTY16(),
947
    // 0x260
948
    NRPN_TABLE_ITEM_EMPTY16(),
949
    // 0x270
950
    NRPN_TABLE_ITEM_EMPTY16(),
951
 
952
    // 0x280
953
    NRPN_TABLE_ITEM(  Env2, Amplitude,               0, 0, 255, 1),
1960 tk 954
    NRPN_TABLE_ITEM(  Env2, CurvePos,                0, 0, MBCV_ENV_NUM_CURVES-1, 0),
955
    NRPN_TABLE_ITEM(  Env2, CurveNeg,                0, 0, MBCV_ENV_NUM_CURVES-1, 0),
1903 tk 956
    NRPN_TABLE_ITEM(  Env2, Offset,                  0, 0, 255, 0),
957
    NRPN_TABLE_ITEM(  Env2, Rate,                    0, 0, 255, 0),
958
    NRPN_TABLE_ITEM_EMPTY(),
959
    NRPN_TABLE_ITEM_EMPTY(),
960
    NRPN_TABLE_ITEM_EMPTY(),
961
 
962
    // 0x288
963
    NRPN_TABLE_ITEM(  Env2, LoopAttack,              0, 0, 16, 0),
964
    NRPN_TABLE_ITEM(  Env2, SustainStep,             0, 0, 16, 0),
965
    NRPN_TABLE_ITEM(  Env2, LoopRelease,             0, 0, 16, 0),
966
    NRPN_TABLE_ITEM(  Env2, LastStep,                0, 0, 16, 0),
967
    NRPN_TABLE_ITEM_EMPTY(),
968
    NRPN_TABLE_ITEM_EMPTY(),
969
    NRPN_TABLE_ITEM_EMPTY(),
970
    NRPN_TABLE_ITEM_EMPTY(),
971
 
972
    // 0x290
973
    NRPN_TABLE_ITEM(  Env2, ModeClkSync,             0, 0, 1, 0),
974
    NRPN_TABLE_ITEM(  Env2, ModeKeySync,             0, 0, 1, 0),
975
    NRPN_TABLE_ITEM(  Env2, ModeOneshot,             0, 0, 1, 0),
976
    NRPN_TABLE_ITEM(  Env2, ModeFast,                0, 0, 1, 0),
977
    NRPN_TABLE_ITEM_EMPTY(),
978
    NRPN_TABLE_ITEM_EMPTY(),
979
    NRPN_TABLE_ITEM_EMPTY(),
980
    NRPN_TABLE_ITEM_EMPTY(),
981
    NRPN_TABLE_ITEM_EMPTY8(),
982
 
983
    // 0x2a0
984
    NRPN_TABLE_ITEM(  Env2, DepthPitch,              0, 0, 255, 1),
985
    NRPN_TABLE_ITEM(  Env2, DepthLfo1Amplitude,      0, 0, 255, 1),
986
    NRPN_TABLE_ITEM(  Env2, DepthLfo1Rate,           0, 0, 255, 1),
987
    NRPN_TABLE_ITEM(  Env2, DepthLfo2Amplitude,      0, 0, 255, 1),
988
    NRPN_TABLE_ITEM(  Env2, DepthLfo2Rate,           0, 0, 255, 1),
989
    NRPN_TABLE_ITEM_EMPTY(),
990
    NRPN_TABLE_ITEM_EMPTY(),
991
    NRPN_TABLE_ITEM_EMPTY(),
992
    NRPN_TABLE_ITEM_EMPTY8(),
993
 
994
    // 0x2b0
995
    NRPN_TABLE_ITEM_EMPTY16(),
996
 
997
    // 0x2c0
998
    NRPN_TABLE_ITEM(  Env2, Level,                   0, 0, 255, 0),
999
    NRPN_TABLE_ITEM(  Env2, Level,                   1, 0, 255, 0),
1000
    NRPN_TABLE_ITEM(  Env2, Level,                   2, 0, 255, 0),
1001
    NRPN_TABLE_ITEM(  Env2, Level,                   3, 0, 255, 0),
1002
    NRPN_TABLE_ITEM(  Env2, Level,                   4, 0, 255, 0),
1003
    NRPN_TABLE_ITEM(  Env2, Level,                   5, 0, 255, 0),
1004
    NRPN_TABLE_ITEM(  Env2, Level,                   6, 0, 255, 0),
1005
    NRPN_TABLE_ITEM(  Env2, Level,                   7, 0, 255, 0),
1006
    NRPN_TABLE_ITEM(  Env2, Level,                   8, 0, 255, 0),
1007
    NRPN_TABLE_ITEM(  Env2, Level,                   9, 0, 255, 0),
1008
    NRPN_TABLE_ITEM(  Env2, Level,                  10, 0, 255, 0),
1009
    NRPN_TABLE_ITEM(  Env2, Level,                  11, 0, 255, 0),
1010
    NRPN_TABLE_ITEM(  Env2, Level,                  12, 0, 255, 0),
1011
    NRPN_TABLE_ITEM(  Env2, Level,                  13, 0, 255, 0),
1012
    NRPN_TABLE_ITEM(  Env2, Level,                  14, 0, 255, 0),
1013
    NRPN_TABLE_ITEM(  Env2, Level,                  15, 0, 255, 0),
1014
    NRPN_TABLE_ITEM(  Env2, Level,                  16, 0, 255, 0),
1015
    NRPN_TABLE_ITEM(  Env2, Level,                  17, 0, 255, 0),
1016
    NRPN_TABLE_ITEM(  Env2, Level,                  18, 0, 255, 0),
1017
    NRPN_TABLE_ITEM(  Env2, Level,                  19, 0, 255, 0),
1018
    NRPN_TABLE_ITEM(  Env2, Level,                  20, 0, 255, 0),
1019
    NRPN_TABLE_ITEM(  Env2, Level,                  21, 0, 255, 0),
1020
    NRPN_TABLE_ITEM(  Env2, Level,                  22, 0, 255, 0),
1021
    NRPN_TABLE_ITEM(  Env2, Level,                  23, 0, 255, 0),
1022
    NRPN_TABLE_ITEM(  Env2, Level,                  24, 0, 255, 0),
1023
    NRPN_TABLE_ITEM(  Env2, Level,                  25, 0, 255, 0),
1024
    NRPN_TABLE_ITEM(  Env2, Level,                  26, 0, 255, 0),
1025
    NRPN_TABLE_ITEM(  Env2, Level,                  27, 0, 255, 0),
1026
    NRPN_TABLE_ITEM(  Env2, Level,                  28, 0, 255, 0),
1027
    NRPN_TABLE_ITEM(  Env2, Level,                  29, 0, 255, 0),
1028
    NRPN_TABLE_ITEM(  Env2, Level,                  30, 0, 255, 0),
1029
    NRPN_TABLE_ITEM(  Env2, Level,                  31, 0, 255, 0),
1030
 
1031
    // 0x2e0
1032
    NRPN_TABLE_ITEM_EMPTY16(),
1033
    // 0x2f0
1034
    NRPN_TABLE_ITEM_EMPTY16(),
1035
 
1036
    // 0x300
1037
    NRPN_TABLE_ITEM(  Mod, Depth,                    0, 0, 255, 1),
1960 tk 1038
    NRPN_TABLE_ITEM(  Mod, Offset,                   0, 0, 255, 1),
1903 tk 1039
    NRPN_TABLE_ITEM(  Mod, Src1,                     0, 0, MBCV_NUM_MOD_SRC-1, 0),
1040
    NRPN_TABLE_ITEM(  Mod, Src1Chn,                  0, 0, CV_SE_NUM-1, 0),
1041
    NRPN_TABLE_ITEM(  Mod, Src2,                     0, 0, MBCV_NUM_MOD_SRC-1, 0),
1042
    NRPN_TABLE_ITEM(  Mod, Src2Chn,                  0, 0, CV_SE_NUM-1, 0),
1043
    NRPN_TABLE_ITEM(  Mod, Op,                       0, 0, 14, 0), // TODO: create enum for operations
1044
    NRPN_TABLE_ITEM(  Mod, Dst1,                     0, 0, MBCV_NUM_MOD_DST-1, 0),
1045
    NRPN_TABLE_ITEM(  Mod, Dst1Inv,                  0, 0, 1, 0),
1046
    NRPN_TABLE_ITEM(  Mod, Dst2,                     0, 0, MBCV_NUM_MOD_DST-1, 0),
1047
    NRPN_TABLE_ITEM(  Mod, Dst2Inv,                  0, 0, 1, 0),
1048
    NRPN_TABLE_ITEM_EMPTY(),
1049
    NRPN_TABLE_ITEM_EMPTY(),
1050
    NRPN_TABLE_ITEM_EMPTY(),
1051
    NRPN_TABLE_ITEM_EMPTY(),
1052
    NRPN_TABLE_ITEM_EMPTY(),
1053
 
1054
    // 0x310
1055
    NRPN_TABLE_ITEM(  Mod, Depth,                    1, 0, 255, 1),
1960 tk 1056
    NRPN_TABLE_ITEM(  Mod, Offset,                   1, 0, 255, 1),
1903 tk 1057
    NRPN_TABLE_ITEM(  Mod, Src1,                     1, 0, MBCV_NUM_MOD_SRC-1, 0),
1058
    NRPN_TABLE_ITEM(  Mod, Src1Chn,                  1, 0, CV_SE_NUM-1, 0),
1059
    NRPN_TABLE_ITEM(  Mod, Src2,                     1, 0, MBCV_NUM_MOD_SRC-1, 0),
1060
    NRPN_TABLE_ITEM(  Mod, Src2Chn,                  1, 0, CV_SE_NUM-1, 0),
1061
    NRPN_TABLE_ITEM(  Mod, Op,                       1, 0, 14, 0), // TODO: create enum for operations
1062
    NRPN_TABLE_ITEM(  Mod, Dst1,                     1, 0, MBCV_NUM_MOD_DST-1, 0),
1063
    NRPN_TABLE_ITEM(  Mod, Dst1Inv,                  1, 0, 1, 0),
1064
    NRPN_TABLE_ITEM(  Mod, Dst2,                     1, 0, MBCV_NUM_MOD_DST-1, 0),
1065
    NRPN_TABLE_ITEM(  Mod, Dst2Inv,                  1, 0, 1, 0),
1066
    NRPN_TABLE_ITEM_EMPTY(),
1067
    NRPN_TABLE_ITEM_EMPTY(),
1068
    NRPN_TABLE_ITEM_EMPTY(),
1069
    NRPN_TABLE_ITEM_EMPTY(),
1070
    NRPN_TABLE_ITEM_EMPTY(),
1071
 
1072
    // 0x320
1073
    NRPN_TABLE_ITEM(  Mod, Depth,                    2, 0, 255, 1),
1960 tk 1074
    NRPN_TABLE_ITEM(  Mod, Offset,                   2, 0, 255, 1),
1903 tk 1075
    NRPN_TABLE_ITEM(  Mod, Src1,                     2, 0, MBCV_NUM_MOD_SRC-1, 0),
1076
    NRPN_TABLE_ITEM(  Mod, Src1Chn,                  2, 0, CV_SE_NUM-1, 0),
1077
    NRPN_TABLE_ITEM(  Mod, Src2,                     2, 0, MBCV_NUM_MOD_SRC-1, 0),
1078
    NRPN_TABLE_ITEM(  Mod, Src2Chn,                  2, 0, CV_SE_NUM-1, 0),
1079
    NRPN_TABLE_ITEM(  Mod, Op,                       2, 0, 14, 0), // TODO: create enum for operations
1080
    NRPN_TABLE_ITEM(  Mod, Dst1,                     2, 0, MBCV_NUM_MOD_DST-1, 0),
1081
    NRPN_TABLE_ITEM(  Mod, Dst1Inv,                  2, 0, 1, 0),
1082
    NRPN_TABLE_ITEM(  Mod, Dst2,                     2, 0, MBCV_NUM_MOD_DST-1, 0),
1083
    NRPN_TABLE_ITEM(  Mod, Dst2Inv,                  2, 0, 1, 0),
1084
    NRPN_TABLE_ITEM_EMPTY(),
1085
    NRPN_TABLE_ITEM_EMPTY(),
1086
    NRPN_TABLE_ITEM_EMPTY(),
1087
    NRPN_TABLE_ITEM_EMPTY(),
1088
    NRPN_TABLE_ITEM_EMPTY(),
1089
 
1090
    // 0x330
1091
    NRPN_TABLE_ITEM(  Mod, Depth,                    3, 0, 255, 1),
1960 tk 1092
    NRPN_TABLE_ITEM(  Mod, Offset,                   3, 0, 255, 1),
1903 tk 1093
    NRPN_TABLE_ITEM(  Mod, Src1,                     3, 0, MBCV_NUM_MOD_SRC-1, 0),
1094
    NRPN_TABLE_ITEM(  Mod, Src1Chn,                  3, 0, CV_SE_NUM-1, 0),
1095
    NRPN_TABLE_ITEM(  Mod, Src2,                     3, 0, MBCV_NUM_MOD_SRC-1, 0),
1096
    NRPN_TABLE_ITEM(  Mod, Src2Chn,                  3, 0, CV_SE_NUM-1, 0),
1097
    NRPN_TABLE_ITEM(  Mod, Op,                       3, 0, 14, 0), // TODO: create enum for operations
1098
    NRPN_TABLE_ITEM(  Mod, Dst1,                     3, 0, MBCV_NUM_MOD_DST-1, 0),
1099
    NRPN_TABLE_ITEM(  Mod, Dst1Inv,                  3, 0, 1, 0),
1100
    NRPN_TABLE_ITEM(  Mod, Dst2,                     3, 0, MBCV_NUM_MOD_DST-1, 0),
1101
    NRPN_TABLE_ITEM(  Mod, Dst2Inv,                  3, 0, 1, 0),
1102
    NRPN_TABLE_ITEM_EMPTY(),
1103
    NRPN_TABLE_ITEM_EMPTY(),
1104
    NRPN_TABLE_ITEM_EMPTY(),
1105
    NRPN_TABLE_ITEM_EMPTY(),
1106
    NRPN_TABLE_ITEM_EMPTY(),
1107
 
1108
    // 0x340
1109
    NRPN_TABLE_ITEM_EMPTY16(),
1110
    // 0x350
1111
    NRPN_TABLE_ITEM_EMPTY16(),
1112
    // 0x360
1113
    NRPN_TABLE_ITEM_EMPTY16(),
1114
    // 0x370
1115
    NRPN_TABLE_ITEM_EMPTY16(),
1116
 
1117
};
1118
 
1119
 
1120
/////////////////////////////////////////////////////////////////////////////
1121
// will set NRPN depending on first 10 bits
1122
// MSBs already decoded in MbCvEnvironment
1123
// returns false if parameter not mapped
1124
/////////////////////////////////////////////////////////////////////////////
1125
bool MbCv::setNRPN(u16 nrpnNumber, u16 value)
1126
{
1127
    u32 par = nrpnNumber & 0x3ff;
1128
    if( par < MBCV_NRPN_TABLE_SIZE ) {
1129
        MbCvTableEntry_t *t = (MbCvTableEntry_t *)&mbCvNrpnTable[par];
1130
        if( t->setFunct != NULL ) {
1131
            t->setFunct(this, t->arg, value);
1132
            return true;
1133
        }
1134
    }
1135
 
1136
    return false; // parameter not mapped
1137
}
1138
 
1139
 
1140
/////////////////////////////////////////////////////////////////////////////
1141
// returns NRPN value depending on first 10 bits
1142
// MSBs already decoded in MbCvEnvironment
1143
// returns false if parameter not mapped
1144
/////////////////////////////////////////////////////////////////////////////
1145
bool MbCv::getNRPN(u16 nrpnNumber, u16 *value)
1146
{
1147
    u32 par = nrpnNumber & 0x3ff;
1148
    if( par < MBCV_NRPN_TABLE_SIZE ) {
1149
        MbCvTableEntry_t *t = (MbCvTableEntry_t *)&mbCvNrpnTable[par];
1150
        if( t->getFunct != NULL ) {
1151
            t->getFunct(this, t->arg, value);
1152
            return true;
1153
        }
1154
    }
1155
 
1156
    return false; // parameter not mapped
1157
}
1158
 
1159
/////////////////////////////////////////////////////////////////////////////
1160
// returns NRPN informations depending on first 10 bits
1161
// MSBs already decoded in MbCvEnvironment
1162
// returns false if parameter not mapped
1163
/////////////////////////////////////////////////////////////////////////////
1164
bool MbCv::getNRPNInfo(u16 nrpnNumber, MbCvNrpnInfoT *info)
1165
{
1166
    u32 par = nrpnNumber & 0x3ff;
1167
    if( par < MBCV_NRPN_TABLE_SIZE ) {
1168
        MbCvTableEntry_t *t = (MbCvTableEntry_t *)&mbCvNrpnTable[par];
1169
        if( t->getFunct != NULL ) {
1170
            t->getFunct(this, t->arg, &info->value);
1171
            info->cv = cvNum;
1172
            info->is_bidir = t->is_bidir;
1173
            info->min = t->min;
1174
            info->max = t->max;
1175
 
1176
            {
1911 tk 1177
                char nameString[40];
1178
                char nameString1[21];
1903 tk 1179
 
1911 tk 1180
                sprintf(nameString1, t->groupString, t->arg+1);
1181
                sprintf(nameString, "CV%d %s", cvNum+1, nameString1);
1903 tk 1182
 
1183
                // 20 chars max; pad with spaces
1911 tk 1184
                int len = strlen(nameString);
1903 tk 1185
                for(int pos=len; pos<20; ++pos)
1911 tk 1186
                    nameString[pos] = ' ';
1187
                nameString[20] = 0;
1188
                memcpy(info->nameString, nameString, 21);
1903 tk 1189
            }
1911 tk 1190
 
1191
            {
1192
                char valueString[40];
1193
                char nameString1[21];
1194
 
1195
                sprintf(nameString1, t->nameString, t->arg+1);
1196
 
1197
                if( info->is_bidir ) {
1198
                    int range = info->max - info->min + 1;
1199
                    sprintf(valueString, "%s:%4d", nameString1, (int)info->value - (range/2));
1200
                } else {
1201
                    if( info->min == 0 && info->max == 1 ) {
1202
                        sprintf(valueString, "%s: %s", nameString1, info->value ? "on " : "off");
1203
                    } else {
1204
                        sprintf(valueString, "%s:%4d", nameString1, info->value);
1205
                    }
1206
                }
1207
 
1208
                // 20 chars max; pad with spaces
1209
                int len = strlen(valueString);
1210
                for(int pos=len; pos<20; ++pos)
1211
                    valueString[pos] = ' ';
1212
 
1213
                valueString[20] = 0;
1214
                memcpy(info->valueString, valueString, 21);
1215
            }
1216
 
1903 tk 1217
            return true;
1218
        }
1219
    }
1220
 
1221
    return false; // parameter not mapped
1222
}
1223