1
0
Fork 0
forked from len0rd/rockbox

Further work on libgme's emu2413. Fully remove floating point, introduce another precalculated table, directly use predefined tables instead of copying them. Reduces memory and codesize by several KB.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30494 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Andree Buschmann 2011-09-10 10:45:44 +00:00
parent e8dc7a6d07
commit 4096cb1830
2 changed files with 87 additions and 27 deletions

View file

@ -182,8 +182,21 @@ static e_uint16 halfsintable[PG_WIDTH];
static e_uint16 *waveform[2] = { fullsintable, halfsintable }; static e_uint16 *waveform[2] = { fullsintable, halfsintable };
/* LFO Table */ /* LFO Table */
static e_int32 pmtable[PM_PG_WIDTH]; #ifdef EMU2413_CALCUL_TABLES
static e_int32 amtable[AM_PG_WIDTH]; static e_int32 pmtable[PM_PG_WIDTH];
static e_int32 amtable[AM_PG_WIDTH];
#define PMTABLE(x) pmtable[x]
#define AMTABLE(x) amtable[x]
#else
#define PMTABLE(x) (e_int32)pm_coeff[x]
#if (PM_PG_WIDTH != 256)
#error PM_PG_WIDTH must be set to 256 if EMU2413_CALCUL_TABLES is not defined
#endif
#define AMTABLE(x) (e_int32)am_coeff[x]
#if (AM_PG_WIDTH != 256)
#error AM_PG_WIDTH must be set to 256 if EMU2413_CALCUL_TABLES is not defined
#endif
#endif
/* Phase delta for LFO */ /* Phase delta for LFO */
static e_uint32 pm_dphase; static e_uint32 pm_dphase;
@ -193,7 +206,15 @@ static e_uint32 am_dphase;
static e_int16 DB2LIN_TABLE[(DB_MUTE + DB_MUTE) * 2]; static e_int16 DB2LIN_TABLE[(DB_MUTE + DB_MUTE) * 2];
/* Liner to Log curve conversion table (for Attack rate). */ /* Liner to Log curve conversion table (for Attack rate). */
static e_uint16 AR_ADJUST_TABLE[1 << EG_BITS]; #ifdef EMU2413_CALCUL_TABLES
static e_uint16 ar_adjust_table[1 << EG_BITS];
#define AR_ADJUST_TABLE(x) ar_adjust_table[x]
#else
#define AR_ADJUST_TABLE(x) ar_adjust_coeff[x]
#if (EG_BITS != 7)
#error EG_BITS must be set to 7 if EMU2413_CALCUL_TABLES is not defined
#endif
#endif
/* Empty voice data */ /* Empty voice data */
static OPLL_PATCH null_patch = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static OPLL_PATCH null_patch = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@ -225,6 +246,7 @@ static e_uint32 dphaseTable[512][8][16];
Create tables Create tables
****************************************************/ ****************************************************/
#ifdef EMU2413_CALCUL_TABLES
INLINE static e_int32 INLINE static e_int32
Min (e_int32 i, e_int32 j) Min (e_int32 i, e_int32 j)
{ {
@ -240,15 +262,11 @@ makeAdjustTable (void)
{ {
e_int32 i; e_int32 i;
AR_ADJUST_TABLE[0] = (1 << EG_BITS) - 1; ar_adjust_table[0] = (1 << EG_BITS) - 1;
for (i = 1; i < (1<<EG_BITS); i++) for (i = 1; i < (1<<EG_BITS); i++)
#ifdef EMU2413_CALCUL_TABLES ar_adjust_table[i] = (e_uint16) ((double) (1<<EG_BITS)-1 - ((1<<EG_BITS)-1)*log(i)/log(127));
AR_ADJUST_TABLE[i] = (e_uint16) ((double) (1<<EG_BITS)-1 - ((1<<EG_BITS)-1)*log(i)/log(127));
#else
AR_ADJUST_TABLE[i] = ar_adjust_coeff[i];
#endif
} }
#endif
/* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */ /* Table for dB(0 -- (1<<DB_BITS)-1) to Liner(0 -- DB2LIN_AMP_WIDTH) */
static void static void
@ -308,6 +326,7 @@ makeSinTable (void)
halfsintable[i] = fullsintable[0]; halfsintable[i] = fullsintable[0];
} }
#ifdef EMU2413_CALCUL_TABLES
static double saw(double phase) static double saw(double phase)
{ {
if(phase <= PI/2) if(phase <= PI/2)
@ -326,11 +345,7 @@ makePmTable (void)
for (i = 0; i < PM_PG_WIDTH; i++) for (i = 0; i < PM_PG_WIDTH; i++)
/* pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * sin (2.0 * PI * i / PM_PG_WIDTH) / 1200)); */ /* pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * sin (2.0 * PI * i / PM_PG_WIDTH) / 1200)); */
#ifdef EMU2413_CALCUL_TABLES
pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * saw (2.0 * PI * i / PM_PG_WIDTH) / 1200)); pmtable[i] = (e_int32) ((double) PM_AMP * pow (2, (double) PM_DEPTH * saw (2.0 * PI * i / PM_PG_WIDTH) / 1200));
#else
pmtable[i] = pm_coeff[i];
#endif
} }
/* Table for Amp Modulator */ /* Table for Amp Modulator */
@ -343,6 +358,7 @@ makeAmTable (void)
/* amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + sin (2.0 * PI * i / PM_PG_WIDTH))); */ /* amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + sin (2.0 * PI * i / PM_PG_WIDTH))); */
amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + saw (2.0 * PI * i / PM_PG_WIDTH))); amtable[i] = (e_int32) ((double) AM_DEPTH / 2 / DB_STEP * (1.0 + saw (2.0 * PI * i / PM_PG_WIDTH)));
} }
#endif
#if !defined(ROCKBOX) #if !defined(ROCKBOX)
/* Phase increment counter table */ /* Phase increment counter table */
@ -363,10 +379,11 @@ makeDphaseTable (void)
static void static void
makeTllTable (void) makeTllTable (void)
{ {
#define dB2(x) ((x)*2) /* Multiplication owith 8 to have an integer result. This allows to remove floating point operation. */
#define dB2(x) (int)((x)*2*8)
static double kltable[16] = { static int kltable[16] = {
dB2 (0.000), dB2 (9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625), dB2 ( 0.000), dB2 ( 9.000), dB2 (12.000), dB2 (13.875), dB2 (15.000), dB2 (16.125), dB2 (16.875), dB2 (17.625),
dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000) dB2 (18.000), dB2 (18.750), dB2 (19.125), dB2 (19.500), dB2 (19.875), dB2 (20.250), dB2 (20.625), dB2 (21.000)
}; };
@ -384,11 +401,12 @@ makeTllTable (void)
} }
else else
{ {
tmp = (e_int32) (kltable[fnum] - dB2 (3.000) * (7 - block)); tmp = (e_int32) ((kltable[fnum] - dB2 (3.000) * (7 - block))/8);
if (tmp <= 0) if (tmp <= 0)
tllTable[fnum][block][TL][KL] = TL2EG (TL); tllTable[fnum][block][TL][KL] = TL2EG (TL);
else else
tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp >> (3 - KL)) / EG_STEP) + TL2EG (TL); /* tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp >> (3 - KL)) / EG_STEP) + TL2EG (TL); */
tllTable[fnum][block][TL][KL] = (e_uint32) ((tmp << KL) / (int)(EG_STEP*8)) + TL2EG (TL);
} }
} }
} }
@ -727,7 +745,7 @@ INLINE static void
slotOff (OPLL_SLOT * slot) slotOff (OPLL_SLOT * slot)
{ {
if (slot->eg_mode == ATTACK) if (slot->eg_mode == ATTACK)
slot->eg_phase = EXPAND_BITS (AR_ADJUST_TABLE[HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)], EG_BITS, EG_DP_BITS); slot->eg_phase = EXPAND_BITS (AR_ADJUST_TABLE(HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)), EG_BITS, EG_DP_BITS);
slot->eg_mode = RELEASE; slot->eg_mode = RELEASE;
UPDATE_EG(slot); UPDATE_EG(slot);
} }
@ -993,8 +1011,8 @@ internal_refresh (void)
#endif #endif
makeDphaseARTable (); makeDphaseARTable ();
makeDphaseDRTable (); makeDphaseDRTable ();
pm_dphase = (e_uint32) RATE_ADJUST (PM_SPEED * PM_DP_WIDTH / (clk / 72)); pm_dphase = (e_uint32) RATE_ADJUST ((int)(PM_SPEED * PM_DP_WIDTH) / (clk / 72));
am_dphase = (e_uint32) RATE_ADJUST (AM_SPEED * AM_DP_WIDTH / (clk / 72)); am_dphase = (e_uint32) RATE_ADJUST ((int)(AM_SPEED * AM_DP_WIDTH) / (clk / 72));
} }
static void static void
@ -1003,10 +1021,12 @@ maketables (e_uint32 c, e_uint32 r)
if (c != clk) if (c != clk)
{ {
clk = c; clk = c;
#ifdef EMU2413_CALCUL_TABLES
makePmTable (); makePmTable ();
makeAmTable (); makeAmTable ();
makeDB2LinTable ();
makeAdjustTable (); makeAdjustTable ();
#endif
makeDB2LinTable ();
makeTllTable (); makeTllTable ();
makeRksTable (); makeRksTable ();
makeSinTable (); makeSinTable ();
@ -1173,8 +1193,8 @@ update_ampm (OPLL * opll)
{ {
opll->pm_phase = (opll->pm_phase + pm_dphase) & (PM_DP_WIDTH - 1); opll->pm_phase = (opll->pm_phase + pm_dphase) & (PM_DP_WIDTH - 1);
opll->am_phase = (opll->am_phase + am_dphase) & (AM_DP_WIDTH - 1); opll->am_phase = (opll->am_phase + am_dphase) & (AM_DP_WIDTH - 1);
opll->lfo_am = amtable[HIGHBITS (opll->am_phase, AM_DP_BITS - AM_PG_BITS)]; opll->lfo_am = AMTABLE(HIGHBITS (opll->am_phase, AM_DP_BITS - AM_PG_BITS));
opll->lfo_pm = pmtable[HIGHBITS (opll->pm_phase, PM_DP_BITS - PM_PG_BITS)]; opll->lfo_pm = PMTABLE(HIGHBITS (opll->pm_phase, PM_DP_BITS - PM_PG_BITS));
} }
/* PG */ /* PG */
@ -1215,7 +1235,7 @@ calc_envelope (OPLL_SLOT * slot, e_int32 lfo)
switch (slot->eg_mode) switch (slot->eg_mode)
{ {
case ATTACK: case ATTACK:
egout = AR_ADJUST_TABLE[HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS)]; egout = AR_ADJUST_TABLE(HIGHBITS (slot->eg_phase, EG_DP_BITS - EG_BITS));
slot->eg_phase += slot->eg_dphase; slot->eg_phase += slot->eg_dphase;
if((EG_DP_WIDTH & slot->eg_phase)||(slot->patch->AR==15)) if((EG_DP_WIDTH & slot->eg_phase)||(slot->patch->AR==15))
{ {

View file

@ -28,7 +28,7 @@ static const e_uint16 sin_coeff[] = {
0, 0, 0, 0,
}; };
static const e_int32 pm_coeff[] = { static const e_int16 pm_coeff[] = {
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
@ -68,6 +68,46 @@ static const e_int32 pm_coeff[] = {
255, 255, 255, 255, 255, 255, 255, 255,
}; };
static const e_int8 am_coeff[] = {
13, 13, 13, 13, 13, 14, 14,
14, 14, 14, 15, 15, 15, 15,
15, 16, 16, 16, 16, 16, 17,
17, 17, 17, 17, 18, 18, 18,
18, 18, 19, 19, 19, 19, 19,
20, 20, 20, 20, 20, 21, 21,
21, 21, 21, 22, 22, 22, 22,
22, 23, 23, 23, 23, 23, 24,
24, 24, 24, 24, 25, 25, 25,
25, 26, 25, 25, 25, 25, 24,
24, 24, 24, 24, 23, 23, 23,
23, 23, 22, 22, 22, 22, 22,
21, 21, 21, 21, 21, 20, 20,
20, 20, 20, 19, 19, 19, 19,
19, 18, 18, 18, 18, 18, 17,
17, 17, 17, 17, 16, 16, 16,
16, 16, 15, 15, 15, 15, 15,
14, 14, 14, 14, 14, 13, 13,
13, 13, 13, 12, 12, 12, 12,
11, 11, 11, 11, 11, 10, 10,
10, 10, 10, 9, 9, 9, 9,
9, 8, 8, 8, 8, 8, 7,
7, 7, 7, 7, 6, 6, 6,
6, 6, 5, 5, 5, 5, 5,
4, 4, 4, 4, 4, 3, 3,
3, 3, 3, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 2,
2, 2, 2, 2, 3, 3, 3,
3, 3, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 6, 6,
6, 6, 6, 7, 7, 7, 7,
7, 8, 8, 8, 8, 8, 9,
9, 9, 9, 9, 10, 10, 10,
10, 10, 11, 11, 11, 11, 11,
12, 12, 12, 12,
};
static const e_int16 db2lin_coeff[] = { static const e_int16 db2lin_coeff[] = {
255, 249, 244, 239, 233, 228, 224, 255, 249, 244, 239, 233, 228, 224,
219, 214, 209, 205, 201, 196, 192, 219, 214, 209, 205, 201, 196, 192,