Run/process function for plugins with MIDI input. This synthesizes the MIDI voices with a sum of sine waves. */
| 114 | This synthesizes the MIDI voices with a sum of sine waves. |
| 115 | */ |
| 116 | void run(const float**, float** outputs, uint32_t frames, |
| 117 | const MidiEvent* midiEvents, uint32_t midiEventCount) override |
| 118 | { |
| 119 | for (uint32_t i = 0; i < midiEventCount; ++i) |
| 120 | { |
| 121 | if (midiEvents[i].size <= 3) |
| 122 | { |
| 123 | uint8_t status = midiEvents[i].data[0]; |
| 124 | uint8_t note = midiEvents[i].data[1] & 127; |
| 125 | uint8_t velocity = midiEvents[i].data[2] & 127; |
| 126 | |
| 127 | switch (status & 0xf0) |
| 128 | { |
| 129 | case 0x90: |
| 130 | if (velocity != 0) |
| 131 | { |
| 132 | fNotesPlayed[note] = velocity; |
| 133 | break; |
| 134 | } |
| 135 | /* fall through */ |
| 136 | case 0x80: |
| 137 | fNotesPlayed[note] = 0; |
| 138 | fOscillatorPhases[note] = 0; |
| 139 | break; |
| 140 | } |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | float* const output = outputs[0]; |
| 145 | std::memset(output, 0, frames * sizeof(float)); |
| 146 | |
| 147 | for (uint32_t noteNumber = 0; noteNumber < 128; ++noteNumber) |
| 148 | { |
| 149 | if (fNotesPlayed[noteNumber] == 0) |
| 150 | continue; |
| 151 | |
| 152 | float notePitch = 8.17579891564 * std::exp(0.0577622650 * noteNumber); |
| 153 | |
| 154 | float phase = fOscillatorPhases[noteNumber]; |
| 155 | float timeStep = notePitch / getSampleRate(); |
| 156 | float k2pi = 2.0 * M_PI; |
| 157 | float gain = 0.1; |
| 158 | |
| 159 | for (uint32_t i = 0; i < frames; ++i) |
| 160 | { |
| 161 | output[i] += gain * std::sin(k2pi * phase); |
| 162 | phase += timeStep; |
| 163 | phase -= (int)phase; |
| 164 | } |
| 165 | |
| 166 | fOscillatorPhases[noteNumber] = phase; |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | // ------------------------------------------------------------------------------------------------------- |
| 171 |
nothing calls this directly
no test coverage detected