Voice state fixes

This commit is contained in:
Jack Andersen 2016-05-16 17:23:35 -10:00
parent 970b7775ee
commit 51892eccc1
2 changed files with 26 additions and 21 deletions

View File

@ -59,7 +59,7 @@ class Voice : public Entity
uint32_t m_lastSamplePos = 0; /**< Last sample position (or last loop sample) */ uint32_t m_lastSamplePos = 0; /**< Last sample position (or last loop sample) */
int16_t m_prev1 = 0; /**< DSPADPCM prev sample */ int16_t m_prev1 = 0; /**< DSPADPCM prev sample */
int16_t m_prev2 = 0; /**< DSPADPCM prev-prev sample */ int16_t m_prev2 = 0; /**< DSPADPCM prev-prev sample */
double m_sampleRate; /**< Current sample rate computed from relative sample key or SETPITCH */ double m_sampleRate = 32000.0; /**< Current sample rate computed from relative sample key or SETPITCH */
double m_voiceTime; /**< Current seconds of voice playback (per-sample resolution) */ double m_voiceTime; /**< Current seconds of voice playback (per-sample resolution) */
VoiceState m_voxState = VoiceState::Dead; /**< Current high-level state of voice */ VoiceState m_voxState = VoiceState::Dead; /**< Current high-level state of voice */
@ -72,7 +72,7 @@ class Voice : public Entity
float m_curReverbVol; /**< Current reverb volume of voice */ float m_curReverbVol; /**< Current reverb volume of voice */
float m_curPan; /**< Current pan of voice */ float m_curPan; /**< Current pan of voice */
float m_curSpan; /**< Current surround pan of voice */ float m_curSpan; /**< Current surround pan of voice */
float m_curPitchWheel; /**< Current normalized wheel value for control */ float m_curPitchWheel = 0.f; /**< Current normalized wheel value for control */
int32_t m_pitchWheelUp; /**< Up range for pitchwheel control in cents */ int32_t m_pitchWheelUp; /**< Up range for pitchwheel control in cents */
int32_t m_pitchWheelDown; /**< Down range for pitchwheel control in cents */ int32_t m_pitchWheelDown; /**< Down range for pitchwheel control in cents */
int32_t m_pitchWheelVal; /**< Current resolved pitchwheel delta for control */ int32_t m_pitchWheelVal; /**< Current resolved pitchwheel delta for control */
@ -96,6 +96,8 @@ class Voice : public Entity
int16_t m_pitchSweep2Add; /**< Value to add to PITCHSWEEP2 controller each cycle */ int16_t m_pitchSweep2Add; /**< Value to add to PITCHSWEEP2 controller each cycle */
uint8_t m_pitchSweep1Times; /**< Remaining times to advance PITCHSWEEP1 controller */ uint8_t m_pitchSweep1Times; /**< Remaining times to advance PITCHSWEEP1 controller */
uint8_t m_pitchSweep2Times; /**< Remaining times to advance PITCHSWEEP2 controller */ uint8_t m_pitchSweep2Times; /**< Remaining times to advance PITCHSWEEP2 controller */
uint8_t m_pitchSweep1It; /**< Current iteration of PITCHSWEEP1 controller */
uint8_t m_pitchSweep2It; /**< Current iteration of PITCHSWEEP2 controller */
float m_panningTime; /**< time since last PANNING command, -1 for no active pan-sweep */ float m_panningTime; /**< time since last PANNING command, -1 for no active pan-sweep */
float m_panningDur; /**< requested duration of last PANNING command */ float m_panningDur; /**< requested duration of last PANNING command */

View File

@ -44,13 +44,16 @@ void Voice::_reset()
m_curPan = 0.f; m_curPan = 0.f;
m_curSpan = 0.f; m_curSpan = 0.f;
m_curAftertouch = 0; m_curAftertouch = 0;
m_pitchWheelUp = 6; m_pitchWheelUp = 600;
m_pitchWheelDown = 6; m_pitchWheelDown = 600;
m_pitchWheelVal = 0; m_pitchWheelVal = 0;
m_pitchDirty = true;
m_pitchSweep1 = 0; m_pitchSweep1 = 0;
m_pitchSweep1Times = 0; m_pitchSweep1Times = 0;
m_pitchSweep1It = 0;
m_pitchSweep2 = 0; m_pitchSweep2 = 0;
m_pitchSweep2Times = 0; m_pitchSweep2Times = 0;
m_pitchSweep2It = 0;
m_envelopeTime = -1.f; m_envelopeTime = -1.f;
m_panningTime = -1.f; m_panningTime = -1.f;
m_vibratoLevel = 0; m_vibratoLevel = 0;
@ -257,7 +260,7 @@ bool Voice::_advanceSample(int16_t& samp, int32_t& newPitch)
float start = (m_panPos - 64) / 64.f; float start = (m_panPos - 64) / 64.f;
float end = (m_panPos + m_panWidth - 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)); float t = std::max(0.f, std::min(1.f, m_panningTime / m_panningDur));
setPan((start * (1.0f - t)) + (end * t)); m_curPan = (start * (1.0f - t)) + (end * t);
refresh = true; refresh = true;
/* Done with panning */ /* Done with panning */
@ -272,7 +275,7 @@ bool Voice::_advanceSample(int16_t& samp, int32_t& newPitch)
float start = (m_spanPos - 64) / 64.f; float start = (m_spanPos - 64) / 64.f;
float end = (m_spanPos + m_spanWidth - 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)); float t = std::max(0.f, std::min(1.f, m_spanningTime / m_spanningDur));
setSurroundPan((start * (1.0f - t)) + (end * t)); m_curSpan = (start * (1.0f - t)) + (end * t);
refresh = true; refresh = true;
/* Done with spanning */ /* Done with spanning */
@ -291,18 +294,18 @@ bool Voice::_advanceSample(int16_t& samp, int32_t& newPitch)
} }
/* Process pitch sweep 1 */ /* Process pitch sweep 1 */
if (m_pitchSweep1Times) if (m_pitchSweep1It < m_pitchSweep1Times)
{ {
m_pitchSweep1 += m_pitchSweep1Add; ++m_pitchSweep1It;
--m_pitchSweep1Times; m_pitchSweep1 = m_pitchSweep1Add * m_pitchSweep1It / m_pitchSweep1Times;
refresh = true; refresh = true;
} }
/* Process pitch sweep 2 */ /* Process pitch sweep 2 */
if (m_pitchSweep2Times) if (m_pitchSweep2It < m_pitchSweep2Times)
{ {
m_pitchSweep2 += m_pitchSweep2Add; ++m_pitchSweep2It;
--m_pitchSweep2Times; m_pitchSweep2 = m_pitchSweep2Add * m_pitchSweep2It / m_pitchSweep2Times;
refresh = true; refresh = true;
} }
@ -319,7 +322,7 @@ size_t Voice::supplyAudio(size_t samples, int16_t* data)
/* Attempt to load stopped sample for immediate decoding */ /* Attempt to load stopped sample for immediate decoding */
if (!m_curSample) if (!m_curSample)
{ {
dead = m_state.advance(*this, 0.0); dead = m_state.advance(*this, samples / m_sampleRate);
if (!dead) if (!dead)
{ {
memset(data, 0, sizeof(int16_t) * samples); memset(data, 0, sizeof(int16_t) * samples);
@ -444,7 +447,6 @@ size_t Voice::supplyAudio(size_t samples, int16_t* data)
m_volAdsr.isComplete()) m_volAdsr.isComplete())
{ {
m_voxState = VoiceState::Dead; m_voxState = VoiceState::Dead;
m_backendVoice->stop();
} }
return samples; return samples;
} }
@ -467,6 +469,7 @@ std::shared_ptr<Voice> Voice::_startChildMacro(ObjectId macroId, int macroStep,
_destroyVoice(vox.get()); _destroyVoice(vox.get());
return {}; return {};
} }
vox->setVolume(m_userVol);
return vox; return vox;
} }
@ -607,9 +610,7 @@ void Voice::startSample(int16_t sampId, int32_t offset)
{ {
if (m_curSample->first.m_loopLengthSamples) if (m_curSample->first.m_loopLengthSamples)
{ {
if (offset <= m_curSample->first.m_loopStartSample) if (offset > m_curSample->first.m_loopStartSample)
offset = clamp(0, offset, numSamples);
else
offset = ((offset - m_curSample->first.m_loopStartSample) % offset = ((offset - m_curSample->first.m_loopStartSample) %
m_curSample->first.m_loopLengthSamples) + m_curSample->first.m_loopLengthSamples) +
m_curSample->first.m_loopStartSample; m_curSample->first.m_loopStartSample;
@ -753,14 +754,16 @@ void Voice::setTremolo(float tremoloScale, float tremoloModScale)
void Voice::setPitchSweep1(uint8_t times, int16_t add) void Voice::setPitchSweep1(uint8_t times, int16_t add)
{ {
m_pitchSweep1 = 0; m_pitchSweep1 = 0;
m_pitchSweep1Times = times; m_pitchSweep1It = 0;
m_pitchSweep1Times = times * 160;
m_pitchSweep1Add = add; m_pitchSweep1Add = add;
} }
void Voice::setPitchSweep2(uint8_t times, int16_t add) void Voice::setPitchSweep2(uint8_t times, int16_t add)
{ {
m_pitchSweep2 = 0; m_pitchSweep2 = 0;
m_pitchSweep2Times = times; m_pitchSweep2It = 0;
m_pitchSweep2Times = times * 160;
m_pitchSweep2Add = add; m_pitchSweep2Add = add;
} }
@ -807,9 +810,9 @@ void Voice::setPitchWheel(float pitchWheel)
{ {
m_curPitchWheel = amuse::clamp(-1.f, pitchWheel, 1.f); m_curPitchWheel = amuse::clamp(-1.f, pitchWheel, 1.f);
if (pitchWheel > 0.f) if (pitchWheel > 0.f)
m_pitchWheelVal = m_pitchWheelUp * m_curPitchWheel * 100; m_pitchWheelVal = m_pitchWheelUp * m_curPitchWheel;
else if (pitchWheel < 0.f) else if (pitchWheel < 0.f)
m_pitchWheelVal = m_pitchWheelDown * m_curPitchWheel * 100; m_pitchWheelVal = m_pitchWheelDown * m_curPitchWheel;
else else
m_pitchWheelVal = 0; m_pitchWheelVal = 0;
m_pitchDirty = true; m_pitchDirty = true;