summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2007-11-22 01:29:14 +0000
committerThom Johansen <thomj@rockbox.org>2007-11-22 01:29:14 +0000
commit57a27c69a9f3b9b69aff9360c09f7298ffd7b670 (patch)
tree252dcf43c2ed5058047d1aac98c00ff24e97f067 /apps
parent14ac7cafc81940f5f389515cb5134e6c52f37813 (diff)
downloadrockbox-57a27c69a9f3b9b69aff9360c09f7298ffd7b670.tar.gz
rockbox-57a27c69a9f3b9b69aff9360c09f7298ffd7b670.zip
Sync Speex to SVN.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15750 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/codecs/libspeex/config-speex.h4
-rw-r--r--apps/codecs/libspeex/jitter.c423
-rw-r--r--apps/codecs/libspeex/modes.h2
-rw-r--r--apps/codecs/libspeex/modes_wb.c36
-rw-r--r--apps/codecs/libspeex/nb_celp.c40
-rw-r--r--apps/codecs/libspeex/nb_celp.h5
-rw-r--r--apps/codecs/libspeex/preprocess.c17
-rw-r--r--apps/codecs/libspeex/quant_lsp.c1
-rw-r--r--apps/codecs/libspeex/sb_celp.c18
-rw-r--r--apps/codecs/libspeex/sb_celp.h4
-rw-r--r--apps/codecs/libspeex/speex.c6
-rw-r--r--apps/codecs/libspeex/speex/speex.h14
-rw-r--r--apps/codecs/libspeex/speex/speex_jitter.h24
-rw-r--r--apps/codecs/libspeex/speex_callbacks.c8
-rw-r--r--apps/codecs/libspeex/speex_header.c2
-rw-r--r--apps/codecs/libspeex/stereo.c96
-rw-r--r--apps/codecs/libspeex/vbr.c3
17 files changed, 375 insertions, 328 deletions
diff --git a/apps/codecs/libspeex/config-speex.h b/apps/codecs/libspeex/config-speex.h
index 70d86f6299..db15948330 100644
--- a/apps/codecs/libspeex/config-speex.h
+++ b/apps/codecs/libspeex/config-speex.h
@@ -11,6 +11,10 @@
/* config.h.in. Generated from configure.ac by autoheader. */
#ifndef ROCKBOX_VOICE_ENCODER
+
+#define DISABLE_FLOAT_API
+#define DISABLE_VBR
+
/* Make use of ARM4E assembly optimizations */
#if defined(CPU_ARM)
#define ARM4_ASM
diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c
index e31a131bba..710e36272c 100644
--- a/apps/codecs/libspeex/jitter.c
+++ b/apps/codecs/libspeex/jitter.c
@@ -34,8 +34,10 @@
/*
TODO:
-- Write generic functions for computing stats and shifting the histogram
-- Take into account the delay step when computing the stats and when shifting
+- Add short-term estimate
+- Defensive programming
+ + warn when last returned < last desired (begative buffering)
+ + warn if update_delay not called between get() and tick() or is called twice in a row
- 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
@@ -62,9 +64,6 @@ TODO:
#define NULL 0
#endif
-#define LATE_BINS 15
-#define MAX_MARGIN 30 /**< Number of bins in margin histogram */
-
#define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */
#define TSUB(a,b) ((spx_int32_t)((a)-(b)))
@@ -74,16 +73,18 @@ TODO:
#define LT32(a,b) (((spx_int32_t)((a)-(b)))<0)
#define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0)
+#define ROUND_DOWN(x, step) ((x)<0 ? ((x)-(step)+1)/(step)*(step) : (x)/(step)*(step))
+
#define MAX_TIMINGS 20
#define MAX_BUFFERS 3
-#define TOP_DELAY 25
-#define WINDOW_SIZE 200
+#define TOP_DELAY 20
+/** Buffer that keeps the time of arrival of the latest packets */
struct TimingBuffer {
- int filled;
- int curr_count;
- spx_int16_t timing[MAX_TIMINGS];
- spx_int16_t counts[MAX_TIMINGS];
+ int filled; /**< Number of entries occupied in "timing" and "counts"*/
+ int curr_count; /**< Number of packet timings we got (including those we discarded) */
+ spx_int16_t timing[MAX_TIMINGS]; /**< Sorted list of all timings ("latest" packets first) */
+ spx_int16_t counts[MAX_TIMINGS]; /**< Order the packets were put in (will be used for short-term estimate) */
};
static void tb_init(struct TimingBuffer *tb)
@@ -92,16 +93,18 @@ static void tb_init(struct TimingBuffer *tb)
tb->curr_count = 0;
}
+/* Add the timing of a new packet to the TimingBuffer */
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);*/
+ /* Discard packet that won't make it into the list because they're too early */
if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1])
{
tb->curr_count++;
return;
}
+
+ /* Find where the timing info goes in the sorted list */
pos = 0;
/* FIXME: Do bisection instead of linear search */
while (pos<tb->filled && timing >= tb->timing[pos])
@@ -109,56 +112,107 @@ static void tb_add(struct TimingBuffer *tb, spx_int16_t timing)
pos++;
}
- /*fprintf(stderr, "pos = %d filled = %d\n", pos, tb->filled);*/
speex_assert(pos <= tb->filled && pos < MAX_TIMINGS);
- fprintf(stderr, "OK\n");
+
+ /* Shift everything so we can perform the insertion */
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");*/
+ /* Insert */
tb->timing[pos] = timing;
tb->counts[pos] = tb->curr_count;
- /*{
- int i;
- for (i=0;i<MAX_TIMINGS;i++)
- fprintf(stderr, "%d ", tb->timing[i]);
- fprintf(stderr, "\n");
- }*/
+
tb->curr_count++;
if (tb->filled<MAX_TIMINGS)
tb->filled++;
- /*fprintf(stderr, "added\n");*/
}
+
+
+/** Jitter buffer structure */
+struct JitterBuffer_ {
+ spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */
+ spx_uint32_t last_returned_timestamp; /**< Useful for getting the next packet with the same timestamp (for fragmented media) */
+ spx_uint32_t next_stop; /**< Estimated time the next get() will be called */
+
+ spx_int32_t buffered; /**< Amount of data we think is still buffered by the application (timestamp units)*/
+
+ 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 */
+
+ spx_int32_t delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */
+ spx_int32_t concealment_size; /**< Size of the packet loss concealment "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 */
+ int window_size; /**< Total window over which the late frames are counted */
+ int subwindow_size; /**< Sub-window size for faster computation */
+ int max_late_rate; /**< Absolute maximum amount of late packets tolerable (in percent) */
+ int latency_tradeoff; /**< Latency equivalent of losing one percent of packets */
+ int auto_tradeoff; /**< Latency equivalent of losing one percent of packets (automatic default) */
+
+ int lost_count; /**< Number of consecutive lost packets */
+};
+
/** 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)
+ */
+static spx_int16_t compute_opt_delay(JitterBuffer *jitter)
{
int i;
spx_int16_t opt=0;
spx_int32_t best_cost=0x7fffffff;
int late = 0;
int pos[MAX_BUFFERS];
+ int tot_count;
+ float late_factor;
+ int penalty_taken = 0;
+ int best = 0;
+ int worst = 0;
+ spx_int32_t deltaT;
+ struct TimingBuffer *tb;
+
+ tb = jitter->_tb;
+
+ /* Number of packet timings we have received (including those we didn't keep) */
+ tot_count = 0;
+ for (i=0;i<MAX_BUFFERS;i++)
+ tot_count += tb[i].curr_count;
+ if (tot_count==0)
+ return 0;
+
+ /* Compute cost for one lost packet */
+ if (jitter->latency_tradeoff != 0)
+ late_factor = jitter->latency_tradeoff * 100.0f / tot_count;
+ else
+ late_factor = jitter->auto_tradeoff * jitter->window_size/tot_count;
- /*fprintf(stderr, "tbs_get_opt_delay\n");*/
+ /*fprintf(stderr, "late_factor = %f\n", late_factor);*/
for (i=0;i<MAX_BUFFERS;i++)
pos[i] = 0;
+ /* Pick the TOP_DELAY "latest" packets (doesn't need to actually be late
+ for the current settings) */
for (i=0;i<TOP_DELAY;i++)
{
int j;
int next=-1;
int latest = 32767;
+ /* Pick latest amoung all sub-windows */
for (j=0;j<MAX_BUFFERS;j++)
{
if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
@@ -167,16 +221,19 @@ static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t late_f
latest = tb[j].timing[pos[j]];
}
}
- late++;
if (next != -1)
{
spx_int32_t cost;
+
+ if (i==0)
+ worst = latest;
+ best = latest;
+ latest = ROUND_DOWN(latest, jitter->delay_step);
pos[next]++;
- /* When considering reducing delay, "on-time" frames could twice (this provides hysteresis) */
- if (latest > 0)
- late++;
+
+ /* Actual cost function that tells us how bad using this delay would be */
cost = -latest + late_factor*late;
- /*fprintf(stderr, "cost %d = -%d + %d * %d\n", cost, latest, late_factor, late);*/
+ /*fprintf(stderr, "cost %d = %d + %f * %d\n", cost, -latest, late_factor, late);*/
if (cost < best_cost)
{
best_cost = cost;
@@ -185,61 +242,50 @@ static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t late_f
} else {
break;
}
+
+ /* For the next timing we will consider, there will be one more late packet to count */
+ late++;
+ /* Two-frame penalty if we're going to increase the amount of late frames (hysteresis) */
+ if (latest >= 0 && !penalty_taken)
+ {
+ penalty_taken = 1;
+ late+=2;
+ }
}
+
+ deltaT = best-worst;
+ /* This is a default "automatic latency tradeoff" when none is provided */
+ jitter->auto_tradeoff = 1 + deltaT/TOP_DELAY;
+ /*fprintf(stderr, "auto_tradeoff = %d (%d %d %d)\n", jitter->auto_tradeoff, best, worst, i);*/
+
+ /* FIXME: Compute a short-term estimate too and combine with the long-term one */
+
+ /* Prevents reducing the buffer size when we haven't really had much data */
+ if (tot_count < TOP_DELAY && opt > 0)
+ return 0;
return opt;
}
-/** Jitter buffer structure */
-struct JitterBuffer_ {
- spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */
- 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 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 */
- float loss_rate; /**< Average loss rate */
-};
/** Initialise jitter buffer */
-JitterBuffer *jitter_buffer_init(int resolution)
+JitterBuffer *jitter_buffer_init(void)
{
JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer));
if (jitter)
{
int i;
+ spx_int32_t tmp;
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
jitter->packets[i].data=NULL;
- jitter->resolution = resolution;
- jitter->delay_step = resolution;
- jitter->res_delay_step = 1;
+ jitter->delay_step = 1;
+ jitter->concealment_size = 1;
/*FIXME: Should this be 0 or 1?*/
- jitter->buffer_margin = 1;
+ jitter->buffer_margin = 0;
jitter->late_cutoff = 50;
jitter->destroy = NULL;
+ jitter->latency_tradeoff = 0;
+ tmp = 4;
+ jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MAX_LATE_RATE, &tmp);
jitter_buffer_reset(jitter);
}
return jitter;
@@ -265,12 +311,8 @@ void jitter_buffer_reset(JitterBuffer *jitter)
jitter->next_stop = 0;
jitter->reset_state = 1;
jitter->lost_count = 0;
- jitter->loss_rate = 0;
- for (i=0;i<MAX_MARGIN;i++)
- {
- jitter->shortterm_margin[i] = 0;
- jitter->longterm_margin[i] = 0;
- }
+ jitter->buffered = 0;
+ jitter->auto_tradeoff = 32000;
for (i=0;i<MAX_BUFFERS;i++)
{
@@ -287,13 +329,15 @@ void jitter_buffer_destroy(JitterBuffer *jitter)
speex_free(jitter);
}
+/** Take the following timing into consideration for future calculations */
static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
{
if (timing < -32767)
timing = -32767;
if (timing > 32767)
timing = 32767;
- if (jitter->timeBuffers[0]->curr_count >= WINDOW_SIZE)
+ /* If the current sub-window is full, perform a rotation and discard oldest sub-widow */
+ if (jitter->timeBuffers[0]->curr_count >= jitter->subwindow_size)
{
int i;
/*fprintf(stderr, "Rotate buffer\n");*/
@@ -304,129 +348,25 @@ static void update_timings(JitterBuffer *jitter, spx_int32_t timing)
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);*/
}
+/** Compensate all timings when we do an adjustment of the buffering */
static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
{
int i, j;
for (i=0;i<MAX_BUFFERS;i++)
{
- for (j=0;j<jitter->timeBuffers[i]->filled;i++)
+ for (j=0;j<jitter->timeBuffers[i]->filled;j++)
jitter->timeBuffers[i]->timing[j] += amount;
}
}
-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 */
- spx_int32_t int_margin;
- /* First, apply the "damping" of the recursive average to all bins */
- for (i=0;i<MAX_MARGIN;i++)
- {
- jitter->shortterm_margin[i] *= .98;
- jitter->longterm_margin[i] *= .995;
- }
- /* What histogram bin the packet should be counted in */
- int_margin = LATE_BINS + arrival_margin;
- if (int_margin>MAX_MARGIN-1)
- int_margin = MAX_MARGIN-1;
- if (int_margin<0)
- int_margin = 0;
- /* Add the packet to the right bin */
- jitter->shortterm_margin[int_margin] += .02;
- jitter->longterm_margin[int_margin] += .005;
- } else {
- /* Packet has arrived *way* too late, we pretty much consider it lost and not take it into account in the histogram */
- /*fprintf (stderr, "way too late = %d\n", arrival_margin);*/
- if (jitter->lost_count>20)
- {
- jitter_buffer_reset(jitter);
- }
- }
-}
-
-static void shift_histogram(JitterBuffer *jitter, int amount)
-{
- int i, c;
- if (amount == 0)
- return;
- if (amount > 0)
- {
- /* FIXME: This is terribly inefficient */
- for (c=0;c<amount;c++)
- {
- 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;i<MAX_MARGIN-1;i++)
- {
- jitter->shortterm_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;
- }
- }
-}
-
-static void compute_statistics(JitterBuffer *jitter)
-{
- int i;
- jitter->late_ratio_short = 0;
- jitter->late_ratio_long = 0;
- /* Count the proportion of packets that are late */
- for (i=0;i<LATE_BINS;i++)
- {
- jitter->late_ratio_short += jitter->shortterm_margin[i];
- jitter->late_ratio_long += jitter->longterm_margin[i];
- }
-
- /* Count the proportion of packets that are just on time */
- jitter->ontime_ratio_short = 0;
- jitter->ontime_ratio_long = 0;
- for (;i<LATE_BINS+jitter->res_delay_step;i++)
- {
- jitter->ontime_ratio_short = jitter->shortterm_margin[i];
- jitter->ontime_ratio_long = jitter->longterm_margin[i];
- }
-
- jitter->early_ratio_short = 0;
- jitter->early_ratio_long = 0;
- /* Count the proportion of packets that are early */
- for (;i<MAX_MARGIN;i++)
- {
- jitter->early_ratio_short += jitter->shortterm_margin[i];
- jitter->early_ratio_long += jitter->longterm_margin[i];
- }
-}
/** 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);*/
/* Syncing on the first packet to arrive */
@@ -457,14 +397,7 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
/* Check if packet is late (could still be useful though) */
if (LT32(packet->timestamp, jitter->next_stop))
{
- /*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);
+ update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop) - jitter->buffer_margin);
late = 1;
} else {
late = 0;
@@ -534,22 +467,26 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
int i;
unsigned int j;
int incomplete = 0;
+ spx_int16_t opt;
jitter->last_returned_timestamp = jitter->pointer_timestamp;
- if (jitter->interp_requested)
+ if (jitter->interp_requested != 0)
{
- jitter->interp_requested = 0;
if (start_offset)
*start_offset = 0;
packet->timestamp = jitter->pointer_timestamp;
- packet->span = jitter->delay_step;
+ packet->span = jitter->interp_requested;
/* Increment the pointer because it got decremented in the delay update */
- jitter->pointer_timestamp += jitter->delay_step;
+ jitter->pointer_timestamp += jitter->interp_requested;
packet->len = 0;
/*fprintf (stderr, "Deferred interpolate\n");*/
+ jitter->interp_requested = 0;
+
+ jitter->buffered = packet->span - desired_span;
+
return JITTER_BUFFER_MISSING;
}
@@ -618,23 +555,11 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
/* We (obviously) haven't lost this packet */
jitter->lost_count = 0;
- jitter->loss_rate = .999*jitter->loss_rate;
/* 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);
-
+ update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]) - jitter->buffer_margin);
}
@@ -663,6 +588,8 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
/* Point to the end of the current packet */
jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span;
+ jitter->buffered = *start_offset + packet->span - desired_span;
+
if (incomplete)
return JITTER_BUFFER_INCOMPLETE;
else
@@ -676,22 +603,21 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
jitter->lost_count++;
/*fprintf (stderr, "m");*/
/*fprintf (stderr, "lost_count = %d\n", jitter->lost_count);*/
- jitter->loss_rate = .999*jitter->loss_rate + .001;
if (start_offset)
*start_offset = 0;
- compute_statistics(jitter);
+ opt = compute_opt_delay(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 (opt < 0)
{
- /* Increase buffering */
+ /* Need to increase buffering */
/* Shift histogram to compensate */
- shift_histogram(jitter, jitter->res_delay_step);
+ shift_timings(jitter, -opt);
packet->timestamp = jitter->pointer_timestamp;
- packet->span = jitter->delay_step;
+ packet->span = -opt;
/* Don't move the pointer_timestamp forward */
packet->len = 0;
@@ -700,12 +626,15 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3
} else {
/* Normal packet loss */
packet->timestamp = jitter->pointer_timestamp;
+
+ desired_span = ROUND_DOWN(desired_span, jitter->concealment_size);
packet->span = desired_span;
jitter->pointer_timestamp += desired_span;
packet->len = 0;
/*fprintf (stderr, "Normal loss\n");*/
}
+ jitter->buffered = packet->span - desired_span;
return JITTER_BUFFER_MISSING;
}
@@ -752,43 +681,44 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter)
void jitter_buffer_tick(JitterBuffer *jitter)
{
- jitter->next_stop = jitter->pointer_timestamp;
+ if (jitter->buffered >= 0)
+ {
+ jitter->next_stop = jitter->pointer_timestamp - jitter->buffered;
+ } else {
+ jitter->next_stop = jitter->pointer_timestamp;
+ speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered);
+ }
+ jitter->buffered = 0;
}
void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem)
{
+ if (jitter->buffered < 0)
+ speex_warning_int("jitter buffer sees negative buffering, you code might be broken. Value is ", jitter->buffered);
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;
+ spx_int16_t opt = compute_opt_delay(jitter);
+ /*fprintf(stderr, "opt adjustment is %d ", opt);*/
- compute_statistics(jitter);
-
- /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */
- if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03)
+ if (opt < 0)
{
- /* If too many packets are arriving late */
- shift_histogram(jitter, jitter->res_delay_step);
+ shift_timings(jitter, -opt);
- jitter->pointer_timestamp -= jitter->delay_step;
- jitter->interp_requested = 1;
- /*fprintf (stderr, "Decision to interpolate\n");*/
- return JITTER_BUFFER_ADJUST_INTERPOLATE;
-
- } 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)
+ jitter->pointer_timestamp += opt;
+ jitter->interp_requested = -opt;
+ /*fprintf (stderr, "Decision to interpolate %d samples\n", -opt);*/
+ } else if (opt > 0)
{
- /* Many frames arriving early */
- shift_histogram(jitter, -jitter->res_delay_step);
-
- jitter->pointer_timestamp += jitter->delay_step;
- /*fprintf (stderr, "Decision to drop\n");*/
- return JITTER_BUFFER_ADJUST_DROP;
+ shift_timings(jitter, -opt);
+ jitter->pointer_timestamp += opt;
+ /*fprintf (stderr, "Decision to drop %d samples\n", opt);*/
}
- return JITTER_BUFFER_ADJUST_OK;
+ return opt;
}
/* Used like the ioctl function to control the jitter buffer parameters */
@@ -822,11 +752,30 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr)
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;
+ case JITTER_BUFFER_SET_CONCEALMENT_SIZE:
+ jitter->concealment_size = *(spx_int32_t*)ptr;
+ break;
+ case JITTER_BUFFER_GET_CONCEALMENT_SIZE:
+ *(spx_int32_t*)ptr = jitter->concealment_size;
+ break;
+ case JITTER_BUFFER_SET_MAX_LATE_RATE:
+ jitter->max_late_rate = *(spx_int32_t*)ptr;
+ jitter->window_size = 100*TOP_DELAY/jitter->max_late_rate;
+ jitter->subwindow_size = jitter->window_size/MAX_BUFFERS;
+ break;
+ case JITTER_BUFFER_GET_MAX_LATE_RATE:
+ *(spx_int32_t*)ptr = jitter->max_late_rate;
+ break;
+ case JITTER_BUFFER_SET_LATE_COST:
+ jitter->latency_tradeoff = *(spx_int32_t*)ptr;
+ break;
+ case JITTER_BUFFER_GET_LATE_COST:
+ *(spx_int32_t*)ptr = jitter->latency_tradeoff;
+ break;
default:
speex_warning_int("Unknown jitter_buffer_ctl request: ", request);
return -1;
diff --git a/apps/codecs/libspeex/modes.h b/apps/codecs/libspeex/modes.h
index d0ff842ffa..26e2d86180 100644
--- a/apps/codecs/libspeex/modes.h
+++ b/apps/codecs/libspeex/modes.h
@@ -146,7 +146,9 @@ typedef struct SpeexSBMode {
int defaultSubmode; /**< Default sub-mode to use when encoding */
int low_quality_map[11]; /**< Mode corresponding to each quality setting */
int quality_map[11]; /**< Mode corresponding to each quality setting */
+#ifndef DISABLE_VBR
const float (*vbr_thresh)[11];
+#endif
int nb_modes;
} SpeexSBMode;
diff --git a/apps/codecs/libspeex/modes_wb.c b/apps/codecs/libspeex/modes_wb.c
index 8e351db60d..7fac15b852 100644
--- a/apps/codecs/libspeex/modes_wb.c
+++ b/apps/codecs/libspeex/modes_wb.c
@@ -236,17 +236,15 @@ static const SpeexSBMode sb_wb_mode = {
0.9, 0.6, /* gamma1, gamma2 */
#endif
QCONST16(.0002,15), /*lpc_floor*/
- QCONST16(0.9f,15),
- {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
- 3,
- {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
- {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
-#ifndef SPEEX_DISABLE_ENCODER
- vbr_hb_thresh,
-#else
- NULL,
+ QCONST16(0.9f,15),
+ {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
+ 3,
+ {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
+ {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
+#ifndef DISABLE_VBR
+ vbr_hb_thresh,
#endif
- 5
+ 5
};
@@ -296,17 +294,15 @@ static const SpeexSBMode sb_uwb_mode = {
0.9, 0.6, /* gamma1, gamma2 */
#endif
QCONST16(.0002,15), /*lpc_floor*/
- QCONST16(0.7f,15),
- {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
- 1,
- {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
- {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
-#ifndef SPEEX_DISABLE_ENCODER
- vbr_uhb_thresh,
-#else
- NULL,
+ QCONST16(0.7f,15),
+ {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
+ 1,
+ {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+ {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+#ifndef DISABLE_VBR
+ vbr_uhb_thresh,
#endif
- 2
+ 2
};
#endif
diff --git a/apps/codecs/libspeex/nb_celp.c b/apps/codecs/libspeex/nb_celp.c
index d1e8caed09..84cf1bb6d7 100644
--- a/apps/codecs/libspeex/nb_celp.c
+++ b/apps/codecs/libspeex/nb_celp.c
@@ -110,6 +110,7 @@ const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f};
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)
{
@@ -185,6 +186,7 @@ void *nb_encoder_init(const SpeexMode *m)
st->pitch = (int*)speex_alloc((st->nbSubframes)*sizeof(int));
+#ifndef DISABLE_VBR
st->vbr = (VBRState*)speex_alloc(sizeof(VBRState));
vbr_init(st->vbr);
st->vbr_quality = 8;
@@ -192,13 +194,15 @@ void *nb_encoder_init(const SpeexMode *m)
st->vbr_max = 0;
st->vad_enabled = 0;
st->dtx_enabled = 0;
+ st->dtx_count=0;
st->abr_enabled = 0;
st->abr_drift = 0;
+ st->abr_drift2 = 0;
+#endif /* #ifndef DISABLE_VBR */
st->plc_tuning = 2;
st->complexity=2;
st->sampling_rate=8000;
- st->dtx_count=0;
st->isWideband = 0;
st->highpass_enabled = 1;
@@ -230,8 +234,10 @@ void nb_encoder_destroy(void *state)
speex_free (st->pi_gain);
speex_free (st->pitch);
+#ifndef DISABLE_VBR
vbr_destroy(st->vbr);
speex_free (st->vbr);
+#endif /* #ifndef DISABLE_VBR */
#ifdef VORBIS_PSYCHO
vorbis_psy_destroy(st->psy);
@@ -344,8 +350,11 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
/*Open-loop pitch*/
- if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) ||
- SUBMODE(lbr_pitch) != -1)
+ if (!st->submodes[st->submodeID] || (st->complexity>2 && SUBMODE(have_subframe_gain)<3) || SUBMODE(forced_pitch_gain) || SUBMODE(lbr_pitch) != -1
+#ifndef DISABLE_VBR
+ || st->vbr_enabled || st->vad_enabled
+#endif
+ )
{
int nol_pitch[6];
spx_word16_t nol_pitch_coef[6];
@@ -418,6 +427,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
#endif
/*VBR stuff*/
+#ifndef DISABLE_VBR
if (st->vbr && (st->vbr_enabled||st->vad_enabled))
{
float lsp_dist=0;
@@ -529,6 +539,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
} else {
st->relative_quality = -1;
}
+#endif /* #ifndef DISABLE_VBR */
if (st->encode_submode)
{
@@ -694,8 +705,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
bw_lpc(st->gamma2, interp_lpc, bw_lpc2, st->lpcSize);
else
{
- bw_lpc2[0]=1;
- for (i=1;i<=st->lpcSize;i++)
+ for (i=0;i<st->lpcSize;i++)
bw_lpc2[i]=0;
}
/*print_vec(st->bw_lpc1, 10, "bw_lpc");*/
@@ -907,9 +917,11 @@ int nb_encode(void *state, void *vin, SpeexBits *bits)
if (st->submodeID==1)
{
+#ifndef DISABLE_VBR
if (st->dtx_count)
speex_bits_pack(bits, 15, 4);
else
+#endif
speex_bits_pack(bits, 0, 4);
}
@@ -1615,7 +1627,8 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_MODE:
(*(spx_int32_t*)ptr) = st->submodeID;
break;
- case SPEEX_SET_VBR:
+#ifndef DISABLE_VBR
+ case SPEEX_SET_VBR:
st->vbr_enabled = (*(spx_int32_t*)ptr);
break;
case SPEEX_GET_VBR:
@@ -1663,12 +1676,15 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_ABR:
(*(spx_int32_t*)ptr) = st->abr_enabled;
break;
+#endif /* #ifndef DISABLE_VBR */
+#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
case SPEEX_SET_VBR_QUALITY:
st->vbr_quality = (*(float*)ptr);
break;
case SPEEX_GET_VBR_QUALITY:
(*(float*)ptr) = st->vbr_quality;
break;
+#endif /* !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
case SPEEX_SET_QUALITY:
{
int quality = (*(spx_int32_t*)ptr);
@@ -1746,12 +1762,14 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_PLC_TUNING:
(*(spx_int32_t*)ptr)=(st->plc_tuning);
break;
+#ifndef DISABLE_VBR
case SPEEX_SET_VBR_MAX_BITRATE:
st->vbr_max = (*(spx_int32_t*)ptr);
break;
case SPEEX_GET_VBR_MAX_BITRATE:
(*(spx_int32_t*)ptr) = st->vbr_max;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_HIGHPASS:
st->highpass_enabled = (*(spx_int32_t*)ptr);
break;
@@ -1775,9 +1793,11 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
((spx_word16_t*)ptr)[i] = compute_rms16(st->exc+i*st->subframeSize, st->subframeSize);
}
break;
+#ifndef DISABLE_VBR
case SPEEX_GET_RELATIVE_QUALITY:
(*(float*)ptr)=st->relative_quality;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_INNOVATION_SAVE:
st->innov_rms_save = (spx_word16_t*)ptr;
break;
@@ -1870,10 +1890,10 @@ int nb_decoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_HIGHPASS:
(*(spx_int32_t*)ptr) = st->highpass_enabled;
break;
+ /* FIXME: Convert to fixed-point and re-enable even when float API is disabled */
+#ifndef DISABLE_FLOAT_API
case SPEEX_GET_ACTIVITY:
{
- /* We don't use this, dummy it out to get rid of the float stuff */
-#if 0
float ret;
ret = log(st->level/st->min_level)/log(st->max_level/st->min_level);
if (ret>1)
@@ -1883,11 +1903,9 @@ int nb_decoder_ctl(void *state, int request, void *ptr)
ret = 0;
/*printf ("%f %f %f %f\n", st->level, st->min_level, st->max_level, ret);*/
(*(spx_int32_t*)ptr) = (int)(100*ret);
-#else
- (*(spx_int32_t*)ptr) = (int)(0);
-#endif
}
break;
+#endif
case SPEEX_GET_PI_GAIN:
{
int i;
diff --git a/apps/codecs/libspeex/nb_celp.h b/apps/codecs/libspeex/nb_celp.h
index 7f90f7c05c..30abdee842 100644
--- a/apps/codecs/libspeex/nb_celp.h
+++ b/apps/codecs/libspeex/nb_celp.h
@@ -92,7 +92,8 @@ typedef struct EncState {
spx_mem_t mem_hp[2]; /**< High-pass filter memory */
spx_word32_t *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation RMS is copied here */
-
+
+#ifndef DISABLE_VBR
VBRState *vbr; /**< State of the VBR data */
float vbr_quality; /**< Quality setting for VBR encoding */
float relative_quality; /**< Relative quality that will be needed by VBR */
@@ -105,6 +106,8 @@ typedef struct EncState {
float abr_drift;
float abr_drift2;
float abr_count;
+#endif /* #ifndef DISABLE_VBR */
+
int complexity; /**< Complexity setting (0-10 from least complex to most complex) */
spx_int32_t sampling_rate;
int plc_tuning;
diff --git a/apps/codecs/libspeex/preprocess.c b/apps/codecs/libspeex/preprocess.c
index 5d5befe736..07a2ad3479 100644
--- a/apps/codecs/libspeex/preprocess.c
+++ b/apps/codecs/libspeex/preprocess.c
@@ -277,7 +277,7 @@ static void conj_window(spx_word16_t *w, int len)
x=QCONST16(2.f,13)-x+QCONST16(2.f,13); /* 4 - x */
}
x = MULT16_16_Q14(QCONST16(1.271903f,14), x);
- tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(QCONST32(x,2))));
+ tmp = SQR16_Q15(QCONST16(.5f,15)-MULT16_16_P15(QCONST16(.5f,15),spx_cos_norm(SHL32(EXTEND32(x),2))));
if (inv)
tmp=SUB16(Q15_ONE,tmp);
w[i]=spx_sqrt(SHL32(EXTEND32(tmp),15));
@@ -1065,7 +1065,7 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
case SPEEX_PREPROCESS_GET_AGC:
(*(spx_int32_t*)ptr) = st->agc_enabled;
break;
-
+#ifndef DISABLE_FLOAT_API
case SPEEX_PREPROCESS_SET_AGC_LEVEL:
st->agc_level = (*(float*)ptr);
if (st->agc_level<1)
@@ -1076,6 +1076,7 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
case SPEEX_PREPROCESS_GET_AGC_LEVEL:
(*(float*)ptr) = st->agc_level;
break;
+#endif /* #ifndef DISABLE_FLOAT_API */
case SPEEX_PREPROCESS_SET_AGC_INCREMENT:
st->max_increase_step = exp(0.11513f * (*(spx_int32_t*)ptr)*st->frame_size / st->sampling_rate);
break;
@@ -1113,17 +1114,21 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
break;
case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL:
- st->reverb_level = (*(float*)ptr);
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*st->reverb_level = (*(float*)ptr);*/
break;
case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL:
- (*(float*)ptr) = st->reverb_level;
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*(*(float*)ptr) = st->reverb_level;*/
break;
case SPEEX_PREPROCESS_SET_DEREVERB_DECAY:
- st->reverb_decay = (*(float*)ptr);
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*st->reverb_decay = (*(float*)ptr);*/
break;
case SPEEX_PREPROCESS_GET_DEREVERB_DECAY:
- (*(float*)ptr) = st->reverb_decay;
+ /* FIXME: Re-enable when de-reverberation is actually enabled again */
+ /*(*(float*)ptr) = st->reverb_decay;*/
break;
case SPEEX_PREPROCESS_SET_PROB_START:
diff --git a/apps/codecs/libspeex/quant_lsp.c b/apps/codecs/libspeex/quant_lsp.c
index 441a257a49..9b9104c842 100644
--- a/apps/codecs/libspeex/quant_lsp.c
+++ b/apps/codecs/libspeex/quant_lsp.c
@@ -389,4 +389,3 @@ void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
#endif
-
diff --git a/apps/codecs/libspeex/sb_celp.c b/apps/codecs/libspeex/sb_celp.c
index 17cfc73a4e..313a62e93f 100644
--- a/apps/codecs/libspeex/sb_celp.c
+++ b/apps/codecs/libspeex/sb_celp.c
@@ -253,6 +253,7 @@ void *sb_encoder_init(const SpeexMode *m)
for (i=0;i<st->lpcSize;i++)
st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1);
+#ifndef DISABLE_VBR
st->vbr_quality = 8;
st->vbr_enabled = 0;
st->vbr_max = 0;
@@ -260,6 +261,7 @@ void *sb_encoder_init(const SpeexMode *m)
st->vad_enabled = 0;
st->abr_enabled = 0;
st->relative_quality=0;
+#endif /* #ifndef DISABLE_VBR */
st->complexity=2;
speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
@@ -336,6 +338,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
/* Compute the two sub-bands by filtering with QMF h0*/
qmf_decomp(in, h0, low, high, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
+#ifndef DISABLE_VBR
if (st->vbr_enabled || st->vad_enabled)
{
/* Need to compute things here before the signal is trashed by the encoder */
@@ -343,6 +346,8 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
e_low = compute_rms16(low, st->frame_size);
e_high = compute_rms16(high, st->frame_size);
}
+#endif /* #ifndef DISABLE_VBR */
+
ALLOC(low_innov_rms, st->nbSubframes, spx_word16_t);
speex_encoder_ctl(st->st_low, SPEEX_SET_INNOVATION_SAVE, low_innov_rms);
/* Encode the narrowband part*/
@@ -418,6 +423,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
}
}
+#ifndef DISABLE_VBR
/* VBR code */
if ((st->vbr_enabled || st->vad_enabled) && !dtx)
{
@@ -494,6 +500,7 @@ int sb_encode(void *state, void *vin, SpeexBits *bits)
}
/*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
}
+#endif /* #ifndef DISABLE_VBR */
if (st->encode_submode)
{
@@ -1146,6 +1153,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_SET_MODE:
speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
break;
+#ifndef DISABLE_VBR
case SPEEX_SET_VBR:
st->vbr_enabled = (*(spx_int32_t*)ptr);
speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
@@ -1160,6 +1168,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_VAD:
(*(spx_int32_t*)ptr) = st->vad_enabled;
break;
+#endif /* #ifndef DISABLE_VBR */
+#if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API)
case SPEEX_SET_VBR_QUALITY:
{
spx_int32_t q;
@@ -1177,6 +1187,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_VBR_QUALITY:
(*(float*)ptr) = st->vbr_quality;
break;
+#endif /* #if !defined(DISABLE_VBR) && !defined(DISABLE_FLOAT_API) */
+#ifndef DISABLE_VBR
case SPEEX_SET_ABR:
st->abr_enabled = (*(spx_int32_t*)ptr);
st->vbr_enabled = st->abr_enabled!=0;
@@ -1207,6 +1219,8 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_ABR:
(*(spx_int32_t*)ptr) = st->abr_enabled;
break;
+#endif /* #ifndef DISABLE_VBR */
+
case SPEEX_SET_QUALITY:
{
spx_int32_t nb_qual;
@@ -1293,6 +1307,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_PLC_TUNING:
speex_encoder_ctl(st->st_low, SPEEX_GET_PLC_TUNING, ptr);
break;
+#ifndef DISABLE_VBR
case SPEEX_SET_VBR_MAX_BITRATE:
{
st->vbr_max = (*(spx_int32_t*)ptr);
@@ -1324,6 +1339,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
case SPEEX_GET_VBR_MAX_BITRATE:
(*(spx_int32_t*)ptr) = st->vbr_max;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_HIGHPASS:
speex_encoder_ctl(st->st_low, SPEEX_SET_HIGHPASS, ptr);
break;
@@ -1348,9 +1364,11 @@ int sb_encoder_ctl(void *state, int request, void *ptr)
((spx_word16_t*)ptr)[i] = st->exc_rms[i];
}
break;
+#ifndef DISABLE_VBR
case SPEEX_GET_RELATIVE_QUALITY:
(*(float*)ptr)=st->relative_quality;
break;
+#endif /* #ifndef DISABLE_VBR */
case SPEEX_SET_INNOVATION_SAVE:
st->innov_rms_save = (spx_word16_t*)ptr;
break;
diff --git a/apps/codecs/libspeex/sb_celp.h b/apps/codecs/libspeex/sb_celp.h
index 0d171b3f8b..51aa3d0e13 100644
--- a/apps/codecs/libspeex/sb_celp.h
+++ b/apps/codecs/libspeex/sb_celp.h
@@ -72,6 +72,7 @@ typedef struct SBEncState {
spx_word16_t *exc_rms;
spx_word16_t *innov_rms_save; /**< If non-NULL, innovation is copied here */
+#ifndef DISABLE_VBR
float vbr_quality; /**< Quality setting for VBR encoding */
int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */
spx_int32_t vbr_max; /**< Max bit-rate allowed in VBR mode (total) */
@@ -82,7 +83,8 @@ typedef struct SBEncState {
float abr_count;
int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */
float relative_quality;
-
+#endif /* #ifndef DISABLE_VBR */
+
int encode_submode;
const SpeexSubmode * const *submodes;
int submodeID;
diff --git a/apps/codecs/libspeex/speex.c b/apps/codecs/libspeex/speex.c
index 6bf362edbb..a77653f21a 100644
--- a/apps/codecs/libspeex/speex.c
+++ b/apps/codecs/libspeex/speex.c
@@ -85,6 +85,7 @@ int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
#ifdef FIXED_POINT
#ifndef SPEEX_DISABLE_ENCODER
+#ifndef DISABLE_FLOAT_API
int speex_encode(void *state, float *in, SpeexBits *bits)
{
int i;
@@ -102,6 +103,7 @@ int speex_encode(void *state, float *in, SpeexBits *bits)
}
return (*((SpeexMode**)state))->enc(state, short_in, bits);
}
+#endif /* #ifndef DISABLE_FLOAT_API */
int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
{
@@ -111,7 +113,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
}
#endif /* SPEEX_DISABLE_ENCODER */
-#if 0
+#ifndef DISABLE_FLOAT_API
int speex_decode(void *state, SpeexBits *bits, float *out)
{
int i, ret;
@@ -123,7 +125,7 @@ int speex_decode(void *state, SpeexBits *bits, float *out)
out[i] = short_out[i];
return ret;
}
-#endif
+#endif /* #ifndef DISABLE_FLOAT_API */
int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
{
diff --git a/apps/codecs/libspeex/speex/speex.h b/apps/codecs/libspeex/speex/speex.h
index 05123d21b2..ffb0714f1c 100644
--- a/apps/codecs/libspeex/speex/speex.h
+++ b/apps/codecs/libspeex/speex/speex.h
@@ -212,11 +212,6 @@ extern "C" {
/** modeID for the defined ultra-wideband mode */
#define SPEEX_MODEID_UWB 2
-#ifdef EPIC_48K
-/** modeID for the Epic 48K mode */
-#define SPEEX_MODEID_NB_48K 1000
-#endif
-
struct SpeexMode;
@@ -410,19 +405,16 @@ extern const SpeexMode speex_wb_mode;
/** Default "ultra-wideband" mode */
extern const SpeexMode speex_uwb_mode;
-#ifdef EPIC_48K
-/** 4.8 kbps narrowband mode */
-extern const SpeexMode speex_nb_48k_mode;
-#endif
-
/** List of all modes available */
extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
/** Obtain one of the modes available */
const SpeexMode * speex_lib_get_mode (int mode);
-/* We actually override the fucntion in the narrowband case so that we can avoid linking in the wideband stuff */
+#ifndef WIN32
+/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */
#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode))
+#endif
#ifdef __cplusplus
}
diff --git a/apps/codecs/libspeex/speex/speex_jitter.h b/apps/codecs/libspeex/speex/speex_jitter.h
index 7c948d474e..d1af5b0210 100644
--- a/apps/codecs/libspeex/speex/speex_jitter.h
+++ b/apps/codecs/libspeex/speex/speex_jitter.h
@@ -62,6 +62,8 @@ 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_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */
+ spx_uint16_t flags; /**< Info about the returned packet */
spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */
};
@@ -88,27 +90,37 @@ struct _JitterBufferPacket {
/** Included because of an early misspelling (will remove in next release) */
#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3
-/** */
+/** Assign a function to destroy unused packet. When setting that, the jitter
+ buffer no longer copies packet data. */
#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4
/** */
#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5
-/** */
+/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */
#define JITTER_BUFFER_SET_DELAY_STEP 6
/** */
#define JITTER_BUFFER_GET_DELAY_STEP 7
+/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */
+#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8
+#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9
+
+/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss
+ should be half of that or less. */
+#define JITTER_BUFFER_SET_MAX_LATE_RATE 10
+#define JITTER_BUFFER_GET_MAX_LATE_RATE 11
+
+/** Equivalent cost of one percent late packet in timestamp units */
+#define JITTER_BUFFER_SET_LATE_COST 12
+#define JITTER_BUFFER_GET_LATE_COST 13
-#define JITTER_BUFFER_ADJUST_INTERPOLATE -1
-#define JITTER_BUFFER_ADJUST_OK 0
-#define JITTER_BUFFER_ADJUST_DROP 1
/** Initialises jitter buffer
*
* @param tick Number of samples per "tick", i.e. the time period of the elements that will be retrieved
* @return Newly created jitter buffer state
*/
-JitterBuffer *jitter_buffer_init(int tick);
+JitterBuffer *jitter_buffer_init(void);
/** Restores jitter buffer to its original state
*
diff --git a/apps/codecs/libspeex/speex_callbacks.c b/apps/codecs/libspeex/speex_callbacks.c
index 252bc90f6f..58d7b7b92a 100644
--- a/apps/codecs/libspeex/speex_callbacks.c
+++ b/apps/codecs/libspeex/speex_callbacks.c
@@ -96,6 +96,7 @@ int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data
return 0;
}
+#ifndef DISABLE_VBR
int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
{
spx_int32_t vbr;
@@ -103,6 +104,7 @@ int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
return 0;
}
+#endif /* #ifndef DISABLE_VBR */
int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
{
@@ -112,17 +114,15 @@ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
return 0;
}
+#ifndef DISABLE_VBR
int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
{
- /* We don't use this, get rid of the float reference */
-#if 0
float qual;
qual = speex_bits_unpack_unsigned(bits, 4);
speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
-#endif
return 0;
}
-
+#endif /* #ifndef DISABLE_VBR */
int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
{
diff --git a/apps/codecs/libspeex/speex_header.c b/apps/codecs/libspeex/speex_header.c
index 30f47206c4..a96e2a24c5 100644
--- a/apps/codecs/libspeex/speex_header.c
+++ b/apps/codecs/libspeex/speex_header.c
@@ -48,7 +48,7 @@
static inline spx_int32_t le_int(spx_int32_t i)
{
#ifdef ROCKBOX
- return letoh32(i);
+ return letoh32(i);
#elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
spx_uint32_t ui, ret;
ui = i;
diff --git a/apps/codecs/libspeex/stereo.c b/apps/codecs/libspeex/stereo.c
index 5f74197054..2dce283ac3 100644
--- a/apps/codecs/libspeex/stereo.c
+++ b/apps/codecs/libspeex/stereo.c
@@ -57,6 +57,10 @@ static const float e_ratio_quant_bounds[3] = {0.2825f, 0.356f, 0.4485f};
#else
static const spx_word16_t e_ratio_quant[4] = {8192, 10332, 13009, 16384};
static const spx_word16_t e_ratio_quant_bounds[3] = {9257, 11665, 14696};
+static const spx_word16_t balance_bounds[31] = {18, 23, 30, 38, 49, 63, 81, 104,
+ 134, 172, 221, 284, 364, 468, 600, 771,
+ 990, 1271, 1632, 2096, 2691, 3455, 4436, 5696,
+ 7314, 9392, 12059, 15484, 19882, 25529, 32766};
#endif
/* This is an ugly compatibility hack that properly resets the stereo state
@@ -104,6 +108,7 @@ void speex_stereo_state_destroy(SpeexStereoState *stereo)
}
#ifndef SPEEX_DISABLE_ENCODER
+#ifndef DISABLE_FLOAT_API
void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
{
int i, tmp;
@@ -137,50 +142,87 @@ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
speex_bits_pack(bits, (int)balance, 5);
/* FIXME: this is a hack */
- tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 3);
+ tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 4);
speex_bits_pack(bits, tmp, 2);
}
+#endif /* #ifndef DISABLE_FLOAT_API */
void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
{
int i, tmp;
- float e_left=0, e_right=0, e_tot=0;
- float balance, e_ratio;
+ spx_word32_t e_left=0, e_right=0, e_tot=0;
+ spx_word32_t balance, e_ratio;
+ spx_word32_t largest, smallest;
+ int balance_id;
+#ifdef FIXED_POINT
+ int shift;
+#endif
+
+ /* In band marker */
+ speex_bits_pack(bits, 14, 5);
+ /* Stereo marker */
+ speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
+
for (i=0;i<frame_size;i++)
{
- e_left += ((float)data[2*i])*data[2*i];
- e_right += ((float)data[2*i+1])*data[2*i+1];
+ e_left += SHR32(MULT16_16(data[2*i],data[2*i]),8);
+ e_right += SHR32(MULT16_16(data[2*i+1],data[2*i+1]),8);
+#ifdef FIXED_POINT
+ /* I think this is actually unbiased */
+ data[i] = SHR16(data[2*i],1)+PSHR16(data[2*i+1],1);
+#else
data[i] = .5*(((float)data[2*i])+data[2*i+1]);
- e_tot += ((float)data[i])*data[i];
+#endif
+ e_tot += SHR32(MULT16_16(data[i],data[i]),8);
}
- balance=(e_left+1)/(e_right+1);
- e_ratio = e_tot/(1+e_left+e_right);
-
- /*Quantization*/
- speex_bits_pack(bits, 14, 5);
- speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
-
- balance=4*log(balance);
-
- /*Pack sign*/
- if (balance>0)
+ if (e_left > e_right)
+ {
speex_bits_pack(bits, 0, 1);
- else
+ largest = e_left;
+ smallest = e_right;
+ } else {
speex_bits_pack(bits, 1, 1);
- balance=floor(.5+fabs(balance));
- if (balance>30)
- balance=31;
+ largest = e_right;
+ smallest = e_left;
+ }
+
+ /* Balance quantization */
+#ifdef FIXED_POINT
+ shift = spx_ilog2(largest)-15;
+ largest = VSHR32(largest, shift-4);
+ smallest = VSHR32(smallest, shift);
+ balance = DIV32(largest, ADD32(smallest, 1));
+ if (balance > 32767)
+ balance = 32767;
+ balance_id = scal_quant(EXTRACT16(balance), balance_bounds, 32);
+#else
+ balance=(largest+1.)/(smallest+1.);
+ balance=4*log(balance);
+ balance_id=floor(.5+fabs(balance));
+ if (balance_id>30)
+ balance_id=31;
+#endif
- speex_bits_pack(bits, (int)balance, 5);
+ speex_bits_pack(bits, balance_id, 5);
- /* FIXME: this is a hack */
- tmp=scal_quant(e_ratio*Q15_ONE, e_ratio_quant_bounds, 3);
+ /* "coherence" quantisation */
+#ifdef FIXED_POINT
+ shift = spx_ilog2(e_tot);
+ e_tot = VSHR32(e_tot, shift-25);
+ e_left = VSHR32(e_left, shift-10);
+ e_right = VSHR32(e_right, shift-10);
+ e_ratio = DIV32(e_tot, e_left+e_right+1);
+#else
+ e_ratio = e_tot/(1.+e_left+e_right);
+#endif
+
+ tmp=scal_quant(EXTRACT16(e_ratio), e_ratio_quant_bounds, 4);
+ /*fprintf (stderr, "%d %d %d %d\n", largest, smallest, balance_id, e_ratio);*/
speex_bits_pack(bits, tmp, 2);
}
#endif /* SPEEX_DISABLE_ENCODER */
-/* We don't want to decode to floats yet, disable */
-#if 0
+#ifndef DISABLE_FLOAT_API
void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
{
int i;
@@ -206,7 +248,7 @@ void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *_stereo)
data[2*i+1] = (float)MULT16_16_P14(stereo->smooth_right, tmp);
}
}
-#endif
+#endif /* #ifndef DISABLE_FLOAT_API */
void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *_stereo)
{
diff --git a/apps/codecs/libspeex/vbr.c b/apps/codecs/libspeex/vbr.c
index cc538b3fe9..32b33bc10e 100644
--- a/apps/codecs/libspeex/vbr.c
+++ b/apps/codecs/libspeex/vbr.c
@@ -45,6 +45,7 @@
#define MIN_ENERGY 6000
#define NOISE_POW .3
+#ifndef DISABLE_VBR
const float vbr_nb_thresh[9][11]={
{-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f}, /* CNG */
@@ -270,3 +271,5 @@ float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float p
void vbr_destroy(VBRState *vbr)
{
}
+
+#endif /* #ifndef DISABLE_VBR */