Author: titmuss
Date: Thu May 22 04:51:51 2008
New Revision: 2512
URL: http://svn.slimdevices.com?rev=2512&root=Jive&view=rev
Log:
Bug: N/A
Description:
Added fade in and crossfade.
Added:
7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.c (with props)
7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h (with props)
Modified:
7.2/trunk/squeezeplay/src/squeezeplay/Makefile.am
7.2/trunk/squeezeplay/src/squeezeplay/Makefile.in
7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode.c
7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c
7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h
Modified: 7.2/trunk/squeezeplay/src/squeezeplay/Makefile.am
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/Makefile.am?rev=2512&root=Jive&r1=2511&r2=2512&view=diff
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/Makefile.am (original)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/Makefile.am Thu May 22 04:51:51 2008
@@ -59,6 +59,7 @@
libjiveaudio_la_SOURCES = \
src/audio/fifo.c \
+ src/audio/fixed_math.c \
src/audio/mqueue.c \
src/audio/streambuf.c \
src/audio/decode/decode.c \
Modified: 7.2/trunk/squeezeplay/src/squeezeplay/Makefile.in
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/Makefile.in?rev=2512&root=Jive&r1=2511&r2=2512&view=diff
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/Makefile.in (original)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/Makefile.in Thu May 22 04:51:51 2008
@@ -86,9 +86,10 @@
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libjiveaudio_la_DEPENDENCIES =
-am_libjiveaudio_la_OBJECTS = fifo.lo mqueue.lo streambuf.lo decode.lo \
- decode_flac.lo decode_mad.lo decode_output.lo decode_pcm.lo \
- decode_portaudio.lo decode_tones.lo
+am_libjiveaudio_la_OBJECTS = fifo.lo fixed_math.lo mqueue.lo \
+ streambuf.lo decode.lo decode_flac.lo decode_mad.lo \
+ decode_output.lo decode_pcm.lo decode_portaudio.lo \
+ decode_tones.lo
libjiveaudio_la_OBJECTS = $(am_libjiveaudio_la_OBJECTS)
libjivenet_la_DEPENDENCIES =
am_libjivenet_la_OBJECTS = jive_dns.lo
@@ -384,6 +385,7 @@
libjiveui_la_LIBADD = -ltolua++ -llua -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL
libjiveaudio_la_SOURCES = \
src/audio/fifo.c \
+ src/audio/fixed_math.c \
src/audio/mqueue.c \
src/audio/streambuf.c \
src/audio/decode/decode.c \
@@ -1038,6 +1040,7 @@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
[EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@@ -1091,6 +1094,13 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/audio/fifo.c'
object='fifo.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE)
$(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS)
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
$(CFLAGS) -c -o fifo.lo `test -f 'src/audio/fifo.c' || echo
'$(srcdir)/'`src/audio/fifo.c
+
+fixed_math.lo: src/audio/fixed_math.c
[EMAIL PROTECTED]@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS)
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
$(CFLAGS) -MT fixed_math.lo -MD -MP -MF "$(DEPDIR)/fixed_math.Tpo" -c -o
fixed_math.lo `test -f 'src/audio/fixed_math.c' || echo
'$(srcdir)/'`src/audio/fixed_math.c; \
[EMAIL PROTECTED]@ then mv -f "$(DEPDIR)/fixed_math.Tpo"
"$(DEPDIR)/fixed_math.Plo"; else rm -f "$(DEPDIR)/fixed_math.Tpo"; exit 1; fi
[EMAIL PROTECTED]@@am__fastdepCC_FALSE@ source='src/audio/fixed_math.c'
object='fixed_math.lo' libtool=yes @AMDEPBACKSLASH@
[EMAIL PROTECTED]@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE)
$(depcomp) @AMDEPBACKSLASH@
[EMAIL PROTECTED]@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS)
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
$(CFLAGS) -c -o fixed_math.lo `test -f 'src/audio/fixed_math.c' || echo
'$(srcdir)/'`src/audio/fixed_math.c
mqueue.lo: src/audio/mqueue.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS)
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
$(CFLAGS) -MT mqueue.lo -MD -MP -MF "$(DEPDIR)/mqueue.Tpo" -c -o mqueue.lo
`test -f 'src/audio/mqueue.c' || echo '$(srcdir)/'`src/audio/mqueue.c; \
Modified: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode.c
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode.c?rev=2512&root=Jive&r1=2511&r2=2512&view=diff
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode.c (original)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode.c Thu May 22
04:51:51 2008
@@ -200,6 +200,7 @@
decode_first_buffer = TRUE;
// XXXX decode_set_output_threshold(output_threshold);
+ decode_set_transition(transition_type, transition_period);
// XXXX decode_set_track_gain((replay_gain) ? replay_gain :
FILTER_VOLUME_ONE);
// XXXX decode_set_track_polarity_inversion(polarity_inversion);
Modified: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c?rev=2512&root=Jive&r1=2511&r2=2512&view=diff
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c
(original)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_output.c Thu
May 22 04:51:51 2008
@@ -9,6 +9,7 @@
#include "common.h"
#include "audio/fifo.h"
+#include "audio/fixed_math.h"
#include "audio/decode/decode.h"
#include "audio/decode/decode_priv.h"
@@ -20,6 +21,29 @@
/* Has the audio output been initialized? */
static bool_t output_started = FALSE;
+/* Track transition information */
+static u32_t decode_transition_type = 0;
+static u32_t decode_transition_period = 0;
+
+static bool_t crossfade_started;
+static size_t crossfade_ptr;
+static fft_fixed transition_gain;
+static fft_fixed transition_gain_step;
+static u32_t transition_sample_step;
+static u32_t transition_samples_in_step;
+
+
+#define TRANSITION_NONE 0x0
+#define TRANSITION_CROSSFADE 0x1
+#define TRANSITION_FADE_IN 0x2
+#define TRANSITION_FADE_OUT 0x4
+
+/* Transition steps per second should be a common factor
+ * of all supported sample rates.
+ */
+#define TRANSITION_STEPS_PER_SECOND 10
+#define TRANSITION_MINIMUM_SECONDS 1
+
void decode_output_begin(void) {
// XXXX fifo mutex
@@ -38,6 +62,8 @@
void decode_output_end(void) {
+ // XXXX fifo mutex
+
output_started = FALSE;
decode_audio->stop();
@@ -93,6 +119,83 @@
}
+/* Determine whether we have enough audio in the output buffer to do
+ * a transition. Start at the requested transition interval and go
+ * down till we find an interval that we have enough audio for.
+ */
+static fft_fixed determine_transition_interval(int sample_rate, u32_t
transition_period, u32_t *nbytes) {
+ u32_t bytes_used, sample_step_bytes;
+ fft_fixed interval, interval_step;
+
+ bytes_used = fifo_bytes_used(&decode_fifo);
+ *nbytes = SAMPLES_TO_BYTES(TRANSITION_MINIMUM_SECONDS * sample_rate);
+ if (bytes_used < *nbytes) {
+ return 0;
+ }
+
+ *nbytes = SAMPLES_TO_BYTES(transition_period * sample_rate);
+ transition_sample_step = sample_rate / TRANSITION_STEPS_PER_SECOND;
+ sample_step_bytes = SAMPLES_TO_BYTES(transition_sample_step);
+
+ interval = s32_to_fixed(transition_period);
+ interval_step = fixed_div(FIXED_ONE, TRANSITION_STEPS_PER_SECOND);
+
+ while (bytes_used < (*nbytes + sample_step_bytes)) {
+ *nbytes -= sample_step_bytes;
+ interval -= interval_step;
+ }
+
+ return interval;
+}
+
+/* How many bytes till we're done with the transition.
+ */
+static size_t decode_transition_bytes_remaining() {
+ return (crossfade_ptr >= decode_fifo.wptr) ? (crossfade_ptr -
decode_fifo.wptr) : (decode_fifo.wptr - crossfade_ptr + decode_fifo.size);
+}
+
+
+/* Called to copy samples to the decode fifo when we are doing
+ * a transition - crossfade or fade in. This method applies gain
+ * to both the new signal and the one that's already in the fifo.
+ */
+static void decode_transition_copy_bytes(sample_t *buffer, int nbytes) {
+ sample_t chunk[nbytes * sizeof(sample_t)];
+ sample_t *chunk_ptr = chunk;
+ sample_t sample;
+ int nsamples, s;
+
+ // XXXX process in smaller buffers, of size transition_samples_in_step
+
+ nsamples = BYTES_TO_SAMPLES(nbytes);
+
+ if (crossfade_started) {
+ memcpy(chunk, decode_fifo_buf + decode_fifo.wptr, nbytes);
+ }
+ else {
+ memset(chunk, 0, nbytes);
+ }
+
+ fft_fixed in_gain = transition_gain;
+ fft_fixed out_gain = FIXED_ONE - in_gain;
+ for (s=0; s<nsamples * 2; s++) {
+
+ sample = fixed_mul(out_gain, *chunk_ptr);
+ sample += fixed_mul(in_gain, *buffer++);
+ *chunk_ptr++ = sample;
+ }
+
+ transition_samples_in_step += nsamples;
+ while (transition_samples_in_step >= transition_sample_step) {
+ transition_samples_in_step -= transition_sample_step;
+ transition_gain += transition_gain_step;
+ }
+
+ memcpy(decode_fifo_buf + decode_fifo.wptr, chunk, nbytes);
+ fifo_wptr_incby(&decode_fifo, nbytes);
+}
+
+
void decode_output_samples(sample_t *buffer, u32_t nsamples, int sample_rate,
bool_t need_scaling, bool_t start_immediately,
bool_t copyright_asserted) {
@@ -113,8 +216,62 @@
fifo_lock(&decode_fifo);
if (decode_first_buffer) {
+ crossfade_started = FALSE;
+ track_start_point = decode_fifo.wptr;
+
+ if (decode_transition_type & TRANSITION_CROSSFADE) {
+ u32_t crossfadeBytes;
+
+ /* We are being asked to do a crossfade. Find out
+ * if it is possible.
+ */
+ fft_fixed interval =
determine_transition_interval(sample_rate, decode_transition_period,
&crossfadeBytes);
+
+ if (interval) {
+ printf("Starting CROSSFADE over %d seconds,
requiring %d bytes\n", fixed_to_s32(interval), crossfadeBytes);
+
+ /* Buffer position to stop crossfade */
+ crossfade_ptr = decode_fifo.wptr;
+
+ /* Buffer position to start crossfade */
+ decode_fifo.wptr = (crossfadeBytes <=
decode_fifo.wptr) ? (decode_fifo.wptr - crossfadeBytes) : (decode_fifo.wptr -
crossfadeBytes + decode_fifo.size);
+
+ /* Gain steps */
+ transition_gain_step = fixed_div(FIXED_ONE,
fixed_mul(interval, s32_to_fixed(TRANSITION_STEPS_PER_SECOND)));
+ transition_gain = 0;
+ transition_samples_in_step = 0;
+
+ crossfade_started = TRUE;
+ track_start_point = decode_fifo.wptr;
+ }
+ /*
+ * else there aren't enough leftover samples from the
+ * previous track, so abort the transition.
+ */
+ }
+ else if (decode_transition_type & TRANSITION_FADE_IN) {
+ u32_t transition_period;
+
+ /* The transition is a fade in. */
+
+ transition_period = decode_transition_period;
+
+ /* Halve the period if we're also fading out */
+ if (decode_transition_type & TRANSITION_FADE_OUT) {
+ transition_period >>= 1;
+ }
+
+ printf("Starting FADE_IN over %d seconds\n",
transition_period);
+
+ /* Gain steps */
+ transition_gain_step = fixed_div(FIXED_ONE,
s32_to_fixed(transition_period * TRANSITION_STEPS_PER_SECOND));
+ transition_gain = 0;
+ transition_sample_step = sample_rate /
TRANSITION_STEPS_PER_SECOND;
+ transition_samples_in_step = 0;
+ }
+
current_sample_rate = sample_rate;
- track_start_point = decode_fifo.wptr;
+
check_start_point = TRUE;
decode_first_buffer = FALSE;
}
@@ -122,17 +279,45 @@
bytes_out = SAMPLES_TO_BYTES(nsamples);
while (bytes_out) {
- size_t wrap, bytes_write;
-
+ size_t wrap, bytes_write, bytes_remaining;
+
+ /* The size of the output write is limied by the
+ * space untill our fifo wraps.
+ */
wrap = fifo_bytes_until_wptr_wrap(&decode_fifo);
+
+ /* When crossfading limit the output write to the
+ * end of the transition.
+ */
+ if (crossfade_started) {
+ bytes_remaining = decode_transition_bytes_remaining();
+printf("bytes_till_end=%d\n", bytes_remaining);
+
+ if (bytes_remaining < wrap) {
+ wrap = bytes_remaining;
+ }
+ }
bytes_write = bytes_out;
if (bytes_write > wrap) {
bytes_write = wrap;
}
- memcpy(decode_fifo_buf + decode_fifo.wptr, buffer, bytes_write);
- fifo_wptr_incby(&decode_fifo, bytes_write);
+ if (transition_gain_step) {
+ decode_transition_copy_bytes(buffer, bytes_write);
+
+ if ((crossfade_started && decode_fifo.wptr ==
crossfade_ptr)
+ || transition_gain >= FIXED_ONE) {
+ printf("Completed transition\n");
+
+ transition_gain_step = 0;
+ crossfade_started = FALSE;
+ }
+ }
+ else {
+ memcpy(decode_fifo_buf + decode_fifo.wptr, buffer,
bytes_write);
+ fifo_wptr_incby(&decode_fifo, bytes_write);
+ }
buffer += (bytes_write / sizeof(sample_t));
bytes_out -= bytes_write;
@@ -211,3 +396,31 @@
int decode_output_samplerate() {
return current_sample_rate;
}
+
+
+void decode_set_transition(u32_t type, u32_t period) {
+ if (!period) {
+ decode_transition_type = TRANSITION_NONE;
+ return;
+ }
+
+ switch (type - '0') {
+ case 0:
+ decode_transition_type = TRANSITION_NONE;
+ break;
+ case 1:
+ decode_transition_type = TRANSITION_CROSSFADE;
+ break;
+ case 2:
+ decode_transition_type = TRANSITION_FADE_IN;
+ break;
+ case 3:
+ decode_transition_type = TRANSITION_FADE_OUT;
+ break;
+ case 4:
+ decode_transition_type = TRANSITION_FADE_IN |
TRANSITION_FADE_OUT;
+ break;
+ }
+
+ decode_transition_period = period;
+}
Modified: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h?rev=2512&root=Jive&r1=2511&r2=2512&view=diff
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h
(original)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/decode/decode_priv.h Thu
May 22 04:51:51 2008
@@ -51,6 +51,8 @@
extern void decode_output_remove_padding(u32_t nsamples, u32_t sample_rate);
extern int decode_output_samplerate();
+
+extern void decode_set_transition(u32_t type, u32_t period);
/* Stream metadata */
Added: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.c
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.c?rev=2512&root=Jive&view=auto
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.c (added)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.c Thu May 22
04:51:51 2008
@@ -1,0 +1,260 @@
+/**
+ * Derived from Java version of:
+ *
+ * 16:16 fixed point math routines, for IAppli/CLDC platform.
+ * A fixed point number is a 32 bit int containing 16 bits of integer
+ * and 16 bits of fraction.
+ *
+ * (C) 2001 Beartronics
+ * Author: Henry Minsky ([EMAIL PROTECTED])
+ *
+ * Licensed under terms "Artistic License"
+ * http://www.opensource.org/licenses/artistic-license.html
+ *
+ * Numerical algorithms based on
+ *
http://www.cs.clemson.edu/html_docs/SUNWspro/common-tools/numerical_comp_guide/ncg_examples.doc.html
+ *
+ * Trig routines based on numerical algorithms described in
+ * http://www.magic-software.com/MgcNumerics.html
+ *
+ * http://www.dattalo.com/technical/theory/logs.html
+ *
+ */
+
+/*
+ * Modification history:
+ * 12/02/04 - vidur - Ported fixed math routines to use Ubicom SDK types
+ * 1/12/05 - vidur - Added log10 and exp10 implementations
+ */
+
+#include "fixed_math.h"
+
+fft_fixed fixed_sqrt(fft_fixed n) {
+ int i;
+ fft_fixed s;
+
+ s = (n + 65536) >> 1;
+ for (i = 0; i < 8; i++) {
+ //converge six times
+ s = (s + fixed_div(n, s)) >> 1;
+ }
+ return s;
+}
+
+fft_fixed fixed_round(fft_fixed n) {
+ if (n > 0) {
+ if ((n & 0x8000) != 0) {
+ return (((n+0x10000)>>16)<<16);
+ } else {
+ return (((n)>>16)<<16);
+ }
+ } else {
+ fft_fixed k;
+ n = -n;
+ if ((n & 0x8000) != 0) {
+ k = (((n+0x10000)>>16)<<16);
+ } else {
+ k = (((n)>>16)<<16);
+ }
+ return -k;
+ }
+}
+
+#define FIXED_PI 205887
+#define FIXED_PI_OVER_2 FIXED_PI/2
+#define FIXED_E 178145
+#define FIXED_HALF 2<<15
+
+#define SK1 498
+#define SK2 10882
+
+
+/** Computes SIN(f), f is a fixed point number in radians.
+ * 0 <= f <= 2PI
+ */
+fft_fixed fixed_sin(fft_fixed f) {
+ int sign;
+ fft_fixed sqr, result;
+
+ // If in range -pi/4 to pi/4: nothing needs to be done.
+ // otherwise, we need to get f into that range and account for
+ // sign change.
+
+ sign = 1;
+ if (f < 0) {
+ f = -f;
+ sign = -1;
+ }
+ if ((f > FIXED_PI_OVER_2) && (f <= FIXED_PI)) {
+ f = FIXED_PI - f;
+ } else if ((f > FIXED_PI) && (f <= (FIXED_PI + FIXED_PI_OVER_2))) {
+ f = f - FIXED_PI;
+ sign *= -1;
+ } else if (f > (FIXED_PI + FIXED_PI_OVER_2)) {
+ f = (FIXED_PI<<1)-f;
+ sign *= -1;
+ }
+
+ sqr = fixed_mul(f,f);
+ result = SK1;
+ result = fixed_mul(result, sqr);
+ result -= SK2;
+ result = fixed_mul(result, sqr);
+ result += (1<<16);
+ result = fixed_mul(result, f);
+ return sign * result;
+}
+
+#define CK1 2328
+#define CK2 32551
+
+/** Computes COS(f), f is a fixed point number in radians.
+ * 0 <= f <= PI/2
+ */
+fft_fixed fixed_cos(fft_fixed f) {
+ int sign;
+ fft_fixed sqr, result;
+
+ if (f < 0) {
+ f = -f;
+ }
+ sign = 1;
+ if ((f > FIXED_PI_OVER_2) && (f <= FIXED_PI)) {
+ f = FIXED_PI - f;
+ sign = -1;
+ } else if ((f > FIXED_PI_OVER_2) && (f <= (FIXED_PI +
FIXED_PI_OVER_2))) {
+ f = f - FIXED_PI;
+ sign = -1;
+ } else if (f > (FIXED_PI + FIXED_PI_OVER_2)) {
+ f = (FIXED_PI<<1)-f;
+ }
+
+ sqr = fixed_mul(f,f);
+ result = CK1;
+ result = fixed_mul(result, sqr);
+ result -= CK2;
+ result = fixed_mul(result, sqr);
+ result += (1<<16);
+ return result * sign;
+}
+
+static fft_fixed fpfact[] = {
+ 1<<16,
+ 1<<16,
+ 2<<16,
+ 6<<16,
+ 24<<16,
+ 120<<16,
+ 720<<16,
+ 5040<<16,
+ 40320<<16
+};
+
+fft_fixed fixed_exp(fft_fixed x) {
+ fft_fixed result = 1<<16;
+ fft_fixed x2 = fixed_mul(x,x);
+ fft_fixed x3 = fixed_mul(x2,x);
+ fft_fixed x4 = fixed_mul(x2,x2);
+ fft_fixed x5 = fixed_mul(x4,x);
+ fft_fixed x6 = fixed_mul(x4,x2);
+ fft_fixed x7 = fixed_mul(x6,x);
+ fft_fixed x8 = fixed_mul(x4,x4);
+ return result + x
+ + fixed_div(x2,fpfact[2])
+ + fixed_div(x3,fpfact[3])
+ + fixed_div(x4,fpfact[4])
+ + fixed_div(x5,fpfact[5])
+ + fixed_div(x6,fpfact[6])
+ + fixed_div(x7,fpfact[7])
+ + fixed_div(x8,fpfact[8]);
+}
+
+fft_fixed fixed_pow(fft_fixed x, fft_fixed y) {
+ if (x == 0) {
+ return 0;
+ }
+
+ if (y == 0) {
+ return FIXED_ONE;
+ }
+
+ return fixed_exp(fixed_mul(y, fixed_ln(x)));
+}
+
+static fft_fixed log2arr[] = {
+ 26573,
+ 14624,
+ 7719,
+ 3973,
+ 2017,
+ 1016,
+ 510,
+ 256,
+ 128,
+ 64,
+ 32,
+ 16,
+ 8,
+ 4,
+ 2,
+ 1,
+ 0,
+ 0,
+ 0
+};
+
+static fft_fixed lnscale[] = {
+ 0,
+ 45426,
+ 90852,
+ 136278,
+ 181704,
+ 227130,
+ 272557,
+ 317983,
+ 363409,
+ 408835,
+ 454261,
+ 499687,
+ 545113,
+ 590539,
+ 635965,
+ 681391,
+ 726817
+};
+
+fft_fixed fixed_ln(fft_fixed x) {
+ // prescale so x is between 1 and 2
+ int i, shift = 0;
+ fft_fixed g, d;
+
+ while (x > 1<<17) {
+ shift++;
+ x >>= 1;
+ }
+
+ g = 0;
+ d = FIXED_HALF;
+ for (i = 1; i < 16; i++) {
+ if (x > ((1<<16) + d)) {
+ x = fixed_div(x, ( (1<<16) + d));
+ g += log2arr[i-1]; // log2arr[i-1] = log2(1+d);
+ }
+ d >>= 1;
+ }
+ return g + lnscale[shift];
+}
+
+#define FIXED_LOG_E 0x6f2e
+
+// log10 is log10(e) * ln(x)
+fft_fixed fixed_log10(fft_fixed x) {
+ return fixed_mul(FIXED_LOG_E, fixed_ln(x));
+}
+
+#define FIXED_LN_10 0x24d76
+
+// exp10(x) is exp(x * ln(10))
+fft_fixed fixed_exp10(fft_fixed x) {
+ return fixed_exp(fixed_mul(x, FIXED_LN_10));
+}
Propchange: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.c
------------------------------------------------------------------------------
svn:executable = *
Added: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h
URL:
http://svn.slimdevices.com/7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h?rev=2512&root=Jive&view=auto
==============================================================================
--- 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h (added)
+++ 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h Thu May 22
04:51:51 2008
@@ -1,0 +1,90 @@
+/**
+ * Derived from Java version of:
+ *
+ * 16:16 fixed point math routines, for IAppli/CLDC platform.
+ * A fixed point number is a 32 bit int containing 16 bits of integer
+ * and 16 bits of fraction.
+ *
+ * (C) 2001 Beartronics
+ * Author: Henry Minsky ([EMAIL PROTECTED])
+ *
+ * Licensed under terms "Artistic License"
+ * http://www.opensource.org/licenses/artistic-license.html
+ *
+ * Numerical algorithms based on
+ *
http://www.cs.clemson.edu/html_docs/SUNWspro/common-tools/numerical_comp_guide/ncg_examples.doc.html
+ *
+ * Trig routines based on numerical algorithms described in
+ * http://www.magic-software.com/MgcNumerics.html
+ *
+ * http://www.dattalo.com/technical/theory/logs.html
+ *
+ */
+
+/*
+ * Modification history:
+ * 12/02/04 - vidur - Ported fixed math routines to use Ubicom SDK types
+ * 1/12/05 - vidur - Added log10 and exp10 implementations
+ */
+
+#ifndef __FIXED_MATH_H__
+#define __FIXED_MATH_H__
+
+#include "common.h"
+
+typedef s32_t fft_fixed;
+
+#define FIXED_ONE 0x10000
+#define FIXED_FRAC_BITS 16
+
+inline s32_t fixed_to_s32(fft_fixed x) {
+ return x >> 16;
+}
+
+inline fft_fixed s32_to_fixed(s32_t x) {
+ return x << 16;
+}
+
+inline double fixed_to_double(fft_fixed x) {
+ return ((double)((x) / (double) (1L << 16)));
+}
+
+inline fft_fixed double_to_fixed(double x) {
+ return ((fft_fixed) ((x) * (double) (1L << 16) + 0.5));
+}
+
+inline fft_fixed fixed_mul(fft_fixed x, fft_fixed y) {
+ s64_t z = (s64_t)x * (s64_t)y;
+ return (s32_t) (z >> 16);
+}
+
+inline fft_fixed fixed_div(fft_fixed x, fft_fixed y) {
+ s64_t z = ((s64_t)x << 32);
+ return (s32_t) ((z / y) >> 16);
+}
+
+extern fft_fixed fixed_sqrt(fft_fixed n);
+
+extern fft_fixed fixed_round(fft_fixed n);
+
+/** Computes SIN(f), f is a fixed point number in radians.
+ * 0 <= f <= 2PI
+ */
+extern fft_fixed fixed_sin(fft_fixed f);
+
+/** Computes COS(f), f is a fixed point number in radians.
+ * 0 <= f <= PI/2
+ */
+extern fft_fixed fixed_cos(fft_fixed f);
+
+extern fft_fixed fixed_pow(fft_fixed x, fft_fixed y);
+
+extern fft_fixed fixed_exp(fft_fixed x);
+
+extern fft_fixed fixed_ln(fft_fixed x);
+
+extern fft_fixed fixed_log10(fft_fixed x);
+
+extern fft_fixed fixed_exp10(fft_fixed x);
+
+#endif // __FIXED_MATH_H__
Propchange: 7.2/trunk/squeezeplay/src/squeezeplay/src/audio/fixed_math.h
------------------------------------------------------------------------------
svn:executable = *
_______________________________________________
Jive-checkins mailing list
[email protected]
http://lists.slimdevices.com/cgi-bin/mailman/listinfo/jive-checkins