opl types update
This commit is contained in:
parent
c0919b0eed
commit
fe947ea7f3
3 changed files with 116 additions and 118 deletions
|
@ -16,8 +16,6 @@ import common.util.Identifyable;
|
||||||
|
|
||||||
import javax.sound.sampled.SourceDataLine;
|
import javax.sound.sampled.SourceDataLine;
|
||||||
|
|
||||||
import client.audio.AudioInterface.BankInstr;
|
|
||||||
import client.audio.AudioInterface.BankHandle.BankChannel;
|
|
||||||
import client.audio.OPLChip.OPLChannel;
|
import client.audio.OPLChip.OPLChannel;
|
||||||
import client.audio.OPLChip.OPLSlot;
|
import client.audio.OPLChip.OPLSlot;
|
||||||
import client.util.FileUtils;
|
import client.util.FileUtils;
|
||||||
|
|
|
@ -9,37 +9,37 @@ public class OPLChip {
|
||||||
};
|
};
|
||||||
|
|
||||||
private static interface ModGen {
|
private static interface ModGen {
|
||||||
short getModulation();
|
int getModulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static interface WaveFunc {
|
private static interface WaveFunc {
|
||||||
short calcPhase(short phase, short envelope);
|
int calcPhase(int phase, int envelope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OPLSlot implements ModGen {
|
public class OPLSlot implements ModGen {
|
||||||
private final OPLChannel channel;
|
private final OPLChannel channel;
|
||||||
|
|
||||||
public short out;
|
public int out;
|
||||||
public short fbmodv;
|
public int 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 short prout;
|
public int prout;
|
||||||
public short eg_rout;
|
public int eg_rout;
|
||||||
public short eg_out;
|
public int eg_out;
|
||||||
public EnvState eg_gen;
|
public EnvState eg_gen;
|
||||||
public byte eg_ksl;
|
public int 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 byte reg_mult;
|
public int reg_mult;
|
||||||
public byte reg_ksl;
|
public int reg_ksl;
|
||||||
public byte reg_tl;
|
public int reg_tl;
|
||||||
public byte reg_ar;
|
public int reg_ar;
|
||||||
public byte reg_dr;
|
public int reg_dr;
|
||||||
public byte reg_sl;
|
public int reg_sl;
|
||||||
public byte reg_rr;
|
public int 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 short getModulation() {
|
public int 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 = (short)((this.prout + this.out) >> (0x09 - this.fb));
|
this.fbmodv = (this.prout + this.out) >> (0x09 - this.fb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -84,21 +84,20 @@ public class OPLChip {
|
||||||
this.prout = this.out;
|
this.prout = this.out;
|
||||||
// envelope
|
// envelope
|
||||||
boolean nonzero;
|
boolean nonzero;
|
||||||
byte rate;
|
int rate;
|
||||||
byte rate_hi;
|
int rate_hi;
|
||||||
byte rate_lo;
|
int rate_lo;
|
||||||
byte reg_rate = 0;
|
int reg_rate = 0;
|
||||||
byte ks;
|
int ks;
|
||||||
byte eg_shift, shift;
|
int eg_shift, shift;
|
||||||
short eg_rout;
|
int eg_rout;
|
||||||
short eg_inc;
|
int 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 = (short)(this.eg_rout + (this.reg_tl << 2)
|
this.eg_out = this.eg_rout + (this.reg_tl << 2) + (this.eg_ksl >> KSL_SHIFT[this.reg_ksl]) + this.trem.getModulation();
|
||||||
+ (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;
|
||||||
|
@ -126,16 +125,16 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.pg_reset = reset;
|
this.pg_reset = reset;
|
||||||
ks = (byte)(this.ksv >> (this.reg_ksr ? 0 : 2));
|
ks = this.ksv >> (this.reg_ksr ? 0 : 2);
|
||||||
nonzero = (reg_rate != 0);
|
nonzero = (reg_rate != 0);
|
||||||
rate = (byte)(ks + (reg_rate << 2));
|
rate = ks + (reg_rate << 2);
|
||||||
rate_hi = (byte)(rate >> 2);
|
rate_hi = rate >> 2;
|
||||||
rate_lo = (byte)(rate & 0x03);
|
rate_lo = rate & 0x03;
|
||||||
if ((rate_hi & 0x10) != 0)
|
if ((rate_hi & 0x10) != 0)
|
||||||
{
|
{
|
||||||
rate_hi = 0x0f;
|
rate_hi = 0x0f;
|
||||||
}
|
}
|
||||||
eg_shift = (byte)(rate_hi + OPLChip.this.eg_add);
|
eg_shift = rate_hi + OPLChip.this.eg_add;
|
||||||
shift = 0;
|
shift = 0;
|
||||||
if (nonzero)
|
if (nonzero)
|
||||||
{
|
{
|
||||||
|
@ -149,10 +148,10 @@ public class OPLChip {
|
||||||
shift = 1;
|
shift = 1;
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
shift = (byte)((rate_lo >> 1) & 0x01);
|
shift = (rate_lo >> 1) & 0x01;
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
shift = (byte)(rate_lo & 0x01);
|
shift = rate_lo & 0x01;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -161,14 +160,14 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shift = (byte)((rate_hi & 0x03) + EG_INC[rate_lo][OPLChip.this.timer & 0x03]);
|
shift = (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 = (byte)(OPLChip.this.eg_state ? 1 : 0);
|
shift = OPLChip.this.eg_state ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,7 +197,7 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
else if (this.key && shift > 0 && rate_hi != 0x0f)
|
else if (this.key && shift > 0 && rate_hi != 0x0f)
|
||||||
{
|
{
|
||||||
eg_inc = (short)(~this.eg_rout >> (4 - shift));
|
eg_inc = ((~this.eg_rout) & 0xffff) >> (4 - shift);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DECAY:
|
case DECAY:
|
||||||
|
@ -208,24 +207,24 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
else if (!eg_off && !reset && shift > 0)
|
else if (!eg_off && !reset && shift > 0)
|
||||||
{
|
{
|
||||||
eg_inc = (short)(1 << (shift - 1));
|
eg_inc = 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 = (short)(1 << (shift - 1));
|
eg_inc = 1 << (shift - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.eg_rout = (short)((eg_rout + eg_inc) & 0x1ff);
|
this.eg_rout = (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;
|
||||||
}
|
}
|
||||||
|
@ -253,7 +252,7 @@ public class OPLChip {
|
||||||
range >>= OPLChip.this.vibshift;
|
range >>= OPLChip.this.vibshift;
|
||||||
if ((vibpos & 4) != 0)
|
if ((vibpos & 4) != 0)
|
||||||
{
|
{
|
||||||
range = (byte)-range;
|
range = -range;
|
||||||
}
|
}
|
||||||
f_num += range;
|
f_num += range;
|
||||||
}
|
}
|
||||||
|
@ -264,18 +263,17 @@ 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((short)(this.pg_phase_out + this.mod.getModulation()), this.eg_out);
|
this.out = WAVE_FUNCS[this.reg_wf].calcPhase(this.pg_phase_out + this.mod.getModulation(), this.eg_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateKSL()
|
private void updateKSL()
|
||||||
{
|
{
|
||||||
short ksl = (short)((KSL[this.f_num >> 6] << 2)
|
int ksl = (KSL[this.f_num >> 6] << 2) - ((0x08 - this.block) << 5);
|
||||||
- ((0x08 - this.block) << 5));
|
|
||||||
if (ksl < 0)
|
if (ksl < 0)
|
||||||
{
|
{
|
||||||
ksl = 0;
|
ksl = 0;
|
||||||
}
|
}
|
||||||
this.eg_ksl = (byte)ksl;
|
this.eg_ksl = ksl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void keyOn()
|
private void keyOn()
|
||||||
|
@ -309,27 +307,27 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMultiplier(int mult) {
|
public void setMultiplier(int mult) {
|
||||||
this.reg_mult = (byte)(mult & 0x0f);
|
this.reg_mult = mult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKSL(int ksl) {
|
public void setKSL(int ksl) {
|
||||||
this.reg_ksl = (byte)(ksl & 0x03);
|
this.reg_ksl = ksl;
|
||||||
this.updateKSL();
|
this.updateKSL();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLevel(int level) {
|
public void setLevel(int level) {
|
||||||
this.reg_tl = (byte)(level & 0x3f);
|
this.reg_tl = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = (byte)(attack & 0x0f);
|
this.reg_ar = attack;
|
||||||
this.reg_dr = (byte)(decay & 0x0f);
|
this.reg_dr = decay;
|
||||||
this.reg_sl = (byte)(sustain & 0x0f);
|
this.reg_sl = sustain;
|
||||||
if (this.reg_sl == 0x0f)
|
if (this.reg_sl == 0x0f)
|
||||||
{
|
{
|
||||||
this.reg_sl = 0x1f;
|
this.reg_sl = 0x1f;
|
||||||
}
|
}
|
||||||
this.reg_rr = (byte)(release & 0x0f);
|
this.reg_rr = release;
|
||||||
if (this.reg_rr == 0x00)
|
if (this.reg_rr == 0x00)
|
||||||
{
|
{
|
||||||
this.reg_rr = 0x01;
|
this.reg_rr = 0x01;
|
||||||
|
@ -337,7 +335,7 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWaveform(int waveform) {
|
public void setWaveform(int waveform) {
|
||||||
this.reg_wf = (byte)(waveform & 0x07);
|
this.reg_wf = waveform;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFrequency() {
|
private void updateFrequency() {
|
||||||
|
@ -522,7 +520,7 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLevel(boolean right, int velocity, int volume, int pan) {
|
private void updateLevel(boolean right, int velocity, int volume, int pan) {
|
||||||
int function = (int)OPLChip.this.velo_func;
|
int function = OPLChip.this.velo_func;
|
||||||
double lvl = ((function == -128) ? 1.0 :
|
double lvl = ((function == -128) ? 1.0 :
|
||||||
(function != 0 ? velofunc(((double)velocity)/127.0, function < 0 ? (0.1+(1.0-((((double)(-function))-1.0)/126.0))*9.9) : (1.0+((((double)function)-1.0)/126.0)*9.0)) :
|
(function != 0 ? velofunc(((double)velocity)/127.0, function < 0 ? (0.1+(1.0-((((double)(-function))-1.0)/126.0))*9.9) : (1.0+((((double)function)-1.0)/126.0)*9.0)) :
|
||||||
(((double)velocity)/127.0))) * (((double)volume)/127.0) * (1.0-(0.9*((double)(right ? -pan : pan))/63.0));
|
(((double)velocity)/127.0))) * (((double)volume)/127.0) * (1.0-(0.9*((double)(right ? -pan : pan))/63.0));
|
||||||
|
@ -552,7 +550,7 @@ public class OPLChip {
|
||||||
|
|
||||||
//Tables
|
//Tables
|
||||||
|
|
||||||
private static final short[] LOG_SIN = {
|
private static final int[] 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,
|
||||||
|
@ -587,7 +585,7 @@ public class OPLChip {
|
||||||
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
|
0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final short[] EXP = {
|
private static final int[] 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,
|
||||||
|
@ -626,15 +624,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 byte[] KSL = {
|
private static final int[] 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 byte[] KSL_SHIFT = {
|
private static final int[] KSL_SHIFT = {
|
||||||
8, 1, 2, 0
|
8, 1, 2, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final byte[][] EG_INC = {
|
private static final int[][] 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 },
|
||||||
|
@ -691,41 +689,41 @@ public class OPLChip {
|
||||||
private final int[] output = new int[2];
|
private final int[] output = new int[2];
|
||||||
private final int rateratio;
|
private final int rateratio;
|
||||||
|
|
||||||
private final byte nts;
|
private final int nts;
|
||||||
private final byte vibshift;
|
private final int vibshift;
|
||||||
private final byte tremoloshift;
|
private final int tremoloshift;
|
||||||
private final byte velo_func;
|
private final int velo_func;
|
||||||
|
|
||||||
private short timer;
|
private int timer;
|
||||||
private long eg_timer;
|
private long eg_timer;
|
||||||
private byte eg_timerrem;
|
private boolean eg_timerrem;
|
||||||
private boolean eg_state;
|
private boolean eg_state;
|
||||||
private byte eg_add;
|
private int eg_add;
|
||||||
private byte vibpos;
|
private int vibpos;
|
||||||
private short tremolov;
|
private int tremolov;
|
||||||
private short tremolopos;
|
private int tremolopos;
|
||||||
|
|
||||||
private int samplecnt;
|
private int samplecnt;
|
||||||
|
|
||||||
//Envelope generator
|
//Envelope generator
|
||||||
|
|
||||||
private static short waveExp(int level)
|
private static int waveExp(int level)
|
||||||
{
|
{
|
||||||
if (level > 0x1fff)
|
if (level > 0x1fff)
|
||||||
{
|
{
|
||||||
level = 0x1fff;
|
level = 0x1fff;
|
||||||
}
|
}
|
||||||
return (short)((EXP[level & 0xff] << 1) >> (level >> 8));
|
return (EXP[level & 0xff] << 1) >> (level >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave0(short phase, short envelope)
|
private static int wave0(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
short neg = 0;
|
int neg = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x200) != 0)
|
if ((phase & 0x200) != 0)
|
||||||
{
|
{
|
||||||
neg = (short)0xffff;
|
neg = 0xffff;
|
||||||
}
|
}
|
||||||
if ((phase & 0x100) != 0)
|
if ((phase & 0x100) != 0)
|
||||||
{
|
{
|
||||||
|
@ -735,12 +733,12 @@ public class OPLChip {
|
||||||
{
|
{
|
||||||
out = LOG_SIN[phase & 0xff];
|
out = LOG_SIN[phase & 0xff];
|
||||||
}
|
}
|
||||||
return (short)(waveExp(out + (envelope << 3)) ^ neg);
|
return waveExp(out + (envelope << 3)) ^ neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave1(short phase, short envelope)
|
private static int wave1(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x200) != 0)
|
if ((phase & 0x200) != 0)
|
||||||
{
|
{
|
||||||
|
@ -757,9 +755,9 @@ public class OPLChip {
|
||||||
return waveExp(out + (envelope << 3));
|
return waveExp(out + (envelope << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave2(short phase, short envelope)
|
private static int wave2(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x100) != 0)
|
if ((phase & 0x100) != 0)
|
||||||
{
|
{
|
||||||
|
@ -772,9 +770,9 @@ public class OPLChip {
|
||||||
return waveExp(out + (envelope << 3));
|
return waveExp(out + (envelope << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave3(short phase, short envelope)
|
private static int wave3(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x100) != 0)
|
if ((phase & 0x100) != 0)
|
||||||
{
|
{
|
||||||
|
@ -787,14 +785,14 @@ public class OPLChip {
|
||||||
return waveExp(out + (envelope << 3));
|
return waveExp(out + (envelope << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave4(short phase, short envelope)
|
private static int wave4(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
short neg = 0;
|
int neg = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x300) == 0x100)
|
if ((phase & 0x300) == 0x100)
|
||||||
{
|
{
|
||||||
neg = (short)0xffff;
|
neg = 0xffff;
|
||||||
}
|
}
|
||||||
if ((phase & 0x200) != 0)
|
if ((phase & 0x200) != 0)
|
||||||
{
|
{
|
||||||
|
@ -808,12 +806,12 @@ public class OPLChip {
|
||||||
{
|
{
|
||||||
out = LOG_SIN[(phase << 1) & 0xff];
|
out = LOG_SIN[(phase << 1) & 0xff];
|
||||||
}
|
}
|
||||||
return (short)(waveExp(out + (envelope << 3)) ^ neg);
|
return waveExp(out + (envelope << 3)) ^ neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave5(short phase, short envelope)
|
private static int wave5(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x200) != 0)
|
if ((phase & 0x200) != 0)
|
||||||
{
|
{
|
||||||
|
@ -830,29 +828,29 @@ public class OPLChip {
|
||||||
return waveExp(out + (envelope << 3));
|
return waveExp(out + (envelope << 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave6(short phase, short envelope)
|
private static int wave6(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short neg = 0;
|
int neg = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x200) != 0)
|
if ((phase & 0x200) != 0)
|
||||||
{
|
{
|
||||||
neg = (short)0xffff;
|
neg = 0xffff;
|
||||||
}
|
}
|
||||||
return (short)(waveExp(envelope << 3) ^ neg);
|
return waveExp(envelope << 3) ^ neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static short wave7(short phase, short envelope)
|
private static int wave7(int phase, int envelope)
|
||||||
{
|
{
|
||||||
short out = 0;
|
int out = 0;
|
||||||
short neg = 0;
|
int neg = 0;
|
||||||
phase &= 0x3ff;
|
phase &= 0x3ff;
|
||||||
if ((phase & 0x200) != 0)
|
if ((phase & 0x200) != 0)
|
||||||
{
|
{
|
||||||
neg = (short)0xffff;
|
neg = 0xffff;
|
||||||
phase = (short)((phase & 0x1ff) ^ 0x1ff);
|
phase = (phase & 0x1ff) ^ 0x1ff;
|
||||||
}
|
}
|
||||||
out = (short)(phase << 3);
|
out = phase << 3;
|
||||||
return (short)(waveExp(out + (envelope << 3)) ^ neg);
|
return waveExp(out + (envelope << 3)) ^ neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void genFrame()
|
private void genFrame()
|
||||||
|
@ -883,29 +881,31 @@ public class OPLChip {
|
||||||
|
|
||||||
if ((this.timer & 0x3f) == 0x3f)
|
if ((this.timer & 0x3f) == 0x3f)
|
||||||
{
|
{
|
||||||
this.tremolopos = (short)((this.tremolopos + 1) % 210);
|
this.tremolopos = (this.tremolopos + 1) % 210;
|
||||||
}
|
}
|
||||||
if (this.tremolopos < 105)
|
if (this.tremolopos < 105)
|
||||||
{
|
{
|
||||||
this.tremolov = (short)(this.tremolopos >> this.tremoloshift);
|
this.tremolov = this.tremolopos >> this.tremoloshift;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.tremolov = (short)((210 - this.tremolopos) >> this.tremoloshift);
|
this.tremolov = (210 - this.tremolopos) >> this.tremoloshift;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this.timer & 0x3ff) == 0x3ff)
|
if ((this.timer & 0x3ff) == 0x3ff)
|
||||||
{
|
{
|
||||||
this.vibpos = (byte)((this.vibpos + 1) & 7);
|
this.vibpos = (this.vibpos + 1) & 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.timer++;
|
this.timer++;
|
||||||
|
if(this.timer == 0x10000)
|
||||||
|
this.timer = 0;
|
||||||
|
|
||||||
this.eg_add = 0;
|
this.eg_add = 0;
|
||||||
if (this.eg_timer != 0)
|
if (this.eg_timer != 0)
|
||||||
{
|
{
|
||||||
byte shift = 0;
|
int shift = 0;
|
||||||
while (shift < 36 && ((this.eg_timer >> shift) & 1) == 0)
|
while (shift < 36 && ((this.eg_timer >> shift) & 1L) == 0L)
|
||||||
{
|
{
|
||||||
shift++;
|
shift++;
|
||||||
}
|
}
|
||||||
|
@ -915,21 +915,21 @@ public class OPLChip {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.eg_add = (byte)(shift + 1);
|
this.eg_add = shift + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.eg_timerrem != 0 || this.eg_state)
|
if (this.eg_timerrem || this.eg_state)
|
||||||
{
|
{
|
||||||
if (this.eg_timer == 0xfffffffffL)
|
if (this.eg_timer == 0xfffffffffL)
|
||||||
{
|
{
|
||||||
this.eg_timer = 0;
|
this.eg_timer = 0;
|
||||||
this.eg_timerrem = 1;
|
this.eg_timerrem = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.eg_timer++;
|
this.eg_timer++;
|
||||||
this.eg_timerrem = 0;
|
this.eg_timerrem = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,10 +956,10 @@ public class OPLChip {
|
||||||
public OPLChip(int samplerate, int voices, int velo_func, int nts, boolean deeptremolo, boolean deepvibrato) {
|
public OPLChip(int samplerate, int voices, int velo_func, int nts, boolean deeptremolo, boolean deepvibrato) {
|
||||||
this.channel = new OPLChannel[voices];
|
this.channel = new OPLChannel[voices];
|
||||||
this.rateratio = (samplerate << RSM_FRAC) / 49716;
|
this.rateratio = (samplerate << RSM_FRAC) / 49716;
|
||||||
this.velo_func = (byte)velo_func;
|
this.velo_func = velo_func;
|
||||||
this.nts = (byte)nts;
|
this.nts = nts;
|
||||||
this.tremoloshift = (byte)(deeptremolo ? 2 : 4);
|
this.tremoloshift = deeptremolo ? 2 : 4;
|
||||||
this.vibshift = (byte)(deepvibrato ? 0 : 1);
|
this.vibshift = deepvibrato ? 0 : 1;
|
||||||
for(int z = 0; z < this.channel.length; z++) {
|
for(int z = 0; z < this.channel.length; z++) {
|
||||||
this.channel[z] = new OPLChannel();
|
this.channel[z] = new OPLChannel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ public class GuiMenu extends Gui {
|
||||||
}, "MIDI-Player"));
|
}, "MIDI-Player"));
|
||||||
this.add(new ActButton(0, 130, 180, 0, new ButtonCallback() {
|
this.add(new ActButton(0, 130, 180, 0, new ButtonCallback() {
|
||||||
public void use(ActButton elem, PressType action) {
|
public void use(ActButton elem, PressType action) {
|
||||||
GuiMenu.this.gm.testMidi(22);
|
GuiMenu.this.gm.testMidi(0);
|
||||||
}
|
}
|
||||||
}, "MIDI-Bank testen"));
|
}, "MIDI-Bank testen"));
|
||||||
this.add(new ActButton(0, 150, 180, 0, new ButtonCallback() {
|
this.add(new ActButton(0, 150, 180, 0, new ButtonCallback() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue