None
frac32buffer.bipolar out
frac32.u.map octDbl
frac32.s.map.kdecaytime.exp Attack
frac32.s.map.kdecaytime.exp Release
int32 Max Key
int32 Min Key
float dp[128]; // delta phase
float p[128];
float coef1[128]; // for gain compensation in DPW algo
float gates[128];
float g[128];
float env[128];
float z[BUFSIZE];
float z1;
float octDbl;
const float l = 0.0f;
const float r = 0.25f;
const float a = (l - 1) / r;
const float K = -0.5f * (l + 1) * r;
const float b = 1.0f + K;
const float A = 0.5 * (l - 1) / r;
const float C = -((1.0f / 3) * A * r * r * r + 0.5 * r * r - 0.5f * K + K * r);
const float C_K = C - K;
int syncRefresh = 0;
int minKey;
// _____________________________________________________________________
int i, j;
for (i = 0; i < 128; i++) {
p[i] = gates[i] = g[i] = env[i] = 0.0f;
}
z1 = 0.0f;
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dp[0] = 1.7032914407591056E-4f;
dp[1] = 1.804574420422344E-4f;
dp[2] = 1.9118799994622893E-4f;
dp[3] = 2.0255663002739644E-4f;
dp[4] = 2.1460127403181634E-4f;
dp[5] = 2.2736212983919527E-4f;
dp[6] = 2.4088178561955362E-4f;
dp[7] = 2.5520536196728464E-4f;
dp[8] = 2.703806624869435E-4f;
dp[9] = 2.8645833333333333E-4f;
dp[10] = 3.0349203223833975E-4f;
dp[11] = 3.2153860758862255E-4f;
for (i = 12; i <= 127; i++) {
dp[i] = 2 * dp[i - 12];
coef1[i] = ((1 << 25) / 127.0f) / (dp[i]);
}
minKey = param_Min_space_Key < param_Max_space_Key ? param_Min_space_Key
: param_Max_space_Key;
int maxKey = param_Min_space_Key >= param_Max_space_Key ? param_Min_space_Key
: param_Max_space_Key;
float attack = 1.0f - param_Attack / ((float)((1UL << 31) - 1));
float release = 1.0f - param_Release / ((float)((1UL << 31) - 1));
octDbl = arm::q_to_float(param_octDbl, 27);
// _____________________________________________________________________
// g: gates levels taking account of doubling
// resync (lock) of phases to avoid drift caused by calc inaccuracies
float pRef = p[minKey + syncRefresh];
g[minKey + syncRefresh] =
(gates[minKey + syncRefresh]) * coef1[minKey + syncRefresh];
for (int i = minKey + syncRefresh + 12; i <= maxKey; i += 12) {
g[i] = (gates[i] + octDbl * gates[i - 12]) * coef1[i];
pRef *= 2;
if (pRef >= 1)
pRef -= 1;
p[i] = pRef;
}
syncRefresh++;
if (syncRefresh >= 12)
syncRefresh = 0;
// DPW anti ali
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// lower key generator resets the output buffer
{
int i = minKey;
float _env = env[i];
env[i] += (g[i] > env[i] ? attack : release) * (g[i] - env[i]);
float denv = (env[i] - _env) * (1.0f / BUFSIZE);
float _dp = dp[i];
float _p = p[i];
for (int j = 0; j < BUFSIZE; j++) {
_p += _dp;
_p -= (_p > 1);
z[j] = (K * _p + C_K + (_p < r) * (K + _p * (1 + A * _p))) * (_env += denv);
}
p[i] = _p;
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
// higher key generators are added to the output buffer
for (int i = minKey + 1; i <= maxKey; i++) {
float _env = env[i];
env[i] += (g[i] > env[i] ? attack : release) * (g[i] - env[i]);
float denv = (env[i] - _env) * (1.0f / BUFSIZE);
float _dp = dp[i];
float _p = p[i];
for (int j = 0; j < BUFSIZE; j++) {
_p += _dp;
_p -= (_p > 1);
z[j] +=
(K * _p + C_K + (_p < r) * (K + _p * (1 + A * _p))) * (_env += denv);
}
p[i] = _p;
}
// _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
for (int j = 0; j < BUFSIZE; j++) {
outlet_out[j] = (int32_t)(z[j] - z1); // differentiation of the output
z1 = z[j];
}
if (status == MIDI_NOTE_ON + attr_midichannel) {
// gates[data1 & 0x7F] = data2 * coef1[data1];
int j = data1 & 0x7F;
if (j >= minKey || data2 == 0) {
gates[j] = data2 == 0 ? 0 : 100;
// update doubling
if (j >= 12)
g[j] = (gates[j] + octDbl * gates[j - 12]) * coef1[j];
if (j < 128 - 12)
g[j + 12] = (gates[j + 12] + octDbl * gates[j]) * coef1[j];
}
} else if (status == MIDI_NOTE_OFF + attr_midichannel) {
int j = data1 & 0x7F;
gates[j] = 0;
// update doubling
if (j >= 12)
g[j] = (gates[j] + octDbl * gates[j - 12]) * coef1[j];
if (j < 128 - 12)
g[j + 12] = (gates[j + 12] + octDbl * gates[j]) * coef1[j];
} else if ((status == attr_midichannel + MIDI_CONTROL_CHANGE) &&
(data1 == MIDI_C_ALL_NOTES_OFF)) {
for (int i = 0; i < 128; i++)
gates[data1 & 0x7F] = 0;
}