MCPcopy Create free account
hub / github.com/DISTRHO/DPF / run

Function run

examples/Metronome/ExamplePluginMetronome.cpp:272–338  ·  view source on GitHub ↗

Run/process function for plugins without MIDI input. `inputs` is commented out because this plugin has no inputs. */

Source from the content-addressed store, hash-verified

270 `inputs` is commented out because this plugin has no inputs.
271 */
272 void run(const float** /* inputs */, float** outputs, uint32_t frames) override
273 {
274 const TimePosition& timePos(getTimePosition());
275 float* const output = outputs[0];
276
277 if (timePos.playing && timePos.bbt.valid)
278 {
279 // Better to use double when manipulating time.
280 double secondsPerBeat = 60.0 / timePos.bbt.beatsPerMinute;
281 double framesPerBeat = sampleRate * secondsPerBeat;
282 double beatFraction = timePos.bbt.tick / timePos.bbt.ticksPerBeat;
283
284 // If beatFraction is zero, next beat is exactly at the start of currenct cycle.
285 // Otherwise, reset counter to the frames to the next beat.
286 counter = d_isZero(beatFraction)
287 ? 0
288 : static_cast<uint32_t>(framesPerBeat * (1.0 - beatFraction));
289
290 // Compute deltaPhase in normalized frequency.
291 // semitone is midi note number, which is A4 (440Hz at standard tuning) at 69.
292 // Frequency goes up to 1 octave higher at the start of bar.
293 float frequency = 440.0f * std::pow(2.0f, (100.0f * (semitone - 69.0f) + cent) / 1200.0f);
294 float deltaPhase = frequency / sampleRate;
295 float octave = timePos.bbt.beat == 1 ? 2.0f : 1.0f;
296
297 // Envelope reaches 1e-5 at decayTime after triggering.
298 decay = std::pow(1e-5, 1.0 / (decayTime * sampleRate));
299
300 // Reset phase and frequency at the start of transpose.
301 if (!wasPlaying)
302 {
303 phase = 0.0f;
304
305 deltaPhaseSmoother.value = deltaPhase;
306 envelopeSmoother.value = 0.0f;
307 gainSmoother.value = 0.0f;
308 }
309
310 for (uint32_t i = 0; i < frames; ++i)
311 {
312 if (counter <= 0)
313 {
314 envelope = 1.0f;
315 counter = static_cast<uint32_t>(framesPerBeat + 0.5);
316 octave = (!wasPlaying || timePos.bbt.beat == static_cast<int32_t>(timePos.bbt.beatsPerBar)) ? 2.0f
317 : 1.0f;
318 }
319 --counter;
320
321 envelope *= decay;
322
323 phase += octave * deltaPhaseSmoother.process(deltaPhase);
324 phase -= std::floor(phase);
325
326 output[i] = gainSmoother.process(gain)
327 * envelopeSmoother.process(envelope)
328 * std::sin(float(2.0 * M_PI) * phase);
329 }

Callers

nothing calls this directly

Calls 2

d_isZeroFunction · 0.85
processMethod · 0.45

Tested by

no test coverage detected