#ifndef FM_GEN_INL_H
#define FM_GEN_INL_H
#define FM_PI 3.14159265358979323846
#define FM_SINEPRESIS 2
#define FM_OPSINBITS 10
#define FM_OPSINENTS (1 << FM_OPSINBITS)
#define FM_EGCBITS 18
#define FM_LFOCBITS 14
#ifdef FM_TUNEBUILD
#define FM_PGBITS 2
#define FM_RATIOBITS 0
#else
#define FM_PGBITS 9
#define FM_RATIOBITS 7
#endif
#define FM_EGBITS 16
#define PARAMCHANGE(i)
namespace FM
{
inline void Operator::ResetFB()
{
out_ = out2_ = 0;
}
inline void Operator::KeyOn()
{
if (!keyon_)
{
keyon_ = true;
if (eg_phase_ == off || eg_phase_ == release)
{
ssg_phase_ = -1;
ShiftPhase(attack);
EGUpdate();
in2_ = out_ = out2_ = 0;
pg_count_ = 0;
}
}
}
inline void Operator::KeyOff()
{
if (keyon_)
{
keyon_ = false;
ShiftPhase(release);
}
}
inline int Operator::IsOn()
{
return eg_phase_ - off;
}
inline void Operator::SetDT(uint dt)
{
detune_ = dt * 0x20, param_changed_ = true;
PARAMCHANGE(4);
}
inline void Operator::SetDT2(uint dt2)
{
detune2_ = dt2 & 3, param_changed_ = true;
PARAMCHANGE(5);
}
inline void Operator::SetMULTI(uint mul)
{
multiple_ = mul, param_changed_ = true;
PARAMCHANGE(6);
}
inline void Operator::SetTL(uint tl, bool csm)
{
if (!csm)
{
tl_ = tl, param_changed_ = true;
PARAMCHANGE(7);
}
tl_latch_ = tl;
}
inline void Operator::SetAR(uint ar)
{
ar_ = ar;
param_changed_ = true;
PARAMCHANGE(8);
}
inline void Operator::SetDR(uint dr)
{
dr_ = dr;
param_changed_ = true;
PARAMCHANGE(9);
}
inline void Operator::SetSR(uint sr)
{
sr_ = sr;
param_changed_ = true;
PARAMCHANGE(10);
}
inline void Operator::SetSL(uint sl)
{
sl_ = sl;
param_changed_ = true;
PARAMCHANGE(11);
}
inline void Operator::SetRR(uint rr)
{
rr_ = rr;
param_changed_ = true;
PARAMCHANGE(12);
}
inline void Operator::SetKS(uint ks)
{
ks_ = ks;
param_changed_ = true;
PARAMCHANGE(13);
}
inline void Operator::SetSSGEC(uint ssgec)
{
if (ssgec & 8)
{
ssg_type_ = ssgec;
switch (eg_phase_)
{
case attack:
ssg_phase_ = 0;
break;
case decay:
ssg_phase_ = 1;
break;
default:
ssg_phase_ = 2;
break;
}
}
else
ssg_type_ = 0;
}
inline void Operator::SetAMON(bool amon)
{
amon_ = amon;
param_changed_ = true;
PARAMCHANGE(14);
}
inline void Operator::Mute(bool mute)
{
mute_ = mute;
param_changed_ = true;
PARAMCHANGE(15);
}
inline void Operator::SetMS(uint ms)
{
ms_ = ms;
param_changed_ = true;
PARAMCHANGE(16);
}
inline void Channel4::SetType(OpType type)
{
for (int i=0; i<4; i++)
op[i].type_ = type;
}
inline void Channel4::SetFB(uint feedback)
{
fb = fbtable[feedback];
}
inline void Channel4::SetMS(uint ms)
{
op[0].SetMS(ms);
op[1].SetMS(ms);
op[2].SetMS(ms);
op[3].SetMS(ms);
}
inline void Channel4::Mute(bool m)
{
for (int i=0; i<4; i++)
op[i].Mute(m);
}
inline void Channel4::Refresh()
{
for (int i=0; i<4; i++)
op[i].param_changed_ = true;
PARAMCHANGE(3);
}
inline void Channel4::SetChip(Chip* chip)
{
chip_ = chip;
for (int i=0; i<4; i++)
op[i].SetChip(chip);
}
inline void StoreSample(Sample& dest, ISample data)
{
if (sizeof(Sample) == 2)
dest = (Sample) Limit(dest + data, 0x7fff, -0x8000);
else
dest += data;
}
inline void Chip::SetAML(uint l)
{
aml_ = l & (FM_LFOENTS - 1);
}
inline void Chip::SetPML(uint l)
{
pml_ = l & (FM_LFOENTS - 1);
}
}
#endif