Example #1
0
/* 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;
    }
  }
}
Example #2
0
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 &noteEntry = 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;
        }
    }
}