From 85b325fdb991a0602a2f16a55fc1df2c303aded1 Mon Sep 17 00:00:00 2001 From: Thom Johansen Date: Wed, 14 Nov 2007 02:15:56 +0000 Subject: Sync Speex to SVN. Disable stereo compatibility hack since we don't needed it and it produced warnings. Remove unneeded math.h git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15613 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libspeex/_kiss_fft_guts.h | 2 +- apps/codecs/libspeex/arch.h | 48 ++ apps/codecs/libspeex/bits.c | 2 +- apps/codecs/libspeex/cb_search.c | 2 +- apps/codecs/libspeex/cb_search.h | 2 +- apps/codecs/libspeex/fftwrap.c | 2 +- apps/codecs/libspeex/fftwrap.h | 2 +- apps/codecs/libspeex/filterbank.c | 2 +- apps/codecs/libspeex/filterbank.h | 2 +- apps/codecs/libspeex/filters.c | 2 +- apps/codecs/libspeex/filters.h | 2 +- apps/codecs/libspeex/jitter.c | 753 ++++++++++++++++++-------- apps/codecs/libspeex/kiss_fft.c | 2 +- apps/codecs/libspeex/kiss_fft.h | 4 +- apps/codecs/libspeex/lpc.h | 2 +- apps/codecs/libspeex/lsp.h | 2 +- apps/codecs/libspeex/ltp.h | 2 +- apps/codecs/libspeex/math.h | 32 -- apps/codecs/libspeex/math_approx.h | 2 +- apps/codecs/libspeex/mdf.c | 2 +- apps/codecs/libspeex/medfilter.c | 2 +- apps/codecs/libspeex/misc.h | 99 ---- apps/codecs/libspeex/modes.c | 3 +- apps/codecs/libspeex/modes.h | 4 +- apps/codecs/libspeex/modes_wb.c | 4 +- apps/codecs/libspeex/nb_celp.c | 22 +- apps/codecs/libspeex/nb_celp.h | 3 +- apps/codecs/libspeex/oggframing.c | 2 +- apps/codecs/libspeex/os_support.h | 7 +- apps/codecs/libspeex/preprocess.c | 15 +- apps/codecs/libspeex/pseudofloat.h | 2 +- apps/codecs/libspeex/quant_lsp.c | 2 +- apps/codecs/libspeex/quant_lsp.h | 2 +- apps/codecs/libspeex/resample.c | 2 +- apps/codecs/libspeex/sb_celp.c | 16 +- apps/codecs/libspeex/sb_celp.h | 3 +- apps/codecs/libspeex/smallft.c | 2 +- apps/codecs/libspeex/speex/speex_jitter.h | 68 +-- apps/codecs/libspeex/speex/speex_preprocess.h | 4 + apps/codecs/libspeex/speex/speex_stereo.h | 2 +- apps/codecs/libspeex/speex_callbacks.c | 2 +- apps/codecs/libspeex/speex_header.c | 20 +- apps/codecs/libspeex/stereo.c | 4 +- apps/codecs/libspeex/vbr.h | 2 +- apps/codecs/libspeex/vorbis_psy.c | 2 +- apps/codecs/libspeex/vq.c | 2 +- apps/codecs/libspeex/vq.h | 2 +- apps/codecs/libspeex/window.c | 10 +- 48 files changed, 697 insertions(+), 480 deletions(-) delete mode 100644 apps/codecs/libspeex/math.h delete mode 100644 apps/codecs/libspeex/misc.h (limited to 'apps') diff --git a/apps/codecs/libspeex/_kiss_fft_guts.h b/apps/codecs/libspeex/_kiss_fft_guts.h index 3023b98b06..e9bb018c4b 100644 --- a/apps/codecs/libspeex/_kiss_fft_guts.h +++ b/apps/codecs/libspeex/_kiss_fft_guts.h @@ -51,7 +51,7 @@ struct kiss_fft_state{ C_ADDTO( res , a) : res += a * */ #ifdef FIXED_POINT -#include "misc.h" +#include "arch.h" # define FRACBITS 15 # define SAMPPROD spx_int32_t #define SAMP_MAX 32767 diff --git a/apps/codecs/libspeex/arch.h b/apps/codecs/libspeex/arch.h index 1e48e93388..9db16ff34d 100644 --- a/apps/codecs/libspeex/arch.h +++ b/apps/codecs/libspeex/arch.h @@ -35,6 +35,47 @@ #ifndef ARCH_H #define ARCH_H +#include "config-speex.h" + +#ifndef SPEEX_VERSION +#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ +#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ +#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */ +#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ +#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */ +#endif + +/* A couple test to catch stupid option combinations */ +#ifdef FIXED_POINT + +#ifdef FLOATING_POINT +#error You cannot compile as floating point and fixed point at the same time +#endif +#ifdef _USE_SSE +#error SSE is only for floating-point +#endif +#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) +#error Make up your mind. What CPU do you have? +#endif +#ifdef VORBIS_PSYCHO +#error Vorbis-psy model currently not implemented in fixed-point +#endif + +#else + +#ifndef FLOATING_POINT +#error You now need to define either FIXED_POINT or FLOATING_POINT +#endif +#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) +#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? +#endif +#ifdef FIXED_POINT_DEBUG +#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" +#endif + + +#endif + #ifndef OUTSIDE_SPEEX #include "speex/speex_types.h" #endif @@ -192,4 +233,11 @@ typedef float spx_word32_t; #endif + + +#ifdef FIXED_DEBUG +long long spx_mips=0; +#endif + + #endif diff --git a/apps/codecs/libspeex/bits.c b/apps/codecs/libspeex/bits.c index b85db6e1a8..d4b02a5a86 100644 --- a/apps/codecs/libspeex/bits.c +++ b/apps/codecs/libspeex/bits.c @@ -37,7 +37,7 @@ #endif #include -#include "misc.h" +#include "arch.h" #include "os_support.h" /* Maximum size of the bit-stream (for fixed-size allocation) */ diff --git a/apps/codecs/libspeex/cb_search.c b/apps/codecs/libspeex/cb_search.c index ecb3918298..a3857c3afa 100644 --- a/apps/codecs/libspeex/cb_search.c +++ b/apps/codecs/libspeex/cb_search.c @@ -37,7 +37,7 @@ #include "filters.h" #include "stack_alloc.h" #include "vq.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" #include "os_support.h" diff --git a/apps/codecs/libspeex/cb_search.h b/apps/codecs/libspeex/cb_search.h index fd5c110ed6..7687b453fd 100644 --- a/apps/codecs/libspeex/cb_search.h +++ b/apps/codecs/libspeex/cb_search.h @@ -36,7 +36,7 @@ #define CB_SEARCH_H #include -#include "misc.h" +#include "arch.h" /** Split codebook parameters. */ typedef struct split_cb_params { diff --git a/apps/codecs/libspeex/fftwrap.c b/apps/codecs/libspeex/fftwrap.c index e4cf3b028b..2312f755d6 100644 --- a/apps/codecs/libspeex/fftwrap.c +++ b/apps/codecs/libspeex/fftwrap.c @@ -40,7 +40,7 @@ #define USE_KISS_FFT -#include "misc.h" +#include "arch.h" #include "os_support.h" #define MAX_FFT_SIZE 2048 diff --git a/apps/codecs/libspeex/fftwrap.h b/apps/codecs/libspeex/fftwrap.h index 826b38e979..dfaf489441 100644 --- a/apps/codecs/libspeex/fftwrap.h +++ b/apps/codecs/libspeex/fftwrap.h @@ -35,7 +35,7 @@ #ifndef FFTWRAP_H #define FFTWRAP_H -#include "misc.h" +#include "arch.h" /** Compute tables for an FFT */ void *spx_fft_init(int size); diff --git a/apps/codecs/libspeex/filterbank.c b/apps/codecs/libspeex/filterbank.c index f50c70e0ad..d2a8f1af90 100644 --- a/apps/codecs/libspeex/filterbank.c +++ b/apps/codecs/libspeex/filterbank.c @@ -36,7 +36,7 @@ #endif #include "filterbank.h" -#include "misc.h" +#include "arch.h" #include #include "math_approx.h" #include "os_support.h" diff --git a/apps/codecs/libspeex/filterbank.h b/apps/codecs/libspeex/filterbank.h index 5ded6b93ee..3e889a22f7 100644 --- a/apps/codecs/libspeex/filterbank.h +++ b/apps/codecs/libspeex/filterbank.h @@ -34,7 +34,7 @@ #ifndef FILTERBANK_H #define FILTERBANK_H -#include "misc.h" +#include "arch.h" typedef struct { int *bank_left; diff --git a/apps/codecs/libspeex/filters.c b/apps/codecs/libspeex/filters.c index a41148fcfb..aaffa9441f 100644 --- a/apps/codecs/libspeex/filters.c +++ b/apps/codecs/libspeex/filters.c @@ -36,7 +36,7 @@ #include "filters.h" #include "stack_alloc.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" #include "ltp.h" #include diff --git a/apps/codecs/libspeex/filters.h b/apps/codecs/libspeex/filters.h index b08e94d320..e3a5980e70 100644 --- a/apps/codecs/libspeex/filters.h +++ b/apps/codecs/libspeex/filters.h @@ -35,7 +35,7 @@ #ifndef FILTERS_H #define FILTERS_H -#include "misc.h" +#include "arch.h" spx_word16_t compute_rms(const spx_sig_t *x, int len); spx_word16_t compute_rms16(const spx_word16_t *x, int len); diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c index 57bb4c2958..e31a131bba 100644 --- a/apps/codecs/libspeex/jitter.c +++ b/apps/codecs/libspeex/jitter.c @@ -32,12 +32,27 @@ */ +/* +TODO: +- Write generic functions for computing stats and shifting the histogram +- Take into account the delay step when computing the stats and when shifting +- Linked list structure for holding the packets instead of the current fixed-size array + + return memory to a pool + + allow pre-allocation of the pool + + optional max number of elements +- Statistics + + drift + + loss + + late + + jitter + + buffering delay +*/ #ifdef HAVE_CONFIG_H #include "config-speex.h" #endif -#include "misc.h" +#include "arch.h" #include #include #include @@ -52,29 +67,157 @@ #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ - +#define TSUB(a,b) ((spx_int32_t)((a)-(b))) #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) +#define MAX_TIMINGS 20 +#define MAX_BUFFERS 3 +#define TOP_DELAY 25 +#define WINDOW_SIZE 200 + +struct TimingBuffer { + int filled; + int curr_count; + spx_int16_t timing[MAX_TIMINGS]; + spx_int16_t counts[MAX_TIMINGS]; +}; + +static void tb_init(struct TimingBuffer *tb) +{ + tb->filled = 0; + tb->curr_count = 0; +} + +static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) +{ + int pos; + /*fprintf(stderr, "timing = %d\n", timing);*/ + /*fprintf(stderr, "timing = %d, latest = %d, earliest = %d, filled = %d\n", timing, tb->timing[0], tb->timing[tb->filled-1], tb->filled);*/ + if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) + { + tb->curr_count++; + return; + } + pos = 0; + /* FIXME: Do bisection instead of linear search */ + while (posfilled && timing >= tb->timing[pos]) + { + pos++; + } + + /*fprintf(stderr, "pos = %d filled = %d\n", pos, tb->filled);*/ + speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); + fprintf(stderr, "OK\n"); + if (pos < tb->filled) + { + int move_size = tb->filled-pos; + if (tb->filled == MAX_TIMINGS) + move_size -= 1; + /*fprintf(stderr, "speex_move(%d %d %d)\n", pos+1, pos, move_size);*/ + speex_move(&tb->timing[pos+1], &tb->timing[pos], move_size*sizeof(tb->timing[0])); + speex_move(&tb->counts[pos+1], &tb->counts[pos], move_size*sizeof(tb->counts[0])); + } + /*fprintf(stderr, "moved\n");*/ + tb->timing[pos] = timing; + tb->counts[pos] = tb->curr_count; + /*{ + int i; + for (i=0;itiming[i]); + fprintf(stderr, "\n"); + }*/ + tb->curr_count++; + if (tb->filledfilled++; + /*fprintf(stderr, "added\n");*/ +} + +/** Based on available data, this computes the optimal delay for the jitter buffer. + The optimised function is in timestamp units and is: + cost = delay + late_factor*[number of frames that would be late if we used that delay] + @param tb Array of buffers + @param late_factor Equivalent cost of a late frame (in timestamp units) +*/ +static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t late_factor) +{ + int i; + spx_int16_t opt=0; + spx_int32_t best_cost=0x7fffffff; + int late = 0; + int pos[MAX_BUFFERS]; + + /*fprintf(stderr, "tbs_get_opt_delay\n");*/ + for (i=0;i 0) + late++; + cost = -latest + late_factor*late; + /*fprintf(stderr, "cost %d = -%d + %d * %d\n", cost, latest, late_factor, late);*/ + if (cost < best_cost) + { + best_cost = cost; + opt = latest; + } + } else { + break; + } + } + return opt; +} + /** Jitter buffer structure */ struct JitterBuffer_ { spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ - spx_uint32_t current_timestamp; /**< Timestamp of the local clock (what we will *play* next) */ - - char *buf[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Buffer of packets (NULL if slot is free) */ - spx_uint32_t timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ - int span[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ - int len[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Number of bytes in packet */ + spx_uint32_t last_returned_timestamp; + spx_uint32_t next_stop; + + JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ + spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ + + void (*destroy) (void *); /**< Callback for destroying a packet */ - int tick_size; /**< Output granularity */ + int resolution; /**< Time resolution for histogram (timestamp units) */ + int delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ + int res_delay_step; /**< Size of the steps when adjusting buffering (resolution units) */ int reset_state; /**< True if state was just reset */ int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ int late_cutoff; /**< How late must a packet be for it not to be considered at all */ int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ + struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ + struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ + + float late_ratio_short; + float late_ratio_long; + float ontime_ratio_short; + float ontime_ratio_long; + float early_ratio_short; + float early_ratio_long; + int lost_count; /**< Number of consecutive lost packets */ float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */ float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */ @@ -82,17 +225,21 @@ struct JitterBuffer_ { }; /** Initialise jitter buffer */ -JitterBuffer *jitter_buffer_init(int tick) +JitterBuffer *jitter_buffer_init(int resolution) { JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); if (jitter) { int i; for (i=0;ibuf[i]=NULL; - jitter->tick_size = tick; + jitter->packets[i].data=NULL; + jitter->resolution = resolution; + jitter->delay_step = resolution; + jitter->res_delay_step = 1; + /*FIXME: Should this be 0 or 1?*/ jitter->buffer_margin = 1; jitter->late_cutoff = 50; + jitter->destroy = NULL; jitter_buffer_reset(jitter); } return jitter; @@ -104,15 +251,18 @@ void jitter_buffer_reset(JitterBuffer *jitter) int i; for (i=0;ibuf[i]) + if (jitter->packets[i].data) { - speex_free(jitter->buf[i]); - jitter->buf[i] = NULL; + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; } } /* Timestamp is actually undefined at this point */ jitter->pointer_timestamp = 0; - jitter->current_timestamp = 0; + jitter->next_stop = 0; jitter->reset_state = 1; jitter->lost_count = 0; jitter->loss_rate = 0; @@ -121,6 +271,12 @@ void jitter_buffer_reset(JitterBuffer *jitter) jitter->shortterm_margin[i] = 0; jitter->longterm_margin[i] = 0; } + + for (i=0;i_tb[i]); + jitter->timeBuffers[i] = &jitter->_tb[i]; + } /*fprintf (stderr, "reset\n");*/ } @@ -131,79 +287,45 @@ void jitter_buffer_destroy(JitterBuffer *jitter) speex_free(jitter); } -/** Put one packet into the jitter buffer */ -void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) +static void update_timings(JitterBuffer *jitter, spx_int32_t timing) { - int i,j; - spx_int32_t arrival_margin; - /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ - if (jitter->reset_state) - { - jitter->reset_state=0; - jitter->pointer_timestamp = packet->timestamp; - jitter->current_timestamp = packet->timestamp; - /*fprintf(stderr, "reset to %d\n", timestamp);*/ - } - - /* Cleanup buffer (remove old packets that weren't played) */ - for (i=0;i 32767) + timing = 32767; + if (jitter->timeBuffers[0]->curr_count >= WINDOW_SIZE) { - /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ - if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp)) - { - /*fprintf (stderr, "cleaned (not played)\n");*/ - speex_free(jitter->buf[i]); - jitter->buf[i] = NULL; - } + int i; + /*fprintf(stderr, "Rotate buffer\n");*/ + struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; + for (i=MAX_BUFFERS-1;i>=1;i--) + jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; + jitter->timeBuffers[0] = tmp; + tb_init(jitter->timeBuffers[0]); } + tb_add(jitter->timeBuffers[0], timing); + spx_int16_t opt = tbs_get_opt_delay(jitter->_tb, 2); + /*fprintf(stderr, "opt adjustment is %d\n", opt);*/ +} - /*Find an empty slot in the buffer*/ - for (i=0;ibuf[i]==NULL) - break; + for (j=0;jtimeBuffers[i]->filled;i++) + jitter->timeBuffers[i]->timing[j] += amount; } +} - /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/ - /*No place left in the buffer*/ - if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) - { - int earliest=jitter->timestamp[0]; - i=0; - for (j=1;jbuf[i] || LT32(jitter->timestamp[j],earliest)) - { - earliest = jitter->timestamp[j]; - i=j; - } - } - speex_free(jitter->buf[i]); - jitter->buf[i]=NULL; - if (jitter->lost_count>20) - { - jitter_buffer_reset(jitter); - } - /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ - } - - /* Copy packet in buffer */ - jitter->buf[i]=(char*)speex_alloc(packet->len); - for (j=0;j<(int)packet->len;j++) - jitter->buf[i][j]=packet->data[j]; - jitter->timestamp[i]=packet->timestamp; - jitter->span[i]=packet->span; - jitter->len[i]=packet->len; - - /* Adjust the buffer size depending on network conditions. - The arrival margin is how much in advance (or late) the packet it */ - arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->current_timestamp))/jitter->tick_size - jitter->buffer_margin; - +static void update_histogram(JitterBuffer *jitter, spx_int32_t arrival_margin) +{ + int i; if (arrival_margin >= -jitter->late_cutoff) { /* Here we compute the histogram based on the time of arrival of the packet. - This is based on a (first-order) recursive average. We keep both a short-term - histogram and a long-term histogram */ + This is based on a (first-order) recursive average. We keep both a short-term + histogram and a long-term histogram */ spx_int32_t int_margin; /* First, apply the "damping" of the recursive average to all bins */ for (i=0;i 0) { - int count = 0; - for (j=0;jbuf[j]) - count++; + jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; + jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; + for (i=MAX_MARGIN-3;i>=0;i--) + { + jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; + jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; + } + jitter->shortterm_margin[0] = 0; + jitter->longterm_margin[0] = 0; + } + } else { + /* FIXME: This is terribly inefficient */ + for (c=0;c<-amount;c++) + { + jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; + jitter->longterm_margin[0] += jitter->longterm_margin[1]; + for (i=1;ishortterm_margin[i] = jitter->shortterm_margin[i+1]; + jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; + } + jitter->shortterm_margin[MAX_MARGIN-1] = 0; + jitter->longterm_margin[MAX_MARGIN-1] = 0; } - fprintf (stderr, "buffer_size = %d\n", count); } -#endif } -/** Get one packet from the jitter buffer */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) +static void compute_statistics(JitterBuffer *jitter) { int i; - unsigned int j; - float late_ratio_short; - float late_ratio_long; - float ontime_ratio_short; - float ontime_ratio_long; - float early_ratio_short; - float early_ratio_long; - int chunk_size; - int incomplete = 0; - - if (jitter->interp_requested) + jitter->late_ratio_short = 0; + jitter->late_ratio_long = 0; + /* Count the proportion of packets that are late */ + for (i=0;iinterp_requested = 0; - if (start_offset) - *start_offset = 0; - packet->timestamp = jitter->pointer_timestamp; - packet->span = jitter->tick_size; - jitter->pointer_timestamp += jitter->tick_size; - packet->len = 0; - return JITTER_BUFFER_MISSING; + jitter->late_ratio_short += jitter->shortterm_margin[i]; + jitter->late_ratio_long += jitter->longterm_margin[i]; } - if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) + + /* Count the proportion of packets that are just on time */ + jitter->ontime_ratio_short = 0; + jitter->ontime_ratio_long = 0; + for (;ires_delay_step;i++) { - jitter->current_timestamp = jitter->pointer_timestamp; - speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); + jitter->ontime_ratio_short = jitter->shortterm_margin[i]; + jitter->ontime_ratio_long = jitter->longterm_margin[i]; } - /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ + + jitter->early_ratio_short = 0; + jitter->early_ratio_long = 0; + /* Count the proportion of packets that are early */ + for (;iearly_ratio_short += jitter->shortterm_margin[i]; + jitter->early_ratio_long += jitter->longterm_margin[i]; + } +} - /* FIXME: This should be only what remaining of the current tick */ - chunk_size = jitter->tick_size; +/** Put one packet into the jitter buffer */ +void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) +{ + int i,j; + int late; + spx_int32_t arrival_margin; + spx_int32_t arrival_time; + /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ - /* Compiling arrival statistics */ + /* Syncing on the first packet to arrive */ + if (jitter->reset_state) + { + jitter->reset_state=0; + jitter->pointer_timestamp = packet->timestamp; + jitter->next_stop = packet->timestamp; + /*fprintf(stderr, "reset to %d\n", timestamp);*/ + } - late_ratio_short = 0; - late_ratio_long = 0; - /* Count the proportion of packets that are late */ - for (i=0;ishortterm_margin[i]; - late_ratio_long += jitter->longterm_margin[i]; + /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) + { + /*fprintf (stderr, "cleaned (not played)\n");*/ + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data = NULL; + } } - /* Count the proportion of packets that are just on time */ - ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; - ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; - early_ratio_short = early_ratio_long = 0; - /* Count the proportion of packets that are early */ - for (i=LATE_BINS+1;itimestamp, jitter->next_stop, jitter->pointer_timestamp);*/ + /* Check if packet is late (could still be useful though) */ + if (LT32(packet->timestamp, jitter->next_stop)) { - early_ratio_short += jitter->shortterm_margin[i]; - early_ratio_long += jitter->longterm_margin[i]; + /*fprintf(stderr, "late by %d\n", jitter->next_stop - packet->timestamp);*/ + + /* The arrival margin is how much in advance (or in this case late) the packet it (in resolution units) */ + arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop))/jitter->resolution - jitter->buffer_margin; + + /*fprintf(stderr, "put arrival_margin = %d\n", arrival_margin);*/ + /*update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop));*/ + update_histogram(jitter, arrival_margin); + late = 1; + } else { + late = 0; } - if (0&&jitter->pointer_timestamp%1000==0) + + /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ + if (GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) { - /*fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);*/ - /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/ + + /*Find an empty slot in the buffer*/ + for (i=0;ipackets[i].data==NULL) + break; + } + + /*No place left in the buffer, need to make room for it by discarding the oldest packet */ + if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) + { + int earliest=jitter->packets[0].timestamp; + i=0; + for (j=1;jpackets[i].data || LT32(jitter->packets[j].timestamp,earliest)) + { + earliest = jitter->packets[j].timestamp; + i=j; + } + } + if (jitter->destroy) + jitter->destroy(jitter->packets[i].data); + else + speex_free(jitter->packets[i].data); + jitter->packets[i].data=NULL; + if (jitter->lost_count>20) + { + jitter_buffer_reset(jitter); + } + /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ + } + + /* Copy packet in buffer */ + if (jitter->destroy) + { + jitter->packets[i].data = packet->data; + } else { + jitter->packets[i].data=(char*)speex_alloc(packet->len); + for (j=0;jlen;j++) + jitter->packets[i].data[j]=packet->data[j]; + } + jitter->packets[i].timestamp=packet->timestamp; + jitter->packets[i].span=packet->span; + jitter->packets[i].len=packet->len; + jitter->packets[i].user_data=packet->user_data; + if (late) + jitter->arrival[i] = 0; + else + jitter->arrival[i] = jitter->next_stop; } +} + +/** Get one packet from the jitter buffer */ +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) +{ + int i; + unsigned int j; + int incomplete = 0; + + jitter->last_returned_timestamp = jitter->pointer_timestamp; + + if (jitter->interp_requested) + { + jitter->interp_requested = 0; + if (start_offset) + *start_offset = 0; + packet->timestamp = jitter->pointer_timestamp; + packet->span = jitter->delay_step; + + /* Increment the pointer because it got decremented in the delay update */ + jitter->pointer_timestamp += jitter->delay_step; + packet->len = 0; + /*fprintf (stderr, "Deferred interpolate\n");*/ + + return JITTER_BUFFER_MISSING; + } + /* Searching for the packet that fits best */ /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ for (i=0;ibuf[i] && jitter->timestamp[i]==jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) + if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->pointer_timestamp && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) break; } @@ -318,7 +567,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 { for (i=0;ibuf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GE32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp+desired_span)) break; } } @@ -328,7 +577,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 { for (i=0;ibuf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GT32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp)) + if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp, jitter->pointer_timestamp) && GT32(jitter->packets[i].timestamp+jitter->packets[i].span,jitter->pointer_timestamp)) break; } } @@ -343,12 +592,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 for (i=0;ibuf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp)) + if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) { - if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span))) + if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) { - best_time = jitter->timestamp[i]; - best_span = jitter->span[i]; + best_time = jitter->packets[i].timestamp; + best_span = jitter->packets[i].span; besti = i; found = 1; } @@ -358,31 +607,62 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 { i=besti; incomplete = 1; - /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/ + /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ } } /* If we find something */ if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) { + + /* We (obviously) haven't lost this packet */ jitter->lost_count = 0; jitter->loss_rate = .999*jitter->loss_rate; - /* Check for potential overflow */ - packet->len = jitter->len[i]; + + /* In this case, 0 isn't as a valid timestamp */ + if (jitter->arrival[i] != 0) + { + spx_int32_t arrival_margin; + /*fprintf(stderr, "early by %d\n", jitter->packets[i].timestamp - jitter->arrival[i]);*/ + + /* The arrival margin is how much in advance (or in this case late) the packet it (in resolution units) */ + arrival_margin = (((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]))/jitter->resolution - jitter->buffer_margin; + + /*fprintf(stderr, "get arrival_margin = %d\n", arrival_margin);*/ + + /*update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]));*/ + + update_histogram(jitter, arrival_margin); + + } + + + /* FIXME: Check for potential overflow */ + packet->len = jitter->packets[i].len; /* Copy packet */ - for (j=0;jlen;j++) - packet->data[j] = jitter->buf[i][j]; - /* Remove packet */ - speex_free(jitter->buf[i]); - jitter->buf[i] = NULL; + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + } else { + for (j=0;jlen;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; /* Set timestamp and span (if requested) */ if (start_offset) - *start_offset = (spx_int32_t)jitter->timestamp[i]-(spx_int32_t)jitter->pointer_timestamp; - packet->timestamp = jitter->timestamp[i]; - packet->span = jitter->span[i]; - /* Point at the end of the current packet */ - jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i]; + *start_offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; + + packet->timestamp = jitter->packets[i].timestamp; + jitter->last_returned_timestamp = packet->timestamp; + + packet->span = jitter->packets[i].span; + packet->user_data = jitter->packets[i].user_data; + /* Point to the end of the current packet */ + jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; + if (incomplete) return JITTER_BUFFER_INCOMPLETE; else @@ -391,6 +671,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 /* If we haven't found anything worth returning */ + /*fprintf (stderr, "not found\n");*/ jitter->lost_count++; /*fprintf (stderr, "m");*/ @@ -398,34 +679,71 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 jitter->loss_rate = .999*jitter->loss_rate + .001; if (start_offset) *start_offset = 0; - packet->timestamp = jitter->pointer_timestamp; - packet->span = jitter->tick_size; - jitter->pointer_timestamp += chunk_size; - packet->len = 0; - /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ - if (late_ratio_short > .1 || late_ratio_long > .03) + compute_statistics(jitter); + + /* Should we force an increase in the buffer or just do normal interpolation? */ + if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03) { - /* If too many packets are arriving late */ - jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; - jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; - for (i=MAX_MARGIN-3;i>=0;i--) - { - jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; - jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; - } - jitter->shortterm_margin[0] = 0; - jitter->longterm_margin[0] = 0; - jitter->pointer_timestamp -= jitter->tick_size; - jitter->current_timestamp -= jitter->tick_size; - /*fprintf (stderr, "i");*/ - /*fprintf (stderr, "interpolate (getting some slack)\n");*/ + /* Increase buffering */ + + /* Shift histogram to compensate */ + shift_histogram(jitter, jitter->res_delay_step); + + packet->timestamp = jitter->pointer_timestamp; + packet->span = jitter->delay_step; + /* Don't move the pointer_timestamp forward */ + packet->len = 0; + + /*jitter->pointer_timestamp -= jitter->delay_step;*/ + /*fprintf (stderr, "Forced to interpolate\n");*/ + } else { + /* Normal packet loss */ + packet->timestamp = jitter->pointer_timestamp; + packet->span = desired_span; + jitter->pointer_timestamp += desired_span; + packet->len = 0; + /*fprintf (stderr, "Normal loss\n");*/ } return JITTER_BUFFER_MISSING; } +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) +{ + int i, j; + for (i=0;ipackets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) + break; + } + if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) + { + /* Copy packet */ + packet->len = jitter->packets[i].len; + if (jitter->destroy) + { + packet->data = jitter->packets[i].data; + } else { + for (j=0;jlen;j++) + packet->data[j] = jitter->packets[i].data[j]; + /* Remove packet */ + speex_free(jitter->packets[i].data); + } + jitter->packets[i].data = NULL; + packet->timestamp = jitter->packets[i].timestamp; + packet->span = jitter->packets[i].span; + packet->user_data = jitter->packets[i].user_data; + return JITTER_BUFFER_OK; + } else { + packet->data = NULL; + packet->len = 0; + packet->span = 0; + return JITTER_BUFFER_MISSING; + } +} + /** Get pointer timestamp of jitter buffer */ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) { @@ -434,81 +752,39 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) void jitter_buffer_tick(JitterBuffer *jitter) { - jitter->current_timestamp += jitter->tick_size; + jitter->next_stop = jitter->pointer_timestamp; +} + +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) +{ + jitter->next_stop = jitter->pointer_timestamp - rem; } /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) { int i; - float late_ratio_short; - float late_ratio_long; - float ontime_ratio_short; - float ontime_ratio_long; - float early_ratio_short; - float early_ratio_long; - if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) - { - jitter->current_timestamp = jitter->pointer_timestamp; - speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); - } - /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ + compute_statistics(jitter); - /* FIXME: This should be only what remaining of the current tick */ - late_ratio_short = 0; - late_ratio_long = 0; - /* Count the proportion of packets that are late */ - for (i=0;ishortterm_margin[i]; - late_ratio_long += jitter->longterm_margin[i]; - } - /* Count the proportion of packets that are just on time */ - ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; - ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; - early_ratio_short = early_ratio_long = 0; - /* Count the proportion of packets that are early */ - for (i=LATE_BINS+1;ishortterm_margin[i]; - early_ratio_long += jitter->longterm_margin[i]; - } - /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ - if (late_ratio_short > .1 || late_ratio_long > .03) + if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03) { /* If too many packets are arriving late */ - jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; - jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; - for (i=MAX_MARGIN-3;i>=0;i--) - { - jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; - jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; - } - jitter->shortterm_margin[0] = 0; - jitter->longterm_margin[0] = 0; - jitter->pointer_timestamp -= jitter->tick_size; - jitter->current_timestamp -= jitter->tick_size; + shift_histogram(jitter, jitter->res_delay_step); + + jitter->pointer_timestamp -= jitter->delay_step; jitter->interp_requested = 1; + /*fprintf (stderr, "Decision to interpolate\n");*/ return JITTER_BUFFER_ADJUST_INTERPOLATE; - } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8) + } else if (jitter->late_ratio_short + jitter->ontime_ratio_short < .005 && jitter->late_ratio_long + jitter->ontime_ratio_long < .01 && jitter->early_ratio_short > .8) { /* Many frames arriving early */ - jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; - jitter->longterm_margin[0] += jitter->longterm_margin[1]; - for (i=1;ishortterm_margin[i] = jitter->shortterm_margin[i+1]; - jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; - } - jitter->shortterm_margin[MAX_MARGIN-1] = 0; - jitter->longterm_margin[MAX_MARGIN-1] = 0; - /*fprintf (stderr, "drop frame\n");*/ - /*fprintf (stderr, "d");*/ - jitter->pointer_timestamp += jitter->tick_size; - jitter->current_timestamp += jitter->tick_size; + shift_histogram(jitter, -jitter->res_delay_step); + + jitter->pointer_timestamp += jitter->delay_step; + /*fprintf (stderr, "Decision to drop\n");*/ return JITTER_BUFFER_ADJUST_DROP; } @@ -531,13 +807,26 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) count = 0; for (i=0;ibuf[i] && LE32(jitter->pointer_timestamp, jitter->timestamp[i])) + if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) { count++; } } *(spx_int32_t*)ptr = count; break; + case JITTER_BUFFER_SET_DESTROY_CALLBACK: + jitter->destroy = (void (*) (void *))ptr; + break; + case JITTER_BUFFER_GET_DESTROY_CALLBACK: + *(void (**) (void *))ptr = jitter->destroy; + break; + case JITTER_BUFFER_SET_DELAY_STEP: + jitter->delay_step = *(spx_int32_t*)ptr; + jitter->res_delay_step = jitter->delay_step/jitter->resolution; + break; + case JITTER_BUFFER_GET_DELAY_STEP: + *(spx_int32_t*)ptr = jitter->delay_step; + break; default: speex_warning_int("Unknown jitter_buffer_ctl request: ", request); return -1; diff --git a/apps/codecs/libspeex/kiss_fft.c b/apps/codecs/libspeex/kiss_fft.c index 599ba66845..775edfff36 100644 --- a/apps/codecs/libspeex/kiss_fft.c +++ b/apps/codecs/libspeex/kiss_fft.c @@ -19,7 +19,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #endif #include "_kiss_fft_guts.h" -#include "misc.h" +#include "arch.h" #include "os_support.h" /* The guts header contains all the multiplication and addition macros that are defined for diff --git a/apps/codecs/libspeex/kiss_fft.h b/apps/codecs/libspeex/kiss_fft.h index 54627e7da0..fa3f2c6042 100644 --- a/apps/codecs/libspeex/kiss_fft.h +++ b/apps/codecs/libspeex/kiss_fft.h @@ -3,7 +3,7 @@ #include #include -#include "misc.h" +#include "arch.h" #ifdef __cplusplus extern "C" { @@ -32,7 +32,7 @@ extern "C" { #ifdef FIXED_POINT -#include "misc.h" +#include "arch.h" # define kiss_fft_scalar spx_int16_t #else # ifndef kiss_fft_scalar diff --git a/apps/codecs/libspeex/lpc.h b/apps/codecs/libspeex/lpc.h index d64df96741..952ecdd933 100644 --- a/apps/codecs/libspeex/lpc.h +++ b/apps/codecs/libspeex/lpc.h @@ -35,7 +35,7 @@ #ifndef LPC_H #define LPC_H -#include "misc.h" +#include "arch.h" void _spx_autocorr( const spx_word16_t * x, /* in: [0...n-1] samples x */ diff --git a/apps/codecs/libspeex/lsp.h b/apps/codecs/libspeex/lsp.h index 9d0345f426..648652fb9e 100644 --- a/apps/codecs/libspeex/lsp.h +++ b/apps/codecs/libspeex/lsp.h @@ -51,7 +51,7 @@ Modified by Jean-Marc Valin #ifndef __AK2LSPD__ #define __AK2LSPD__ -#include "misc.h" +#include "arch.h" int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); diff --git a/apps/codecs/libspeex/ltp.h b/apps/codecs/libspeex/ltp.h index bc050c6392..1e435bc36e 100644 --- a/apps/codecs/libspeex/ltp.h +++ b/apps/codecs/libspeex/ltp.h @@ -33,7 +33,7 @@ */ #include -#include "misc.h" +#include "arch.h" /** LTP parameters. */ typedef struct { diff --git a/apps/codecs/libspeex/math.h b/apps/codecs/libspeex/math.h deleted file mode 100644 index 5c1781df52..0000000000 --- a/apps/codecs/libspeex/math.h +++ /dev/null @@ -1,32 +0,0 @@ -/************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2007 Dan Everton - * - * All files in this archive are subject to the GNU General Public License. - * See the file COPYING in the source tree root for full license agreement. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifndef MATH_H -#define MATH_H - -float floor(float); -float exp(float); -float sqrt(float); -float fabs(float); -float log(float); -float pow(float, float); -float sin(float); -float cos(float); - -#endif - diff --git a/apps/codecs/libspeex/math_approx.h b/apps/codecs/libspeex/math_approx.h index 4f61e8645a..9ca830755d 100644 --- a/apps/codecs/libspeex/math_approx.h +++ b/apps/codecs/libspeex/math_approx.h @@ -35,7 +35,7 @@ #ifndef MATH_APPROX_H #define MATH_APPROX_H -#include "misc.h" +#include "arch.h" #ifndef FIXED_POINT diff --git a/apps/codecs/libspeex/mdf.c b/apps/codecs/libspeex/mdf.c index 8840c34e08..2e863cf274 100644 --- a/apps/codecs/libspeex/mdf.c +++ b/apps/codecs/libspeex/mdf.c @@ -69,7 +69,7 @@ #include "config-speex.h" #endif -#include "misc.h" +#include "arch.h" #include "speex/speex_echo.h" #include "fftwrap.h" #include "pseudofloat.h" diff --git a/apps/codecs/libspeex/medfilter.c b/apps/codecs/libspeex/medfilter.c index e4bc1c6ce9..57f403f00a 100644 --- a/apps/codecs/libspeex/medfilter.c +++ b/apps/codecs/libspeex/medfilter.c @@ -37,7 +37,7 @@ #endif #include "medfilter.h" -#include "misc.h" +#include "arch.h" MedianFilter *median_filter_new(int N) { diff --git a/apps/codecs/libspeex/misc.h b/apps/codecs/libspeex/misc.h deleted file mode 100644 index 7dcc4f25f9..0000000000 --- a/apps/codecs/libspeex/misc.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file misc.h - @brief Various compatibility routines for Speex -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef MISC_H -#define MISC_H - -#include "config-speex.h" - -#ifndef SPEEX_VERSION -#define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ -#define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ -#define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */ -#define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ -#define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */ -#endif - -/* A couple test to catch stupid option combinations */ -#ifdef FIXED_POINT - -#ifdef _USE_SSE -#error SSE is only for floating-point -#endif -#if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) -#error Make up your mind. What CPU do you have? -#endif -#ifdef VORBIS_PSYCHO -#error Vorbis-psy model currently not implemented in fixed-point -#endif - -#else - -#if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) -#error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? -#endif -#ifdef FIXED_POINT_DEBUG -#error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" -#endif - - -#endif - -#include "arch.h" - -/** Convert little endian */ -static inline spx_int32_t le_int(spx_int32_t i) -{ -#if 1 - return letoh32(i); -#elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) - spx_uint32_t ui, ret; - ui = i; - ret = ui>>24; - ret |= (ui>>8)&0x0000ff00; - ret |= (ui<<8)&0x00ff0000; - ret |= (ui<<24); - return ret; -#else - return i; -#endif -} - - -#ifdef FIXED_DEBUG -long long spx_mips=0; -#endif - - -#endif diff --git a/apps/codecs/libspeex/modes.c b/apps/codecs/libspeex/modes.c index cf4ef3246c..20ea287344 100644 --- a/apps/codecs/libspeex/modes.c +++ b/apps/codecs/libspeex/modes.c @@ -43,7 +43,7 @@ #include "sb_celp.h" #include "nb_celp.h" #include "vbr.h" -#include "misc.h" +#include "arch.h" #include #ifndef NULL @@ -439,7 +439,6 @@ static const SpeexNBMode nb_mode = { #else 0.9, 0.6, /* gamma1, gamma2 */ #endif - .012, /*lag_factor*/ QCONST16(.0002,15), /*lpc_floor*/ {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7, &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, diff --git a/apps/codecs/libspeex/modes.h b/apps/codecs/libspeex/modes.h index 9ce674a498..d0ff842ffa 100644 --- a/apps/codecs/libspeex/modes.h +++ b/apps/codecs/libspeex/modes.h @@ -38,7 +38,7 @@ #include #include -#include "misc.h" +#include "arch.h" #define NB_SUBMODES 16 #define NB_SUBMODE_BITS 4 @@ -123,7 +123,6 @@ typedef struct SpeexNBMode { spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ spx_word16_t gamma2; /**< Perceptual filter parameter #2 */ - float lag_factor; /**< Lag-windowing parameter */ spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ @@ -140,7 +139,6 @@ typedef struct SpeexSBMode { int lpcSize; /**< Order of LPC filter */ spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ spx_word16_t gamma2; /**< Perceptual filter parameter #1 */ - float lag_factor; /**< Lag-windowing parameter */ spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ spx_word16_t folding_gain; diff --git a/apps/codecs/libspeex/modes_wb.c b/apps/codecs/libspeex/modes_wb.c index 1684ba6493..af16cdd775 100644 --- a/apps/codecs/libspeex/modes_wb.c +++ b/apps/codecs/libspeex/modes_wb.c @@ -43,7 +43,7 @@ #include "sb_celp.h" #include "nb_celp.h" #include "vbr.h" -#include "misc.h" +#include "arch.h" #include #include "os_support.h" @@ -231,7 +231,6 @@ static const SpeexSBMode sb_wb_mode = { #else 0.9, 0.6, /* gamma1, gamma2 */ #endif - .012, /*lag_factor*/ QCONST16(.0002,15), /*lpc_floor*/ QCONST16(0.9f,15), {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL}, @@ -291,7 +290,6 @@ static const SpeexSBMode sb_uwb_mode = { #else 0.9, 0.6, /* gamma1, gamma2 */ #endif - .012, /*lag_factor*/ QCONST16(.0002,15), /*lpc_floor*/ QCONST16(0.7f,15), {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL}, diff --git a/apps/codecs/libspeex/nb_celp.c b/apps/codecs/libspeex/nb_celp.c index 7dc4920ede..49e2403d8b 100644 --- a/apps/codecs/libspeex/nb_celp.c +++ b/apps/codecs/libspeex/nb_celp.c @@ -45,7 +45,7 @@ #include "vq.h" #include #include "vbr.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" #include "os_support.h" #include @@ -108,6 +108,7 @@ const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f}; #define sqr(x) ((x)*(x)) +extern const spx_word16_t lag_window[]; extern const spx_word16_t lpc_window[]; #ifndef SPEEX_DISABLE_ENCODER void *nb_encoder_init(const SpeexMode *m) @@ -137,7 +138,6 @@ void *nb_encoder_init(const SpeexMode *m) st->gamma2=mode->gamma2; st->min_pitch=mode->pitchStart; st->max_pitch=mode->pitchEnd; - st->lag_factor=mode->lag_factor; st->lpc_floor = mode->lpc_floor; st->submodes=mode->submodes; @@ -166,17 +166,13 @@ void *nb_encoder_init(const SpeexMode *m) st->window= lpc_window; /* Create the window for autocorrelation (lag-windowing) */ - st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i)); + st->lagWindow = lag_window; st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); st->first = 1; for (i=0;ilpcSize;i++) - { - st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1); - } + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); @@ -225,8 +221,6 @@ void nb_encoder_destroy(void *state) speex_free (st->old_qlsp); speex_free (st->swBuf); - speex_free (st->lagWindow); - speex_free (st->old_lsp); speex_free (st->mem_sp); speex_free (st->mem_sw); @@ -274,7 +268,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) char *stack; VARDECL(spx_word16_t *syn_resp); VARDECL(spx_word16_t *real_exc); - + spx_word32_t ener=0; spx_word16_t fine_gain; spx_word16_t *in = (spx_word16_t*)vin; @@ -591,6 +585,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) if (SUBMODE(forced_pitch_gain)) { int quant; + /* This just damps the pitch a bit, because it tends to be too aggressive when forced */ + ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef); #ifdef FIXED_POINT quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT); #else @@ -1120,7 +1116,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) VARDECL(spx_coef_t *ak); VARDECL(spx_lsp_t *qlsp); spx_word16_t pitch_average=0; - + spx_word16_t *out = (spx_word16_t*)vout; VARDECL(spx_lsp_t *interp_qlsp); @@ -1724,7 +1720,7 @@ int nb_encoder_ctl(void *state, int request, void *ptr) st->bounded_pitch = 1; st->first = 1; for (i=0;ilpcSize;i++) - st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); for (i=0;ilpcSize;i++) st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; for (i=0;iframeSize+st->max_pitch+1;i++) diff --git a/apps/codecs/libspeex/nb_celp.h b/apps/codecs/libspeex/nb_celp.h index 28ee9325a1..7f90f7c05c 100644 --- a/apps/codecs/libspeex/nb_celp.h +++ b/apps/codecs/libspeex/nb_celp.h @@ -73,7 +73,6 @@ typedef struct EncState { spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */ spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */ - float lag_factor; /**< Lag windowing Gaussian width */ spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ char *stack; /**< Pseudo-stack allocation for temporary memory */ spx_word16_t *winBuf; /**< Input buffer (original signal) */ @@ -82,7 +81,7 @@ typedef struct EncState { spx_word16_t *swBuf; /**< Weighted signal buffer */ spx_word16_t *sw; /**< Start of weighted signal frame */ const spx_word16_t *window; /**< Temporary (Hanning) window */ - spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ + const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ spx_lsp_t *old_lsp; /**< LSPs for previous frame */ spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */ spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */ diff --git a/apps/codecs/libspeex/oggframing.c b/apps/codecs/libspeex/oggframing.c index ab48de33c3..6a0ee21412 100644 --- a/apps/codecs/libspeex/oggframing.c +++ b/apps/codecs/libspeex/oggframing.c @@ -23,7 +23,7 @@ //#include "config-tremor.h" #include #include "speex/ogg.h" -#include "misc.h" +#include "arch.h" /* A complete description of Ogg framing exists in docs/framing.html */ diff --git a/apps/codecs/libspeex/os_support.h b/apps/codecs/libspeex/os_support.h index 92262f1942..7e4b25b3d9 100644 --- a/apps/codecs/libspeex/os_support.h +++ b/apps/codecs/libspeex/os_support.h @@ -41,10 +41,14 @@ #include #include -/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */ +/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free + NOTE: speex_alloc needs to CLEAR THE MEMORY */ #ifndef OVERRIDE_SPEEX_ALLOC static inline void *speex_alloc (int size) { + /* WARNING: this is not equivalent to malloc(). If you want to use malloc() + or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise + you will experience strange bugs */ return calloc(size,1); } #endif @@ -53,6 +57,7 @@ static inline void *speex_alloc (int size) #ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH static inline void *speex_alloc_scratch (int size) { + /* Scratch space doesn't need to be cleared */ return calloc(size,1); } #endif diff --git a/apps/codecs/libspeex/preprocess.c b/apps/codecs/libspeex/preprocess.c index da2da4a599..5d5befe736 100644 --- a/apps/codecs/libspeex/preprocess.c +++ b/apps/codecs/libspeex/preprocess.c @@ -62,7 +62,7 @@ #include #include "speex/speex_preprocess.h" #include "speex/speex_echo.h" -#include "misc.h" +#include "arch.h" #include "fftwrap.h" #include "filterbank.h" #include "math_approx.h" @@ -1127,16 +1127,16 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) break; case SPEEX_PREPROCESS_SET_PROB_START: - *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr)); - st->speech_prob_start = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100); + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); break; case SPEEX_PREPROCESS_GET_PROB_START: (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); break; case SPEEX_PREPROCESS_SET_PROB_CONTINUE: - *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr)); - st->speech_prob_continue = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100); + *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); + st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); break; case SPEEX_PREPROCESS_GET_PROB_CONTINUE: (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); @@ -1166,6 +1166,11 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) case SPEEX_PREPROCESS_GET_ECHO_STATE: ptr = (void*)st->echo_state; break; +#ifndef FIXED_POINT + case SPEEX_PREPROCESS_GET_AGC_LOUDNESS: + (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP); + break; +#endif default: speex_warning_int("Unknown speex_preprocess_ctl request: ", request); diff --git a/apps/codecs/libspeex/pseudofloat.h b/apps/codecs/libspeex/pseudofloat.h index a237e32620..448dd61ffe 100644 --- a/apps/codecs/libspeex/pseudofloat.h +++ b/apps/codecs/libspeex/pseudofloat.h @@ -44,7 +44,7 @@ #ifndef PSEUDOFLOAT_H #define PSEUDOFLOAT_H -#include "misc.h" +#include "arch.h" #include "os_support.h" #include "math_approx.h" #include diff --git a/apps/codecs/libspeex/quant_lsp.c b/apps/codecs/libspeex/quant_lsp.c index 10d5762017..441a257a49 100644 --- a/apps/codecs/libspeex/quant_lsp.c +++ b/apps/codecs/libspeex/quant_lsp.c @@ -41,7 +41,7 @@ #define M_PI 3.14159265358979323846 #endif -#include "misc.h" +#include "arch.h" #ifdef BFIN_ASM #include "quant_lsp_bfin.h" diff --git a/apps/codecs/libspeex/quant_lsp.h b/apps/codecs/libspeex/quant_lsp.h index 828dffc4f5..3bf4d4021c 100644 --- a/apps/codecs/libspeex/quant_lsp.h +++ b/apps/codecs/libspeex/quant_lsp.h @@ -36,7 +36,7 @@ #define QUANT_LSP_H #include -#include "misc.h" +#include "arch.h" #define MAX_LSP_SIZE 20 diff --git a/apps/codecs/libspeex/resample.c b/apps/codecs/libspeex/resample.c index ae134ea783..82e85bef43 100644 --- a/apps/codecs/libspeex/resample.c +++ b/apps/codecs/libspeex/resample.c @@ -70,7 +70,7 @@ static void speex_free (void *ptr) {free(ptr);} #else /* OUTSIDE_SPEEX */ #include "speex/speex_resampler.h" -#include "misc.h" +#include "arch.h" #include "os_support.h" #endif /* OUTSIDE_SPEEX */ diff --git a/apps/codecs/libspeex/sb_celp.c b/apps/codecs/libspeex/sb_celp.c index 3314f6b87e..192c873d9e 100644 --- a/apps/codecs/libspeex/sb_celp.c +++ b/apps/codecs/libspeex/sb_celp.c @@ -43,7 +43,7 @@ #include "quant_lsp.h" #include "vq.h" #include "ltp.h" -#include "misc.h" +#include "arch.h" #include "math_approx.h" #include "os_support.h" @@ -183,6 +183,7 @@ static const float h0[64] = { #endif +extern const spx_word16_t lag_window[]; extern const spx_word16_t lpc_window[]; #ifndef SPEEX_DISABLE_ENCODER @@ -224,7 +225,6 @@ void *sb_encoder_init(const SpeexMode *m) tmp=1; speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp); - st->lag_factor = mode->lag_factor; st->lpc_floor = mode->lpc_floor; st->gamma1=mode->gamma1; st->gamma2=mode->gamma2; @@ -237,9 +237,7 @@ void *sb_encoder_init(const SpeexMode *m) st->window= lpc_window; - st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i)); + st->lagWindow = lag_window; st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); @@ -253,9 +251,7 @@ void *sb_encoder_init(const SpeexMode *m) st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); for (i=0;ilpcSize;i++) - { - st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1); - } + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); st->vbr_quality = 8; st->vbr_enabled = 0; @@ -288,8 +284,6 @@ void sb_encoder_destroy(void *state) speex_free(st->h0_mem); speex_free(st->h1_mem); - speex_free(st->lagWindow); - speex_free(st->old_lsp); speex_free(st->old_qlsp); speex_free(st->interp_qlpc); @@ -1271,7 +1265,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr) int i; st->first = 1; for (i=0;ilpcSize;i++) - st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); + st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); for (i=0;ilpcSize;i++) st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; for (i=0;i #include "smallft.h" -#include "misc.h" +#include "arch.h" #include "os_support.h" static void drfti1(int n, float *wa, int *ifac){ diff --git a/apps/codecs/libspeex/speex/speex_jitter.h b/apps/codecs/libspeex/speex/speex_jitter.h index 3f3a43c240..7c948d474e 100644 --- a/apps/codecs/libspeex/speex/speex_jitter.h +++ b/apps/codecs/libspeex/speex/speex_jitter.h @@ -41,8 +41,7 @@ * @{ */ -#include "speex.h" -#include "speex_bits.h" +#include "speex_types.h" #ifdef __cplusplus extern "C" { @@ -63,6 +62,7 @@ struct _JitterBufferPacket { spx_uint32_t len; /**< Length of the packet in bytes */ spx_uint32_t timestamp; /**< Timestamp for the packet */ spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ + spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ }; /** Packet has been retrieved */ @@ -82,11 +82,21 @@ struct _JitterBufferPacket { /** Get minimum amount of extra buffering required (margin) */ #define JITTER_BUFFER_GET_MARGIN 1 /* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ + /** Get the amount of available packets currently buffered */ #define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 /** Included because of an early misspelling (will remove in next release) */ #define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 +/** */ +#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 +/** */ +#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 + +/** */ +#define JITTER_BUFFER_SET_DELAY_STEP 6 +/** */ +#define JITTER_BUFFER_GET_DELAY_STEP 7 #define JITTER_BUFFER_ADJUST_INTERPOLATE -1 @@ -123,9 +133,18 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); * * @param jitter Jitter buffer state * @param packet Returned packet + * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) * @param current_timestamp Timestamp for the returned packet */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); + +/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. + * This is mainly useful for media where a single "frame" can be split into several packets. + * + * @param jitter Jitter buffer state + * @param packet Returned packet + */ +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); /** Get pointer timestamp of jitter buffer * @@ -139,6 +158,12 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); */ void jitter_buffer_tick(JitterBuffer *jitter); +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); + /** Used like the ioctl function to control the jitter buffer parameters * * @param jitter Jitter buffer state @@ -152,45 +177,8 @@ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, /* @} */ -/** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex - * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size - * to maintain good quality and low latency. This is a simplified version that works only - * with Speex, but is much easier to use. - * @{ -*/ - -/** Speex jitter-buffer state. Never use it directly! */ -typedef struct SpeexJitter { - SpeexBits current_packet; /**< Current Speex packet */ - int valid_bits; /**< True if Speex bits are valid */ - JitterBuffer *packets; /**< Generic jitter buffer state */ - void *dec; /**< Pointer to Speex decoder */ - spx_int32_t frame_size; /**< Frame size of Speex decoder */ -} SpeexJitter; - -/** Initialise jitter buffer - * - * @param jitter State of the Speex jitter buffer - * @param decoder Speex decoder to call - * @param sampling_rate Sampling rate used by the decoder -*/ -void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate); - -/** Destroy jitter buffer */ -void speex_jitter_destroy(SpeexJitter *jitter); - -/** Put one packet into the jitter buffer */ -void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp); - -/** Get one packet from the jitter buffer */ -void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset); - -/** Get pointer timestamp of jitter buffer */ -int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); - #ifdef __cplusplus } #endif -/* @} */ #endif diff --git a/apps/codecs/libspeex/speex/speex_preprocess.h b/apps/codecs/libspeex/speex/speex_preprocess.h index 863b83fe14..273efaff79 100644 --- a/apps/codecs/libspeex/speex/speex_preprocess.h +++ b/apps/codecs/libspeex/speex/speex_preprocess.h @@ -178,6 +178,10 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); /** Get maximal gain in dB (int32) */ #define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 +/* Can't set loudness */ +/** Get loudness */ +#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 + #ifdef __cplusplus } #endif diff --git a/apps/codecs/libspeex/speex/speex_stereo.h b/apps/codecs/libspeex/speex/speex_stereo.h index b817a5535e..67e2a8d4e0 100644 --- a/apps/codecs/libspeex/speex/speex_stereo.h +++ b/apps/codecs/libspeex/speex/speex_stereo.h @@ -60,7 +60,7 @@ typedef struct SpeexStereoState { #define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} /** Initialise/create a stereo stereo state */ -SpeexStereoState *speex_stereo_state_init(); +SpeexStereoState *speex_stereo_state_init(void); /** Reset/re-initialise an already allocated stereo state */ void speex_stereo_state_reset(SpeexStereoState *stereo); diff --git a/apps/codecs/libspeex/speex_callbacks.c b/apps/codecs/libspeex/speex_callbacks.c index ca29e1b32b..252bc90f6f 100644 --- a/apps/codecs/libspeex/speex_callbacks.c +++ b/apps/codecs/libspeex/speex_callbacks.c @@ -37,7 +37,7 @@ #endif #include -#include "misc.h" +#include "arch.h" #include "os_support.h" int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) diff --git a/apps/codecs/libspeex/speex_header.c b/apps/codecs/libspeex/speex_header.c index 6d1e010828..eb4c199d46 100644 --- a/apps/codecs/libspeex/speex_header.c +++ b/apps/codecs/libspeex/speex_header.c @@ -35,7 +35,7 @@ #include "config-speex.h" #endif -#include "misc.h" +#include "arch.h" #include #include #include "os_support.h" @@ -44,6 +44,24 @@ #define NULL 0 #endif +/** Convert little endian */ +static inline spx_int32_t le_int(spx_int32_t i) +{ +#if 1 + return letoh32(i); +#elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) + spx_uint32_t ui, ret; + ui = i; + ret = ui>>24; + ret |= (ui>>8)&0x0000ff00; + ret |= (ui<<8)&0x00ff0000; + ret |= (ui<<24); + return ret; +#else + return i; +#endif +} + #define ENDIAN_SWITCH(x) {x=le_int(x);} diff --git a/apps/codecs/libspeex/stereo.c b/apps/codecs/libspeex/stereo.c index c63c974798..9fa812dd72 100644 --- a/apps/codecs/libspeex/stereo.c +++ b/apps/codecs/libspeex/stereo.c @@ -213,7 +213,7 @@ void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState spx_word16_t e_left, e_right, e_ratio; RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; - COMPATIBILITY_HACK(stereo); + /* COMPATIBILITY_HACK(stereo); */ balance=stereo->balance; e_ratio=stereo->e_ratio; @@ -240,7 +240,7 @@ int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) stereo = (RealSpeexStereoState*)data; - COMPATIBILITY_HACK(stereo); + /* COMPATIBILITY_HACK(stereo); */ if (speex_bits_unpack_unsigned(bits, 1)) sign=-1; diff --git a/apps/codecs/libspeex/vbr.h b/apps/codecs/libspeex/vbr.h index 34e1d4c358..ff1e3e46f2 100644 --- a/apps/codecs/libspeex/vbr.h +++ b/apps/codecs/libspeex/vbr.h @@ -37,7 +37,7 @@ #ifndef VBR_H #define VBR_H -#include "misc.h" +#include "arch.h" #define VBR_MEMORY_SIZE 5 diff --git a/apps/codecs/libspeex/vorbis_psy.c b/apps/codecs/libspeex/vorbis_psy.c index fe01af145f..91cf49c69c 100644 --- a/apps/codecs/libspeex/vorbis_psy.c +++ b/apps/codecs/libspeex/vorbis_psy.c @@ -35,7 +35,7 @@ #ifdef VORBIS_PSYCHO -#include "misc.h" +#include "arch.h" #include "smallft.h" #include "lpc.h" #include "vorbis_psy.h" diff --git a/apps/codecs/libspeex/vq.c b/apps/codecs/libspeex/vq.c index f9ee3b4a86..1c66b32b16 100644 --- a/apps/codecs/libspeex/vq.c +++ b/apps/codecs/libspeex/vq.c @@ -36,7 +36,7 @@ #include "vq.h" #include "stack_alloc.h" -#include "misc.h" +#include "arch.h" #ifdef _USE_SSE #include diff --git a/apps/codecs/libspeex/vq.h b/apps/codecs/libspeex/vq.h index 7ca81975c6..478d8696bd 100644 --- a/apps/codecs/libspeex/vq.h +++ b/apps/codecs/libspeex/vq.h @@ -35,7 +35,7 @@ #ifndef VQ_H #define VQ_H -#include "misc.h" +#include "arch.h" int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries); int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries); diff --git a/apps/codecs/libspeex/window.c b/apps/codecs/libspeex/window.c index 41757ff0d0..84ed4916cf 100644 --- a/apps/codecs/libspeex/window.c +++ b/apps/codecs/libspeex/window.c @@ -33,9 +33,13 @@ #include "config-speex.h" #endif -#include "misc.h" +#include "arch.h" #ifdef FIXED_POINT +const spx_word16_t lag_window[11] ICONST_ATTR = { + 16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330 +}; + const spx_word16_t lpc_window[200] ICONST_ATTR = { 1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436, 1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884, @@ -64,6 +68,10 @@ const spx_word16_t lpc_window[200] ICONST_ATTR = { 6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696 }; #else +const spx_word16_t lag_window[11] = { + 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258 +}; + const spx_word16_t lpc_window[200] = { 0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f, 0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f, -- cgit v1.2.3