From 25714e465a3da8036d769539b0beadcb8d0d355a Mon Sep 17 00:00:00 2001 From: Rylee Lyman Date: Wed, 12 Oct 2022 10:37:19 -0400 Subject: [PATCH] v0.1 --- plugins/FormantTriPTR/FormantTriPTR.cpp | 3559 +++++++++++++++++++- plugins/FormantTriPTR/FormantTriPTR.hpp | 49 +- plugins/FormantTriPTR/FormantTriPTR.sc | 6 +- plugins/FormantTriPTR/FormantTriPTR.schelp | 10 +- 4 files changed, 3606 insertions(+), 18 deletions(-) diff --git a/plugins/FormantTriPTR/FormantTriPTR.cpp b/plugins/FormantTriPTR/FormantTriPTR.cpp index 967d7eb..2f89d3c 100644 --- a/plugins/FormantTriPTR/FormantTriPTR.cpp +++ b/plugins/FormantTriPTR/FormantTriPTR.cpp @@ -9,19 +9,3562 @@ static InterfaceTable* ft; namespace FormantTriPTR { FormantTriPTR::FormantTriPTR() { - mCalcFunc = make_calc_function(); - next(1); + if (isAudioRateIn(0)) { + if (isAudioRateIn(1)) { + if (isAudioRateIn(2)) { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + else { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + } + else { + if (isAudioRateIn(2)) { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + else { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + } + } + else { + if (isAudioRateIn(1)) { + if (isAudioRateIn(2)) { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + else { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + } + else { + if (isAudioRateIn(2)) { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + else { + if (isAudioRateIn(3)) { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + else { + if (isAudioRateIn(4)) { + mCalcFunc = make_calc_function(); + } + else { + mCalcFunc = make_calc_function(); + } + } + } + } + } + next_kkkkk(1); +} + +inline double FormantTriPTR::rise_prime(double p, double t0, double t2, double t3, + double w, double v, double a, double b, double c, + double dc, double p1, double p2, double p3) { + if (p < t0) { + // y = 0.5*v*p3*x^4 - 1 + return 0.5 * v * p3 * p * p * p * p - 1.f; + } + else if (p < t2) { + // y = v*p3*x^4 - 0.5*v*p2*x^3 + .75*v*p1*x^2 - .125*A*T0 + 0.5*A*x - 1 + return v * p3 * p * p * p * p - 0.5f * v * p2 * p * p * p + + 0.75f * v * p1 * p * p - .125f * a * t0 + 0.5 * a * p - 1.f; + } + else if (p < t3) { + // y = -0.5*v*p3*x^4 + 0.5*v*p2*x^3 - 2.25*v*p1*x^2 + 1.875*A*T0 - 3.5*A*x - 1 + return -0.5f * v * p3 * p * p * p * p + 0.5f * v * p2 * p * p * p + - 2.25f * v * p1 * p * p + 1.875f * a * t0 - 3.5f * a * p - 1.f; + } + else { + return a * p - a * dc - 1.f; + } + /* else { + double p = p - w; + if (p < t0) { + // y = A*x - A*DC + 1 + 0.5*P3*x^4 + return a * p - a * dc + 1.f + 0.5f * p3 * p * p * p * p; + } + else if (p < t2) { + // y = A*x - A*DC + 1 - P3*x^4 + 0.5*P2*x^3 - 0.75*P1*x^2 + 0.5*C*x - 0.125*C*T0 + return a * p - a * dc + 1.f - p3 * p * p * p * p + + 0.5f * p2 * p * p * p - 0.75f * p1 * p * p + 0.5 * c * p + - 0.125f * c * t0; + } + else if (p < t3) { + // y = A*x - A*DC + 1 + 0.5*P3*x^4 - P2*x^3 + 4.5*P1*x^2 - 7*C*x + 3.75*C*T0 + return a * p - a * dc + 1.f + 0.5f * p3 * p * p * p * p + - 0.5f * p2 * p * p * p + 2.25f * p1 * p * p + - 3.5f * c * p + 1.875f * c * t0; + } + else if (p < v) { + // y = B*x - B*DC + 1 + return b * p - b * dc + 1.f; + } + else { + double p = p - 1.f + w; + if (p < t0) { + // y = B*x - 1 - 1.5*B*T0 - 0.5*w*P3*x^4 + return b * p - 1.f - 1.5f * b * t0 - 0.5f * w * p3 * p * p * p * p; + } + else if (p < t2) { + // y = 0.5*B*x - 1 - 1.375*B*T0 + 0.75*w*P1*x^2 - 0.5*w*P2*x^3 + w*P3*x^4 + return 0.5f * b * p - 1.f - 1.375f * b * t0 + 0.75 * w * p1 * p * p + - 0.5 * w * p2 * p * p * p + w * p3 * p * p * p * p; + } + else if (p < t3) { + // y = 4.5*B*x - 1 - 3.375*B*T0 - 2.25*w*P1*x^2 + 0.5*w*P2*x^3 - 0.5*w*P3*x^4 + return 4.5f * b * p - 1.f - 3.375f * b * t0 - 2.25f * w * p1 * p * p + + 0.5f * w * p2 * p * p * p - 0.5f * w * p3 * p * p * p * p; + } + else { + return -1.f; + } + } + } + */ +} + +inline double FormantTriPTR::rise(double p, double t0, double t2, double t3, + double w, double a, double b, double c, + double dc, double p1, double p2, double p3) { + if (p < t0) { + // y = B*x - B*DC - 1 - 0.5*P3*x^4 + return b * p - b * dc - 1.f - 0.5f * p3 * p * p * p * p; + } + else if (p < t2) { + // y = B*x - B*DC - 1 + P3*x^4 - 0.5*P2*x^3 + 0.75*P1*x^2 - 0.5*C*x + 0.125*C*T0 + return b * p - b * dc - 1.f + p3 * p * p * p * p + - 0.5f * p2 * p * p * p + 0.75f * p1 * p * p - 0.5f * c * p + + 0.125f * c * t0; + } + else if (p < t3) { + // y = B*x - B*DC - 1 - 0.5*P3*x^4 + 0.5*P2*x^3 - 2.25*P1*x^2 + 3.5*C*x - 1.875*C*T0 + return b * p - b * dc - 1.f - 0.5f * p3 * p * p * p * p + + 0.5f * p2 * p * p * p - 2.25f * p1 * p * p + + 3.5f * c * p - 1.875f * c * t0; + } + else { + return a * p - a * dc - 1.f; + } +} + +inline double FormantTriPTR::fall(double p, double t0, double t2, double t3, + double w, double v, double a, double b, double c, + double dc, double p1, double p2, double p3) { + if (p < t0) { + // y = A*x - A*DC + 1 + 0.5*P3*x^4 + return a * p - a * dc + 1.f + 0.5f * p3 * p * p * p * p; + } + else if (p < t2) { + // y = A*x - A*DC + 1 - P3*x^4 + 0.5*P2*x^3 - 0.75*P1*x^2 + 0.5*C*x - 0.125*C*T0 + return a * p - a * dc + 1.f - p3 * p * p * p * p + + 0.5f * p2 * p * p * p - 0.75f * p1 * p * p + 0.5 * c * p + - 0.125f * c * t0; + } + else if (p < t3) { + // y = A*x - A*DC + 1 + 0.5*P3*x^4 - P2*x^3 + 4.5*P1*x^2 - 7*C*x + 3.75*C*T0 + return a * p - a * dc + 1.f + 0.5f * p3 * p * p * p * p + - 0.5f * p2 * p * p * p + 2.25f * p1 * p * p + - 3.5f * c * p + 1.875f * c * t0; + } + else if (p < v) { + // y = B*x - B*DC + 1 + return b * p - b * dc + 1.f; + } + else { + p = p - v; + if (p < t0) { + // y = B*x - 1 - 1.5*B*T0 - 0.5*w*P3*x^4 + return b * p - 1.f - 1.5f * b * t0 - 0.5f * w * p3 * p * p * p * p; + } + else if (p < t2) { + // y = 0.5*B*x - 1 - 1.375*B*T0 + 0.75*w*P1*x^2 - 0.5*w*P2*x^3 + w*P3*x^4 + return 0.5f * b * p - 1.f - 1.375f * b * t0 + 0.75 * w * p1 * p * p + - 0.5 * w * p2 * p * p * p + w * p3 * p * p * p * p; + } + else if (p < t3) { + // y = 4.5*B*x - 1 - 3.375*B*T0 - 2.25*w*P1*x^2 + 0.5*w*P2*x^3 - 0.5*w*P3*x^4 + return 4.5f * b * p - 1.f - 3.375f * b * t0 - 2.25f * w * p1 * p * p + + 0.5f * w * p2 * p * p * p - 0.5f * w * p3 * p * p * p * p; + } + else { + return -1.f; + } + } +} + +void FormantTriPTR::next_aaaaa(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float* width = in(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aaaak(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float* width = in(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aaaka(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float* width = in(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aaakk(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float* width = in(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aakaa(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float width = in0(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aakak(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float width = in0(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aakka(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float width = in0(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_aakkk(int nSamples) { + const float* freq = in(0); + const float* formant = in(1); + const float width = in0(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akaaa(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float* width = in(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akaak(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float* width = in(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akaka(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float* width = in(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akakk(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float* width = in(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akkaa(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float width = in0(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akkak(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float width = in0(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akkka(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float width = in0(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_akkkk(int nSamples) { + const float* freq = in(0); + const float formant = in0(1); + const float width = in0(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + for(int i = 0; i < nSamples; ++i) { + double posfreq = freq[i] < 0.f ? -1.f * freq[i] : freq[i]; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kaaaa(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float* width = in(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kaaak(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float* width = in(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kaaka(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float* width = in(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kaakk(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float* width = in(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kakaa(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float width = in0(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kakak(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float width = in0(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kakka(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float width = in0(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kakkk(int nSamples) { + const float freq = in0(0); + const float* formant = in(1); + const float width = in0(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + for(int i = 0; i < nSamples; ++i) { + double form = formant[i] == 0.f ? 0.01f : formant[i]; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkaaa(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float* width = in(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + for(int i = 0; i < nSamples; ++i) { + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkaak(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float* width = in(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + for(int i = 0; i < nSamples; ++i) { + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkaka(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float* width = in(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + for(int i = 0; i < nSamples; ++i) { + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkakk(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float* width = in(2); + const float phase = in0(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + for(int i = 0; i < nSamples; ++i) { + double w = width[i] < 0.01f ? 0.01f : width[i] > 0.99f ? 0.99f : width[i]; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkkaa(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float width = in0(2); + const float* phase = in(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + for(int i = 0; i < nSamples; ++i) { + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkkak(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float width = in0(2); + const float* phase = in(3); + const float sync = in0(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + for(int i = 0; i < nSamples; ++i) { + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase[i] - phasein) + step; + counter = counter + (phase[i] - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase[i]; + lastsync = sync; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; +} + +void FormantTriPTR::next_kkkka(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float width = in0(2); + const float phase = in0(3); + const float* sync = in(4); + float* outbuf = out(0); + + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + for(int i = 0; i < nSamples; ++i) { + double out1 = 0.f; + if (sync[i] > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync[i]; + lastval = out1; + } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; } -void FormantTriPTR::next(int nSamples) { - const float* input = in(0); - const float* gain = in(1); +void FormantTriPTR::next_kkkkk(int nSamples) { + const float freq = in0(0); + const float formant = in0(1); + const float width = in0(2); + const float phase = in0(3); + const float sync = in0(4); float* outbuf = out(0); - // simple gain function - for (int i = 0; i < nSamples; ++i) { - outbuf[i] = input[i] * gain[i]; + double pos = mPhase; + double counter = mCounter; + double phasein = mPhaseIn; + double lastsync = mSync; + double rateinv = 1 / sampleRate(); + double lastval = mLast; + double offset = mOffset; + double posfreq = freq < 0.f ? -1.f * freq : freq; + double step = posfreq * rateinv; + double step2 = 2.f * step; + double step3 = 3.f * step; + double samples = 1.f / step; + double form = formant == 0.f ? 0.01f : formant; + form = form < 0.f ? -1.f * form : form; + double ratio = posfreq / form; + double w = width < 0.01f ? 0.01f : width > 0.99f ? 0.99f : width; + w = w * ratio; + double a = 2.f / w; + double b = 2.f / (w - ratio); + double v = ratio - w; + double c = 0.5f * a * b; + double dc = 1.5f * step; + double p1 = c * samples; + double p2 = p1 * samples; + double p3 = p2 * samples / 12.f; + double turnaround = (1.f - offset - b * dc) * 0.5 * w; + for(int i = 0; i < nSamples; ++i) { + double out1 = 0.f; + if (sync > 0.f && lastsync == 0.f) { + pos = 0.f; + counter = pos; + } + else { + pos = pos + (phase - phasein) + step; + counter = counter + (phase - phasein) + step; + while (pos > 1.f) { + pos -= 1.f; + } + while (pos < 0.f) { + pos += 1.f; + } + if (counter <= turnaround) { + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // retrigger while falling + else if (pos <= step) { + if (ratio > 1.f) { + offset = lastval + b * dc; + } + else { + offset = lastval; + } + turnaround = (1.f - offset - b * dc) * 0.5 * w; + counter = step; + if (ratio > 1.f) { + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + else { + out1 = offset + 1 + rise_prime(counter, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + // should we start rising again? + else if (ratio > 1.0f && counter > turnaround + v) { + while (counter > turnaround + v) { + counter -= turnaround + v; + } + offset = -1.f + b * dc; + turnaround = w; + out1 = offset + 1 + rise(counter, step, step2, step3, w, a, b, c, dc, p1, p2, p3); + } + // falling + else { + out1 = fall(counter - turnaround, step, step2, step3, w, v, a, b, c, dc, p1, p2, p3); + } + } + outbuf[i] = out1; + phasein = phase; + lastsync = sync; + lastval = out1; } + mPhase = pos; + mSync = lastsync; + mPhaseIn = phasein; + mCounter = counter; + mOffset = offset; + mLast = lastval; + // mTurnaround = turnaround; } } // namespace FormantTriPTR diff --git a/plugins/FormantTriPTR/FormantTriPTR.hpp b/plugins/FormantTriPTR/FormantTriPTR.hpp index 6892a33..d50a80e 100644 --- a/plugins/FormantTriPTR/FormantTriPTR.hpp +++ b/plugins/FormantTriPTR/FormantTriPTR.hpp @@ -16,9 +16,56 @@ class FormantTriPTR : public SCUnit { private: // Calc function - void next(int nSamples); + void next_aaaaa(int nSamples); + void next_aaaak(int nSamples); + void next_aaaka(int nSamples); + void next_aaakk(int nSamples); + void next_aakaa(int nSamples); + void next_aakak(int nSamples); + void next_aakka(int nSamples); + void next_aakkk(int nSamples); + void next_akaaa(int nSamples); + void next_akaak(int nSamples); + void next_akaka(int nSamples); + void next_akakk(int nSamples); + void next_akkaa(int nSamples); + void next_akkak(int nSamples); + void next_akkka(int nSamples); + void next_akkkk(int nSamples); + void next_kaaaa(int nSamples); + void next_kaaak(int nSamples); + void next_kaaka(int nSamples); + void next_kaakk(int nSamples); + void next_kakaa(int nSamples); + void next_kakak(int nSamples); + void next_kakka(int nSamples); + void next_kakkk(int nSamples); + void next_kkaaa(int nSamples); + void next_kkaak(int nSamples); + void next_kkaka(int nSamples); + void next_kkakk(int nSamples); + void next_kkkaa(int nSamples); + void next_kkkak(int nSamples); + void next_kkkka(int nSamples); + void next_kkkkk(int nSamples); + double rise_prime(double p, double t0, double t2, double t3, + double w, double v, double a, double b, double c, + double dc, double p1, double p2, double p3); + double rise(double p, double t0, double t2, double t3, + double w, double a, double b, double c, + double dc, double p1, double p2, double p3); + double fall(double p, double t0, double t2, double t3, + double w, double v, double a, double b, double c, + double dc, double p1, double p2, double p3); // Member variables + double mPhase = 0; + double mCounter = 0; + double mSync = 0; + double mPhaseIn = 0; + double mLast = -1; + double mOffset = -1; + // double mTurnaround = -1; }; } // namespace FormantTriPTR diff --git a/plugins/FormantTriPTR/FormantTriPTR.sc b/plugins/FormantTriPTR/FormantTriPTR.sc index f3e6310..24ec5ca 100644 --- a/plugins/FormantTriPTR/FormantTriPTR.sc +++ b/plugins/FormantTriPTR/FormantTriPTR.sc @@ -1,10 +1,8 @@ FormantTriPTR : UGen { - *ar { |input, gain| - /* TODO */ - ^this.multiNew('audio', input, gain); + *ar { |freq=440.0, formant=440.0, width=0.5, phase=0.0, sync=0.0| + ^this.multiNew('audio', freq, formant, width, phase, sync); } checkInputs { - /* TODO */ ^this.checkValidInputs; } } diff --git a/plugins/FormantTriPTR/FormantTriPTR.schelp b/plugins/FormantTriPTR/FormantTriPTR.schelp index f53e7aa..c18e966 100644 --- a/plugins/FormantTriPTR/FormantTriPTR.schelp +++ b/plugins/FormantTriPTR/FormantTriPTR.schelp @@ -1,7 +1,7 @@ class:: FormantTriPTR summary:: PTR triangle wave oscillator with variable slope and formant -related:: TODO -categories:: UGens>TODO +related:: Classes/Saw +categories:: UGens description:: @@ -12,15 +12,15 @@ classmethods:: method::ar, kr -argument::TODO +argument::freq, formant, width, phase, sync -argument::TODO +argument::freq, formant, width, phase, sync examples:: code:: -{ FormantTriPTR.ar(/* TODO */) }.play +{ FormantTriPTR.ar(440.0, 440.0) }.play ::