1
0
Fork 0

opl types update 2

This commit is contained in:
Sen 2025-08-25 14:41:40 +02:00
parent fe947ea7f3
commit ce5770e58c
Signed by: sen
GPG key ID: 3AC50A6F47D1B722

View file

@ -9,37 +9,37 @@ public class OPLChip {
}; };
private static interface ModGen { private static interface ModGen {
int getModulation(); short getModulation();
} }
private static interface WaveFunc { private static interface WaveFunc {
int calcPhase(int phase, int envelope); short calcPhase(short phase, short envelope);
} }
public class OPLSlot implements ModGen { public class OPLSlot implements ModGen {
private final OPLChannel channel; private final OPLChannel channel;
public int out; public short out;
public int fbmodv; public short fbmodv;
public final ModGen fbmod = () -> OPLSlot.this.fbmodv; public final ModGen fbmod = () -> OPLSlot.this.fbmodv;
public ModGen mod; public ModGen mod;
public int fb; public int fb;
public int prout; public short prout;
public int eg_rout; public short eg_rout;
public int eg_out; public short eg_out;
public EnvState eg_gen; public EnvState eg_gen;
public int eg_ksl; public byte eg_ksl;
public ModGen trem; public ModGen trem;
public boolean reg_vib; public boolean reg_vib;
public boolean reg_type; public boolean reg_type;
public boolean reg_ksr; public boolean reg_ksr;
public int reg_mult; public byte reg_mult;
public int reg_ksl; public byte reg_ksl;
public int reg_tl; public byte reg_tl;
public int reg_ar; public byte reg_ar;
public int reg_dr; public byte reg_dr;
public int reg_sl; public byte reg_sl;
public int reg_rr; public byte reg_rr;
public int reg_wf; public int reg_wf;
public boolean key; public boolean key;
public boolean detrigger; public boolean detrigger;
@ -66,7 +66,7 @@ public class OPLChip {
this.trem = OPLChip.this.zeromod; this.trem = OPLChip.this.zeromod;
} }
public int getModulation() { public short getModulation() {
return this.out; return this.out;
} }
@ -75,7 +75,7 @@ public class OPLChip {
// feedback // feedback
if (this.fb != 0x00) if (this.fb != 0x00)
{ {
this.fbmodv = (this.prout + this.out) >> (0x09 - this.fb); this.fbmodv = (short)((this.prout + this.out) >> (0x09 - this.fb));
} }
else else
{ {
@ -84,20 +84,21 @@ public class OPLChip {
this.prout = this.out; this.prout = this.out;
// envelope // envelope
boolean nonzero; boolean nonzero;
int rate; byte rate;
int rate_hi; byte rate_hi;
int rate_lo; byte rate_lo;
int reg_rate = 0; byte reg_rate = 0;
int ks; byte ks;
int eg_shift, shift; byte eg_shift, shift;
int eg_rout; short eg_rout;
int eg_inc; short eg_inc;
boolean eg_off; boolean eg_off;
boolean reset = false; boolean reset = false;
if(this.retrigger) { if(this.retrigger) {
this.eg_rout = 0x1ff; this.eg_rout = 0x1ff;
} }
this.eg_out = this.eg_rout + (this.reg_tl << 2) + (this.eg_ksl >> KSL_SHIFT[this.reg_ksl]) + this.trem.getModulation(); this.eg_out = (short)(this.eg_rout + (this.reg_tl << 2)
+ (this.eg_ksl >> KSL_SHIFT[this.reg_ksl]) + this.trem.getModulation());
if (this.key && this.eg_gen == EnvState.RELEASE) if (this.key && this.eg_gen == EnvState.RELEASE)
{ {
reset = true; reset = true;
@ -125,16 +126,16 @@ public class OPLChip {
} }
} }
this.pg_reset = reset; this.pg_reset = reset;
ks = this.ksv >> (this.reg_ksr ? 0 : 2); ks = (byte)(this.ksv >> (this.reg_ksr ? 0 : 2));
nonzero = (reg_rate != 0); nonzero = (reg_rate != 0);
rate = ks + (reg_rate << 2); rate = (byte)(ks + (reg_rate << 2));
rate_hi = rate >> 2; rate_hi = (byte)(rate >> 2);
rate_lo = rate & 0x03; rate_lo = (byte)(rate & 0x03);
if ((rate_hi & 0x10) != 0) if ((rate_hi & 0x10) != 0)
{ {
rate_hi = 0x0f; rate_hi = 0x0f;
} }
eg_shift = rate_hi + OPLChip.this.eg_add; eg_shift = (byte)(rate_hi + OPLChip.this.eg_add);
shift = 0; shift = 0;
if (nonzero) if (nonzero)
{ {
@ -148,10 +149,10 @@ public class OPLChip {
shift = 1; shift = 1;
break; break;
case 13: case 13:
shift = (rate_lo >> 1) & 0x01; shift = (byte)((rate_lo >> 1) & 0x01);
break; break;
case 14: case 14:
shift = rate_lo & 0x01; shift = (byte)(rate_lo & 0x01);
break; break;
default: default:
break; break;
@ -160,14 +161,14 @@ public class OPLChip {
} }
else else
{ {
shift = (rate_hi & 0x03) + EG_INC[rate_lo][OPLChip.this.timer & 0x03]; shift = (byte)((rate_hi & 0x03) + EG_INC[rate_lo][OPLChip.this.timer & 0x03]);
if ((shift & 0x04) != 0) if ((shift & 0x04) != 0)
{ {
shift = 0x03; shift = 0x03;
} }
if (shift == 0) if (shift == 0)
{ {
shift = OPLChip.this.eg_state ? 1 : 0; shift = (byte)(OPLChip.this.eg_state ? 1 : 0);
} }
} }
} }
@ -197,7 +198,7 @@ public class OPLChip {
} }
else if (this.key && shift > 0 && rate_hi != 0x0f) else if (this.key && shift > 0 && rate_hi != 0x0f)
{ {
eg_inc = ((~this.eg_rout) & 0xffff) >> (4 - shift); eg_inc = (short)(~this.eg_rout >> (4 - shift));
} }
break; break;
case DECAY: case DECAY:
@ -207,24 +208,24 @@ public class OPLChip {
} }
else if (!eg_off && !reset && shift > 0) else if (!eg_off && !reset && shift > 0)
{ {
eg_inc = 1 << (shift - 1); eg_inc = (short)(1 << (shift - 1));
} }
break; break;
case SUSTAIN: case SUSTAIN:
case RELEASE: case RELEASE:
if (!eg_off && !reset && shift > 0) if (!eg_off && !reset && shift > 0)
{ {
eg_inc = 1 << (shift - 1); eg_inc = (short)(1 << (shift - 1));
} }
break; break;
} }
this.eg_rout = (eg_rout + eg_inc) & 0x1ff; this.eg_rout = (short)((eg_rout + eg_inc) & 0x1ff);
/* Key off */ /* Key off */
if (reset) if (reset)
{ {
this.eg_gen = EnvState.ATTACK; this.eg_gen = EnvState.ATTACK;
} }
if (!this.key) if (!(this.key))
{ {
this.eg_gen = EnvState.RELEASE; this.eg_gen = EnvState.RELEASE;
} }
@ -252,7 +253,7 @@ public class OPLChip {
range >>= OPLChip.this.vibshift; range >>= OPLChip.this.vibshift;
if ((vibpos & 4) != 0) if ((vibpos & 4) != 0)
{ {
range = -range; range = (byte)-range;
} }
f_num += range; f_num += range;
} }
@ -263,17 +264,18 @@ public class OPLChip {
this.pg_phase += (basefreq * MULT[this.reg_mult]) >> 1; this.pg_phase += (basefreq * MULT[this.reg_mult]) >> 1;
this.pg_phase_out = phase; this.pg_phase_out = phase;
// output // output
this.out = WAVE_FUNCS[this.reg_wf].calcPhase(this.pg_phase_out + this.mod.getModulation(), this.eg_out); this.out = WAVE_FUNCS[this.reg_wf].calcPhase((short)(this.pg_phase_out + this.mod.getModulation()), this.eg_out);
} }
private void updateKSL() private void updateKSL()
{ {
int ksl = (KSL[this.f_num >> 6] << 2) - ((0x08 - this.block) << 5); short ksl = (short)((KSL[this.f_num >> 6] << 2)
- ((0x08 - this.block) << 5));
if (ksl < 0) if (ksl < 0)
{ {
ksl = 0; ksl = 0;
} }
this.eg_ksl = ksl; this.eg_ksl = (byte)ksl;
} }
private void keyOn() private void keyOn()
@ -307,27 +309,27 @@ public class OPLChip {
} }
public void setMultiplier(int mult) { public void setMultiplier(int mult) {
this.reg_mult = mult; this.reg_mult = (byte)(mult & 0x0f);
} }
public void setKSL(int ksl) { public void setKSL(int ksl) {
this.reg_ksl = ksl; this.reg_ksl = (byte)(ksl & 0x03);
this.updateKSL(); this.updateKSL();
} }
public void setLevel(int level) { public void setLevel(int level) {
this.reg_tl = level; this.reg_tl = (byte)(level & 0x3f);
} }
public void setEnvelope(int attack, int decay, int sustain, int release) { public void setEnvelope(int attack, int decay, int sustain, int release) {
this.reg_ar = attack; this.reg_ar = (byte)(attack & 0x0f);
this.reg_dr = decay; this.reg_dr = (byte)(decay & 0x0f);
this.reg_sl = sustain; this.reg_sl = (byte)(sustain & 0x0f);
if (this.reg_sl == 0x0f) if (this.reg_sl == 0x0f)
{ {
this.reg_sl = 0x1f; this.reg_sl = 0x1f;
} }
this.reg_rr = release; this.reg_rr = (byte)(release & 0x0f);
if (this.reg_rr == 0x00) if (this.reg_rr == 0x00)
{ {
this.reg_rr = 0x01; this.reg_rr = 0x01;
@ -335,7 +337,7 @@ public class OPLChip {
} }
public void setWaveform(int waveform) { public void setWaveform(int waveform) {
this.reg_wf = waveform; this.reg_wf = (byte)(waveform & 0x07);
} }
private void updateFrequency() { private void updateFrequency() {
@ -550,7 +552,7 @@ public class OPLChip {
//Tables //Tables
private static final int[] LOG_SIN = { private static final short[] LOG_SIN = {
0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471,
0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365,
0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd,
@ -585,7 +587,7 @@ public class OPLChip {
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
}; };
private static final int[] EXP = { private static final short[] EXP = {
0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4, 0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4,
0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9, 0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9,
0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f, 0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f,
@ -624,15 +626,15 @@ public class OPLChip {
1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30
}; };
private static final int[] KSL = { private static final byte[] KSL = {
0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64
}; };
private static final int[] KSL_SHIFT = { private static final byte[] KSL_SHIFT = {
8, 1, 2, 0 8, 1, 2, 0
}; };
private static final int[][] EG_INC = { private static final byte[][] EG_INC = {
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },
{ 1, 0, 0, 0 }, { 1, 0, 0, 0 },
{ 1, 0, 1, 0 }, { 1, 0, 1, 0 },
@ -700,30 +702,30 @@ public class OPLChip {
private boolean eg_state; private boolean eg_state;
private int eg_add; private int eg_add;
private int vibpos; private int vibpos;
private int tremolov; private short tremolov;
private int tremolopos; private int tremolopos;
private int samplecnt; private int samplecnt;
//Envelope generator //Envelope generator
private static int waveExp(int level) private static short waveExp(int level)
{ {
if (level > 0x1fff) if (level > 0x1fff)
{ {
level = 0x1fff; level = 0x1fff;
} }
return (EXP[level & 0xff] << 1) >> (level >> 8); return (short)((EXP[level & 0xff] << 1) >> (level >> 8));
} }
private static int wave0(int phase, int envelope) private static short wave0(short phase, short envelope)
{ {
int out = 0; short out = 0;
int neg = 0; short neg = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x200) != 0) if ((phase & 0x200) != 0)
{ {
neg = 0xffff; neg = (short)0xffff;
} }
if ((phase & 0x100) != 0) if ((phase & 0x100) != 0)
{ {
@ -733,12 +735,12 @@ public class OPLChip {
{ {
out = LOG_SIN[phase & 0xff]; out = LOG_SIN[phase & 0xff];
} }
return waveExp(out + (envelope << 3)) ^ neg; return (short)(waveExp(out + (envelope << 3)) ^ neg);
} }
private static int wave1(int phase, int envelope) private static short wave1(short phase, short envelope)
{ {
int out = 0; short out = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x200) != 0) if ((phase & 0x200) != 0)
{ {
@ -755,9 +757,9 @@ public class OPLChip {
return waveExp(out + (envelope << 3)); return waveExp(out + (envelope << 3));
} }
private static int wave2(int phase, int envelope) private static short wave2(short phase, short envelope)
{ {
int out = 0; short out = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x100) != 0) if ((phase & 0x100) != 0)
{ {
@ -770,9 +772,9 @@ public class OPLChip {
return waveExp(out + (envelope << 3)); return waveExp(out + (envelope << 3));
} }
private static int wave3(int phase, int envelope) private static short wave3(short phase, short envelope)
{ {
int out = 0; short out = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x100) != 0) if ((phase & 0x100) != 0)
{ {
@ -785,14 +787,14 @@ public class OPLChip {
return waveExp(out + (envelope << 3)); return waveExp(out + (envelope << 3));
} }
private static int wave4(int phase, int envelope) private static short wave4(short phase, short envelope)
{ {
int out = 0; short out = 0;
int neg = 0; short neg = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x300) == 0x100) if ((phase & 0x300) == 0x100)
{ {
neg = 0xffff; neg = (short)0xffff;
} }
if ((phase & 0x200) != 0) if ((phase & 0x200) != 0)
{ {
@ -806,12 +808,12 @@ public class OPLChip {
{ {
out = LOG_SIN[(phase << 1) & 0xff]; out = LOG_SIN[(phase << 1) & 0xff];
} }
return waveExp(out + (envelope << 3)) ^ neg; return (short)(waveExp(out + (envelope << 3)) ^ neg);
} }
private static int wave5(int phase, int envelope) private static short wave5(short phase, short envelope)
{ {
int out = 0; short out = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x200) != 0) if ((phase & 0x200) != 0)
{ {
@ -828,29 +830,29 @@ public class OPLChip {
return waveExp(out + (envelope << 3)); return waveExp(out + (envelope << 3));
} }
private static int wave6(int phase, int envelope) private static short wave6(short phase, short envelope)
{ {
int neg = 0; short neg = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x200) != 0) if ((phase & 0x200) != 0)
{ {
neg = 0xffff; neg = (short)0xffff;
} }
return waveExp(envelope << 3) ^ neg; return (short)(waveExp(envelope << 3) ^ neg);
} }
private static int wave7(int phase, int envelope) private static short wave7(short phase, short envelope)
{ {
int out = 0; short out = 0;
int neg = 0; short neg = 0;
phase &= 0x3ff; phase &= 0x3ff;
if ((phase & 0x200) != 0) if ((phase & 0x200) != 0)
{ {
neg = 0xffff; neg = (short)0xffff;
phase = (phase & 0x1ff) ^ 0x1ff; phase = (short)((phase & 0x1ff) ^ 0x1ff);
} }
out = phase << 3; out = (short)(phase << 3);
return waveExp(out + (envelope << 3)) ^ neg; return (short)(waveExp(out + (envelope << 3)) ^ neg);
} }
private void genFrame() private void genFrame()
@ -885,11 +887,11 @@ public class OPLChip {
} }
if (this.tremolopos < 105) if (this.tremolopos < 105)
{ {
this.tremolov = this.tremolopos >> this.tremoloshift; this.tremolov = (short)(this.tremolopos >> this.tremoloshift);
} }
else else
{ {
this.tremolov = (210 - this.tremolopos) >> this.tremoloshift; this.tremolov = (short)((210 - this.tremolopos) >> this.tremoloshift);
} }
if ((this.timer & 0x3ff) == 0x3ff) if ((this.timer & 0x3ff) == 0x3ff)
@ -904,7 +906,7 @@ public class OPLChip {
this.eg_add = 0; this.eg_add = 0;
if (this.eg_timer != 0) if (this.eg_timer != 0)
{ {
int shift = 0; byte shift = 0;
while (shift < 36 && ((this.eg_timer >> shift) & 1L) == 0L) while (shift < 36 && ((this.eg_timer >> shift) & 1L) == 0L)
{ {
shift++; shift++;
@ -974,5 +976,4 @@ public class OPLChip {
} }
return false; return false;
} }
}
}