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.

723 lines
22KB

  1. // Copyright 2013 Olivier Gillet.
  2. //
  3. // Author: Olivier Gillet (ol.gillet@gmail.com)
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. // See http://creativecommons.org/licenses/MIT/ for more information.
  24. //
  25. // -----------------------------------------------------------------------------
  26. //
  27. // Part.
  28. #include "yarns/part.h"
  29. #include <algorithm>
  30. #include "stmlib/midi/midi.h"
  31. #include "stmlib/utils/random.h"
  32. #include "yarns/just_intonation_processor.h"
  33. #include "yarns/midi_handler.h"
  34. #include "yarns/resources.h"
  35. #include "yarns/voice.h"
  36. namespace yarns {
  37. const uint8_t clock_divisions[] = {
  38. 96, 48, 32, 24, 16, 12, 8, 6, 4, 3, 2, 1
  39. };
  40. using namespace stmlib;
  41. using namespace stmlib_midi;
  42. using namespace std;
  43. void Part::Init() {
  44. pressed_keys_.Init();
  45. mono_allocator_.Init();
  46. poly_allocator_.Init();
  47. generated_notes_.Init();
  48. std::fill(
  49. &active_note_[0],
  50. &active_note_[kMaxNumVoices],
  51. VOICE_ALLOCATION_NOT_FOUND);
  52. num_voices_ = 0;
  53. polychained_ = false;
  54. ignore_note_off_messages_ = false;
  55. seq_recording_ = false;
  56. seq_running_ = false;
  57. release_latched_keys_on_next_note_on_ = false;
  58. }
  59. void Part::AllocateVoices(Voice* voice, uint8_t num_voices, bool polychain) {
  60. AllNotesOff();
  61. num_voices_ = std::min(num_voices, kMaxNumVoices);
  62. polychained_ = polychain;
  63. for (uint8_t i = 0; i < num_voices_; ++i) {
  64. voice_[i] = voice + i;
  65. }
  66. poly_allocator_.Clear();
  67. poly_allocator_.set_size(num_voices_ * (polychain ? 2 : 1));
  68. TouchVoices();
  69. }
  70. bool Part::NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
  71. bool sent_from_step_editor = channel & 0x80;
  72. if (release_latched_keys_on_next_note_on_) {
  73. bool still_latched = ignore_note_off_messages_;
  74. // Releasing all latched key will generate "fake" NoteOff messages. We
  75. // should note ignore them.
  76. ignore_note_off_messages_ = false;
  77. ReleaseLatchedNotes();
  78. release_latched_keys_on_next_note_on_ = still_latched;
  79. ignore_note_off_messages_ = still_latched;
  80. }
  81. pressed_keys_.NoteOn(note, velocity);
  82. if ((!(seq_.num_steps && seq_running_) && !seq_.arp_range)
  83. || sent_from_step_editor) {
  84. InternalNoteOn(note, velocity);
  85. }
  86. if (seq_recording_ && !sent_from_step_editor) {
  87. RecordStep(SequencerStep(note, velocity));
  88. }
  89. return midi_.out_mode == MIDI_OUT_MODE_THRU && !polychained_;
  90. }
  91. bool Part::NoteOff(uint8_t channel, uint8_t note) {
  92. bool sent_from_step_editor = channel & 0x80;
  93. if (ignore_note_off_messages_) {
  94. for (uint8_t i = 1; i <= pressed_keys_.max_size(); ++i) {
  95. // Flag the note so that it is removed once the sustain pedal is released.
  96. NoteEntry* e = pressed_keys_.mutable_note(i);
  97. if (e->note == note && e->velocity) {
  98. e->velocity |= 0x80;
  99. }
  100. }
  101. } else {
  102. pressed_keys_.NoteOff(note);
  103. if ((!(seq_.num_steps && seq_running_) && !seq_.arp_range) ||
  104. sent_from_step_editor) {
  105. InternalNoteOff(note);
  106. }
  107. }
  108. return midi_.out_mode == MIDI_OUT_MODE_THRU && !polychained_;
  109. }
  110. bool Part::ControlChange(uint8_t channel, uint8_t controller, uint8_t value) {
  111. switch (controller) {
  112. case kCCModulationWheelMsb:
  113. case kCCBreathController:
  114. case kCCFootPedalMsb:
  115. for (uint8_t i = 0; i < num_voices_; ++i) {
  116. voice_[i]->ControlChange(controller, value);
  117. }
  118. break;
  119. case kCCOmniModeOff:
  120. midi_.channel = channel;
  121. break;
  122. case kCCOmniModeOn:
  123. midi_.channel = 0x10;
  124. break;
  125. case kCCMonoModeOn:
  126. voicing_.allocation_mode = VOICE_ALLOCATION_MODE_MONO;
  127. TouchVoiceAllocation();
  128. break;
  129. case kCCPolyModeOn:
  130. voicing_.allocation_mode = VOICE_ALLOCATION_MODE_POLY;
  131. TouchVoiceAllocation();
  132. break;
  133. case kCCHoldPedal:
  134. {
  135. if (value >= 64) {
  136. ignore_note_off_messages_ = true;
  137. } else {
  138. ignore_note_off_messages_ = false;
  139. ReleaseLatchedNotes();
  140. }
  141. }
  142. break;
  143. case 0x70:
  144. if (seq_recording_) {
  145. RecordStep(SEQUENCER_STEP_TIE);
  146. }
  147. break;
  148. case 0x71:
  149. if (seq_recording_) {
  150. RecordStep(SEQUENCER_STEP_REST);
  151. }
  152. break;
  153. case 0x78:
  154. AllNotesOff();
  155. break;
  156. case 0x79:
  157. ResetAllControllers();
  158. break;
  159. case 0x7b:
  160. AllNotesOff();
  161. break;
  162. }
  163. return midi_.out_mode != MIDI_OUT_MODE_OFF;
  164. }
  165. bool Part::PitchBend(uint8_t channel, uint16_t pitch_bend) {
  166. for (uint8_t i = 0; i < num_voices_; ++i) {
  167. voice_[i]->PitchBend(pitch_bend);
  168. }
  169. if (seq_recording_ &&
  170. (pitch_bend > 8192 + 2048 || pitch_bend < 8192 - 2048)) {
  171. seq_.step[seq_rec_step_].data[1] |= 0x80;
  172. }
  173. return midi_.out_mode != MIDI_OUT_MODE_OFF;
  174. }
  175. bool Part::Aftertouch(uint8_t channel, uint8_t note, uint8_t velocity) {
  176. if (voicing_.allocation_mode != VOICE_ALLOCATION_MODE_MONO) {
  177. uint8_t voice_index = \
  178. voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY ? \
  179. poly_allocator_.Find(note) : \
  180. FindVoiceForNote(note);
  181. if (voice_index < poly_allocator_.size()) {
  182. voice_[voice_index]->Aftertouch(velocity);
  183. }
  184. } else {
  185. Aftertouch(channel, velocity);
  186. }
  187. return midi_.out_mode != MIDI_OUT_MODE_OFF;
  188. }
  189. bool Part::Aftertouch(uint8_t channel, uint8_t velocity) {
  190. for (uint8_t i = 0; i < num_voices_; ++i) {
  191. voice_[i]->Aftertouch(velocity);
  192. }
  193. return midi_.out_mode != MIDI_OUT_MODE_OFF;
  194. }
  195. void Part::Reset() {
  196. Stop();
  197. for (uint8_t i = 0; i < num_voices_; ++i) {
  198. voice_[i]->NoteOff();
  199. voice_[i]->ResetAllControllers();
  200. }
  201. }
  202. void Part::Clock() {
  203. if (!arp_seq_prescaler_) {
  204. if (seq_.num_steps && seq_running_) {
  205. ClockSequencer();
  206. } else if (seq_.arp_range) {
  207. ClockArpeggiator();
  208. }
  209. }
  210. if (!gate_length_counter_ && generated_notes_.size()) {
  211. StopSequencerArpeggiatorNotes();
  212. } else {
  213. --gate_length_counter_;
  214. }
  215. ++arp_seq_prescaler_;
  216. if (arp_seq_prescaler_ >= clock_divisions[seq_.clock_division]) {
  217. arp_seq_prescaler_ = 0;
  218. }
  219. if (voicing_.modulation_rate >= 100) {
  220. uint32_t num_ticks = clock_divisions[voicing_.modulation_rate - 100];
  221. uint32_t expected_phase = (lfo_counter_ % num_ticks) * 65536 / num_ticks;
  222. for (uint8_t i = 0; i < num_voices_; ++i) {
  223. voice_[i]->TapLfo(expected_phase << 16);
  224. }
  225. }
  226. ++lfo_counter_;
  227. }
  228. void Part::Start(bool started_by_keyboard) {
  229. arp_seq_prescaler_ = 0;
  230. seq_step_ = 0;
  231. seq_running_ = !started_by_keyboard;
  232. release_latched_keys_on_next_note_on_ = false;
  233. ignore_note_off_messages_ = false;
  234. if (seq_.arp_direction == ARPEGGIATOR_DIRECTION_DOWN) {
  235. arp_note_ = pressed_keys_.size() - 1;
  236. arp_octave_ = seq_.arp_range - 1;
  237. arp_direction_ = -1;
  238. } else {
  239. arp_note_ = 0;
  240. arp_octave_ = 0;
  241. arp_direction_ = 1;
  242. }
  243. arp_step_ = 0;
  244. lfo_counter_ = 0;
  245. generated_notes_.Clear();
  246. }
  247. void Part::Stop() {
  248. seq_running_ = false;
  249. StopSequencerArpeggiatorNotes();
  250. AllNotesOff();
  251. }
  252. void Part::StartRecording() {
  253. if (seq_recording_) {
  254. return;
  255. }
  256. seq_recording_ = true;
  257. seq_rec_step_ = 0;
  258. seq_overdubbing_ = seq_.num_steps && seq_running_;
  259. if (!seq_overdubbing_) {
  260. std::fill(
  261. &seq_.step[0],
  262. &seq_.step[kNumSteps],
  263. SequencerStep(SEQUENCER_STEP_REST, 0));
  264. seq_.num_steps = 0;
  265. }
  266. }
  267. void Part::StopSequencerArpeggiatorNotes() {
  268. while (generated_notes_.size()) {
  269. uint8_t note = generated_notes_.sorted_note(0).note;
  270. generated_notes_.NoteOff(note);
  271. InternalNoteOff(note);
  272. }
  273. }
  274. void Part::ClockSequencer() {
  275. const SequencerStep& step = seq_.step[seq_step_];
  276. if (step.has_note()) {
  277. int16_t note = step.note();
  278. if (pressed_keys_.size() && !seq_recording_) {
  279. // When we play a monophonic sequence, we can make the guess that root
  280. // note = first note.
  281. // But this is not the case when we are playing several sequences at the
  282. // same time. In this case, we use root note = 60.
  283. int8_t root_note = !has_siblings_ ? seq_.first_note() : 60;
  284. note += pressed_keys_.most_recent_note().note - root_note;
  285. while (note > 127) {
  286. note -= 12;
  287. }
  288. while (note < 0) {
  289. note += 12;
  290. }
  291. }
  292. if (!step.is_slid()) {
  293. StopSequencerArpeggiatorNotes();
  294. InternalNoteOn(note, step.velocity());
  295. } else {
  296. InternalNoteOn(note, step.velocity());
  297. StopSequencerArpeggiatorNotes();
  298. }
  299. generated_notes_.NoteOn(note, step.velocity());
  300. gate_length_counter_ = seq_.gate_length;
  301. }
  302. ++seq_step_;
  303. if (seq_step_ >= seq_.num_steps) {
  304. seq_step_ = 0;
  305. }
  306. if (seq_.step[seq_step_].is_tie() || seq_.step[seq_step_].is_slid()) {
  307. // The next step contains a "sustain" message; or a slid note. Extends
  308. // the duration of the current note.
  309. gate_length_counter_ += clock_divisions[seq_.clock_division];
  310. }
  311. }
  312. void Part::ClockArpeggiator() {
  313. uint32_t pattern_mask = 1 << arp_step_;
  314. uint32_t pattern = lut_arpeggiator_patterns[seq_.arp_pattern];
  315. uint32_t pattern_length = 16;
  316. if (seq_.euclidean_length != 0) {
  317. pattern_length = seq_.euclidean_length;
  318. pattern_mask = 1 << ((arp_step_ + seq_.euclidean_rotate) % pattern_length);
  319. // Read euclidean pattern from ROM.
  320. uint16_t offset = static_cast<uint16_t>(seq_.euclidean_length - 1) * 32;
  321. pattern = lut_euclidean[offset + seq_.euclidean_fill];
  322. }
  323. uint8_t num_notes = pressed_keys_.size();
  324. if ((pattern_mask & pattern) && num_notes) {
  325. // Update arepggiator note/octave counter.
  326. if (num_notes == 1 && seq_.arp_range == 1) {
  327. // This is a corner case for the Up/down pattern code.
  328. // Get it out of the way.
  329. arp_note_ = 0;
  330. arp_octave_ = 0;
  331. } else {
  332. if (seq_.arp_direction == ARPEGGIATOR_DIRECTION_RANDOM) {
  333. uint16_t random = Random::GetSample();
  334. arp_octave_ = (random & 0xff) % seq_.arp_range;
  335. arp_note_ = (random >> 8) % num_notes;
  336. } else {
  337. bool wrapped = true;
  338. while (wrapped) {
  339. if (arp_note_ >= num_notes || arp_note_ < 0) {
  340. arp_octave_ += arp_direction_;
  341. arp_note_ = arp_direction_ > 0 ? 0 : num_notes - 1;
  342. }
  343. wrapped = false;
  344. if (arp_octave_ >= seq_.arp_range || arp_octave_ < 0) {
  345. arp_octave_ = arp_direction_ > 0 ? 0 : seq_.arp_range - 1;
  346. if (seq_.arp_direction == ARPEGGIATOR_DIRECTION_UP_DOWN) {
  347. arp_direction_ = -arp_direction_;
  348. arp_note_ = arp_direction_ > 0 ? 1 : num_notes - 2;
  349. arp_octave_ = arp_direction_ > 0 ? 0 : seq_.arp_range - 1;
  350. wrapped = true;
  351. }
  352. }
  353. }
  354. }
  355. }
  356. // Kill pending notes (if any).
  357. StopSequencerArpeggiatorNotes();
  358. // Trigger arpeggiated note or chord.
  359. if (seq_.arp_direction != ARPEGGIATOR_DIRECTION_CHORD) {
  360. const NoteEntry* arpeggio_note = \
  361. seq_.arp_direction == ARPEGGIATOR_DIRECTION_AS_PLAYED ?
  362. &pressed_keys_.played_note(arp_note_) :
  363. &pressed_keys_.sorted_note(arp_note_);
  364. uint8_t note = arpeggio_note->note;
  365. uint8_t velocity = arpeggio_note->velocity & 0x7f;
  366. note += 12 * arp_octave_;
  367. while (note > 127) {
  368. note -= 12;
  369. }
  370. generated_notes_.NoteOn(note, velocity);
  371. InternalNoteOn(note, velocity);
  372. } else {
  373. for (uint8_t i = 0; i < num_notes; ++i) {
  374. const NoteEntry& chord_note = pressed_keys_.played_note(i);
  375. generated_notes_.NoteOn(chord_note.note, chord_note.velocity & 0x7f);
  376. InternalNoteOn(chord_note.note, chord_note.velocity & 0x7f);
  377. }
  378. }
  379. arp_note_ += arp_direction_;
  380. gate_length_counter_ = seq_.gate_length;
  381. }
  382. ++arp_step_;
  383. if (arp_step_ >= pattern_length) {
  384. arp_step_ = 0;
  385. }
  386. }
  387. void Part::ResetAllControllers() {
  388. ignore_note_off_messages_ = false;
  389. for (uint8_t i = 0; i < num_voices_; ++i) {
  390. voice_[i]->ResetAllControllers();
  391. }
  392. }
  393. void Part::AllNotesOff() {
  394. poly_allocator_.ClearNotes();
  395. mono_allocator_.Clear();
  396. pressed_keys_.Clear();
  397. for (uint8_t i = 0; i < num_voices_; ++i) {
  398. voice_[i]->NoteOff();
  399. }
  400. std::fill(
  401. &active_note_[0],
  402. &active_note_[kMaxNumVoices],
  403. VOICE_ALLOCATION_NOT_FOUND);
  404. release_latched_keys_on_next_note_on_ = false;
  405. ignore_note_off_messages_ = false;
  406. }
  407. void Part::ReleaseLatchedNotes() {
  408. for (uint8_t i = 1; i <= pressed_keys_.max_size(); ++i) {
  409. NoteEntry* e = pressed_keys_.mutable_note(i);
  410. if (e->velocity & 0x80) {
  411. NoteOff(tx_channel(), e->note);
  412. }
  413. }
  414. }
  415. void Part::DispatchSortedNotes(bool unison) {
  416. uint8_t n = mono_allocator_.size();
  417. for (uint8_t i = 0; i < num_voices_; ++i) {
  418. uint8_t index = 0xff;
  419. if (unison) {
  420. index = n ? (i * n / num_voices_) : 0xff;
  421. } else {
  422. index = i < mono_allocator_.size() ? i : 0xff;
  423. }
  424. if (index != 0xff) {
  425. voice_[i]->NoteOn(
  426. Tune(mono_allocator_.sorted_note(index).note),
  427. mono_allocator_.sorted_note(index).velocity,
  428. voicing_.portamento,
  429. !voice_[i]->gate_on());
  430. active_note_[i] = mono_allocator_.sorted_note(index).note;
  431. } else {
  432. voice_[i]->NoteOff();
  433. active_note_[i] = VOICE_ALLOCATION_NOT_FOUND;
  434. }
  435. }
  436. }
  437. void Part::InternalNoteOn(uint8_t note, uint8_t velocity) {
  438. if (midi_.out_mode == MIDI_OUT_MODE_GENERATED_EVENTS && !polychained_) {
  439. midi_handler.OnInternalNoteOn(tx_channel(), note, velocity);
  440. }
  441. if (voicing_.allocation_mode == VOICE_ALLOCATION_MODE_MONO) {
  442. const NoteEntry& before = mono_allocator_.note_by_priority(
  443. static_cast<NoteStackFlags>(voicing_.allocation_priority));
  444. mono_allocator_.NoteOn(note, velocity);
  445. const NoteEntry& after = mono_allocator_.note_by_priority(
  446. static_cast<NoteStackFlags>(voicing_.allocation_priority));
  447. // Check if the note that has been played should be triggered according
  448. // to selected voice priority rules.
  449. if (before.note != after.note) {
  450. bool legato = mono_allocator_.size() > 1;
  451. for (uint8_t i = 0; i < num_voices_; ++i) {
  452. voice_[i]->NoteOn(
  453. Tune(after.note),
  454. after.velocity,
  455. !voicing_.legato_mode || legato ? voicing_.portamento : 0,
  456. !voicing_.legato_mode || !legato);
  457. }
  458. }
  459. } else if (voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_SORTED ||
  460. voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_UNISON_1 ||
  461. voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_UNISON_2) {
  462. mono_allocator_.NoteOn(note, velocity);
  463. DispatchSortedNotes(
  464. voicing_.allocation_mode != VOICE_ALLOCATION_MODE_POLY_SORTED);
  465. } else {
  466. uint8_t voice_index = 0;
  467. switch (voicing_.allocation_mode) {
  468. case VOICE_ALLOCATION_MODE_POLY:
  469. voice_index = poly_allocator_.NoteOn(note);
  470. break;
  471. case VOICE_ALLOCATION_MODE_POLY_CYCLIC:
  472. if (cyclic_allocation_note_counter_ >= num_voices_) {
  473. cyclic_allocation_note_counter_ = 0;
  474. }
  475. voice_index = cyclic_allocation_note_counter_;
  476. ++cyclic_allocation_note_counter_;
  477. break;
  478. case VOICE_ALLOCATION_MODE_POLY_RANDOM:
  479. voice_index = (Random::GetWord() >> 24) % num_voices_;
  480. break;
  481. case VOICE_ALLOCATION_MODE_POLY_VELOCITY:
  482. voice_index = (static_cast<uint16_t>(velocity) * num_voices_) >> 7;
  483. break;
  484. default:
  485. break;
  486. }
  487. if (voice_index < num_voices_) {
  488. // Prevent the same note from being simultaneously played on two channels.
  489. KillAllInstancesOfNote(note);
  490. voice_[voice_index]->NoteOn(
  491. Tune(note),
  492. velocity,
  493. voicing_.portamento,
  494. true);
  495. active_note_[voice_index] = note;
  496. } else {
  497. // Polychaining forwarding.
  498. midi_handler.OnInternalNoteOn(tx_channel(), note, velocity);
  499. }
  500. }
  501. }
  502. void Part::KillAllInstancesOfNote(uint8_t note) {
  503. while (true) {
  504. uint8_t index = FindVoiceForNote(note);
  505. if (index != VOICE_ALLOCATION_NOT_FOUND) {
  506. voice_[index]->NoteOff();
  507. active_note_[index] = VOICE_ALLOCATION_NOT_FOUND;
  508. } else {
  509. break;
  510. }
  511. }
  512. }
  513. void Part::InternalNoteOff(uint8_t note) {
  514. if (midi_.out_mode == MIDI_OUT_MODE_GENERATED_EVENTS && !polychained_) {
  515. midi_handler.OnInternalNoteOff(tx_channel(), note);
  516. }
  517. if (voicing_.tuning_system == TUNING_SYSTEM_JUST_INTONATION) {
  518. just_intonation_processor.NoteOff(note);
  519. }
  520. if (voicing_.allocation_mode == VOICE_ALLOCATION_MODE_MONO) {
  521. const NoteEntry& before = mono_allocator_.note_by_priority(
  522. static_cast<NoteStackFlags>(voicing_.allocation_priority));
  523. mono_allocator_.NoteOff(note);
  524. const NoteEntry& after = mono_allocator_.note_by_priority(
  525. static_cast<NoteStackFlags>(voicing_.allocation_priority));
  526. if (mono_allocator_.size() == 0) {
  527. // No key is pressed, we just close the gate.
  528. for (uint8_t i = 0; i < num_voices_; ++i) {
  529. voice_[i]->NoteOff();
  530. }
  531. } else if (before.note != after.note) {
  532. // Removing the note gives priority to another note that is still being
  533. // pressed. Slide to this note (or retrigger is legato mode is off).
  534. for (uint8_t i = 0; i < num_voices_; ++i) {
  535. voice_[i]->NoteOn(
  536. Tune(after.note),
  537. after.velocity,
  538. voicing_.portamento,
  539. !voicing_.legato_mode);
  540. }
  541. }
  542. } else if (voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_SORTED ||
  543. voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_UNISON_1 ||
  544. voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_UNISON_2) {
  545. mono_allocator_.NoteOff(note);
  546. KillAllInstancesOfNote(note);
  547. if (voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY_UNISON_1) {
  548. DispatchSortedNotes(true);
  549. }
  550. } else {
  551. uint8_t voice_index = \
  552. voicing_.allocation_mode == VOICE_ALLOCATION_MODE_POLY ? \
  553. poly_allocator_.NoteOff(note) : \
  554. FindVoiceForNote(note);
  555. if (voice_index < num_voices_) {
  556. voice_[voice_index]->NoteOff();
  557. active_note_[voice_index] = VOICE_ALLOCATION_NOT_FOUND;
  558. } else {
  559. midi_handler.OnInternalNoteOff(tx_channel(), note);
  560. }
  561. }
  562. }
  563. void Part::TouchVoiceAllocation() {
  564. AllNotesOff();
  565. ResetAllControllers();
  566. }
  567. void Part::TouchVoices() {
  568. CONSTRAIN(voicing_.aux_cv, 0, 7);
  569. CONSTRAIN(voicing_.aux_cv_2, 0, 7);
  570. for (uint8_t i = 0; i < num_voices_; ++i) {
  571. voice_[i]->set_pitch_bend_range(voicing_.pitch_bend_range);
  572. voice_[i]->set_modulation_rate(voicing_.modulation_rate);
  573. voice_[i]->set_vibrato_range(voicing_.vibrato_range);
  574. voice_[i]->set_trigger_duration(voicing_.trigger_duration);
  575. voice_[i]->set_trigger_scale(voicing_.trigger_scale);
  576. voice_[i]->set_trigger_shape(voicing_.trigger_shape);
  577. voice_[i]->set_aux_cv(voicing_.aux_cv);
  578. voice_[i]->set_aux_cv_2(voicing_.aux_cv_2);
  579. voice_[i]->set_audio_mode(voicing_.audio_mode);
  580. voice_[i]->set_tuning(voicing_.tuning_transpose, voicing_.tuning_fine);
  581. }
  582. }
  583. void Part::Set(uint8_t address, uint8_t value) {
  584. uint8_t* bytes;
  585. bytes = static_cast<uint8_t*>(static_cast<void*>(&midi_));
  586. uint8_t previous_value = bytes[address];
  587. bytes[address] = value;
  588. if (value != previous_value) {
  589. switch (address) {
  590. case PART_MIDI_CHANNEL:
  591. case PART_MIDI_MIN_NOTE:
  592. case PART_MIDI_MAX_NOTE:
  593. case PART_MIDI_MIN_VELOCITY:
  594. case PART_MIDI_MAX_VELOCITY:
  595. // Shut all channels off when a MIDI parameter is changed to prevent
  596. // stuck notes.
  597. AllNotesOff();
  598. break;
  599. case PART_VOICING_ALLOCATION_MODE:
  600. TouchVoiceAllocation();
  601. break;
  602. case PART_VOICING_PITCH_BEND_RANGE:
  603. case PART_VOICING_MODULATION_RATE:
  604. case PART_VOICING_VIBRATO_RANGE:
  605. case PART_VOICING_TRIGGER_DURATION:
  606. case PART_VOICING_TRIGGER_SHAPE:
  607. case PART_VOICING_TRIGGER_SCALE:
  608. case PART_VOICING_AUX_CV:
  609. case PART_VOICING_AUX_CV_2:
  610. case PART_VOICING_AUDIO_MODE:
  611. case PART_VOICING_TUNING_TRANSPOSE:
  612. case PART_VOICING_TUNING_FINE:
  613. TouchVoices();
  614. break;
  615. case PART_SEQUENCER_ARP_DIRECTION:
  616. arp_direction_ = \
  617. seq_.arp_direction == ARPEGGIATOR_DIRECTION_DOWN ? -1 : 1;
  618. break;
  619. }
  620. }
  621. }
  622. int16_t Part::Tune(int16_t midi_note) {
  623. int16_t note = midi_note;
  624. int16_t pitch = note << 7;
  625. uint8_t pitch_class = (note + 240) % 12;
  626. // Just intonation.
  627. if (voicing_.tuning_system == TUNING_SYSTEM_JUST_INTONATION) {
  628. pitch = just_intonation_processor.NoteOn(note);
  629. } else if (voicing_.tuning_system == TUNING_SYSTEM_CUSTOM) {
  630. pitch += custom_pitch_table_[pitch_class];
  631. } else if (voicing_.tuning_system > TUNING_SYSTEM_JUST_INTONATION) {
  632. note -= voicing_.tuning_root;
  633. pitch_class = (note + 240) % 12;
  634. pitch += lookup_table_signed_table[LUT_SCALE_PYTHAGOREAN + \
  635. voicing_.tuning_system - TUNING_SYSTEM_PYTHAGOREAN][pitch_class];
  636. }
  637. return pitch;
  638. }
  639. } // namespace yarns