Ensure rumble pre-pulse

This commit is contained in:
Jack Andersen 2018-01-26 09:46:35 -10:00
parent 13a31be23b
commit 6f7cd14836
3 changed files with 54 additions and 24 deletions

View File

@ -15,8 +15,26 @@ CRumbleGenerator::~CRumbleGenerator()
HardStopAll(); HardStopAll();
} }
#define PWM_MONITOR 0
#if PWM_MONITOR
static bool b_tp = false;
static std::chrono::steady_clock::time_point s_tp;
#endif
void CRumbleGenerator::Update(float dt) void CRumbleGenerator::Update(float dt)
{ {
#if PWM_MONITOR
std::chrono::milliseconds::rep ms = 0;
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
if (!b_tp)
{
b_tp = true;
s_tp = now;
}
else
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - s_tp).count();
#endif
if (!xf0_24_disabled) if (!xf0_24_disabled)
{ {
bool updated = false; bool updated = false;
@ -29,6 +47,10 @@ void CRumbleGenerator::Update(float dt)
xd0_onTime[i] = 0.f; xd0_onTime[i] = 0.f;
if (xe0_commandArray[i] != EMotorState::Stop) if (xe0_commandArray[i] != EMotorState::Stop)
{ {
#if PWM_MONITOR
s_tp = now;
printf("%lldms ON\n", ms);
#endif
xe0_commandArray[i] = EMotorState::Stop; xe0_commandArray[i] = EMotorState::Stop;
updated = true; updated = true;
} }
@ -41,6 +63,10 @@ void CRumbleGenerator::Update(float dt)
xc0_periodTime[i] = 0.f; xc0_periodTime[i] = 0.f;
if (xe0_commandArray[i] != EMotorState::Rumble) if (xe0_commandArray[i] != EMotorState::Rumble)
{ {
#if PWM_MONITOR
s_tp = now;
printf("%lldms Off\n", ms);
#endif
xe0_commandArray[i] = EMotorState::Rumble; xe0_commandArray[i] = EMotorState::Rumble;
updated = true; updated = true;
} }
@ -53,6 +79,10 @@ void CRumbleGenerator::Update(float dt)
xd0_onTime[i] = 0.f; xd0_onTime[i] = 0.f;
if (xe0_commandArray[i] != EMotorState::Stop) if (xe0_commandArray[i] != EMotorState::Stop)
{ {
#if PWM_MONITOR
s_tp = now;
printf("%lldms ON\n", ms);
#endif
xe0_commandArray[i] = EMotorState::Stop; xe0_commandArray[i] = EMotorState::Stop;
updated = true; updated = true;
} }

View File

@ -38,17 +38,17 @@ s16 CRumbleVoice::GetFreeChannel() const
float CRumbleVoice::GetIntensity() const float CRumbleVoice::GetIntensity() const
{ {
return std::min(2.f, return std::min(2.f,
std::max(x10_deltas[0].x0_curLevel, std::max(x10_deltas[0].x0_curIntensity,
std::max(x10_deltas[1].x0_curLevel, std::max(x10_deltas[1].x0_curIntensity,
std::max(x10_deltas[2].x0_curLevel, std::max(x10_deltas[2].x0_curIntensity,
x10_deltas[3].x0_curLevel)))); x10_deltas[3].x0_curIntensity))));
} }
bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt) bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt)
{ {
switch (delta.x20_phase) switch (delta.x20_phase)
{ {
case SAdsrDelta::EPhase::Queued: case SAdsrDelta::EPhase::PrePulse:
if (delta.x4_attackTime < (1.f/30.f)) if (delta.x4_attackTime < (1.f/30.f))
{ {
delta.x4_attackTime += dt; delta.x4_attackTime += dt;
@ -56,7 +56,7 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
else else
{ {
delta.x20_phase = SAdsrDelta::EPhase::Attack; delta.x20_phase = SAdsrDelta::EPhase::Attack;
delta.x0_curLevel = 0.f; delta.x0_curIntensity = 0.f;
delta.x4_attackTime = 0.f; delta.x4_attackTime = 0.f;
} }
break; break;
@ -64,12 +64,12 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
if (delta.x4_attackTime < data.x8_attackDur) if (delta.x4_attackTime < data.x8_attackDur)
{ {
float t = delta.x4_attackTime / data.x8_attackDur; float t = delta.x4_attackTime / data.x8_attackDur;
delta.x0_curLevel = t * delta.x14_attackLevel; delta.x0_curIntensity = t * delta.x14_attackIntensity;
delta.x4_attackTime += dt; delta.x4_attackTime += dt;
} }
else else
{ {
delta.x0_curLevel = delta.x14_attackLevel; delta.x0_curIntensity = delta.x14_attackIntensity;
delta.x20_phase = SAdsrDelta::EPhase::Decay; delta.x20_phase = SAdsrDelta::EPhase::Decay;
} }
break; break;
@ -79,12 +79,12 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
if (delta.x8_decayTime < data.xc_decayDur) if (delta.x8_decayTime < data.xc_decayDur)
{ {
float t = delta.x8_decayTime / data.xc_decayDur; float t = delta.x8_decayTime / data.xc_decayDur;
delta.x0_curLevel = (1.f - t) * delta.x14_attackLevel + t * delta.x18_sustainLevel; delta.x0_curIntensity = (1.f - t) * delta.x14_attackIntensity + t * delta.x18_sustainIntensity;
delta.x8_decayTime += dt; delta.x8_decayTime += dt;
} }
else else
{ {
delta.x0_curLevel = delta.x18_sustainLevel; delta.x0_curIntensity = delta.x18_sustainIntensity;
delta.x20_phase = SAdsrDelta::EPhase::Sustain; delta.x20_phase = SAdsrDelta::EPhase::Sustain;
} }
} }
@ -93,12 +93,12 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
if (delta.x8_decayTime < data.xc_decayDur) if (delta.x8_decayTime < data.xc_decayDur)
{ {
float t = delta.x8_decayTime / data.xc_decayDur; float t = delta.x8_decayTime / data.xc_decayDur;
delta.x0_curLevel = (1.f - t) * delta.x14_attackLevel; delta.x0_curIntensity = (1.f - t) * delta.x14_attackIntensity;
delta.x8_decayTime += dt; delta.x8_decayTime += dt;
} }
else else
{ {
delta.x0_curLevel = 0.f; delta.x0_curIntensity = 0.f;
delta.x20_phase = SAdsrDelta::EPhase::Stop; delta.x20_phase = SAdsrDelta::EPhase::Stop;
} }
if (delta.x20_phase != SAdsrDelta::EPhase::Decay) if (delta.x20_phase != SAdsrDelta::EPhase::Decay)
@ -110,16 +110,16 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
break; break;
case SAdsrDelta::EPhase::Release: case SAdsrDelta::EPhase::Release:
{ {
float a = data.x18_24_hasSustain ? delta.x18_sustainLevel : 0.f; float a = data.x18_24_hasSustain ? delta.x18_sustainIntensity : 0.f;
if (delta.xc_releaseTime < data.x14_releaseDur) if (delta.xc_releaseTime < data.x14_releaseDur)
{ {
float t = delta.xc_releaseTime / data.x14_releaseDur; float t = delta.xc_releaseTime / data.x14_releaseDur;
delta.x0_curLevel = (1.f - t) * a; delta.x0_curIntensity = (1.f - t) * a;
delta.xc_releaseTime += dt; delta.xc_releaseTime += dt;
} }
else else
{ {
delta.x0_curLevel = 0.f; delta.x0_curIntensity = 0.f;
delta.x20_phase = SAdsrDelta::EPhase::Stop; delta.x20_phase = SAdsrDelta::EPhase::Stop;
} }
if (delta.x20_phase != SAdsrDelta::EPhase::Release) if (delta.x20_phase != SAdsrDelta::EPhase::Release)
@ -154,7 +154,7 @@ bool CRumbleVoice::Update(float dt)
{ {
if (UpdateChannel(x10_deltas[i], x0_datas[i], dt)) if (UpdateChannel(x10_deltas[i], x0_datas[i], dt))
{ {
x2c_usedChannels &= (1 << i); x2c_usedChannels &= ~(1 << i);
x10_deltas[i] = SAdsrDelta::Stopped(); x10_deltas[i] = SAdsrDelta::Stopped();
} }
} }
@ -180,8 +180,8 @@ s16 CRumbleVoice::Activate(const SAdsrData& data, s16 idx, float gain, ERumblePr
{ {
x0_datas[idx] = data; x0_datas[idx] = data;
x10_deltas[idx] = SAdsrDelta::Start(prio, !x2c_usedChannels); x10_deltas[idx] = SAdsrDelta::Start(prio, !x2c_usedChannels);
x10_deltas[idx].x14_attackLevel = gain * x0_datas[idx].x0_attackGain; x10_deltas[idx].x14_attackIntensity = gain * x0_datas[idx].x0_attackGain;
x10_deltas[idx].x18_sustainLevel = gain * x0_datas[idx].x10_sustainGain; x10_deltas[idx].x18_sustainIntensity = gain * x0_datas[idx].x10_sustainGain;
x2c_usedChannels |= 1 << idx; x2c_usedChannels |= 1 << idx;
if (data.x18_24_hasSustain) if (data.x18_24_hasSustain)
return CreateRumbleHandle(idx); return CreateRumbleHandle(idx);

View File

@ -54,25 +54,25 @@ struct SAdsrDelta
enum class EPhase enum class EPhase
{ {
Stop, Stop,
Queued, PrePulse,
Attack, Attack,
Decay, Decay,
Sustain, Sustain,
Release Release
}; };
float x0_curLevel = 0.f; float x0_curIntensity = 0.f;
float x4_attackTime = 0.f; float x4_attackTime = 0.f;
float x8_decayTime = 0.f; float x8_decayTime = 0.f;
float xc_releaseTime = 0.f; float xc_releaseTime = 0.f;
float x10_autoReleaseTime = 0.f; float x10_autoReleaseTime = 0.f;
float x14_attackLevel; float x14_attackIntensity;
float x18_sustainLevel; float x18_sustainIntensity;
ERumblePriority x1c_priority; ERumblePriority x1c_priority;
EPhase x20_phase; EPhase x20_phase;
SAdsrDelta(EPhase phase, ERumblePriority priority) SAdsrDelta(EPhase phase, ERumblePriority priority)
: x1c_priority(priority), x20_phase(phase) : x0_curIntensity(phase == EPhase::PrePulse ? 2.f : 0.f), x1c_priority(priority), x20_phase(phase)
{} {}
SAdsrDelta(EPhase phase) SAdsrDelta(EPhase phase)
: x1c_priority(ERumblePriority::None), x20_phase(phase) : x1c_priority(ERumblePriority::None), x20_phase(phase)
@ -80,7 +80,7 @@ struct SAdsrDelta
static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); } static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); }
static SAdsrDelta Start(ERumblePriority priority, bool preQueue) static SAdsrDelta Start(ERumblePriority priority, bool preQueue)
{ return SAdsrDelta(preQueue ? EPhase::Queued : EPhase::Attack, priority); } { return SAdsrDelta(preQueue ? EPhase::PrePulse : EPhase::Attack, priority); }
}; };
class CRumbleVoice class CRumbleVoice