diff options
-rw-r--r-- | backends/midi/adlib.cpp | 4 | ||||
-rw-r--r-- | common/system.h | 11 | ||||
-rw-r--r-- | sound/fmopl.cpp | 137 | ||||
-rw-r--r-- | sound/fmopl.h | 2 |
4 files changed, 97 insertions, 57 deletions
diff --git a/backends/midi/adlib.cpp b/backends/midi/adlib.cpp index 120462f6aa..4f35f0322e 100644 --- a/backends/midi/adlib.cpp +++ b/backends/midi/adlib.cpp @@ -737,6 +737,8 @@ int MidiDriver_ADLIB::open () int i; MidiChannelAdl *mc; + int env_bits = g_system->property(OSystem::PROP_GET_FMOPL_ENV_BITS, NULL); + int eg_ent = g_system->property(OSystem::PROP_GET_FMOPL_EG_ENT, NULL); for (i = 0, mc = _midi_channels; i != ARRAYSIZE(_midi_channels); i++, mc++) { mc->_channel = i; @@ -746,6 +748,8 @@ int MidiDriver_ADLIB::open () _adlib_reg_cache = (byte *)calloc(256, 1); + OPLBuildTables((env_bits ? env_bits : FMOPL_ENV_BITS_HQ), (eg_ent ? eg_ent : FMOPL_EG_ENT_HQ)); + _opl = OPLCreate(OPL_TYPE_YM3812, 3579545, g_system->property(OSystem::PROP_GET_SAMPLE_RATE, 0)); adlib_write(1, 0x20); diff --git a/common/system.h b/common/system.h index 995c2d10be..11bf5df53b 100644 --- a/common/system.h +++ b/common/system.h @@ -72,7 +72,9 @@ public: PROP_SET_GFX_MODE = 4, PROP_SHOW_DEFAULT_CURSOR = 5, PROP_GET_SAMPLE_RATE = 6, - PROP_GET_FULLSCREEN = 7 + PROP_GET_FULLSCREEN = 7, + PROP_GET_FMOPL_ENV_BITS = 8, + PROP_GET_FMOPL_EG_ENT = 9 }; union Property { const char *caption; @@ -260,4 +262,11 @@ enum { #endif }; +enum { + FMOPL_ENV_BITS_HQ = 16, + FMOPL_ENV_BITS_LQ = 8, + FMOPL_EG_ENT_HQ = 4096, + FMOPL_EG_ENT_LQ = 128 +}; + #endif diff --git a/sound/fmopl.cpp b/sound/fmopl.cpp index d635e6ad12..ed2fab72bb 100644 --- a/sound/fmopl.cpp +++ b/sound/fmopl.cpp @@ -62,16 +62,16 @@ /* output level entries (envelope,sinwave) */ /* envelope counter lower bits */ -#define ENV_BITS 16 +int ENV_BITS; /* envelope output entries */ -#define EG_ENT 4096 +int EG_ENT; + /* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */ /* used static memory = EG_ENT*4 (byte) */ - -#define EG_OFF ((2*EG_ENT)<<ENV_BITS) /* OFF */ -#define EG_DED EG_OFF -#define EG_DST (EG_ENT<<ENV_BITS) /* DECAY START */ -#define EG_AED EG_DST +int EG_OFF; /* OFF */ +int EG_DED; +int EG_DST; /* DECAY START */ +int EG_AED; #define EG_AST 0 /* ATTACK START */ #define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step */ @@ -104,61 +104,59 @@ static const int slot_array[32]= -1,-1,-1,-1,-1,-1,-1,-1 }; -#define SC(mydb) ((uint) (mydb / (EG_STEP/2))) +static uint KSL_TABLE[8 * 16]; -static const uint KSL_TABLE[8 * 16] = { +static const double KSL_TABLE_SEED[8 * 16] = { /* OCT 0 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), + 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, /* OCT 1 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(0.750), SC(1.125), SC(1.500), - SC(1.875), SC(2.250), SC(2.625), SC(3.000), + 0.000, 0.000, 0.000, 0.000, + 0.000, 0.000, 0.000, 0.000, + 0.000, 0.750, 1.125, 1.500, + 1.875, 2.250, 2.625, 3.000, /* OCT 2 */ - SC(0.000), SC(0.000), SC(0.000), SC(0.000), - SC(0.000), SC(1.125), SC(1.875), SC(2.625), - SC(3.000), SC(3.750), SC(4.125), SC(4.500), - SC(4.875), SC(5.250), SC(5.625), SC(6.000), + 0.000, 0.000, 0.000, 0.000, + 0.000, 1.125, 1.875, 2.625, + 3.000, 3.750, 4.125, 4.500, + 4.875, 5.250, 5.625, 6.000, /* OCT 3 */ - SC(0.000), SC(0.000), SC(0.000), SC(1.875), - SC(3.000), SC(4.125), SC(4.875), SC(5.625), - SC(6.000), SC(6.750), SC(7.125), SC(7.500), - SC(7.875), SC(8.250), SC(8.625), SC(9.000), + 0.000, 0.000, 0.000, 1.875, + 3.000, 4.125, 4.875, 5.625, + 6.000, 6.750, 7.125, 7.500, + 7.875, 8.250, 8.625, 9.000, /* OCT 4 */ - SC(0.000), SC(0.000), SC(3.000), SC(4.875), - SC(6.000), SC(7.125), SC(7.875), SC(8.625), - SC(9.000), SC(9.750), SC(10.125), SC(10.500), - SC(10.875), SC(11.250), SC(11.625), SC(12.000), + 0.000, 0.000, 3.000, 4.875, + 6.000, 7.125, 7.875, 8.625, + 9.000, 9.750, 10.125, 10.500, + 10.875, 11.250, 11.625, 12.000, /* OCT 5 */ - SC(0.000), SC(3.000), SC(6.000), SC(7.875), - SC(9.000), SC(10.125), SC(10.875), SC(11.625), - SC(12.000), SC(12.750), SC(13.125), SC(13.500), - SC(13.875), SC(14.250), SC(14.625), SC(15.000), + 0.000, 3.000, 6.000, 7.875, + 9.000, 10.125, 10.875, 11.625, + 12.000, 12.750, 13.125, 13.500, + 13.875, 14.250, 14.625, 15.000, /* OCT 6 */ - SC(0.000), SC(6.000), SC(9.000), SC(10.875), - SC(12.000), SC(13.125), SC(13.875), SC(14.625), - SC(15.000), SC(15.750), SC(16.125), SC(16.500), - SC(16.875), SC(17.250), SC(17.625), SC(18.000), + 0.000, 6.000, 9.000, 10.875, + 12.000, 13.125, 13.875, 14.625, + 15.000, 15.750, 16.125, 16.500, + 16.875, 17.250, 17.625, 18.000, /* OCT 7 */ - SC(0.000), SC(9.000), SC(12.000), SC(13.875), - SC(15.000), SC(16.125), SC(16.875), SC(17.625), - SC(18.000), SC(18.750), SC(19.125), SC(19.500), - SC(19.875), SC(20.250), SC(20.625), SC(21.000) + 0.000, 9.000, 12.000, 13.875, + 15.000, 16.125, 16.875, 17.625, + 18.000, 18.750, 19.125, 19.500, + 19.875, 20.250, 20.625, 21.000 }; -#undef SC - /* sustain lebel table (3db per step) */ /* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/ -#define SC(db) (int)(db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST -static const int SL_TABLE[16]={ - SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7), - SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31) + +static int SL_TABLE[16]; + +static const uint SL_TABLE_SEED[16]={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 31 }; -#undef SC #define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */ /* TotalLevel : 48 24 12 6 3 1.5 0.75 (dB) */ @@ -175,7 +173,8 @@ static int *VIB_TABLE; /* envelope output curve table */ /* attack + decay + OFF */ -static int ENV_CURVE[2*EG_ENT+1]; +//static int ENV_CURVE[2*EG_ENT+1]; +static int ENV_CURVE[2 * 4096+1]; // to keep it static ... /* multiple table */ #define ML(a) (int)(a*2) @@ -212,6 +211,32 @@ static int amsIncr; static int vibIncr; static int feedback2; /* connect for SLOT 2 */ +/* --------------------- rebuild tables ------------------- */ + +#define SC_KSL(mydb) ((uint) (mydb / (EG_STEP/2))) +#define SC_SL(db) (int)(db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST + +void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM) { + int i; + + ENV_BITS = ENV_BITS_PARAM; + EG_ENT = EG_ENT_PARAM; + EG_OFF = ((2*EG_ENT)<<ENV_BITS); /* OFF */ + EG_DED = EG_OFF; + EG_DST = (EG_ENT<<ENV_BITS); /* DECAY START */ + EG_AED = EG_DST; + //EG_STEP = (96.0/EG_ENT); + + for (i=0; i<sizeof(KSL_TABLE_SEED); i++) + KSL_TABLE[i] = SC_KSL(KSL_TABLE_SEED[i]); + + for (i=0; i<sizeof(SL_TABLE_SEED); i++) + SL_TABLE[i] = SC_SL(SL_TABLE_SEED[i]); +} + +#undef SC_KSL +#undef SC_SL + /* --------------------- subroutines --------------------- */ inline int Limit( int val, int max, int min ) { @@ -431,7 +456,7 @@ inline void OPL_CALC_CH( OPL_CH *CH ) /* SLOT 1 */ SLOT = &CH->SLOT[SLOT1]; env_out=OPL_CALC_SLOT(SLOT); - if( env_out < EG_ENT-1 ) + if( env_out < (uint)(EG_ENT-1)) { /* PG */ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); @@ -455,7 +480,7 @@ inline void OPL_CALC_CH( OPL_CH *CH ) /* SLOT 2 */ SLOT = &CH->SLOT[SLOT2]; env_out=OPL_CALC_SLOT(SLOT); - if( env_out < EG_ENT-1 ) + if( env_out < (uint)(EG_ENT-1) ) { /* PG */ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); @@ -537,16 +562,16 @@ inline void OPL_CALC_RH( OPL_CH *CH ) tone8 = OP_OUT(SLOT8_2,whitenoise,0 ); /* SD */ - if( env_sd < EG_ENT-1 ) + if( env_sd < (uint)(EG_ENT-1) ) outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8; /* TAM */ - if( env_tam < EG_ENT-1 ) + if( env_tam < (uint)(EG_ENT-1) ) outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2; /* TOP-CY */ - if( env_top < EG_ENT-1 ) + if( env_top < (uint)(EG_ENT-1) ) outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2; /* HH */ - if( env_hh < EG_ENT-1 ) + if( env_hh < (uint)(EG_ENT-1) ) outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2; } @@ -1144,4 +1169,4 @@ int OPLTimerOver(FM_OPL *OPL,int c) /* reload timer */ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); return OPL->status>>7; -} +}
\ No newline at end of file diff --git a/sound/fmopl.h b/sound/fmopl.h index 8e38342e45..64b64d3e73 100644 --- a/sound/fmopl.h +++ b/sound/fmopl.h @@ -135,6 +135,8 @@ typedef struct fm_opl_f { #define OPL_TYPE_YM3526 (0) #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) +void OPLBuildTables(int ENV_BITS_PARAM, int EG_ENT_PARAM); + FM_OPL *OPLCreate(int type, int clock, int rate); void OPLDestroy(FM_OPL *OPL); void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset); |