@@ -50,6 +50,9 @@ LOGMODULE ("mididevice");
50
50
#define MIDI_CC_DETUNE_LEVEL 94
51
51
#define MIDI_CC_ALL_SOUND_OFF 120
52
52
#define MIDI_CC_ALL_NOTES_OFF 123
53
+ #define MIDI_CC_NRPN_PARAM_MSB 99
54
+ #define MIDI_CC_NRPN_PARAM_LSB 98
55
+ #define MIDI_CC_NRPN_DATA_LSB 38
53
56
#define MIDI_PROGRAM_CHANGE 0b1100
54
57
#define MIDI_PITCH_BEND 0b1110
55
58
@@ -58,6 +61,12 @@ LOGMODULE ("mididevice");
58
61
#define MIDI_TIMING_CLOCK 0xF8
59
62
#define MIDI_ACTIVE_SENSING 0xFE
60
63
64
+ #define MIDI_NRPN_PROGRAM_CHANGE 21
65
+
66
+ uint8_t scale (uint8_t max, uint8_t value) {
67
+ return (uint8_t )((((unsigned )value) * max) / 127 );
68
+ }
69
+
61
70
CMIDIDevice::TDeviceMap CMIDIDevice::s_DeviceMap;
62
71
63
72
CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInterface *pUI)
@@ -68,6 +77,8 @@ CMIDIDevice::CMIDIDevice (CMiniDexed *pSynthesizer, CConfig *pConfig, CUserInter
68
77
for (unsigned nTG = 0 ; nTG < CConfig::ToneGenerators; nTG++)
69
78
{
70
79
m_ChannelMap[nTG] = Disabled;
80
+ m_NRPNoffset[nTG] = 0 ;
81
+ m_NRPNop[nTG] = 0 ;
71
82
}
72
83
}
73
84
@@ -347,6 +358,178 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
347
358
m_pSynthesizer->notesOff (pMessage[2 ], nTG);
348
359
}
349
360
break ;
361
+
362
+ case MIDI_CC_NRPN_PARAM_MSB:
363
+ if (pMessage[2 ] <= 6 ) {
364
+ m_NRPNop[nTG] = pMessage[2 ];
365
+ }
366
+ break ;
367
+
368
+ case MIDI_CC_NRPN_PARAM_LSB:
369
+ m_NRPNoffset[nTG] = pMessage[2 ];
370
+ break ;
371
+
372
+ case MIDI_CC_NRPN_DATA_LSB:
373
+ switch (m_NRPNoffset[nTG])
374
+ {
375
+ case MIDI_NRPN_PROGRAM_CHANGE:
376
+ m_pSynthesizer->ProgramChange (pMessage[2 ], nTG);
377
+ break ;
378
+ default :
379
+ if (m_NRPNop[nTG] < 6 )
380
+ {
381
+ switch (m_NRPNoffset[nTG]) {
382
+ case DEXED_OP_EG_R1:
383
+ m_pSynthesizer->m_pTG [nTG]->setOPRate (m_NRPNop[nTG], 0 , scale (99 , pMessage[2 ]));
384
+ break ;
385
+ case DEXED_OP_EG_R2:
386
+ m_pSynthesizer->m_pTG [nTG]->setOPRate (m_NRPNop[nTG], 1 , scale (99 , pMessage[2 ]));
387
+ break ;
388
+ case DEXED_OP_EG_R3:
389
+ m_pSynthesizer->m_pTG [nTG]->setOPRate (m_NRPNop[nTG], 2 , scale (99 , pMessage[2 ]));
390
+ break ;
391
+ case DEXED_OP_EG_R4:
392
+ m_pSynthesizer->m_pTG [nTG]->setOPRate (m_NRPNop[nTG], 3 , scale (99 , pMessage[2 ]));
393
+ break ;
394
+ case DEXED_OP_EG_L1:
395
+ m_pSynthesizer->m_pTG [nTG]->setOPLevel (m_NRPNop[nTG], 0 , scale (99 , pMessage[2 ]));
396
+ break ;
397
+ case DEXED_OP_EG_L2:
398
+ m_pSynthesizer->m_pTG [nTG]->setOPLevel (m_NRPNop[nTG], 1 , scale (99 , pMessage[2 ]));
399
+ break ;
400
+ case DEXED_OP_EG_L3:
401
+ m_pSynthesizer->m_pTG [nTG]->setOPLevel (m_NRPNop[nTG], 2 , scale (99 , pMessage[2 ]));
402
+ break ;
403
+ case DEXED_OP_EG_L4:
404
+ m_pSynthesizer->m_pTG [nTG]->setOPLevel (m_NRPNop[nTG], 3 , scale (99 , pMessage[2 ]));
405
+ break ;
406
+ case DEXED_OP_LEV_SCL_BRK_PT:
407
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardLevelScalingBreakPoint (m_NRPNop[nTG], scale (99 , pMessage[2 ]));
408
+ break ;
409
+ case DEXED_OP_SCL_LEFT_DEPTH:
410
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardLevelScalingDepthLeft (m_NRPNop[nTG], scale (99 , pMessage[2 ]));
411
+ break ;
412
+ case DEXED_OP_SCL_RGHT_DEPTH:
413
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardLevelScalingDepthRight (m_NRPNop[nTG], scale (99 , pMessage[2 ]));
414
+ break ;
415
+ case DEXED_OP_SCL_LEFT_CURVE:
416
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardLevelScalingCurveLeft (m_NRPNop[nTG], scale (3 , pMessage[2 ]));
417
+ break ;
418
+ case DEXED_OP_SCL_RGHT_CURVE:
419
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardLevelScalingCurveRight (m_NRPNop[nTG], scale (3 , pMessage[2 ]));
420
+ break ;
421
+ case DEXED_OP_OSC_RATE_SCALE:
422
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardRateScale (m_NRPNop[nTG], scale (7 , pMessage[2 ]));
423
+ break ;
424
+ case DEXED_OP_AMP_MOD_SENS:
425
+ m_pSynthesizer->m_pTG [nTG]->setOPAmpModulationSensity (m_NRPNop[nTG], scale (3 , pMessage[2 ]));
426
+ break ;
427
+ case DEXED_OP_KEY_VEL_SENS:
428
+ m_pSynthesizer->m_pTG [nTG]->setOPKeyboardVelocitySensity (m_NRPNop[nTG], scale (7 , pMessage[2 ]));
429
+ break ;
430
+ case DEXED_OP_OUTPUT_LEV:
431
+ m_pSynthesizer->m_pTG [nTG]->setOPOutputLevel (m_NRPNop[nTG], scale (99 , pMessage[2 ]));
432
+ break ;
433
+ case DEXED_OP_OSC_MODE:
434
+ m_pSynthesizer->m_pTG [nTG]->setOPMode (m_NRPNop[nTG], scale (1 , pMessage[2 ]));
435
+ break ;
436
+ case DEXED_OP_FREQ_COARSE:
437
+ m_pSynthesizer->m_pTG [nTG]->setOPFrequencyCoarse (m_NRPNop[nTG], scale (31 , pMessage[2 ]));
438
+ break ;
439
+ case DEXED_OP_FREQ_FINE:
440
+ m_pSynthesizer->m_pTG [nTG]->setOPFrequencyFine (m_NRPNop[nTG], scale (99 , pMessage[2 ]));
441
+ break ;
442
+ case DEXED_OP_OSC_DETUNE:
443
+ m_pSynthesizer->m_pTG [nTG]->setOPDetune (m_NRPNop[nTG], scale (14 , pMessage[2 ]));
444
+ break ;
445
+ }
446
+ // TODO: send partial update, but this will do for now
447
+ SendSystemExclusiveVoice (0 , 0 , nTG);
448
+ }
449
+ if (m_NRPNop[nTG] == 6 ) {
450
+ switch (m_NRPNoffset[nTG]) {
451
+ case DEXED_PITCH_EG_R1:
452
+ m_pSynthesizer->m_pTG [nTG]->setPitchRate (0 , scale (99 , pMessage[2 ]));
453
+ break ;
454
+ case DEXED_PITCH_EG_R2:
455
+ m_pSynthesizer->m_pTG [nTG]->setPitchRate (1 , scale (99 , pMessage[2 ]));
456
+
457
+ break ;
458
+ case DEXED_PITCH_EG_R3:
459
+ m_pSynthesizer->m_pTG [nTG]->setPitchRate (2 , scale (99 , pMessage[2 ]));
460
+
461
+ break ;
462
+ case DEXED_PITCH_EG_R4:
463
+ m_pSynthesizer->m_pTG [nTG]->setPitchRate (3 , scale (99 , pMessage[2 ]));
464
+
465
+ break ;
466
+ case DEXED_PITCH_EG_L1:
467
+ m_pSynthesizer->m_pTG [nTG]->setPitchLevel (0 , scale (99 , pMessage[2 ]));
468
+
469
+ break ;
470
+ case DEXED_PITCH_EG_L2:
471
+ m_pSynthesizer->m_pTG [nTG]->setPitchLevel (1 , scale (99 , pMessage[2 ]));
472
+
473
+ break ;
474
+ case DEXED_PITCH_EG_L3:
475
+ m_pSynthesizer->m_pTG [nTG]->setPitchLevel (2 , scale (99 , pMessage[2 ]));
476
+
477
+ break ;
478
+ case DEXED_PITCH_EG_L4:
479
+ m_pSynthesizer->m_pTG [nTG]->setPitchLevel (3 , scale (99 , pMessage[2 ]));
480
+
481
+ break ;
482
+ case DEXED_ALGORITHM:
483
+ m_pSynthesizer->m_pTG [nTG]->setAlgorithm (scale (31 , pMessage[2 ]));
484
+
485
+ break ;
486
+ case DEXED_FEEDBACK:
487
+ m_pSynthesizer->m_pTG [nTG]->setFeedback (scale (7 , pMessage[2 ]));
488
+
489
+ break ;
490
+ case DEXED_OSC_KEY_SYNC:
491
+ m_pSynthesizer->m_pTG [nTG]->setOscillatorSync (scale (1 , pMessage[2 ]));
492
+
493
+ break ;
494
+ case DEXED_LFO_SPEED:
495
+ m_pSynthesizer->m_pTG [nTG]->setLFOSpeed (scale (99 , pMessage[2 ]));
496
+
497
+ break ;
498
+ case DEXED_LFO_DELAY:
499
+ m_pSynthesizer->m_pTG [nTG]->setLFODelay (scale (99 , pMessage[2 ]));
500
+
501
+ break ;
502
+ case DEXED_LFO_PITCH_MOD_DEP:
503
+ m_pSynthesizer->m_pTG [nTG]->setLFOPitchModulationDepth (scale (99 , pMessage[2 ]));
504
+
505
+ break ;
506
+ case DEXED_LFO_AMP_MOD_DEP:
507
+ m_pSynthesizer->m_pTG [nTG]->setLFOAmpModulationDepth (scale (99 , pMessage[2 ]));
508
+
509
+ break ;
510
+ case DEXED_LFO_SYNC:
511
+ m_pSynthesizer->m_pTG [nTG]->setLFOSync (scale (1 , pMessage[2 ]));
512
+
513
+ break ;
514
+ case DEXED_LFO_WAVE:
515
+ m_pSynthesizer->m_pTG [nTG]->setLFOWaveform (scale (4 , pMessage[2 ]));
516
+
517
+ break ;
518
+ case DEXED_LFO_PITCH_MOD_SENS:
519
+ m_pSynthesizer->m_pTG [nTG]->setLFOPitchModulationSensitivity (scale (7 , pMessage[2 ]));
520
+
521
+ break ;
522
+ case DEXED_TRANSPOSE:
523
+ m_pSynthesizer->m_pTG [nTG]->setTranspose (scale (48 , pMessage[2 ]));
524
+
525
+ break ;
526
+ }
527
+ // TODO: send partial update, but this will do for now
528
+ SendSystemExclusiveVoice (0 , 0 , nTG);
529
+ }
530
+ }
531
+ break ;
532
+
350
533
}
351
534
break ;
352
535
0 commit comments