Implement VIBRATO

This commit is contained in:
Jack Andersen 2018-05-18 19:15:12 -10:00
parent 594fb346e1
commit 1fefba66e7
4 changed files with 22 additions and 8 deletions

View File

@ -81,7 +81,7 @@ class SoundMacroState
SetAgeCount, /* unimplemented */ SetAgeCount, /* unimplemented */
SendFlag, /* unimplemented */ SendFlag, /* unimplemented */
PitchWheelR, PitchWheelR,
SetPriority, /* unimplemented */ SetPriority = 0x36, /* unimplemented */
AddPriority, /* unimplemented */ AddPriority, /* unimplemented */
AgeCntSpeed, /* unimplemented */ AgeCntSpeed, /* unimplemented */
AgeCntVel, /* unimplemented */ AgeCntVel, /* unimplemented */

View File

@ -106,8 +106,8 @@ class Voice : public Entity
float m_portamentoTime = -1.f; /**< time since last portamento invocation, -1 for no active portamento-glide */ float m_portamentoTime = -1.f; /**< time since last portamento invocation, -1 for no active portamento-glide */
int32_t m_portamentoTarget; /**< destination pitch for latest portamento invocation */ int32_t m_portamentoTarget; /**< destination pitch for latest portamento invocation */
uint32_t m_pitchSweep1 = 0; /**< Current value of PITCHSWEEP1 controller (in cents) */ int32_t m_pitchSweep1 = 0; /**< Current value of PITCHSWEEP1 controller (in cents) */
uint32_t m_pitchSweep2 = 0; /**< Current value of PITCHSWEEP2 controller (in cents) */ int32_t m_pitchSweep2 = 0; /**< Current value of PITCHSWEEP2 controller (in cents) */
int16_t m_pitchSweep1Add = 0; /**< Value to add to PITCHSWEEP1 controller each cycle */ int16_t m_pitchSweep1Add = 0; /**< Value to add to PITCHSWEEP1 controller each cycle */
int16_t m_pitchSweep2Add = 0; /**< Value to add to PITCHSWEEP2 controller each cycle */ int16_t m_pitchSweep2Add = 0; /**< Value to add to PITCHSWEEP2 controller each cycle */
uint8_t m_pitchSweep1Times = 0; /**< Remaining times to advance PITCHSWEEP1 controller */ uint8_t m_pitchSweep1Times = 0; /**< Remaining times to advance PITCHSWEEP1 controller */
@ -125,6 +125,7 @@ class Voice : public Entity
uint8_t m_spanPos; /**< initial pan value of last SPANNING command */ uint8_t m_spanPos; /**< initial pan value of last SPANNING command */
int8_t m_spanWidth; /**< delta pan value to target of last SPANNING command */ int8_t m_spanWidth; /**< delta pan value to target of last SPANNING command */
float m_vibratoTime = -1.f; /**< time since last VIBRATO command, -1 for no active vibrato */
int32_t m_vibratoLevel = 0; /**< scale of vibrato effect (in cents) */ int32_t m_vibratoLevel = 0; /**< scale of vibrato effect (in cents) */
int32_t m_vibratoModLevel = 0; /**< scale of vibrato mod-wheel influence (in cents) */ int32_t m_vibratoModLevel = 0; /**< scale of vibrato mod-wheel influence (in cents) */
float m_vibratoPeriod = 0.f; /**< vibrato wave period-time, 0.f will disable vibrato */ float m_vibratoPeriod = 0.f; /**< vibrato wave period-time, 0.f will disable vibrato */
@ -260,7 +261,7 @@ public:
void setDoppler(float doppler); void setDoppler(float doppler);
/** Set vibrato parameters for voice */ /** Set vibrato parameters for voice */
void setVibrato(int32_t level, int32_t modLevel, float period); void setVibrato(int32_t level, bool modScale, float period);
/** Configure modwheel influence range over vibrato */ /** Configure modwheel influence range over vibrato */
void setMod2VibratoRange(int32_t modLevel); void setMod2VibratoRange(int32_t modLevel);

View File

@ -689,12 +689,12 @@ bool SoundMacroState::advance(Voice& vox, double dt)
case Op::Vibrato: case Op::Vibrato:
{ {
int32_t level = cmd.m_data[0] * 100 + cmd.m_data[1]; int32_t level = cmd.m_data[0] * 100 + cmd.m_data[1];
int32_t modLevel = cmd.m_data[2]; bool modScale = cmd.m_data[2] != 0;
int8_t ms = cmd.m_data[4]; int8_t ms = cmd.m_data[4];
int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[5]); int16_t timeMs = *reinterpret_cast<int16_t*>(&cmd.m_data[5]);
float q = ms ? 1000.f : m_ticksPerSec; float q = ms ? 1000.f : m_ticksPerSec;
vox.setVibrato(level, modLevel, timeMs / q); vox.setVibrato(level, modScale, timeMs / q);
break; break;
} }
case Op::PitchSweep1: case Op::PitchSweep1:

View File

@ -448,6 +448,18 @@ void Voice::preSupplyAudio(double dt)
refresh = true; refresh = true;
} }
/* Process vibrato */
if (m_vibratoTime >= 0.f)
{
m_vibratoTime += dt;
float vibrato = std::sin(m_vibratoTime / m_vibratoPeriod * (2.f * M_PIF));
if (m_vibratoModWheel)
newPitch += m_vibratoModLevel * vibrato;
else
newPitch += m_vibratoLevel * vibrato;
refresh = true;
}
/* Process pitch sweep 1 */ /* Process pitch sweep 1 */
if (m_pitchSweep1It < m_pitchSweep1Times) if (m_pitchSweep1It < m_pitchSweep1Times)
{ {
@ -1199,10 +1211,11 @@ void Voice::setPedal(bool pedal)
void Voice::setDoppler(float) {} void Voice::setDoppler(float) {}
void Voice::setVibrato(int32_t level, int32_t modLevel, float period) void Voice::setVibrato(int32_t level, bool modScale, float period)
{ {
m_vibratoTime = std::fabs(period) < FLT_EPSILON ? -1.f : 0.f;
m_vibratoLevel = level; m_vibratoLevel = level;
m_vibratoModLevel = modLevel; m_vibratoModWheel = modScale;
m_vibratoPeriod = period; m_vibratoPeriod = period;
} }