forked from len0rd/rockbox
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
This commit is contained in:
parent
91f618f1ba
commit
85b325fdb9
48 changed files with 698 additions and 481 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
/* Maximum size of the bit-stream (for fixed-size allocation) */
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#define CB_SEARCH_H
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
/** Split codebook parameters. */
|
||||
typedef struct split_cb_params {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#define USE_KISS_FFT
|
||||
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
#define MAX_FFT_SIZE 2048
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#endif
|
||||
|
||||
#include "filterbank.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#ifndef FILTERBANK_H
|
||||
#define FILTERBANK_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
typedef struct {
|
||||
int *bank_left;
|
||||
|
|
|
|||
|
|
@ -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 <math.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);
|
||||
|
|
|
|||
|
|
@ -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 <speex/speex.h>
|
||||
#include <speex/speex_bits.h>
|
||||
#include <speex/speex_jitter.h>
|
||||
|
|
@ -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 (pos<tb->filled && 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;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");*/
|
||||
}
|
||||
|
||||
/** 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<MAX_BUFFERS;i++)
|
||||
pos[i] = 0;
|
||||
|
||||
for (i=0;i<TOP_DELAY;i++)
|
||||
{
|
||||
int j;
|
||||
int next=-1;
|
||||
int latest = 32767;
|
||||
for (j=0;j<MAX_BUFFERS;j++)
|
||||
{
|
||||
if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest)
|
||||
{
|
||||
next = j;
|
||||
latest = tb[j].timing[pos[j]];
|
||||
}
|
||||
}
|
||||
late++;
|
||||
if (next != -1)
|
||||
{
|
||||
spx_int32_t cost;
|
||||
pos[next]++;
|
||||
/* When considering reducing delay, "on-time" frames could twice (this provides hysteresis) */
|
||||
if (latest > 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) */
|
||||
spx_uint32_t last_returned_timestamp;
|
||||
spx_uint32_t next_stop;
|
||||
|
||||
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 */
|
||||
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) */
|
||||
|
||||
int tick_size; /**< Output granularity */
|
||||
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 */
|
||||
|
|
@ -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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
jitter->buf[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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->buf[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<MAX_BUFFERS;i++)
|
||||
{
|
||||
tb_init(&jitter->_tb[i]);
|
||||
jitter->timeBuffers[i] = &jitter->_tb[i];
|
||||
}
|
||||
/*fprintf (stderr, "reset\n");*/
|
||||
}
|
||||
|
||||
|
|
@ -131,74 +287,40 @@ 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)
|
||||
if (timing < -32767)
|
||||
timing = -32767;
|
||||
if (timing > 32767)
|
||||
timing = 32767;
|
||||
if (jitter->timeBuffers[0]->curr_count >= WINDOW_SIZE)
|
||||
{
|
||||
jitter->reset_state=0;
|
||||
jitter->pointer_timestamp = packet->timestamp;
|
||||
jitter->current_timestamp = packet->timestamp;
|
||||
/*fprintf(stderr, "reset to %d\n", timestamp);*/
|
||||
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);*/
|
||||
}
|
||||
|
||||
/* Cleanup buffer (remove old packets that weren't played) */
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
static void shift_timings(JitterBuffer *jitter, spx_int16_t amount)
|
||||
{
|
||||
int i, j;
|
||||
for (i=0;i<MAX_BUFFERS;i++)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
for (j=0;j<jitter->timeBuffers[i]->filled;i++)
|
||||
jitter->timeBuffers[i]->timing[j] += amount;
|
||||
}
|
||||
}
|
||||
|
||||
/*Find an empty slot in the buffer*/
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->buf[i]==NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
/*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;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
|
||||
{
|
||||
if (!jitter->buf[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.
|
||||
|
|
@ -228,88 +350,215 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet)
|
|||
jitter_buffer_reset(jitter);
|
||||
}
|
||||
}
|
||||
#if 0 /* Enable to check how much is being buffered */
|
||||
if (rand()%1000==0)
|
||||
}
|
||||
|
||||
static void shift_histogram(JitterBuffer *jitter, int amount)
|
||||
{
|
||||
int i, c;
|
||||
if (amount == 0)
|
||||
return;
|
||||
if (amount > 0)
|
||||
{
|
||||
int count = 0;
|
||||
for (j=0;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
|
||||
/* FIXME: This is terribly inefficient */
|
||||
for (c=0;c<amount;c++)
|
||||
{
|
||||
if (jitter->buf[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];
|
||||
}
|
||||
fprintf (stderr, "buffer_size = %d\n", count);
|
||||
jitter->shortterm_margin[0] = 0;
|
||||
jitter->longterm_margin[0] = 0;
|
||||
}
|
||||
#endif
|
||||
} 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 */
|
||||
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);*/
|
||||
}
|
||||
|
||||
/* Cleanup buffer (remove old packets that weren't played) */
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;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;
|
||||
}
|
||||
}
|
||||
|
||||
/*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/
|
||||
/* 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);
|
||||
late = 1;
|
||||
} else {
|
||||
late = 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))
|
||||
{
|
||||
|
||||
/*Find an empty slot in the buffer*/
|
||||
for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[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;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
|
||||
{
|
||||
if (!jitter->packets[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;j<packet->len;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 *start_offset)
|
||||
int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset)
|
||||
{
|
||||
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;
|
||||
|
||||
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->tick_size;
|
||||
jitter->pointer_timestamp += jitter->tick_size;
|
||||
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;
|
||||
}
|
||||
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);*/
|
||||
|
||||
/* FIXME: This should be only what remaining of the current tick */
|
||||
chunk_size = jitter->tick_size;
|
||||
|
||||
/* Compiling arrival statistics */
|
||||
|
||||
late_ratio_short = 0;
|
||||
late_ratio_long = 0;
|
||||
/* Count the proportion of packets that are late */
|
||||
for (i=0;i<LATE_BINS;i++)
|
||||
{
|
||||
late_ratio_short += jitter->shortterm_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;i<MAX_MARGIN;i++)
|
||||
{
|
||||
early_ratio_short += jitter->shortterm_margin[i];
|
||||
early_ratio_long += jitter->longterm_margin[i];
|
||||
}
|
||||
if (0&&jitter->pointer_timestamp%1000==0)
|
||||
{
|
||||
/*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);*/
|
||||
}
|
||||
|
||||
|
||||
/* 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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->buf[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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->buf[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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->buf[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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
/* check if packet starts within current chunk */
|
||||
if (jitter->buf[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 */
|
||||
if (jitter->destroy)
|
||||
{
|
||||
packet->data = jitter->packets[i].data;
|
||||
} else {
|
||||
for (j=0;j<packet->len;j++)
|
||||
packet->data[j] = jitter->buf[i][j];
|
||||
packet->data[j] = jitter->packets[i].data[j];
|
||||
/* Remove packet */
|
||||
speex_free(jitter->buf[i]);
|
||||
jitter->buf[i] = NULL;
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
/* Increase buffering */
|
||||
|
||||
/* Shift histogram to compensate */
|
||||
shift_histogram(jitter, jitter->res_delay_step);
|
||||
|
||||
packet->timestamp = jitter->pointer_timestamp;
|
||||
packet->span = jitter->tick_size;
|
||||
jitter->pointer_timestamp += chunk_size;
|
||||
packet->span = jitter->delay_step;
|
||||
/* Don't move the pointer_timestamp forward */
|
||||
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)
|
||||
{
|
||||
/* 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");*/
|
||||
/*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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->packets[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;j<packet->len;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);*/
|
||||
|
||||
/* 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;i<LATE_BINS;i++)
|
||||
{
|
||||
late_ratio_short += jitter->shortterm_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;i<MAX_MARGIN;i++)
|
||||
{
|
||||
early_ratio_short += jitter->shortterm_margin[i];
|
||||
early_ratio_long += jitter->longterm_margin[i];
|
||||
}
|
||||
compute_statistics(jitter);
|
||||
|
||||
/* 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;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;
|
||||
/*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;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
|
||||
{
|
||||
if (jitter->buf[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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
/** LTP parameters. */
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
#ifndef MATH_APPROX_H
|
||||
#define MATH_APPROX_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifndef FIXED_POINT
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include "medfilter.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
MedianFilter *median_filter_new(int N)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
|
||||
#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},
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <speex/speex.h>
|
||||
#include <speex/speex_bits.h>
|
||||
#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;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
#include "sb_celp.h"
|
||||
#include "nb_celp.h"
|
||||
#include "vbr.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <math.h>
|
||||
#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},
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#include "vq.h"
|
||||
#include <speex/speex_bits.h>
|
||||
#include "vbr.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "math_approx.h"
|
||||
#include "os_support.h"
|
||||
#include <speex/speex_callbacks.h>
|
||||
|
|
@ -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;i<st->lpcSize+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;i<st->lpcSize;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);
|
||||
|
|
@ -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
|
||||
|
|
@ -1724,7 +1720,7 @@ int nb_encoder_ctl(void *state, int request, void *ptr)
|
|||
st->bounded_pitch = 1;
|
||||
st->first = 1;
|
||||
for (i=0;i<st->lpcSize;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;i<st->lpcSize;i++)
|
||||
st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;
|
||||
for (i=0;i<st->frameSize+st->max_pitch+1;i++)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
//#include "config-tremor.h"
|
||||
#include <string.h>
|
||||
#include "speex/ogg.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
/* A complete description of Ogg framing exists in docs/framing.html */
|
||||
|
||||
|
|
|
|||
|
|
@ -41,10 +41,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** 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
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
#include <math.h>
|
||||
#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);
|
||||
|
|
|
|||
|
|
@ -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 <math.h>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef BFIN_ASM
|
||||
#include "quant_lsp_bfin.h"
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
#define QUANT_LSP_H
|
||||
|
||||
#include <speex/speex_bits.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define MAX_LSP_SIZE 20
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;i<st->lpcSize+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;i<st->lpcSize;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;i<st->lpcSize;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;i<st->lpcSize;i++)
|
||||
st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
|
||||
for (i=0;i<QMF_ORDER;i++)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ typedef struct SBEncState {
|
|||
int windowSize; /**< Length of high-band LPC window*/
|
||||
int lpcSize; /**< Order of high-band LPC analysis */
|
||||
int first; /**< First frame? */
|
||||
float lag_factor; /**< Lag-windowing control parameter */
|
||||
spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */
|
||||
spx_word16_t gamma1; /**< Perceptual weighting coef 1 */
|
||||
spx_word16_t gamma2; /**< Perceptual weighting coef 2 */
|
||||
|
|
@ -61,7 +60,7 @@ typedef struct SBEncState {
|
|||
spx_word16_t *h0_mem, *h1_mem;
|
||||
|
||||
const spx_word16_t *window; /**< LPC analysis window */
|
||||
spx_word16_t *lagWindow; /**< Auto-correlation window */
|
||||
const spx_word16_t *lagWindow; /**< Auto-correlation window */
|
||||
spx_lsp_t *old_lsp; /**< LSPs of previous frame */
|
||||
spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */
|
||||
spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include <math.h>
|
||||
#include "smallft.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
static void drfti1(int n, float *wa, int *ifac){
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#endif
|
||||
|
||||
#include <speex/speex_callbacks.h>
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "os_support.h"
|
||||
|
||||
int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
#include "config-speex.h"
|
||||
#endif
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include <speex/speex_header.h>
|
||||
#include <speex/speex.h>
|
||||
#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);}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#ifndef VBR_H
|
||||
#define VBR_H
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#define VBR_MEMORY_SIZE 5
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#ifdef VORBIS_PSYCHO
|
||||
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
#include "smallft.h"
|
||||
#include "lpc.h"
|
||||
#include "vorbis_psy.h"
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include "vq.h"
|
||||
#include "stack_alloc.h"
|
||||
#include "misc.h"
|
||||
#include "arch.h"
|
||||
|
||||
#ifdef _USE_SSE
|
||||
#include <xmmintrin.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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue