- More culling from fmopl.cpp; make the rate parameters constants since it sounds bad with anything but the real clock rate.

SVN r3940 (trunk)
This commit is contained in:
Randy Heit 2012-11-06 04:34:44 +00:00
parent 92c7c06310
commit 1640f841e8
3 changed files with 18 additions and 99 deletions

View file

@ -155,16 +155,10 @@ Revision History:
#define EG_OFF 0 #define EG_OFF 0
#define OPL_TYPE_WAVESEL 0x01 /* waveform select */ #define OPL_CLOCK 3579545 // master clock (Hz)
#define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ #define OPL_RATE 49716 // sampling rate (Hz)
#define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ #define OPL_TIMERBASE (OPL_CLOCK / 72.0) // Timer base time (==sampling time)
#define OPL_TYPE_IO 0x08 /* I/O port */ #define OPL_FREQBASE (OPL_TIMERBASE / OPL_RATE) // frequency base
/* ---------- Generic interface section ---------- */
#define OPL_TYPE_YM3526 (0)
#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
#define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
/* Saving is necessary for member of the 'R' mark for suspend/resume */ /* Saving is necessary for member of the 'R' mark for suspend/resume */
@ -261,16 +255,11 @@ typedef struct fm_opl_f {
OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */ OPL_UPDATEHANDLER UpdateHandler;/* stream update handler */
int UpdateParam; /* stream update parameter */ int UpdateParam; /* stream update parameter */
UINT8 type; /* chip type */
UINT8 address; /* address register */ UINT8 address; /* address register */
UINT8 status; /* status flag */ UINT8 status; /* status flag */
UINT8 statusmask; /* status mask */ UINT8 statusmask; /* status mask */
UINT8 mode; /* Reg.08 : CSM,notesel,etc. */ UINT8 mode; /* Reg.08 : CSM,notesel,etc. */
int clock; /* master clock (Hz) */
int rate; /* sampling rate (Hz) */
double freqbase; /* frequency base */
double TimerBase; /* Timer base time (==sampling time)*/
bool IsStereo; /* Write stereo output */ bool IsStereo; /* Write stereo output */
} FM_OPL; } FM_OPL;
@ -1117,15 +1106,7 @@ static int init_tables(void)
tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i; tl_tab[ x*2+0 + i*2*TL_RES_LEN ] = tl_tab[ x*2+0 ]>>i;
tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 ]>>i; tl_tab[ x*2+1 + i*2*TL_RES_LEN ] = -tl_tab[ x*2+0 ]>>i;
} }
#if 0
logerror("tl %04i", x*2);
for (i=0; i<12; i++)
logerror(", [%02i] %5i", i*2, tl_tab[ x*2 /*+1*/ + i*2*TL_RES_LEN ] );
logerror("\n");
#endif
} }
/*logerror("FMOPL.C: TL_TAB_LEN = %i elements (%i bytes)\n",TL_TAB_LEN, (int)sizeof(tl_tab));*/
for (i=0; i<SIN_LEN; i++) for (i=0; i<SIN_LEN; i++)
{ {
@ -1148,8 +1129,6 @@ static int init_tables(void)
n = n>>1; n = n>>1;
sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 ); sin_tab[ i ] = n*2 + (m>=0.0? 0: 1 );
/*logerror("FMOPL.C: sin [%4i (hex=%03x)]= %4i (tl_tab value=%5i)\n", i, i, sin_tab[i], tl_tab[sin_tab[i]] );*/
} }
for (i=0; i<SIN_LEN; i++) for (i=0; i<SIN_LEN; i++)
@ -1177,79 +1156,31 @@ static int init_tables(void)
sin_tab[3*SIN_LEN+i] = TL_TAB_LEN; sin_tab[3*SIN_LEN+i] = TL_TAB_LEN;
else else
sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)]; sin_tab[3*SIN_LEN+i] = sin_tab[i & (SIN_MASK>>2)];
/*logerror("FMOPL.C: sin1[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[1*SIN_LEN+i], tl_tab[sin_tab[1*SIN_LEN+i]] );
logerror("FMOPL.C: sin2[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[2*SIN_LEN+i], tl_tab[sin_tab[2*SIN_LEN+i]] );
logerror("FMOPL.C: sin3[%4i]= %4i (tl_tab value=%5i)\n", i, sin_tab[3*SIN_LEN+i], tl_tab[sin_tab[3*SIN_LEN+i]] );*/
} }
/*logerror("FMOPL.C: ENV_QUIET= %08x (dec*8=%i)\n", ENV_QUIET, ENV_QUIET*8 );*/
return 1; return 1;
} }
static void OPLCloseTable( void )
{
}
static void OPL_initalize(FM_OPL *OPL) static void OPL_initalize(FM_OPL *OPL)
{ {
int i; int i;
/* frequency base */
OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / 72.0) / OPL->rate : 0;
#if 0
OPL->rate = (double)OPL->clock / 72.0;
OPL->freqbase = 1.0;
#endif
/* Timer base time */
OPL->TimerBase = 1.0 / ((double)OPL->clock / 72.0 );
/* make fnumber -> increment counter table */ /* make fnumber -> increment counter table */
for( i=0 ; i < 1024 ; i++ ) for( i=0 ; i < 1024 ; i++ )
{ {
/* opn phase increment counter = 20bit */ /* opn phase increment counter = 20bit */
OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL->freqbase * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */ OPL->fn_tab[i] = (UINT32)( (double)i * 64 * OPL_FREQBASE * (1<<(FREQ_SH-10)) ); /* -10 because chip works with 10.10 fixed point, while we use 16.16 */
#if 0
logerror("FMOPL.C: fn_tab[%4i] = %08x (dec=%8i)\n",
i, OPL->fn_tab[i]>>6, OPL->fn_tab[i]>>6 );
#endif
} }
#if 0
for( i=0 ; i < 16 ; i++ )
{
logerror("FMOPL.C: sl_tab[%i] = %08x\n",
i, sl_tab[i] );
}
for( i=0 ; i < 8 ; i++ )
{
int j;
logerror("FMOPL.C: ksl_tab[oct=%2i] =",i);
for (j=0; j<16; j++)
{
logerror("%08x ", ksl_tab[i*16+j] );
}
logerror("\n");
}
#endif
/* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */ /* Amplitude modulation: 27 output levels (triangle waveform); 1 level takes one of: 192, 256 or 448 samples */
/* One entry from LFO_AM_TABLE lasts for 64 samples */ /* One entry from LFO_AM_TABLE lasts for 64 samples */
OPL->lfo_am_inc = UINT32((1.0 / 64.0 ) * (1<<LFO_SH) * OPL->freqbase); OPL->lfo_am_inc = UINT32((1.0 / 64.0 ) * (1<<LFO_SH) * OPL_FREQBASE);
/* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */ /* Vibrato: 8 output levels (triangle waveform); 1 level takes 1024 samples */
OPL->lfo_pm_inc = UINT32((1.0 / 1024.0) * (1<<LFO_SH) * OPL->freqbase); OPL->lfo_pm_inc = UINT32((1.0 / 1024.0) * (1<<LFO_SH) * OPL_FREQBASE);
/*logerror ("OPL->lfo_am_inc = %8x ; OPL->lfo_pm_inc = %8x\n", OPL->lfo_am_inc, OPL->lfo_pm_inc);*/ OPL->eg_timer_add = UINT32((1<<EG_SH) * OPL_FREQBASE);
OPL->eg_timer_add = UINT32((1<<EG_SH) * OPL->freqbase);
OPL->eg_timer_overflow = UINT32(( 1 ) * (1<<EG_SH)); OPL->eg_timer_overflow = UINT32(( 1 ) * (1<<EG_SH));
/*logerror("OPLinit eg_timer_add=%8x eg_timer_overflow=%8x\n", OPL->eg_timer_add, OPL->eg_timer_overflow);*/
// [RH] Support full MIDI panning. (But default to mono and center panning.) // [RH] Support full MIDI panning. (But default to mono and center panning.)
OPL->IsStereo = false; OPL->IsStereo = false;
@ -1400,11 +1331,7 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v)
switch(r&0x1f) switch(r&0x1f)
{ {
case 0x01: /* waveform select enable */ case 0x01: /* waveform select enable */
if(OPL->type&OPL_TYPE_WAVESEL)
{
OPL->wavesel = v&0x20; OPL->wavesel = v&0x20;
/* do not change the waveform previously selected */
}
break; break;
case 0x02: /* Timer 1 */ case 0x02: /* Timer 1 */
OPL->T[0] = (256-v)*4; OPL->T[0] = (256-v)*4;
@ -1428,14 +1355,14 @@ static void OPLWriteReg(FM_OPL *OPL, int r, int v)
/* timer 2 */ /* timer 2 */
if(OPL->st[1] != st2) if(OPL->st[1] != st2)
{ {
double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; double interval = st2 ? (double)OPL->T[1]*OPL_TIMERBASE : 0.0;
OPL->st[1] = st2; OPL->st[1] = st2;
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
} }
/* timer 1 */ /* timer 1 */
if(OPL->st[0] != st1) if(OPL->st[0] != st1)
{ {
double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; double interval = st1 ? (double)OPL->T[0]*OPL_TIMERBASE : 0.0;
OPL->st[0] = st1; OPL->st[0] = st1;
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
} }
@ -1612,10 +1539,6 @@ static void OPL_UnLockTable(void)
{ {
if(num_lock) num_lock--; if(num_lock) num_lock--;
if(num_lock) return; if(num_lock) return;
/* last time */
OPLCloseTable();
} }
static void OPLResetChip(FM_OPL *OPL) static void OPLResetChip(FM_OPL *OPL)
@ -1654,7 +1577,7 @@ static void OPLResetChip(FM_OPL *OPL)
/* Create one of virtual YM3812 */ /* Create one of virtual YM3812 */
/* 'clock' is chip clock in Hz */ /* 'clock' is chip clock in Hz */
/* 'rate' is sampling rate */ /* 'rate' is sampling rate */
static FM_OPL *OPLCreate(int type, int clock, int rate) static FM_OPL *OPLCreate()
{ {
char *ptr; char *ptr;
FM_OPL *OPL; FM_OPL *OPL;
@ -1678,10 +1601,6 @@ static FM_OPL *OPLCreate(int type, int clock, int rate)
ptr += sizeof(FM_OPL); ptr += sizeof(FM_OPL);
OPL->type = type;
OPL->clock = clock;
OPL->rate = rate;
/* init global tables */ /* init global tables */
OPL_initalize(OPL); OPL_initalize(OPL);
@ -1772,15 +1691,15 @@ static int OPLTimerOver(FM_OPL *OPL,int c)
} }
} }
/* reload timer */ /* reload timer */
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL_TIMERBASE);
return OPL->status>>7; return OPL->status>>7;
} }
void *YM3812Init(int clock, int rate) void *YM3812Init()
{ {
/* emulator create */ /* emulator create */
FM_OPL *YM3812 = OPLCreate(OPL_TYPE_YM3812,clock,rate); FM_OPL *YM3812 = OPLCreate();
if (YM3812) if (YM3812)
YM3812ResetChip(YM3812); YM3812ResetChip(YM3812);
return YM3812; return YM3812;

View file

@ -25,7 +25,7 @@ typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data);
typedef unsigned char (*OPL_PORTHANDLER_R)(int param); typedef unsigned char (*OPL_PORTHANDLER_R)(int param);
void *YM3812Init(int clock, int rate); void *YM3812Init();
void YM3812Shutdown(void *chip); void YM3812Shutdown(void *chip);
void YM3812ResetChip(void *chip); void YM3812ResetChip(void *chip);
int YM3812Write(void *chip, int a, int v); int YM3812Write(void *chip, int a, int v);

View file

@ -307,14 +307,14 @@ void OPLio::OPLshutup(void)
int OPLio::OPLinit(uint numchips, bool stereo) int OPLio::OPLinit(uint numchips, bool stereo)
{ {
assert(numchips >= 1 && numchips <= 2); assert(numchips >= 1 && numchips <= 2);
chips[0] = YM3812Init (3579545, int(OPL_SAMPLE_RATE)); chips[0] = YM3812Init();
chips[1] = NULL; chips[1] = NULL;
if (chips[0] != NULL) if (chips[0] != NULL)
{ {
YM3812SetStereo(chips[0], stereo); YM3812SetStereo(chips[0], stereo);
if (numchips > 1) if (numchips > 1)
{ {
chips[1] = YM3812Init (3579545, int(OPL_SAMPLE_RATE)); chips[1] = YM3812Init();
if (chips[1] == NULL) if (chips[1] == NULL)
{ {
YM3812Shutdown(chips[0]); YM3812Shutdown(chips[0]);