You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

814 lines
18KB

  1. #pragma once
  2. #include <algorithm>
  3. #include <dsp/common.hpp>
  4. #include <dsp/filter.hpp>
  5. #include <dsp/digital.hpp>
  6. #include <midi.hpp>
  7. #include <jansson.h>
  8. namespace rack {
  9. namespace dsp {
  10. /** Converts gates and CV to MIDI messages.
  11. CHANNELS is the number of polyphony channels. Use 1 for monophonic.
  12. */
  13. template <int CHANNELS>
  14. struct MidiGenerator {
  15. uint8_t channels;
  16. int8_t vels[CHANNELS];
  17. int8_t notes[CHANNELS];
  18. bool gates[CHANNELS];
  19. int8_t keyPressures[CHANNELS];
  20. int8_t channelPressure;
  21. int8_t ccs[128];
  22. int16_t pw;
  23. bool clk;
  24. bool start;
  25. bool stop;
  26. bool cont;
  27. int64_t frame = -1;
  28. MidiGenerator() {
  29. reset();
  30. }
  31. void reset() {
  32. channels = CHANNELS;
  33. for (int c = 0; c < CHANNELS; c++) {
  34. vels[c] = 100;
  35. notes[c] = 60;
  36. gates[c] = false;
  37. keyPressures[c] = -1;
  38. }
  39. channelPressure = -1;
  40. for (int i = 0; i < 128; i++) {
  41. ccs[i] = -1;
  42. }
  43. pw = 0x2000;
  44. clk = false;
  45. start = false;
  46. stop = false;
  47. cont = false;
  48. }
  49. void panic() {
  50. reset();
  51. // Send all note off commands
  52. for (int note = 0; note <= 127; note++) {
  53. // Note off
  54. midi::Message m;
  55. m.setStatus(0x8);
  56. m.setNote(note);
  57. m.setValue(0);
  58. m.setFrame(frame);
  59. onMessage(m);
  60. }
  61. }
  62. void setChannels(uint8_t channels) {
  63. if (this->channels == channels)
  64. return;
  65. // Disable notes when channels decreases
  66. for (uint8_t c = channels; c < this->channels; c++) {
  67. setNoteGate(notes[c], false, c);
  68. }
  69. this->channels = channels;
  70. }
  71. /** Must be called before setNoteGate(). */
  72. void setVelocity(int8_t vel, int c) {
  73. vels[c] = vel;
  74. }
  75. void setNoteGate(int8_t note, bool gate, int c) {
  76. bool changedNote = gate && gates[c] && (note != notes[c]);
  77. bool enabledGate = gate && !gates[c];
  78. bool disabledGate = !gate && gates[c];
  79. if (changedNote || disabledGate) {
  80. // Note off
  81. midi::Message m;
  82. m.setStatus(0x8);
  83. m.setNote(notes[c]);
  84. m.setValue(vels[c]);
  85. m.setFrame(frame);
  86. onMessage(m);
  87. }
  88. if (changedNote || enabledGate) {
  89. // Note on
  90. midi::Message m;
  91. m.setStatus(0x9);
  92. m.setNote(note);
  93. m.setValue(vels[c]);
  94. m.setFrame(frame);
  95. onMessage(m);
  96. }
  97. notes[c] = note;
  98. gates[c] = gate;
  99. }
  100. void setKeyPressure(int8_t val, int c) {
  101. if (keyPressures[c] == val)
  102. return;
  103. keyPressures[c] = val;
  104. // Polyphonic key pressure
  105. midi::Message m;
  106. m.setStatus(0xa);
  107. m.setNote(notes[c]);
  108. m.setValue(val);
  109. m.setFrame(frame);
  110. onMessage(m);
  111. }
  112. void setChannelPressure(int8_t val) {
  113. if (channelPressure == val)
  114. return;
  115. channelPressure = val;
  116. // Channel pressure
  117. midi::Message m;
  118. m.setSize(2);
  119. m.setStatus(0xd);
  120. m.setNote(val);
  121. m.setFrame(frame);
  122. onMessage(m);
  123. }
  124. void setCc(int8_t cc, int id) {
  125. if (ccs[id] == cc)
  126. return;
  127. ccs[id] = cc;
  128. // Continuous controller
  129. midi::Message m;
  130. m.setStatus(0xb);
  131. m.setNote(id);
  132. m.setValue(cc);
  133. m.setFrame(frame);
  134. onMessage(m);
  135. }
  136. void setModWheel(int8_t cc) {
  137. setCc(cc, 0x01);
  138. }
  139. void setVolume(int8_t cc) {
  140. setCc(cc, 0x07);
  141. }
  142. void setBalance(int8_t cc) {
  143. setCc(cc, 0x08);
  144. }
  145. void setPan(int8_t cc) {
  146. setCc(cc, 0x0a);
  147. }
  148. void setSustainPedal(int8_t cc) {
  149. setCc(cc, 0x40);
  150. }
  151. void setPitchWheel(int16_t pw) {
  152. if (this->pw == pw)
  153. return;
  154. this->pw = pw;
  155. // Pitch wheel
  156. midi::Message m;
  157. m.setStatus(0xe);
  158. m.setNote(pw & 0x7f);
  159. m.setValue((pw >> 7) & 0x7f);
  160. m.setFrame(frame);
  161. onMessage(m);
  162. }
  163. void setClock(bool clk) {
  164. if (this->clk == clk)
  165. return;
  166. this->clk = clk;
  167. if (clk) {
  168. // Timing clock
  169. midi::Message m;
  170. m.setSize(1);
  171. m.setStatus(0xf);
  172. m.setChannel(0x8);
  173. m.setFrame(frame);
  174. onMessage(m);
  175. }
  176. }
  177. void setStart(bool start) {
  178. if (this->start == start)
  179. return;
  180. this->start = start;
  181. if (start) {
  182. // Start
  183. midi::Message m;
  184. m.setSize(1);
  185. m.setStatus(0xf);
  186. m.setChannel(0xa);
  187. m.setFrame(frame);
  188. onMessage(m);
  189. }
  190. }
  191. void setContinue(bool cont) {
  192. if (this->cont == cont)
  193. return;
  194. this->cont = cont;
  195. if (cont) {
  196. // Continue
  197. midi::Message m;
  198. m.setSize(1);
  199. m.setStatus(0xf);
  200. m.setChannel(0xb);
  201. m.setFrame(frame);
  202. onMessage(m);
  203. }
  204. }
  205. void setStop(bool stop) {
  206. if (this->stop == stop)
  207. return;
  208. this->stop = stop;
  209. if (stop) {
  210. // Stop
  211. midi::Message m;
  212. m.setSize(1);
  213. m.setStatus(0xf);
  214. m.setChannel(0xc);
  215. m.setFrame(frame);
  216. onMessage(m);
  217. }
  218. }
  219. void setFrame(int64_t frame) {
  220. this->frame = frame;
  221. }
  222. virtual void onMessage(const midi::Message& message) {}
  223. };
  224. /** Converts MIDI note and transport messages to gates, CV, and other states.
  225. MAX_CHANNELS is the maximum number of polyphonic channels.
  226. */
  227. template <uint8_t MAX_CHANNELS>
  228. struct MidiParser {
  229. // Settings
  230. /** Actual number of output polyphonic channels */
  231. uint8_t channels;
  232. enum MonoMode {
  233. LAST_PRIORITY_MODE,
  234. FIRST_PRIORITY_MODE,
  235. LOWEST_PRIORITY_MODE,
  236. HIGHEST_PRIORITY_MODE,
  237. NUM_MONO_MODES
  238. };
  239. MonoMode monoMode;
  240. /** In monophonic mode, generate Retrigger pulse when the active note is released and another takes over. */
  241. bool retriggerOnResume;
  242. /** Method for assigning notes to polyphony channels */
  243. enum PolyMode {
  244. ROTATE_MODE,
  245. REUSE_MODE,
  246. RESET_MODE,
  247. MPE_MODE,
  248. NUM_POLY_MODES
  249. };
  250. PolyMode polyMode;
  251. /** Set Velocity output from Note Off velocity */
  252. bool releaseVelocityEnabled;
  253. /** Number of semitones to bend up/down by pitch wheel */
  254. float pwRange;
  255. /** Enables pitch-wheel and mod-wheel exponential smoothing */
  256. bool smooth;
  257. /** Number of 24 PPQN clocks between clock divider pulses */
  258. uint32_t clockDivision;
  259. // States
  260. /** Clock index from song start */
  261. int64_t clock;
  262. /** Whether sustain pedal is held. */
  263. bool pedal;
  264. uint8_t notes[MAX_CHANNELS];
  265. bool gates[MAX_CHANNELS];
  266. uint8_t velocities[MAX_CHANNELS];
  267. uint8_t aftertouches[MAX_CHANNELS];
  268. std::vector<uint8_t> heldNotes;
  269. int8_t rotateIndex;
  270. /** Pitch wheel values, from -8192 to 8191.
  271. When MPE is disabled, only the first channel is used.
  272. */
  273. int16_t pws[MAX_CHANNELS];
  274. /** Mod wheel values, from 0 to 127.
  275. */
  276. uint8_t mods[MAX_CHANNELS];
  277. /** Smoothing filters for wheel values */
  278. dsp::ExponentialFilter pwFilters[MAX_CHANNELS];
  279. dsp::ExponentialFilter modFilters[MAX_CHANNELS];
  280. dsp::PulseGenerator clockPulse;
  281. dsp::PulseGenerator clockDividerPulse;
  282. dsp::PulseGenerator retriggerPulses[MAX_CHANNELS];
  283. dsp::PulseGenerator startPulse;
  284. dsp::PulseGenerator stopPulse;
  285. dsp::PulseGenerator continuePulse;
  286. MidiParser() {
  287. heldNotes.reserve(128);
  288. reset();
  289. }
  290. /** Resets settings and performance state */
  291. void reset() {
  292. channels = 1;
  293. monoMode = LAST_PRIORITY_MODE;
  294. retriggerOnResume = false;
  295. polyMode = ROTATE_MODE;
  296. releaseVelocityEnabled = false;
  297. pwRange = 2.f;
  298. smooth = true;
  299. clockDivision = 24;
  300. setFilterLambda(30.f);
  301. panic();
  302. }
  303. /** Resets performance state */
  304. void panic() {
  305. clock = 0;
  306. pedal = false;
  307. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  308. // Middle C
  309. notes[c] = 60;
  310. gates[c] = false;
  311. velocities[c] = 0;
  312. aftertouches[c] = 0;
  313. pws[c] = 0;
  314. mods[c] = 0;
  315. pwFilters[c].reset();
  316. modFilters[c].reset();
  317. }
  318. rotateIndex = -1;
  319. heldNotes.clear();
  320. }
  321. void processFilters(float deltaTime) {
  322. uint8_t wheelChannels = getWheelChannels();
  323. for (uint8_t c = 0; c < wheelChannels; c++) {
  324. float pw = pws[c] / 8191.f;
  325. pw = math::clamp(pw, -1.f, 1.f);
  326. if (smooth)
  327. pw = pwFilters[c].process(deltaTime, pw);
  328. else
  329. pwFilters[c].out = pw;
  330. float mod = mods[c] / 127.f;
  331. mod = math::clamp(mod, 0.f, 1.f);
  332. if (smooth)
  333. mod = modFilters[c].process(deltaTime, mod);
  334. else
  335. modFilters[c].out = mod;
  336. }
  337. }
  338. void processPulses(float deltaTime) {
  339. clockPulse.process(deltaTime);
  340. clockDividerPulse.process(deltaTime);
  341. startPulse.process(deltaTime);
  342. stopPulse.process(deltaTime);
  343. continuePulse.process(deltaTime);
  344. for (uint8_t c = 0; c < channels; c++) {
  345. retriggerPulses[c].process(deltaTime);
  346. }
  347. }
  348. void processMessage(const midi::Message& msg) {
  349. // DEBUG("MIDI: %ld %s", msg.getFrame(), msg.toString().c_str());
  350. switch (msg.getStatus()) {
  351. // note off
  352. case 0x8: {
  353. releaseNote(msg.getNote(), msg.getChannel(), msg.getValue());
  354. } break;
  355. // note on
  356. case 0x9: {
  357. uint8_t velocity = msg.getValue();
  358. if (velocity > 0) {
  359. pressNote(msg.getNote(), msg.getChannel(), velocity);
  360. }
  361. else {
  362. // Note-on event with velocity 0 is an alternative for note-off event.
  363. releaseNote(msg.getNote(), msg.getChannel(), -1);
  364. }
  365. } break;
  366. // key pressure
  367. case 0xa: {
  368. // Set the aftertouches with the same note
  369. // TODO Should we handle the MPE case differently?
  370. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  371. if (notes[c] == msg.getNote())
  372. aftertouches[c] = msg.getValue();
  373. }
  374. } break;
  375. // cc
  376. case 0xb: {
  377. processCC(msg);
  378. } break;
  379. // channel pressure
  380. case 0xd: {
  381. if (channels > 1 && polyMode == MPE_MODE) {
  382. // Set the channel aftertouch
  383. aftertouches[msg.getChannel()] = msg.getNote();
  384. }
  385. else {
  386. // Set all aftertouches
  387. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  388. aftertouches[c] = msg.getNote();
  389. }
  390. }
  391. } break;
  392. // pitch wheel
  393. case 0xe: {
  394. uint8_t c = (channels > 1 && polyMode == MPE_MODE) ? msg.getChannel() : 0;
  395. int16_t pw = msg.getValue();
  396. pw <<= 7;
  397. pw |= msg.getNote();
  398. pw -= 8192;
  399. pws[c] = pw;
  400. } break;
  401. case 0xf: {
  402. processSystem(msg);
  403. } break;
  404. default: break;
  405. }
  406. }
  407. void processCC(const midi::Message& msg) {
  408. switch (msg.getNote()) {
  409. // mod
  410. case 0x01: {
  411. uint8_t c = (channels > 1 && polyMode == MPE_MODE) ? msg.getChannel() : 0;
  412. mods[c] = msg.getValue();
  413. } break;
  414. // sustain
  415. case 0x40: {
  416. if (msg.getValue() >= 64)
  417. pressPedal();
  418. else
  419. releasePedal();
  420. } break;
  421. // all notes off (panic)
  422. case 0x7b: {
  423. if (msg.getValue() == 0) {
  424. panic();
  425. }
  426. } break;
  427. default: break;
  428. }
  429. }
  430. void processSystem(const midi::Message& msg) {
  431. switch (msg.getChannel()) {
  432. // Song Position Pointer
  433. case 0x2: {
  434. int64_t pos = int64_t(msg.getNote()) | (int64_t(msg.getValue()) << 7);
  435. clock = pos * 6;
  436. } break;
  437. // Timing
  438. case 0x8: {
  439. clockPulse.trigger(1e-3);
  440. if (clock % clockDivision == 0) {
  441. clockDividerPulse.trigger(1e-3);
  442. }
  443. clock++;
  444. } break;
  445. // Start
  446. case 0xa: {
  447. startPulse.trigger(1e-3);
  448. clock = 0;
  449. } break;
  450. // Continue
  451. case 0xb: {
  452. continuePulse.trigger(1e-3);
  453. } break;
  454. // Stop
  455. case 0xc: {
  456. stopPulse.trigger(1e-3);
  457. } break;
  458. default: break;
  459. }
  460. }
  461. uint8_t assignChannel(uint8_t note) {
  462. if (channels <= 1)
  463. return 0;
  464. if (polyMode == REUSE_MODE) {
  465. // Try to find channel with the same note
  466. for (uint8_t c = 0; c < channels; c++) {
  467. if (notes[c] == note)
  468. return c;
  469. }
  470. }
  471. if (polyMode == REUSE_MODE || polyMode == ROTATE_MODE) {
  472. // Find next available channel
  473. for (uint8_t i = 0; i < channels; i++) {
  474. rotateIndex++;
  475. if (rotateIndex >= channels)
  476. rotateIndex = 0;
  477. if (!gates[rotateIndex])
  478. return rotateIndex;
  479. }
  480. // No notes are available. Advance rotateIndex once more.
  481. rotateIndex++;
  482. if (rotateIndex >= channels)
  483. rotateIndex = 0;
  484. return rotateIndex;
  485. }
  486. if (polyMode == RESET_MODE) {
  487. for (uint8_t c = 0; c < channels; c++) {
  488. if (!gates[c])
  489. return c;
  490. }
  491. return channels - 1;
  492. }
  493. if (polyMode == MPE_MODE) {
  494. // This case is handled by querying the MIDI message channel.
  495. return 0;
  496. }
  497. return 0;
  498. }
  499. void pressNote(uint8_t note, uint8_t channel, uint8_t velocity) {
  500. // Remove existing similar note
  501. heldNotes.erase(std::remove(heldNotes.begin(), heldNotes.end(), note), heldNotes.end());
  502. // Push note to end
  503. heldNotes.push_back(note);
  504. // Handle polyphony modes
  505. if (channels > 1) {
  506. if (polyMode == MPE_MODE) {
  507. // Output channel equals MIDI channel
  508. }
  509. else {
  510. channel = assignChannel(note);
  511. }
  512. }
  513. // Handle monophonic modes
  514. else {
  515. channel = 0;
  516. if (monoMode == LAST_PRIORITY_MODE) {
  517. // Always play note
  518. }
  519. if (monoMode == FIRST_PRIORITY_MODE) {
  520. if (heldNotes.size() > 1)
  521. return;
  522. }
  523. if (monoMode == LOWEST_PRIORITY_MODE) {
  524. uint8_t minNote = *std::min_element(heldNotes.begin(), heldNotes.end());
  525. if (note != minNote)
  526. return;
  527. }
  528. if (monoMode == HIGHEST_PRIORITY_MODE) {
  529. uint8_t maxNote = *std::max_element(heldNotes.begin(), heldNotes.end());
  530. if (note != maxNote)
  531. return;
  532. }
  533. }
  534. // Set note
  535. notes[channel] = note;
  536. gates[channel] = true;
  537. velocities[channel] = velocity;
  538. retriggerPulses[channel].trigger(1e-3);
  539. }
  540. /** -1 velocity means unset. */
  541. void releaseNote(uint8_t note, int8_t channel, int8_t velocity) {
  542. // Remove the note
  543. heldNotes.erase(std::remove(heldNotes.begin(), heldNotes.end(), note), heldNotes.end());
  544. // Hold note if pedal is pressed
  545. if (pedal)
  546. return;
  547. // Find output channel of released note, if any
  548. if (channels > 1 && polyMode == MPE_MODE) {
  549. // Each MPE channel must be monophonic so the output channel must be the released note channel
  550. }
  551. else {
  552. // Find channel of active note
  553. channel = -1;
  554. for (uint8_t c = 0; c < channels; c++) {
  555. if (gates[c] && notes[c] == note) {
  556. channel = c;
  557. break;
  558. }
  559. }
  560. }
  561. if (channel < 0) {
  562. // Released note is not active on any channel
  563. return;
  564. }
  565. // Deactivate note
  566. gates[channel] = false;
  567. refreshHeld();
  568. // Set velocity
  569. if (releaseVelocityEnabled && velocity >= 0) {
  570. velocities[channel] = velocity;
  571. }
  572. }
  573. /** Deactivates all notes that are not held, and reactivates notes that are. */
  574. void refreshHeld() {
  575. // Monophonic
  576. if (channels <= 1) {
  577. // Reactivate note if at least one is held
  578. if (!heldNotes.empty()) {
  579. if (monoMode == LAST_PRIORITY_MODE) {
  580. notes[0] = heldNotes.back();
  581. }
  582. if (monoMode == FIRST_PRIORITY_MODE) {
  583. notes[0] = heldNotes.front();
  584. }
  585. if (monoMode == LOWEST_PRIORITY_MODE) {
  586. notes[0] = *std::min_element(heldNotes.begin(), heldNotes.end());
  587. }
  588. if (monoMode == HIGHEST_PRIORITY_MODE) {
  589. notes[0] = *std::max_element(heldNotes.begin(), heldNotes.end());
  590. }
  591. gates[0] = true;
  592. if (retriggerOnResume) {
  593. retriggerPulses[0].trigger(1e-3);
  594. }
  595. }
  596. else {
  597. gates[0] = false;
  598. }
  599. }
  600. // Polyphonic
  601. else {
  602. // Deactivate notes that are not held
  603. for (uint8_t c = 0; c < channels; c++) {
  604. if (!gates[c])
  605. continue;
  606. // Check if note is still held
  607. bool held = std::find(heldNotes.begin(), heldNotes.end(), notes[c]) != heldNotes.end();
  608. if (!held)
  609. gates[c] = false;
  610. }
  611. }
  612. }
  613. void pressPedal() {
  614. if (pedal)
  615. return;
  616. pedal = true;
  617. }
  618. void releasePedal() {
  619. if (!pedal)
  620. return;
  621. pedal = false;
  622. refreshHeld();
  623. }
  624. uint8_t getChannels() {
  625. return channels;
  626. }
  627. void setChannels(uint8_t channels) {
  628. if (channels == this->channels)
  629. return;
  630. this->channels = channels;
  631. panic();
  632. }
  633. void setMonoMode(MonoMode monoMode) {
  634. if (monoMode == this->monoMode)
  635. return;
  636. this->monoMode = monoMode;
  637. panic();
  638. }
  639. void setPolyMode(PolyMode polyMode) {
  640. if (polyMode == this->polyMode)
  641. return;
  642. this->polyMode = polyMode;
  643. panic();
  644. }
  645. float getPitchVoltage(uint8_t channel) {
  646. uint8_t wheelChannel = (channels > 1 && polyMode == MPE_MODE) ? channel : 0;
  647. return (notes[channel] - 60.f + pwFilters[wheelChannel].out * pwRange) / 12.f;
  648. }
  649. /** Sets exponential smoothing filter lambda speed. */
  650. void setFilterLambda(float lambda) {
  651. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  652. pwFilters[c].setLambda(lambda);
  653. modFilters[c].setLambda(lambda);
  654. }
  655. }
  656. /** Returns pitch wheel value, from -1 to 1. */
  657. float getPw(uint8_t channel) {
  658. return pwFilters[channel].out;
  659. }
  660. /** Returns mod wheel value, from 0 to 1. */
  661. float getMod(uint8_t channel) {
  662. return modFilters[channel].out;
  663. }
  664. /** Returns number of polyphonic channels for pitch and mod wheels. */
  665. uint8_t getWheelChannels() {
  666. return (channels > 1 && polyMode == MPE_MODE) ? MAX_CHANNELS : 1;
  667. }
  668. json_t* toJson() {
  669. json_t* rootJ = json_object();
  670. json_object_set_new(rootJ, "channels", json_integer(channels));
  671. json_object_set_new(rootJ, "monoMode", json_integer(monoMode));
  672. json_object_set_new(rootJ, "retriggerOnResume", json_boolean(retriggerOnResume));
  673. json_object_set_new(rootJ, "polyMode", json_integer(polyMode));
  674. json_object_set_new(rootJ, "releaseVelocityEnabled", json_boolean(releaseVelocityEnabled));
  675. json_object_set_new(rootJ, "pwRange", json_real(pwRange));
  676. json_object_set_new(rootJ, "smooth", json_boolean(smooth));
  677. json_object_set_new(rootJ, "clockDivision", json_integer(clockDivision));
  678. if (channels > 1 && polyMode == MPE_MODE) {
  679. // Saving/restoring pitch and mod doesn't make much sense for MPE.
  680. }
  681. else {
  682. json_object_set_new(rootJ, "lastPw", json_integer(pws[0]));
  683. json_object_set_new(rootJ, "lastMod", json_integer(mods[0]));
  684. }
  685. // Assume all filter lambdas are the same
  686. json_object_set_new(rootJ, "filterLambda", json_real(pwFilters[0].lambda));
  687. return rootJ;
  688. }
  689. void fromJson(json_t* rootJ) {
  690. json_t* channelsJ = json_object_get(rootJ, "channels");
  691. if (channelsJ)
  692. setChannels(json_integer_value(channelsJ));
  693. json_t* monoModeJ = json_object_get(rootJ, "monoMode");
  694. if (monoModeJ)
  695. monoMode = (MonoMode) json_integer_value(monoModeJ);
  696. json_t* retriggerOnResumeJ = json_object_get(rootJ, "retriggerOnResume");
  697. if (retriggerOnResumeJ)
  698. retriggerOnResume = json_boolean_value(retriggerOnResumeJ);
  699. json_t* polyModeJ = json_object_get(rootJ, "polyMode");
  700. if (polyModeJ)
  701. polyMode = (PolyMode) json_integer_value(polyModeJ);
  702. json_t* releaseVelocityEnabledJ = json_object_get(rootJ, "releaseVelocityEnabled");
  703. if (releaseVelocityEnabledJ)
  704. releaseVelocityEnabled = json_boolean_value(releaseVelocityEnabledJ);
  705. json_t* pwRangeJ = json_object_get(rootJ, "pwRange");
  706. if (pwRangeJ)
  707. pwRange = json_number_value(pwRangeJ);
  708. json_t* smoothJ = json_object_get(rootJ, "smooth");
  709. if (smoothJ)
  710. smooth = json_boolean_value(smoothJ);
  711. json_t* clockDivisionJ = json_object_get(rootJ, "clockDivision");
  712. if (clockDivisionJ)
  713. clockDivision = json_integer_value(clockDivisionJ);
  714. json_t* lastPwJ = json_object_get(rootJ, "lastPw");
  715. if (lastPwJ)
  716. pws[0] = json_integer_value(lastPwJ);
  717. // In Rack <2.5.3, `lastPitch` was used from 0 to 16383.
  718. json_t* lastPitchJ = json_object_get(rootJ, "lastPitch");
  719. if (lastPitchJ)
  720. pws[0] = json_integer_value(lastPitchJ) - 8192;
  721. json_t* lastModJ = json_object_get(rootJ, "lastMod");
  722. if (lastModJ)
  723. mods[0] = json_integer_value(lastModJ);
  724. // Added in Rack 2.5.3
  725. json_t* filterLambdaJ = json_object_get(rootJ, "filterLambda");
  726. if (filterLambdaJ)
  727. setFilterLambda(json_number_value(filterLambdaJ));
  728. }
  729. };
  730. } // namespace dsp
  731. } // namespace rack