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

Reply via email to