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.

813 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. clock = 0;
  293. smooth = true;
  294. channels = 1;
  295. polyMode = ROTATE_MODE;
  296. monoMode = LAST_PRIORITY_MODE;
  297. retriggerOnResume = false;
  298. pwRange = 2.f;
  299. clockDivision = 24;
  300. setFilterLambda(30.f);
  301. panic();
  302. }
  303. /** Resets performance state */
  304. void panic() {
  305. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  306. // Middle C
  307. notes[c] = 60;
  308. gates[c] = false;
  309. velocities[c] = 0;
  310. aftertouches[c] = 0;
  311. pws[c] = 0;
  312. mods[c] = 0;
  313. pwFilters[c].reset();
  314. modFilters[c].reset();
  315. }
  316. pedal = false;
  317. rotateIndex = -1;
  318. heldNotes.clear();
  319. }
  320. void processFilters(float deltaTime) {
  321. uint8_t wheelChannels = getWheelChannels();
  322. for (uint8_t c = 0; c < wheelChannels; c++) {
  323. float pw = pws[c] / 8191.f;
  324. pw = math::clamp(pw, -1.f, 1.f);
  325. if (smooth)
  326. pw = pwFilters[c].process(deltaTime, pw);
  327. else
  328. pwFilters[c].out = pw;
  329. float mod = mods[c] / 127.f;
  330. mod = math::clamp(mod, 0.f, 1.f);
  331. if (smooth)
  332. mod = modFilters[c].process(deltaTime, mod);
  333. else
  334. modFilters[c].out = mod;
  335. }
  336. }
  337. void processPulses(float deltaTime) {
  338. clockPulse.process(deltaTime);
  339. clockDividerPulse.process(deltaTime);
  340. startPulse.process(deltaTime);
  341. stopPulse.process(deltaTime);
  342. continuePulse.process(deltaTime);
  343. for (uint8_t c = 0; c < channels; c++) {
  344. retriggerPulses[c].process(deltaTime);
  345. }
  346. }
  347. void processMessage(const midi::Message& msg) {
  348. // DEBUG("MIDI: %ld %s", msg.getFrame(), msg.toString().c_str());
  349. switch (msg.getStatus()) {
  350. // note off
  351. case 0x8: {
  352. releaseNote(msg.getNote(), msg.getChannel(), msg.getValue());
  353. } break;
  354. // note on
  355. case 0x9: {
  356. uint8_t velocity = msg.getValue();
  357. if (velocity > 0) {
  358. pressNote(msg.getNote(), msg.getChannel(), velocity);
  359. }
  360. else {
  361. // Note-on event with velocity 0 is an alternative for note-off event.
  362. releaseNote(msg.getNote(), msg.getChannel(), -1);
  363. }
  364. } break;
  365. // key pressure
  366. case 0xa: {
  367. // Set the aftertouches with the same note
  368. // TODO Should we handle the MPE case differently?
  369. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  370. if (notes[c] == msg.getNote())
  371. aftertouches[c] = msg.getValue();
  372. }
  373. } break;
  374. // cc
  375. case 0xb: {
  376. processCC(msg);
  377. } break;
  378. // channel pressure
  379. case 0xd: {
  380. if (channels > 1 && polyMode == MPE_MODE) {
  381. // Set the channel aftertouch
  382. aftertouches[msg.getChannel()] = msg.getNote();
  383. }
  384. else {
  385. // Set all aftertouches
  386. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  387. aftertouches[c] = msg.getNote();
  388. }
  389. }
  390. } break;
  391. // pitch wheel
  392. case 0xe: {
  393. uint8_t c = (channels > 1 && polyMode == MPE_MODE) ? msg.getChannel() : 0;
  394. int16_t pw = msg.getValue();
  395. pw <<= 7;
  396. pw |= msg.getNote();
  397. pw -= 8192;
  398. pws[c] = pw;
  399. } break;
  400. case 0xf: {
  401. processSystem(msg);
  402. } break;
  403. default: break;
  404. }
  405. }
  406. void processCC(const midi::Message& msg) {
  407. switch (msg.getNote()) {
  408. // mod
  409. case 0x01: {
  410. uint8_t c = (channels > 1 && polyMode == MPE_MODE) ? msg.getChannel() : 0;
  411. mods[c] = msg.getValue();
  412. } break;
  413. // sustain
  414. case 0x40: {
  415. if (msg.getValue() >= 64)
  416. pressPedal();
  417. else
  418. releasePedal();
  419. } break;
  420. // all notes off (panic)
  421. case 0x7b: {
  422. if (msg.getValue() == 0) {
  423. panic();
  424. }
  425. } break;
  426. default: break;
  427. }
  428. }
  429. void processSystem(const midi::Message& msg) {
  430. switch (msg.getChannel()) {
  431. // Song Position Pointer
  432. case 0x2: {
  433. int64_t pos = int64_t(msg.getNote()) | (int64_t(msg.getValue()) << 7);
  434. clock = pos * 6;
  435. } break;
  436. // Timing
  437. case 0x8: {
  438. clockPulse.trigger(1e-3);
  439. if (clock % clockDivision == 0) {
  440. clockDividerPulse.trigger(1e-3);
  441. }
  442. clock++;
  443. } break;
  444. // Start
  445. case 0xa: {
  446. startPulse.trigger(1e-3);
  447. clock = 0;
  448. } break;
  449. // Continue
  450. case 0xb: {
  451. continuePulse.trigger(1e-3);
  452. } break;
  453. // Stop
  454. case 0xc: {
  455. stopPulse.trigger(1e-3);
  456. } break;
  457. default: break;
  458. }
  459. }
  460. uint8_t assignChannel(uint8_t note) {
  461. if (channels <= 1)
  462. return 0;
  463. if (polyMode == REUSE_MODE) {
  464. // Try to find channel with the same note
  465. for (uint8_t c = 0; c < channels; c++) {
  466. if (notes[c] == note)
  467. return c;
  468. }
  469. }
  470. if (polyMode == REUSE_MODE || polyMode == ROTATE_MODE) {
  471. // Find next available channel
  472. for (uint8_t i = 0; i < channels; i++) {
  473. rotateIndex++;
  474. if (rotateIndex >= channels)
  475. rotateIndex = 0;
  476. if (!gates[rotateIndex])
  477. return rotateIndex;
  478. }
  479. // No notes are available. Advance rotateIndex once more.
  480. rotateIndex++;
  481. if (rotateIndex >= channels)
  482. rotateIndex = 0;
  483. return rotateIndex;
  484. }
  485. if (polyMode == RESET_MODE) {
  486. for (uint8_t c = 0; c < channels; c++) {
  487. if (!gates[c])
  488. return c;
  489. }
  490. return channels - 1;
  491. }
  492. if (polyMode == MPE_MODE) {
  493. // This case is handled by querying the MIDI message channel.
  494. return 0;
  495. }
  496. return 0;
  497. }
  498. void pressNote(uint8_t note, uint8_t channel, uint8_t velocity) {
  499. // Remove existing similar note
  500. heldNotes.erase(std::remove(heldNotes.begin(), heldNotes.end(), note), heldNotes.end());
  501. // Push note to end
  502. heldNotes.push_back(note);
  503. // Handle polyphony modes
  504. if (channels > 1) {
  505. if (polyMode == MPE_MODE) {
  506. // Output channel equals MIDI channel
  507. }
  508. else {
  509. channel = assignChannel(note);
  510. }
  511. }
  512. // Handle monophonic modes
  513. else {
  514. channel = 0;
  515. if (monoMode == LAST_PRIORITY_MODE) {
  516. // Always play note
  517. }
  518. if (monoMode == FIRST_PRIORITY_MODE) {
  519. if (heldNotes.size() > 1)
  520. return;
  521. }
  522. if (monoMode == LOWEST_PRIORITY_MODE) {
  523. uint8_t minNote = *std::min_element(heldNotes.begin(), heldNotes.end());
  524. if (note != minNote)
  525. return;
  526. }
  527. if (monoMode == HIGHEST_PRIORITY_MODE) {
  528. uint8_t maxNote = *std::max_element(heldNotes.begin(), heldNotes.end());
  529. if (note != maxNote)
  530. return;
  531. }
  532. }
  533. // Set note
  534. notes[channel] = note;
  535. gates[channel] = true;
  536. velocities[channel] = velocity;
  537. retriggerPulses[channel].trigger(1e-3);
  538. }
  539. /** -1 velocity means unset. */
  540. void releaseNote(uint8_t note, int8_t channel, int8_t velocity) {
  541. // Remove the note
  542. heldNotes.erase(std::remove(heldNotes.begin(), heldNotes.end(), note), heldNotes.end());
  543. // Hold note if pedal is pressed
  544. if (pedal)
  545. return;
  546. // Find output channel of released note, if any
  547. if (channels > 1 && polyMode == MPE_MODE) {
  548. // Each MPE channel must be monophonic so the output channel must be the released note channel
  549. }
  550. else {
  551. // Find channel of active note
  552. channel = -1;
  553. for (uint8_t c = 0; c < channels; c++) {
  554. if (gates[c] && notes[c] == note) {
  555. channel = c;
  556. break;
  557. }
  558. }
  559. }
  560. if (channel < 0) {
  561. // Released note is not active on any channel
  562. return;
  563. }
  564. // Deactivate note
  565. gates[channel] = false;
  566. refreshHeld();
  567. // Set velocity
  568. if (releaseVelocityEnabled && velocity >= 0) {
  569. velocities[channel] = velocity;
  570. }
  571. }
  572. /** Deactivates all notes that are not held, and reactivates notes that are. */
  573. void refreshHeld() {
  574. // Monophonic
  575. if (channels <= 1) {
  576. // Reactivate note if at least one is held
  577. if (!heldNotes.empty()) {
  578. if (monoMode == LAST_PRIORITY_MODE) {
  579. notes[0] = heldNotes.back();
  580. }
  581. if (monoMode == FIRST_PRIORITY_MODE) {
  582. notes[0] = heldNotes.front();
  583. }
  584. if (monoMode == LOWEST_PRIORITY_MODE) {
  585. notes[0] = *std::min_element(heldNotes.begin(), heldNotes.end());
  586. }
  587. if (monoMode == HIGHEST_PRIORITY_MODE) {
  588. notes[0] = *std::max_element(heldNotes.begin(), heldNotes.end());
  589. }
  590. gates[0] = true;
  591. if (retriggerOnResume) {
  592. retriggerPulses[0].trigger(1e-3);
  593. }
  594. }
  595. else {
  596. gates[0] = false;
  597. }
  598. }
  599. // Polyphonic
  600. else {
  601. // Deactivate notes that are not held
  602. for (uint8_t c = 0; c < channels; c++) {
  603. if (!gates[c])
  604. continue;
  605. // Check if note is still held
  606. bool held = std::find(heldNotes.begin(), heldNotes.end(), notes[c]) != heldNotes.end();
  607. if (!held)
  608. gates[c] = false;
  609. }
  610. }
  611. }
  612. void pressPedal() {
  613. if (pedal)
  614. return;
  615. pedal = true;
  616. }
  617. void releasePedal() {
  618. if (!pedal)
  619. return;
  620. pedal = false;
  621. refreshHeld();
  622. }
  623. uint8_t getChannels() {
  624. return channels;
  625. }
  626. void setChannels(uint8_t channels) {
  627. if (channels == this->channels)
  628. return;
  629. this->channels = channels;
  630. panic();
  631. }
  632. void setMonoMode(MonoMode monoMode) {
  633. if (monoMode == this->monoMode)
  634. return;
  635. this->monoMode = monoMode;
  636. panic();
  637. }
  638. void setPolyMode(PolyMode polyMode) {
  639. if (polyMode == this->polyMode)
  640. return;
  641. this->polyMode = polyMode;
  642. panic();
  643. }
  644. float getPitchVoltage(uint8_t channel) {
  645. uint8_t wheelChannel = (channels > 1 && polyMode == MPE_MODE) ? channel : 0;
  646. return (notes[channel] - 60.f + pwFilters[wheelChannel].out * pwRange) / 12.f;
  647. }
  648. /** Sets exponential smoothing filter lambda speed. */
  649. void setFilterLambda(float lambda) {
  650. for (uint8_t c = 0; c < MAX_CHANNELS; c++) {
  651. pwFilters[c].setLambda(lambda);
  652. modFilters[c].setLambda(lambda);
  653. }
  654. }
  655. /** Returns pitch wheel value, from -1 to 1. */
  656. float getPw(uint8_t channel) {
  657. return pwFilters[channel].out;
  658. }
  659. /** Returns mod wheel value, from 0 to 1. */
  660. float getMod(uint8_t channel) {
  661. return modFilters[channel].out;
  662. }
  663. /** Returns number of polyphonic channels for pitch and mod wheels. */
  664. uint8_t getWheelChannels() {
  665. return (channels > 1 && polyMode == MPE_MODE) ? MAX_CHANNELS : 1;
  666. }
  667. json_t* toJson() {
  668. json_t* rootJ = json_object();
  669. json_object_set_new(rootJ, "channels", json_integer(channels));
  670. json_object_set_new(rootJ, "monoMode", json_integer(monoMode));
  671. json_object_set_new(rootJ, "retriggerOnResume", json_boolean(retriggerOnResume));
  672. json_object_set_new(rootJ, "polyMode", json_integer(polyMode));
  673. json_object_set_new(rootJ, "releaseVelocityEnabled", json_boolean(releaseVelocityEnabled));
  674. json_object_set_new(rootJ, "pwRange", json_real(pwRange));
  675. json_object_set_new(rootJ, "smooth", json_boolean(smooth));
  676. json_object_set_new(rootJ, "clockDivision", json_integer(clockDivision));
  677. if (channels > 1 && polyMode == MPE_MODE) {
  678. // Saving/restoring pitch and mod doesn't make much sense for MPE.
  679. }
  680. else {
  681. json_object_set_new(rootJ, "lastPw", json_integer(pws[0]));
  682. json_object_set_new(rootJ, "lastMod", json_integer(mods[0]));
  683. }
  684. // Assume all filter lambdas are the same
  685. json_object_set_new(rootJ, "filterLambda", json_real(pwFilters[0].lambda));
  686. return rootJ;
  687. }
  688. void fromJson(json_t* rootJ) {
  689. json_t* channelsJ = json_object_get(rootJ, "channels");
  690. if (channelsJ)
  691. setChannels(json_integer_value(channelsJ));
  692. json_t* monoModeJ = json_object_get(rootJ, "monoMode");
  693. if (monoModeJ)
  694. monoMode = (MonoMode) json_integer_value(monoModeJ);
  695. json_t* retriggerOnResumeJ = json_object_get(rootJ, "retriggerOnResume");
  696. if (retriggerOnResumeJ)
  697. retriggerOnResume = json_boolean_value(retriggerOnResumeJ);
  698. json_t* polyModeJ = json_object_get(rootJ, "polyMode");
  699. if (polyModeJ)
  700. polyMode = (PolyMode) json_integer_value(polyModeJ);
  701. json_t* releaseVelocityEnabledJ = json_object_get(rootJ, "releaseVelocityEnabled");
  702. if (releaseVelocityEnabledJ)
  703. releaseVelocityEnabled = json_boolean_value(releaseVelocityEnabledJ);
  704. json_t* pwRangeJ = json_object_get(rootJ, "pwRange");
  705. if (pwRangeJ)
  706. pwRange = json_number_value(pwRangeJ);
  707. json_t* smoothJ = json_object_get(rootJ, "smooth");
  708. if (smoothJ)
  709. smooth = json_boolean_value(smoothJ);
  710. json_t* clockDivisionJ = json_object_get(rootJ, "clockDivision");
  711. if (clockDivisionJ)
  712. clockDivision = json_integer_value(clockDivisionJ);
  713. json_t* lastPwJ = json_object_get(rootJ, "lastPw");
  714. if (lastPwJ)
  715. pws[0] = json_integer_value(lastPwJ);
  716. // In Rack <2.5.3, `lastPitch` was used from 0 to 16383.
  717. json_t* lastPitchJ = json_object_get(rootJ, "lastPitch");
  718. if (lastPitchJ)
  719. pws[0] = json_integer_value(lastPitchJ) - 8192;
  720. json_t* lastModJ = json_object_get(rootJ, "lastMod");
  721. if (lastModJ)
  722. mods[0] = json_integer_value(lastModJ);
  723. // Added in Rack 2.5.3
  724. json_t* filterLambdaJ = json_object_get(rootJ, "filterLambda");
  725. if (filterLambdaJ)
  726. setFilterLambda(json_number_value(filterLambdaJ));
  727. }
  728. };
  729. } // namespace dsp
  730. } // namespace rack