Work on Voice state

This commit is contained in:
Jack Andersen
2016-05-11 11:30:45 -10:00
parent 1102d50f8f
commit e510a0ad84
11 changed files with 610 additions and 264 deletions

View File

@@ -52,17 +52,17 @@ float SoundMacroState::Evaluator::evaluate(Voice& vox, const SoundMacroState& st
break;
case 130:
/* LFO1 */
if (st.m_lfoPeriods[0])
thisValue = std::sin(st.m_execTime / st.m_lfoPeriods[0] * 2.f * M_PIF);
if (vox.m_lfoPeriods[0])
thisValue = std::sin(vox.m_voiceTime / vox.m_lfoPeriods[0] * 2.f * M_PIF);
break;
case 131:
/* LFO2 */
if (st.m_lfoPeriods[1])
thisValue = std::sin(st.m_execTime / st.m_lfoPeriods[1] * 2.f * M_PIF);
if (vox.m_lfoPeriods[1])
thisValue = std::sin(vox.m_voiceTime / vox.m_lfoPeriods[1] * 2.f * M_PIF);
break;
case 132:
/* Surround panning */
thisValue = st.m_curSpan * 64.f + 64.f;
thisValue = vox.m_curSpan * 64.f + 64.f;
break;
case 133:
/* Macro-starting key */
@@ -110,50 +110,30 @@ float SoundMacroState::Evaluator::evaluate(Voice& vox, const SoundMacroState& st
return value;
}
void SoundMacroState::initialize(const unsigned char* ptr)
void SoundMacroState::initialize(const unsigned char* ptr, int step)
{
initialize(ptr, 1000.f, 0, 0, 0);
initialize(ptr, step, 1000.f, 0, 0, 0);
}
void SoundMacroState::initialize(const unsigned char* ptr, float ticksPerSec,
void SoundMacroState::initialize(const unsigned char* ptr, int step, float ticksPerSec,
uint8_t midiKey, uint8_t midiVel, uint8_t midiMod)
{
m_curVol = 1.f;
m_volDirty = true;
m_curPan = 0.f;
m_panDirty = true;
m_curSpan = 0.f;
m_spanDirty = true;
m_ticksPerSec = ticksPerSec;
m_initKey = 0;
m_initVel = 0;
m_initMod = 0;
m_initKey = midiKey;
m_initVel = midiVel;
m_initMod = midiMod;
m_curVel = 0;
m_curMod = 0;
m_curKey = 0;
m_pitchSweep1 = 0;
m_pitchSweep1Times = 0;
m_pitchSweep2 = 0;
m_pitchSweep2Times = 0;
m_pitchDirty = true;
m_pc.clear();
m_pc.push_back({ptr, 0});
m_pc.push_back({ptr, step});
m_execTime = 0.f;
m_keyoff = false;
m_sampleEnd = false;
m_envelopeTime = -1.f;
m_panningTime = -1.f;
m_loopCountdown = -1;
m_lastPlayMacroVid = -1;
m_useAdsrControllers = false;
m_portamentoMode = 0;
m_vibratoLevel = 0;
m_vibratoModLevel = 0;
m_vibratoPeriod = 0.f;
m_tremoloScale = 0.f;
m_tremoloModScale = 0.f;
m_lfoPeriods[0] = 0.f;
m_lfoPeriods[1] = 0.f;
m_header = *reinterpret_cast<const Header*>(ptr);
m_header.swapBig();
}
@@ -164,107 +144,6 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (m_pc.empty() || m_pc.back().first == nullptr || m_pc.back().second == -1)
return true;
/* Process active envelope */
if (m_envelopeTime >= 0.f)
{
m_envelopeTime += dt;
float start = m_envelopeStart / 127.f;
float end = m_envelopeEnd / 127.f;
float t = std::max(0.f, std::min(1.f, m_envelopeTime / m_envelopeDur));
if (m_envelopeCurve)
t = (*m_envelopeCurve)[int(t*127.f)] / 127.f;
m_curVol = (start * (1.0f - t)) + (end * t);
m_volDirty = true;
/* Done with envelope */
if (m_envelopeTime > m_envelopeDur)
m_envelopeTime = -1.f;
}
/* Apply tremolo */
float totalVol = m_curVol;
if (m_tremoloSel && (m_tremoloScale || m_tremoloModScale))
{
float t = m_tremoloSel.evaluate(vox, *this);
if (m_tremoloScale && m_tremoloModScale)
{
float fac = (1.0f - t) + (m_tremoloScale * t);
float modT = vox.getModWheel() / 127.f;
float modFac = (1.0f - modT) + (m_tremoloModScale * modT);
totalVol *= fac * modFac;
}
else if (m_tremoloScale)
{
float fac = (1.0f - t) + (m_tremoloScale * t);
totalVol *= fac;
}
else if (m_tremoloModScale)
{
float modT = vox.getModWheel() / 127.f;
float modFac = (1.0f - modT) + (m_tremoloModScale * modT);
totalVol *= modFac;
}
m_volDirty = true;
}
/* Apply total volume */
if (m_volDirty)
{
vox.setVolume(totalVol);
m_volDirty = false;
}
/* Process active pan-sweep */
if (m_panningTime >= 0.f)
{
m_panningTime += dt;
float start = (m_panPos - 64) / 64.f;
float end = (m_panPos + m_panWidth - 64) / 64.f;
float t = std::max(0.f, std::min(1.f, m_panningTime / m_panningDur));
vox.setPanning((start * (1.0f - t)) + (end * t));
/* Done with panning */
if (m_panningTime > m_panningDur)
m_panningTime = -1.f;
}
/* Process active span-sweep */
if (m_spanningTime >= 0.f)
{
m_spanningTime += dt;
float start = (m_spanPos - 64) / 64.f;
float end = (m_spanPos + m_spanWidth - 64) / 64.f;
float t = std::max(0.f, std::min(1.f, m_spanningTime / m_spanningDur));
vox.setSurroundPanning((start * (1.0f - t)) + (end * t));
/* Done with spanning */
if (m_spanningTime > m_spanningDur)
m_spanningTime = -1.f;
}
/* Process pitch sweep 1 */
if (m_pitchSweep1Times)
{
m_pitchSweep1 += m_pitchSweep1Add;
--m_pitchSweep1Times;
m_pitchDirty = true;
}
/* Process pitch sweep 2 */
if (m_pitchSweep2Times)
{
m_pitchSweep2 += m_pitchSweep2Add;
--m_pitchSweep2Times;
m_pitchDirty = true;
}
/* Apply total pitch */
if (m_pitchDirty)
{
vox.setPitchKey(m_curKey + m_pitchSweep1 + m_pitchSweep2);
m_pitchDirty = false;
}
/* Loop through as many commands as we can for this time period */
while (true)
{
@@ -305,7 +184,8 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (macroId == m_header.m_macroId)
m_pc.back().second = macroStep;
else
vox.loadSoundMacro(macroId, macroStep);
vox.loadSoundMacro(macroId, macroStep, m_ticksPerSec,
m_initKey, m_initVel, m_initMod);
}
break;
@@ -322,7 +202,8 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (macroId == m_header.m_macroId)
m_pc.back().second = macroStep;
else
vox.loadSoundMacro(macroId, macroStep);
vox.loadSoundMacro(macroId, macroStep, m_ticksPerSec,
m_initKey, m_initVel, m_initMod);
}
break;
@@ -398,7 +279,8 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (macroId == m_header.m_macroId)
m_pc.back().second = macroStep;
else
vox.loadSoundMacro(macroId, macroStep);
vox.loadSoundMacro(macroId, macroStep, m_ticksPerSec,
m_initKey, m_initVel, m_initMod);
break;
}
@@ -479,7 +361,8 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (macroId == m_header.m_macroId)
m_pc.back().second = macroStep;
else
vox.loadSoundMacro(macroId, macroStep);
vox.loadSoundMacro(macroId, macroStep, m_ticksPerSec,
m_initKey, m_initVel, m_initMod);
}
break;
@@ -492,7 +375,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
int32_t pan = int32_t(m_initKey - cenKey) * scale / 127 + cenPan;
pan = std::max(-127, std::min(127, pan));
vox.setPanning(pan / 127.f);
vox.setPan(pan / 127.f);
break;
}
case Op::SetAdsr:
@@ -516,14 +399,12 @@ bool SoundMacroState::advance(Voice& vox, float dt)
const Curve* curveData = vox.getAudioGroup().getPool().tableAsCurves(curve);
if (curveData)
{
m_curVol = (*curveData)[eval] / 127.f;
m_volDirty = true;
vox.setVolume((*curveData)[eval] / 127.f);
break;
}
}
m_curVol = eval / 127.f;
m_volDirty = true;
vox.setVolume(eval / 127.f);
break;
}
case Op::Panning:
@@ -532,11 +413,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
int8_t width = cmd.m_data[3];
m_panningTime = 0.f;
m_panningDur = timeMs / 1000.f;
m_panPos = panPos;
m_panWidth = width;
vox.startPanning(timeMs / 1000.0, panPos, width);
break;
}
case Op::Envelope:
@@ -547,22 +424,19 @@ bool SoundMacroState::advance(Voice& vox, float dt)
bool ms = cmd.m_data[4];
int16_t fadeTime = *reinterpret_cast<int16_t*>(&cmd.m_data[5]);
float q = ms ? 1000.f : m_ticksPerSec;
float secTime = fadeTime / q;
double q = ms ? 1000.0 : m_ticksPerSec;
double secTime = fadeTime / q;
int32_t eval = int32_t(m_curVel) * scale / 127 + add;
eval = std::max(0, std::min(127, eval));
m_envelopeTime = 0.f;
m_envelopeDur = secTime;
m_envelopeStart = m_curVel;
m_envelopeEnd = eval;
const Curve* curveData;
if (curve != 0)
m_envelopeCurve = vox.getAudioGroup().getPool().tableAsCurves(curve);
curveData = vox.getAudioGroup().getPool().tableAsCurves(curve);
else
m_envelopeCurve = nullptr;
curveData = nullptr;
vox.startEnvelope(secTime, eval, curveData);
break;
}
case Op::StartSample:
@@ -608,7 +482,8 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (macroId == m_header.m_macroId)
m_pc.back().second = macroStep;
else
vox.loadSoundMacro(macroId, macroStep);
vox.loadSoundMacro(macroId, macroStep, m_ticksPerSec,
m_initKey, m_initVel, m_initMod);
}
break;
@@ -627,16 +502,13 @@ bool SoundMacroState::advance(Voice& vox, float dt)
int32_t eval = int32_t(m_curVel) * scale / 127 + add;
eval = std::max(0, std::min(127, eval));
m_envelopeTime = 0.f;
m_envelopeDur = secTime;
m_envelopeStart = 0.f;
m_envelopeEnd = eval;
const Curve* curveData;
if (curve != 0)
m_envelopeCurve = vox.getAudioGroup().getPool().tableAsCurves(curve);
curveData = vox.getAudioGroup().getPool().tableAsCurves(curve);
else
m_envelopeCurve = nullptr;
curveData = nullptr;
vox.startFadeIn(secTime, eval, curveData);
break;
}
case Op::Spanning:
@@ -645,11 +517,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
int8_t width = cmd.m_data[3];
m_spanningTime = 0.f;
m_spanningDur = timeMs / 1000.f;
m_spanPos = panPos;
m_spanWidth = width;
vox.startSpanning(timeMs / 1000.0, panPos, width);
break;
}
case Op::SetAdsrCtrl:
@@ -682,7 +550,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (!free)
m_curKey = m_curKey / 100 * 100 + detune;
m_pitchDirty = true;
vox.setPitchKey(m_curKey);
break;
}
case Op::AddNote:
@@ -704,7 +572,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
m_inWait = true;
}
m_pitchDirty = true;
vox.setPitchKey(m_curKey);
break;
}
case Op::SetNote:
@@ -725,7 +593,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
m_inWait = true;
}
m_pitchDirty = true;
vox.setPitchKey(m_curKey);
break;
}
case Op::LastNote:
@@ -746,7 +614,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
m_inWait = true;
}
m_pitchDirty = true;
vox.setPitchKey(m_curKey);
break;
}
case Op::Portamento:
@@ -762,20 +630,19 @@ bool SoundMacroState::advance(Voice& vox, float dt)
}
case Op::Vibrato:
{
m_vibratoModLevel = m_vibratoLevel = cmd.m_data[0] * 100 + cmd.m_data[1];
m_vibratoModWheel = cmd.m_data[2];
int32_t level = cmd.m_data[0] * 100 + cmd.m_data[1];
int32_t modLevel = cmd.m_data[2];
int8_t ms = cmd.m_data[4];
int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[5]);
float q = ms ? 1000.f : m_ticksPerSec;
m_vibratoPeriod = timeMs / q;
vox.setVibrato(level, modLevel, timeMs / q);
break;
}
case Op::PitchSweep1:
{
m_pitchSweep1 = 0;
m_pitchSweep1Times = int32_t(cmd.m_data[0]);
m_pitchSweep1Add = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
int32_t times = int32_t(cmd.m_data[0]);
int16_t add = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
int8_t ms = cmd.m_data[4];
int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[5]);
@@ -789,13 +656,13 @@ bool SoundMacroState::advance(Voice& vox, float dt)
m_inWait = true;
}
vox.setPitchSweep1(times, add);
break;
}
case Op::PitchSweep2:
{
m_pitchSweep2 = 0;
m_pitchSweep2Times = int32_t(cmd.m_data[0]);
m_pitchSweep2Add = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
int32_t times = int32_t(cmd.m_data[0]);
int16_t add = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
int8_t ms = cmd.m_data[4];
int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[5]);
@@ -809,6 +676,7 @@ bool SoundMacroState::advance(Voice& vox, float dt)
m_inWait = true;
}
vox.setPitchSweep2(times, add);
break;
}
case Op::SetPitch:
@@ -830,23 +698,21 @@ bool SoundMacroState::advance(Voice& vox, float dt)
{
int16_t scale = *reinterpret_cast<int16_t*>(&cmd.m_data[0]);
bool orgVel = cmd.m_data[2];
m_curVol = int32_t(orgVel ? m_initVel : m_curVel) * scale / 4096.f / 127.f;
m_volDirty = true;
vox.setVolume(int32_t(orgVel ? m_initVel : m_curVel) * scale / 4096.f / 127.f);
break;
}
case Op::Mod2Vibrange:
{
int8_t keys = cmd.m_data[0];
int8_t cents = cmd.m_data[1];
m_vibratoModLevel = keys * 100 + cents;
vox.setMod2VibratoRange(keys * 100 + cents);
break;
}
case Op::SetupTremolo:
{
int16_t scale = *reinterpret_cast<int16_t*>(&cmd.m_data[0]);
int16_t modScale = *reinterpret_cast<int16_t*>(&cmd.m_data[3]);
m_tremoloScale = scale / 4096.f;
m_tremoloModScale = modScale / 4096.f;
vox.setTremolo(scale / 4096.f, modScale / 4096.f);
break;
}
case Op::Return:
@@ -868,7 +734,8 @@ bool SoundMacroState::advance(Voice& vox, float dt)
if (macroId == m_header.m_macroId)
m_pc.push_back({m_pc.back().first, macroStep});
else
vox.loadSoundMacro(macroId, macroStep, true);
vox.loadSoundMacro(macroId, macroStep, m_ticksPerSec,
m_initKey, m_initVel, m_initMod, true);
m_header = *reinterpret_cast<const Header*>(m_pc.back().first);
m_header.swapBig();
@@ -1128,8 +995,10 @@ bool SoundMacroState::advance(Voice& vox, float dt)
{
uint8_t number = cmd.m_data[0];
int16_t period = *reinterpret_cast<int16_t*>(&cmd.m_data[1]);
if (number <= 1)
m_lfoPeriods[number] = period / 1000.f;
if (number == 0)
vox.setLFO1Period(period / 1000.f);
else if (number == 1)
vox.setLFO2Period(period / 1000.f);
break;
}
case Op::SetKeygroup:
@@ -1338,7 +1207,8 @@ void SoundMacroState::keyoffNotify(Voice& vox)
if (m_keyoffTrap.macroId == m_header.m_macroId)
m_pc.back().second = m_keyoffTrap.macroStep;
else
vox.loadSoundMacro(m_keyoffTrap.macroId, m_keyoffTrap.macroStep);
vox.loadSoundMacro(m_keyoffTrap.macroId, m_keyoffTrap.macroStep,
m_ticksPerSec, m_initKey, m_initVel, m_initMod);
}
}
@@ -1353,7 +1223,8 @@ void SoundMacroState::sampleEndNotify(Voice& vox)
if (m_sampleEndTrap.macroId == m_header.m_macroId)
m_pc.back().second = m_sampleEndTrap.macroStep;
else
vox.loadSoundMacro(m_sampleEndTrap.macroId, m_sampleEndTrap.macroStep);
vox.loadSoundMacro(m_sampleEndTrap.macroId, m_sampleEndTrap.macroStep,
m_ticksPerSec, m_initKey, m_initVel, m_initMod);
}
}
@@ -1366,7 +1237,8 @@ void SoundMacroState::messageNotify(Voice& vox, int32_t val)
if (m_messageTrap.macroId == m_header.m_macroId)
m_pc.back().second = m_messageTrap.macroStep;
else
vox.loadSoundMacro(m_messageTrap.macroId, m_messageTrap.macroStep);
vox.loadSoundMacro(m_messageTrap.macroId, m_messageTrap.macroStep,
m_ticksPerSec, m_initKey, m_initVel, m_initMod);
}
}