/* static */ void Arpeggiator::Tick() { ++tick_; if (note_stack.size()) { idle_ticks_ = 0; } ++idle_ticks_; if (idle_ticks_ >= 96) { idle_ticks_ = 96; } app.SendScheduledNotes(channel_); if (tick_ >= midi_clock_prescaler_) { tick_ = 0; uint16_t pattern = ResourcesManager::Lookup<uint16_t, uint8_t>( lut_res_arpeggiator_patterns, pattern_); uint8_t has_arpeggiator_note = (bitmask_ & pattern) ? 255 : 0; if (note_stack.size() && has_arpeggiator_note) { uint8_t note = note_stack.sorted_note(current_step_).note; uint8_t velocity = note_stack.sorted_note(current_step_).velocity; note += 12 * current_octave_; while (note > 127) { note -= 12; } // If there are some Note Off messages for the note about to be triggeered // remove them from the queue and process them now. if (event_scheduler.Remove(note, 0)) { app.Send3(0x80 | channel_, note, 0); } // Send a note on and schedule a note off later. app.Send3(0x90 | channel_, note, velocity); app.SendLater(note, 0, ResourcesManager::Lookup<uint8_t, uint8_t>( midi_clock_tick_per_step, duration_) - 1); StepArpeggio(); } bitmask_ <<= 1; if (!bitmask_) { bitmask_ = 1; } } }
void Timbre::Tick() { ++tick_; if (note_stack.size()) { idle_ticks_ = 0; } ++idle_ticks_; if (idle_ticks_ >= 96) { idle_ticks_ = 96; if (params.engineArp1.clock == CLOCK_INTERNAL) { running_ = 0; FlushQueue(); } } SendScheduledNotes(); if (tick_ >= midi_clock_tick_per_step[(int)params.engineArp2.division]) { tick_ = 0; uint16_t pattern = getArpeggiatorPattern(); uint8_t has_arpeggiator_note = (bitmask_ & pattern) ? 255 : 0; const int num_notes = note_stack.size(); const int direction = params.engineArp1.direction; if (num_notes && has_arpeggiator_note) { if ( ARPEGGIO_DIRECTION_CHORD != direction ) { StepArpeggio(); int step, transpose = 0; if ( current_direction_ > 0 ) { step = start_step_ + current_step_; if ( step >= num_notes ) { step -= num_notes; transpose = 12; } } else { step = (num_notes - 1) - (start_step_ + current_step_); if ( step < 0 ) { step += num_notes; transpose = -12; } } #ifdef DEBUG_ARP_STEP lcd.setRealTimeAction(true); lcd.setCursor(16,0); lcd.print( current_direction_ > 0 ? '+' : '-' ); lcd.print( step ); lcd.setRealTimeAction(false); #endif const NoteEntry ¬eEntry = ARPEGGIO_DIRECTION_PLAYED == direction ? note_stack.played_note(step) : note_stack.sorted_note(step); uint8_t note = noteEntry.note; uint8_t velocity = noteEntry.velocity; note += 12 * current_octave_; if ( __canTranspose( direction ) ) note += transpose; while (note > 127) { note -= 12; } SendNote(note, velocity); } else { for (int i = 0; i < note_stack.size(); ++i ) { const NoteEntry& noteEntry = note_stack.sorted_note(i); SendNote(noteEntry.note, noteEntry.velocity); } } } bitmask_ <<= 1; if (!bitmask_) { bitmask_ = 1; } } }