| 107 | } |
| 108 | |
| 109 | bool process(const ProcessArgs& args, std::vector<rack::engine::Output>& outputs, |
| 110 | const bool velocityMode, int8_t learnedNotes[18], const bool isBypassed) |
| 111 | { |
| 112 | // Cardinal specific |
| 113 | const uint32_t processCounter = pcontext->processCounter; |
| 114 | const bool processCounterChanged = lastProcessCounter != processCounter; |
| 115 | |
| 116 | if (processCounterChanged) |
| 117 | { |
| 118 | lastProcessCounter = processCounter; |
| 119 | midiEvents = pcontext->midiEvents; |
| 120 | midiEventsLeft = pcontext->midiEventCount; |
| 121 | midiEventFrame = 0; |
| 122 | } |
| 123 | |
| 124 | if (isBypassed) |
| 125 | { |
| 126 | ++midiEventFrame; |
| 127 | return processCounterChanged; |
| 128 | } |
| 129 | |
| 130 | while (midiEventsLeft != 0) |
| 131 | { |
| 132 | const MidiEvent& midiEvent(*midiEvents); |
| 133 | |
| 134 | if (midiEvent.frame > midiEventFrame) |
| 135 | break; |
| 136 | |
| 137 | ++midiEvents; |
| 138 | --midiEventsLeft; |
| 139 | |
| 140 | const uint8_t* const data = midiEvent.size > MidiEvent::kDataSize |
| 141 | ? midiEvent.dataExt |
| 142 | : midiEvent.data; |
| 143 | |
| 144 | if (channel != 0 && data[0] < 0xF0) |
| 145 | { |
| 146 | if ((data[0] & 0x0F) != (channel - 1)) |
| 147 | continue; |
| 148 | } |
| 149 | |
| 150 | // adapted from Rack |
| 151 | switch (data[0] & 0xF0) |
| 152 | { |
| 153 | // note on |
| 154 | case 0x90: |
| 155 | if (data[2] > 0) |
| 156 | { |
| 157 | const int c = mpeMode ? (data[0] & 0x0F) : 0; |
| 158 | const int8_t note = data[1]; |
| 159 | // Learn |
| 160 | if (learningId >= 0) |
| 161 | { |
| 162 | // NOTE: does the same as `setLearnedNote` |
| 163 | if (note >= 0) |
| 164 | { |
| 165 | for (int id = 0; id < 18; ++id) |
| 166 | { |
no test coverage detected