moved FM timers back to integer, fixed libsamplerate warnings

This commit is contained in:
ekeeke31 2008-08-19 20:04:21 +00:00
parent d21599f529
commit a5f6f5d9c2
3 changed files with 22 additions and 36 deletions

View File

@ -49,10 +49,10 @@
#undef HAVE_LIBM #undef HAVE_LIBM
/* Define if you have C99's lrint function. */ /* Define if you have C99's lrint function. */
#define HAVE_LRINT 0 #define HAVE_LRINT 1
/* Define if you have C99's lrintf function. */ /* Define if you have C99's lrintf function. */
#define HAVE_LRINTF 0 #define HAVE_LRINTF 1
/* Define to 1 if you have the `malloc' function. */ /* Define to 1 if you have the `malloc' function. */
#undef HAVE_MALLOC #undef HAVE_MALLOC

View File

@ -540,17 +540,17 @@ typedef struct
int clock; /* master clock (Hz) */ int clock; /* master clock (Hz) */
int rate; /* sampling rate (Hz) */ int rate; /* sampling rate (Hz) */
double freqbase; /* frequency base */ double freqbase; /* frequency base */
int TimerBase; /* Timer base time */
UINT8 address[2]; /* address register */ UINT8 address[2]; /* address register */
UINT8 status; /* status flag */ UINT8 status; /* status flag */
UINT32 mode; /* mode CSM / 3SLOT */ UINT32 mode; /* mode CSM / 3SLOT */
UINT8 fn_h; /* freq latch */ UINT8 fn_h; /* freq latch */
int TimerBase; /* Timer base time */
int TA; /* timer a value */ int TA; /* timer a value */
double TAL; /* timer a base */ int TAL; /* timer a base */
double TAC; /* timer a counter */ int TAC; /* timer a counter */
int TB; /* timer b */ int TB; /* timer b */
double TBL; /* timer b base */ int TBL; /* timer b base */
double TBC; /* timer b counter */ int TBC; /* timer b counter */
/* local time tables */ /* local time tables */
INT32 dt_tab[8][32];/* DeTune table */ INT32 dt_tab[8][32];/* DeTune table */
@ -1065,10 +1065,10 @@ INLINE void update_phase_lfo_slot(FM_SLOT *SLOT , INT32 pms, UINT32 block_fnum)
/* keyscale code */ /* keyscale code */
int kc = (blk<<2) | opn_fktable[fn >> 8]; int kc = (blk<<2) | opn_fktable[fn >> 8];
/* phase increment counter */ /* (frequency) phase increment counter */
int fc = (ym2612.OPN.fn_table[fn]>>(7-blk)) + SLOT->DT[kc]; int fc = (ym2612.OPN.fn_table[fn]>>(7-blk)) + SLOT->DT[kc];
/* detects frequency overflow (credits to Nemesis) */ /* (frequency) phase overflow (credits to Nemesis) */
if (fc < 0) fc += fn_max; if (fc < 0) fc += fn_max;
/* update phase */ /* update phase */
@ -1097,10 +1097,10 @@ INLINE void update_phase_lfo_channel(FM_CH *CH)
/* keyscale code */ /* keyscale code */
int kc = (blk<<2) | opn_fktable[fn >> 8]; int kc = (blk<<2) | opn_fktable[fn >> 8];
/* phase increment counter */ /* (frequency) phase increment counter */
int fc = (ym2612.OPN.fn_table[fn]>>(7-blk)); int fc = (ym2612.OPN.fn_table[fn]>>(7-blk));
/* detects frequency overflow (credits to Nemesis) */ /* (frequency) phase overflow (credits to Nemesis) */
int finc = fc + CH->SLOT[SLOT1].DT[kc]; int finc = fc + CH->SLOT[SLOT1].DT[kc];
if (finc < 0) finc += fn_max; if (finc < 0) finc += fn_max;
CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1; CH->SLOT[SLOT1].phase += (finc*CH->SLOT[SLOT1].mul) >> 1;
@ -1206,7 +1206,7 @@ INLINE void refresh_fc_eg_slot(FM_SLOT *SLOT , int fc , int kc )
fc += SLOT->DT[kc]; fc += SLOT->DT[kc];
/* detects frequency overflow (credits to Nemesis) */ /* (frequency) phase overflow (credits to Nemesis) */
if (fc < 0) fc += fn_max; if (fc < 0) fc += fn_max;
/* (frequency) phase increment counter */ /* (frequency) phase increment counter */
@ -1421,7 +1421,7 @@ static void INTERNAL_TIMER_B(int step)
{ {
if (ym2612.OPN.ST.mode & 0x02) if (ym2612.OPN.ST.mode & 0x02)
{ {
if ((ym2612.OPN.ST.TBC -= (ym2612.OPN.ST.TimerBase * (double)step)) <= 0) if ((ym2612.OPN.ST.TBC -= (ym2612.OPN.ST.TimerBase * step)) <= 0)
{ {
/* set status (if enabled) */ /* set status (if enabled) */
if (ym2612.OPN.ST.mode & 0x08) ym2612.OPN.ST.status |= 0x02; if (ym2612.OPN.ST.mode & 0x08) ym2612.OPN.ST.status |= 0x02;
@ -1437,28 +1437,25 @@ static void OPNSetPres(int pres)
{ {
int i; int i;
if (config.hq_fm)
{
ym2612.OPN.ST.rate = ym2612.OPN.ST.clock / pres;
}
/* frequency base */ /* frequency base */
ym2612.OPN.ST.freqbase = ((double) ym2612.OPN.ST.clock / (double) ym2612.OPN.ST.rate) / ((double) pres); ym2612.OPN.ST.freqbase = ((double) ym2612.OPN.ST.clock / (double) ym2612.OPN.ST.rate) / ((double) pres);
/* YM2612 running at original frequency (~53 kHz) */
if (config.hq_fm) ym2612.OPN.ST.freqbase = 1.0;
/* timer increment in usecs (timers are incremented after each updated samples) */ /* timer increment in usecs (timers are incremented after each updated samples) */
ym2612.OPN.ST.TimerBase = 1000000.0 / (double)ym2612.OPN.ST.rate; ym2612.OPN.ST.TimerBase = (int) (ym2612.OPN.ST.freqbase * 4096.0);
ym2612.OPN.eg_timer_add = (UINT32)((1<<EG_SH) * ym2612.OPN.ST.freqbase); ym2612.OPN.eg_timer_add = (UINT32)((1<<EG_SH) * ym2612.OPN.ST.freqbase);
//ym2612.OPN.eg_timer_overflow = ( 3 ) * (1<<EG_SH); //ym2612.OPN.eg_timer_overflow = ( 3 ) * (1<<EG_SH);
ym2612.OPN.eg_timer_overflow = (351 * (1<<EG_SH)) / 144; /* correct frequency (Nemesis: tested on real HW) */ ym2612.OPN.eg_timer_overflow = (351 * (1<<EG_SH)) / 144; /* correct frequency (Nemesis: tested on real HW) */
/* make time tables */ /* make time tables */
init_timetables(dt_tab); init_timetables(dt_tab);
/* there are 2048 FNUMs that can be generated using FNUM/BLK registers /* there are 2048 FNUMs that can be generated using FNUM/BLK registers
but LFO works with one more bit of a precision so we really need 4096 elements */ but LFO works with one more bit of a precision so we really need 4096 elements */
/* calculate fnumber -> increment counter table */ /* calculate fnumber -> increment counter table */
for(i = 0; i < 4096; i++) for(i = 0; i < 4096; i++)
{ {
@ -1503,15 +1500,15 @@ static void OPNWriteMode(int r, int v)
break; break;
case 0x24: /* timer A High 8*/ case 0x24: /* timer A High 8*/
ym2612.OPN.ST.TA = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2); ym2612.OPN.ST.TA = (ym2612.OPN.ST.TA & 0x03)|(((int)v)<<2);
ym2612.OPN.ST.TAL = fm_timera_tab[ym2612.OPN.ST.TA]; ym2612.OPN.ST.TAL = (1024 - ym2612.OPN.ST.TA) << 12;
break; break;
case 0x25: /* timer A Low 2*/ case 0x25: /* timer A Low 2*/
ym2612.OPN.ST.TA = (ym2612.OPN.ST.TA & 0x3fc)|(v&3); ym2612.OPN.ST.TA = (ym2612.OPN.ST.TA & 0x3fc)|(v&3);
ym2612.OPN.ST.TAL = fm_timera_tab[ym2612.OPN.ST.TA]; ym2612.OPN.ST.TAL = (1024 - ym2612.OPN.ST.TA) << 12;
break; break;
case 0x26: /* timer B */ case 0x26: /* timer B */
ym2612.OPN.ST.TB = v; ym2612.OPN.ST.TB = v;
ym2612.OPN.ST.TBL = fm_timerb_tab[ym2612.OPN.ST.TB]; ym2612.OPN.ST.TBL = (256 - ym2612.OPN.ST.TB) << 16;
break; break;
case 0x27: /* mode, timer control */ case 0x27: /* mode, timer control */
set_timers(v); set_timers(v);

View File

@ -41,8 +41,6 @@ static SRC_DATA data;
/* YM2612 data */ /* YM2612 data */
int fm_reg[2][0x100]; /* Register arrays (2x256) */ int fm_reg[2][0x100]; /* Register arrays (2x256) */
double fm_timera_tab[0x400]; /* Precalculated timer A values (in usecs) */
double fm_timerb_tab[0x100]; /* Precalculated timer B values (in usecs) */
/* return the number of samples that should have been rendered so far */ /* return the number of samples that should have been rendered so far */
static inline uint32 fm_sample_cnt(uint8 is_z80) static inline uint32 fm_sample_cnt(uint8 is_z80)
@ -93,18 +91,9 @@ static inline void psg_update()
void sound_init(int rate) void sound_init(int rate)
{ {
int i;
double vclk = Master_Clock / 7.0; /* 68000 and YM2612 clock */ double vclk = Master_Clock / 7.0; /* 68000 and YM2612 clock */
double zclk = Master_Clock / 15.0; /* Z80 and SN76489 clock */ double zclk = Master_Clock / 15.0; /* Z80 and SN76489 clock */
/* Make Timer A table */
/* Formula is "time(us) = (1024 - A) * 144 * 1000000 / clock" */
for(i = 0; i < 1024; i += 1) fm_timera_tab[i] = ((double)((1024 - i) * 144) * 1000000.0 / vclk);
/* Make Timer B table */
/* Formula is "time(us) = 16 * (256 - B) * 144 * 1000000 / clock" */
for(i = 0; i < 256; i += 1) fm_timerb_tab[i] = ((double)((256 - i) * 16 * 144) * 1000000.0 / vclk);
/* cycle-accurate FM samples */ /* cycle-accurate FM samples */
if (config.hq_fm && !config.fm_core) if (config.hq_fm && !config.fm_core)
{ {