forked from len0rd/rockbox
Full precision synth_full and dct32. Replaced all multiplications with proper 64 bit EMAC multiplications, which yields improved sound.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6638 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
7c54b3ad4b
commit
cc518c5f32
4 changed files with 65 additions and 20 deletions
|
@ -14,7 +14,8 @@ ifdef APPEXTRA
|
||||||
INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
|
INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
MADOPTS = -DFPM_DEFAULT -DNDEBUG -O2
|
# NOTE: FPM_ define has been moved to global.h
|
||||||
|
MADOPTS = -DNDEBUG -O2
|
||||||
CFLAGS = $(GCCOPTS) $(MADOPTS)\
|
CFLAGS = $(GCCOPTS) $(MADOPTS)\
|
||||||
$(INCLUDES) $(TARGET) $(EXTRA_DEFINES) -DMEM=${MEMORYSIZE}
|
$(INCLUDES) $(TARGET) $(EXTRA_DEFINES) -DMEM=${MEMORYSIZE}
|
||||||
|
|
||||||
|
|
|
@ -420,6 +420,29 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
|
||||||
|
|
||||||
# define MAD_F_SCALEBITS MAD_F_FRACBITS
|
# define MAD_F_SCALEBITS MAD_F_FRACBITS
|
||||||
|
|
||||||
|
# elif defined(FPM_COLDFIRE_EMAC)
|
||||||
|
|
||||||
|
/* mad_f_mul using the Coldfire MCF5249 EMAC unit. Loses 3 bits of accuracy.
|
||||||
|
Note that we don't define any of the libmad accumulator macros, as
|
||||||
|
any functions that use these should have the relevant sections rewritten
|
||||||
|
in assembler to utilise the EMAC accumulators properly.
|
||||||
|
Assumes the default +/- 3.28 fixed point format
|
||||||
|
*/
|
||||||
|
#define mad_f_mul(x, y) \
|
||||||
|
({ \
|
||||||
|
mad_fixed64hi_t hi; \
|
||||||
|
asm volatile("mac.l %[a], %[b], %%acc0\n\t" \
|
||||||
|
"movclr.l %%acc0, %[hi]\n\t" \
|
||||||
|
"asl.l #3, %[hi]" \
|
||||||
|
: [hi] "=d" (hi) \
|
||||||
|
: [a] "r" ((x)), [b] "r" ((y))); \
|
||||||
|
hi; \
|
||||||
|
})
|
||||||
|
/* Define dummy mad_f_scale64 to prevent libmad from defining MAD_F_SCALEBITS
|
||||||
|
below. Having MAD_F_SCALEBITS defined screws up the PRESHIFT macro in synth.h
|
||||||
|
*/
|
||||||
|
#define mad_f_scale64(hi, lo) (lo)
|
||||||
|
|
||||||
/* --- Default ------------------------------------------------------------- */
|
/* --- Default ------------------------------------------------------------- */
|
||||||
|
|
||||||
# elif defined(FPM_DEFAULT)
|
# elif defined(FPM_DEFAULT)
|
||||||
|
|
|
@ -24,6 +24,12 @@
|
||||||
# ifndef LIBMAD_GLOBAL_H
|
# ifndef LIBMAD_GLOBAL_H
|
||||||
# define LIBMAD_GLOBAL_H
|
# define LIBMAD_GLOBAL_H
|
||||||
|
|
||||||
|
#if CONFIG_CPU==MCF5249 && !defined(SIMULATOR)
|
||||||
|
#define FPM_COLDFIRE_EMAC
|
||||||
|
#else
|
||||||
|
#define FPM_DEFAULT
|
||||||
|
#endif
|
||||||
|
|
||||||
/* conditional debugging */
|
/* conditional debugging */
|
||||||
|
|
||||||
# if defined(DEBUG) && defined(NDEBUG)
|
# if defined(DEBUG) && defined(NDEBUG)
|
||||||
|
|
|
@ -102,7 +102,21 @@ void mad_synth_mute(struct mad_synth *synth)
|
||||||
|
|
||||||
/* possible DCT speed optimization */
|
/* possible DCT speed optimization */
|
||||||
|
|
||||||
# if defined(OPT_SPEED) && defined(MAD_F_MLX)
|
/* This is a Coldfire version of the OPT_SPEED optimisation below, but in the
|
||||||
|
case of Coldfire it doesn't lose any more precision than we would ordinarily
|
||||||
|
lose, */
|
||||||
|
# ifdef FPM_COLDFIRE_EMAC
|
||||||
|
# define OPT_DCTO
|
||||||
|
# define MUL(x, y) \
|
||||||
|
({ \
|
||||||
|
mad_fixed64hi_t hi; \
|
||||||
|
asm volatile("mac.l %[a], %[b], %%acc0\n\t" \
|
||||||
|
"movclr.l %%acc0, %[hi]" \
|
||||||
|
: [hi] "=r" (hi) \
|
||||||
|
: [a] "r" ((x)), [b] "r" ((y))); \
|
||||||
|
hi; \
|
||||||
|
})
|
||||||
|
# elif defined(OPT_SPEED) && defined(MAD_F_MLX)
|
||||||
# define OPT_DCTO
|
# define OPT_DCTO
|
||||||
# define MUL(x, y) \
|
# define MUL(x, y) \
|
||||||
({ mad_fixed64hi_t hi; \
|
({ mad_fixed64hi_t hi; \
|
||||||
|
@ -555,8 +569,8 @@ void synth_full(struct mad_synth *, struct mad_frame const *,
|
||||||
* DESCRIPTION: perform full frequency PCM synthesis
|
* DESCRIPTION: perform full frequency PCM synthesis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* optimised version of synth full, requires OPT_SSO at the moment */
|
/* optimised version of synth_full */
|
||||||
# if CONFIG_CPU==MCF5249 && defined(OPT_SSO) && !defined(SIMULATOR)
|
# ifdef FPM_COLDFIRE_EMAC
|
||||||
static
|
static
|
||||||
void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
unsigned int nch, unsigned int ns)
|
unsigned int nch, unsigned int ns)
|
||||||
|
@ -566,10 +580,9 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
mad_fixed_t const (*sbsample)[36][32];
|
mad_fixed_t const (*sbsample)[36][32];
|
||||||
mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
|
||||||
mad_fixed_t const (*Dptr)[32];
|
mad_fixed_t const (*Dptr)[32];
|
||||||
mad_fixed64hi_t hi = 0;
|
mad_fixed64hi_t hi;
|
||||||
mad_fixed64lo_t lo;
|
|
||||||
|
|
||||||
asm volatile("move.l #0, %macsr"); /* need integer mode */
|
asm volatile("move.l #0x20, %macsr"); /* fractional mode */
|
||||||
|
|
||||||
for (ch = 0; ch < nch; ++ch) {
|
for (ch = 0; ch < nch; ++ch) {
|
||||||
sbsample = &frame->sbsample[ch];
|
sbsample = &frame->sbsample[ch];
|
||||||
|
@ -613,10 +626,12 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
"mac.l %%d5, %%a5, 16(%4), %%a5, %%acc0\n\t"
|
"mac.l %%d5, %%a5, 16(%4), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d6, %%a5, 8(%4), %%a5, %%acc0\n\t"
|
"mac.l %%d6, %%a5, 8(%4), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d7, %%a5, %%acc0\n\t"
|
"mac.l %%d7, %%a5, %%acc0\n\t"
|
||||||
"movclr.l %%acc0, %0"
|
"movclr.l %%acc0, %0\n\t"
|
||||||
: "=ad" (lo) : "a" (*fx), "a" (*Dptr + po), "a" (*fe), "a" (*Dptr + pe) : "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
: "=r" (hi)
|
||||||
|
: "a" (*fx), "a" (*Dptr + po), "a" (*fe), "a" (*Dptr + pe)
|
||||||
|
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
||||||
|
|
||||||
*pcm1++ = SHIFT(MLZ(hi, lo));
|
*pcm1++ = hi << 3; /* shift result to libmad's fixed point format */
|
||||||
|
|
||||||
pcm2 = pcm1 + 30;
|
pcm2 = pcm1 + 30;
|
||||||
|
|
||||||
|
@ -646,12 +661,12 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
"mac.l %%d2, %%a5, 56(%4), %%a5, %%acc0\n\t"
|
"mac.l %%d2, %%a5, 56(%4), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d1, %%a5, (%4), %%a5, %%acc0\n\t"
|
"mac.l %%d1, %%a5, (%4), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d0, %%a5, %%acc0\n\t"
|
"mac.l %%d0, %%a5, %%acc0\n\t"
|
||||||
"movclr.l %%acc0, %0"
|
"movclr.l %%acc0, %0\n\t"
|
||||||
: "=ad" (lo)
|
: "=r" (hi)
|
||||||
: "a" (*fo), "a" (*Dptr + po), "a" (*fe), "a" (*Dptr + pe)
|
: "a" (*fo), "a" (*Dptr + po), "a" (*fe), "a" (*Dptr + pe)
|
||||||
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
||||||
|
|
||||||
*pcm1++ = SHIFT(MLZ(hi, lo));
|
*pcm1++ = hi << 3;
|
||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
"movem.l (%1), %%d0-%%d7\n\t"
|
"movem.l (%1), %%d0-%%d7\n\t"
|
||||||
|
@ -674,12 +689,12 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
"mac.l %%d2, %%a5, 68(%4), %%a5, %%acc0\n\t"
|
"mac.l %%d2, %%a5, 68(%4), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d1, %%a5, 60(%4), %%a5, %%acc0\n\t"
|
"mac.l %%d1, %%a5, 60(%4), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d0, %%a5, %%acc0\n\t"
|
"mac.l %%d0, %%a5, %%acc0\n\t"
|
||||||
"movclr.l %%acc0, %0"
|
"movclr.l %%acc0, %0\n\t"
|
||||||
: "=ad" (lo)
|
: "=r" (hi)
|
||||||
: "a" (*fe), "a" (*Dptr - pe), "a" (*fo), "a" (*Dptr - po)
|
: "a" (*fe), "a" (*Dptr - pe), "a" (*fo), "a" (*Dptr - po)
|
||||||
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
||||||
|
|
||||||
*pcm2-- = SHIFT(MLZ(hi, lo));
|
*pcm2-- = hi << 3;
|
||||||
|
|
||||||
++fo;
|
++fo;
|
||||||
}
|
}
|
||||||
|
@ -696,11 +711,11 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
|
||||||
"mac.l %%d5, %%a5, 16(%2), %%a5, %%acc0\n\t"
|
"mac.l %%d5, %%a5, 16(%2), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d6, %%a5, 8(%2), %%a5, %%acc0\n\t"
|
"mac.l %%d6, %%a5, 8(%2), %%a5, %%acc0\n\t"
|
||||||
"mac.l %%d7, %%a5, %%acc0\n\t"
|
"mac.l %%d7, %%a5, %%acc0\n\t"
|
||||||
"movclr.l %%acc0, %0"
|
"movclr.l %%acc0, %0\n\t"
|
||||||
: "=ad" (lo) : "a" (*fo), "a" (*Dptr + po)
|
: "=r" (hi) : "a" (*fo), "a" (*Dptr + po)
|
||||||
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a5");
|
||||||
|
|
||||||
*pcm1 = SHIFT(-MLZ(hi, lo));
|
*pcm1 = -(hi << 3);
|
||||||
pcm1 += 16;
|
pcm1 += 16;
|
||||||
|
|
||||||
phase = (phase + 1) % 16;
|
phase = (phase + 1) % 16;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue