diff options
Diffstat (limited to 'apps')
48 files changed, 697 insertions, 480 deletions
diff --git a/apps/codecs/libspeex/_kiss_fft_guts.h b/apps/codecs/libspeex/_kiss_fft_guts.h index 3023b98b06..e9bb018c4b 100644 --- a/apps/codecs/libspeex/_kiss_fft_guts.h +++ b/apps/codecs/libspeex/_kiss_fft_guts.h | |||
@@ -51,7 +51,7 @@ struct kiss_fft_state{ | |||
51 | C_ADDTO( res , a) : res += a | 51 | C_ADDTO( res , a) : res += a |
52 | * */ | 52 | * */ |
53 | #ifdef FIXED_POINT | 53 | #ifdef FIXED_POINT |
54 | #include "misc.h" | 54 | #include "arch.h" |
55 | # define FRACBITS 15 | 55 | # define FRACBITS 15 |
56 | # define SAMPPROD spx_int32_t | 56 | # define SAMPPROD spx_int32_t |
57 | #define SAMP_MAX 32767 | 57 | #define SAMP_MAX 32767 |
diff --git a/apps/codecs/libspeex/arch.h b/apps/codecs/libspeex/arch.h index 1e48e93388..9db16ff34d 100644 --- a/apps/codecs/libspeex/arch.h +++ b/apps/codecs/libspeex/arch.h | |||
@@ -35,6 +35,47 @@ | |||
35 | #ifndef ARCH_H | 35 | #ifndef ARCH_H |
36 | #define ARCH_H | 36 | #define ARCH_H |
37 | 37 | ||
38 | #include "config-speex.h" | ||
39 | |||
40 | #ifndef SPEEX_VERSION | ||
41 | #define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ | ||
42 | #define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ | ||
43 | #define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */ | ||
44 | #define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ | ||
45 | #define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */ | ||
46 | #endif | ||
47 | |||
48 | /* A couple test to catch stupid option combinations */ | ||
49 | #ifdef FIXED_POINT | ||
50 | |||
51 | #ifdef FLOATING_POINT | ||
52 | #error You cannot compile as floating point and fixed point at the same time | ||
53 | #endif | ||
54 | #ifdef _USE_SSE | ||
55 | #error SSE is only for floating-point | ||
56 | #endif | ||
57 | #if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) | ||
58 | #error Make up your mind. What CPU do you have? | ||
59 | #endif | ||
60 | #ifdef VORBIS_PSYCHO | ||
61 | #error Vorbis-psy model currently not implemented in fixed-point | ||
62 | #endif | ||
63 | |||
64 | #else | ||
65 | |||
66 | #ifndef FLOATING_POINT | ||
67 | #error You now need to define either FIXED_POINT or FLOATING_POINT | ||
68 | #endif | ||
69 | #if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) | ||
70 | #error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? | ||
71 | #endif | ||
72 | #ifdef FIXED_POINT_DEBUG | ||
73 | #error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" | ||
74 | #endif | ||
75 | |||
76 | |||
77 | #endif | ||
78 | |||
38 | #ifndef OUTSIDE_SPEEX | 79 | #ifndef OUTSIDE_SPEEX |
39 | #include "speex/speex_types.h" | 80 | #include "speex/speex_types.h" |
40 | #endif | 81 | #endif |
@@ -192,4 +233,11 @@ typedef float spx_word32_t; | |||
192 | 233 | ||
193 | #endif | 234 | #endif |
194 | 235 | ||
236 | |||
237 | |||
238 | #ifdef FIXED_DEBUG | ||
239 | long long spx_mips=0; | ||
240 | #endif | ||
241 | |||
242 | |||
195 | #endif | 243 | #endif |
diff --git a/apps/codecs/libspeex/bits.c b/apps/codecs/libspeex/bits.c index b85db6e1a8..d4b02a5a86 100644 --- a/apps/codecs/libspeex/bits.c +++ b/apps/codecs/libspeex/bits.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | #include <speex/speex_bits.h> | 39 | #include <speex/speex_bits.h> |
40 | #include "misc.h" | 40 | #include "arch.h" |
41 | #include "os_support.h" | 41 | #include "os_support.h" |
42 | 42 | ||
43 | /* Maximum size of the bit-stream (for fixed-size allocation) */ | 43 | /* Maximum size of the bit-stream (for fixed-size allocation) */ |
diff --git a/apps/codecs/libspeex/cb_search.c b/apps/codecs/libspeex/cb_search.c index ecb3918298..a3857c3afa 100644 --- a/apps/codecs/libspeex/cb_search.c +++ b/apps/codecs/libspeex/cb_search.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "filters.h" | 37 | #include "filters.h" |
38 | #include "stack_alloc.h" | 38 | #include "stack_alloc.h" |
39 | #include "vq.h" | 39 | #include "vq.h" |
40 | #include "misc.h" | 40 | #include "arch.h" |
41 | #include "math_approx.h" | 41 | #include "math_approx.h" |
42 | #include "os_support.h" | 42 | #include "os_support.h" |
43 | 43 | ||
diff --git a/apps/codecs/libspeex/cb_search.h b/apps/codecs/libspeex/cb_search.h index fd5c110ed6..7687b453fd 100644 --- a/apps/codecs/libspeex/cb_search.h +++ b/apps/codecs/libspeex/cb_search.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #define CB_SEARCH_H | 36 | #define CB_SEARCH_H |
37 | 37 | ||
38 | #include <speex/speex_bits.h> | 38 | #include <speex/speex_bits.h> |
39 | #include "misc.h" | 39 | #include "arch.h" |
40 | 40 | ||
41 | /** Split codebook parameters. */ | 41 | /** Split codebook parameters. */ |
42 | typedef struct split_cb_params { | 42 | typedef struct split_cb_params { |
diff --git a/apps/codecs/libspeex/fftwrap.c b/apps/codecs/libspeex/fftwrap.c index e4cf3b028b..2312f755d6 100644 --- a/apps/codecs/libspeex/fftwrap.c +++ b/apps/codecs/libspeex/fftwrap.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define USE_KISS_FFT | 40 | #define USE_KISS_FFT |
41 | 41 | ||
42 | 42 | ||
43 | #include "misc.h" | 43 | #include "arch.h" |
44 | #include "os_support.h" | 44 | #include "os_support.h" |
45 | 45 | ||
46 | #define MAX_FFT_SIZE 2048 | 46 | #define MAX_FFT_SIZE 2048 |
diff --git a/apps/codecs/libspeex/fftwrap.h b/apps/codecs/libspeex/fftwrap.h index 826b38e979..dfaf489441 100644 --- a/apps/codecs/libspeex/fftwrap.h +++ b/apps/codecs/libspeex/fftwrap.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #ifndef FFTWRAP_H | 35 | #ifndef FFTWRAP_H |
36 | #define FFTWRAP_H | 36 | #define FFTWRAP_H |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | 39 | ||
40 | /** Compute tables for an FFT */ | 40 | /** Compute tables for an FFT */ |
41 | void *spx_fft_init(int size); | 41 | void *spx_fft_init(int size); |
diff --git a/apps/codecs/libspeex/filterbank.c b/apps/codecs/libspeex/filterbank.c index f50c70e0ad..d2a8f1af90 100644 --- a/apps/codecs/libspeex/filterbank.c +++ b/apps/codecs/libspeex/filterbank.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #include "filterbank.h" | 38 | #include "filterbank.h" |
39 | #include "misc.h" | 39 | #include "arch.h" |
40 | #include <math.h> | 40 | #include <math.h> |
41 | #include "math_approx.h" | 41 | #include "math_approx.h" |
42 | #include "os_support.h" | 42 | #include "os_support.h" |
diff --git a/apps/codecs/libspeex/filterbank.h b/apps/codecs/libspeex/filterbank.h index 5ded6b93ee..3e889a22f7 100644 --- a/apps/codecs/libspeex/filterbank.h +++ b/apps/codecs/libspeex/filterbank.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #ifndef FILTERBANK_H | 34 | #ifndef FILTERBANK_H |
35 | #define FILTERBANK_H | 35 | #define FILTERBANK_H |
36 | 36 | ||
37 | #include "misc.h" | 37 | #include "arch.h" |
38 | 38 | ||
39 | typedef struct { | 39 | typedef struct { |
40 | int *bank_left; | 40 | int *bank_left; |
diff --git a/apps/codecs/libspeex/filters.c b/apps/codecs/libspeex/filters.c index a41148fcfb..aaffa9441f 100644 --- a/apps/codecs/libspeex/filters.c +++ b/apps/codecs/libspeex/filters.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | #include "filters.h" | 37 | #include "filters.h" |
38 | #include "stack_alloc.h" | 38 | #include "stack_alloc.h" |
39 | #include "misc.h" | 39 | #include "arch.h" |
40 | #include "math_approx.h" | 40 | #include "math_approx.h" |
41 | #include "ltp.h" | 41 | #include "ltp.h" |
42 | #include <math.h> | 42 | #include <math.h> |
diff --git a/apps/codecs/libspeex/filters.h b/apps/codecs/libspeex/filters.h index b08e94d320..e3a5980e70 100644 --- a/apps/codecs/libspeex/filters.h +++ b/apps/codecs/libspeex/filters.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #ifndef FILTERS_H | 35 | #ifndef FILTERS_H |
36 | #define FILTERS_H | 36 | #define FILTERS_H |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | 39 | ||
40 | spx_word16_t compute_rms(const spx_sig_t *x, int len); | 40 | spx_word16_t compute_rms(const spx_sig_t *x, int len); |
41 | spx_word16_t compute_rms16(const spx_word16_t *x, int len); | 41 | spx_word16_t compute_rms16(const spx_word16_t *x, int len); |
diff --git a/apps/codecs/libspeex/jitter.c b/apps/codecs/libspeex/jitter.c index 57bb4c2958..e31a131bba 100644 --- a/apps/codecs/libspeex/jitter.c +++ b/apps/codecs/libspeex/jitter.c | |||
@@ -32,12 +32,27 @@ | |||
32 | 32 | ||
33 | */ | 33 | */ |
34 | 34 | ||
35 | /* | ||
36 | TODO: | ||
37 | - Write generic functions for computing stats and shifting the histogram | ||
38 | - Take into account the delay step when computing the stats and when shifting | ||
39 | - Linked list structure for holding the packets instead of the current fixed-size array | ||
40 | + return memory to a pool | ||
41 | + allow pre-allocation of the pool | ||
42 | + optional max number of elements | ||
43 | - Statistics | ||
44 | + drift | ||
45 | + loss | ||
46 | + late | ||
47 | + jitter | ||
48 | + buffering delay | ||
49 | */ | ||
35 | #ifdef HAVE_CONFIG_H | 50 | #ifdef HAVE_CONFIG_H |
36 | #include "config-speex.h" | 51 | #include "config-speex.h" |
37 | #endif | 52 | #endif |
38 | 53 | ||
39 | 54 | ||
40 | #include "misc.h" | 55 | #include "arch.h" |
41 | #include <speex/speex.h> | 56 | #include <speex/speex.h> |
42 | #include <speex/speex_bits.h> | 57 | #include <speex/speex_bits.h> |
43 | #include <speex/speex_jitter.h> | 58 | #include <speex/speex_jitter.h> |
@@ -52,29 +67,157 @@ | |||
52 | 67 | ||
53 | #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ | 68 | #define SPEEX_JITTER_MAX_BUFFER_SIZE 200 /**< Maximum number of packets in jitter buffer */ |
54 | 69 | ||
55 | 70 | #define TSUB(a,b) ((spx_int32_t)((a)-(b))) | |
56 | 71 | ||
57 | #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) | 72 | #define GT32(a,b) (((spx_int32_t)((a)-(b)))>0) |
58 | #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) | 73 | #define GE32(a,b) (((spx_int32_t)((a)-(b)))>=0) |
59 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) | 74 | #define LT32(a,b) (((spx_int32_t)((a)-(b)))<0) |
60 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) | 75 | #define LE32(a,b) (((spx_int32_t)((a)-(b)))<=0) |
61 | 76 | ||
77 | #define MAX_TIMINGS 20 | ||
78 | #define MAX_BUFFERS 3 | ||
79 | #define TOP_DELAY 25 | ||
80 | #define WINDOW_SIZE 200 | ||
81 | |||
82 | struct TimingBuffer { | ||
83 | int filled; | ||
84 | int curr_count; | ||
85 | spx_int16_t timing[MAX_TIMINGS]; | ||
86 | spx_int16_t counts[MAX_TIMINGS]; | ||
87 | }; | ||
88 | |||
89 | static void tb_init(struct TimingBuffer *tb) | ||
90 | { | ||
91 | tb->filled = 0; | ||
92 | tb->curr_count = 0; | ||
93 | } | ||
94 | |||
95 | static void tb_add(struct TimingBuffer *tb, spx_int16_t timing) | ||
96 | { | ||
97 | int pos; | ||
98 | /*fprintf(stderr, "timing = %d\n", timing);*/ | ||
99 | /*fprintf(stderr, "timing = %d, latest = %d, earliest = %d, filled = %d\n", timing, tb->timing[0], tb->timing[tb->filled-1], tb->filled);*/ | ||
100 | if (tb->filled >= MAX_TIMINGS && timing >= tb->timing[tb->filled-1]) | ||
101 | { | ||
102 | tb->curr_count++; | ||
103 | return; | ||
104 | } | ||
105 | pos = 0; | ||
106 | /* FIXME: Do bisection instead of linear search */ | ||
107 | while (pos<tb->filled && timing >= tb->timing[pos]) | ||
108 | { | ||
109 | pos++; | ||
110 | } | ||
111 | |||
112 | /*fprintf(stderr, "pos = %d filled = %d\n", pos, tb->filled);*/ | ||
113 | speex_assert(pos <= tb->filled && pos < MAX_TIMINGS); | ||
114 | fprintf(stderr, "OK\n"); | ||
115 | if (pos < tb->filled) | ||
116 | { | ||
117 | int move_size = tb->filled-pos; | ||
118 | if (tb->filled == MAX_TIMINGS) | ||
119 | move_size -= 1; | ||
120 | /*fprintf(stderr, "speex_move(%d %d %d)\n", pos+1, pos, move_size);*/ | ||
121 | speex_move(&tb->timing[pos+1], &tb->timing[pos], move_size*sizeof(tb->timing[0])); | ||
122 | speex_move(&tb->counts[pos+1], &tb->counts[pos], move_size*sizeof(tb->counts[0])); | ||
123 | } | ||
124 | /*fprintf(stderr, "moved\n");*/ | ||
125 | tb->timing[pos] = timing; | ||
126 | tb->counts[pos] = tb->curr_count; | ||
127 | /*{ | ||
128 | int i; | ||
129 | for (i=0;i<MAX_TIMINGS;i++) | ||
130 | fprintf(stderr, "%d ", tb->timing[i]); | ||
131 | fprintf(stderr, "\n"); | ||
132 | }*/ | ||
133 | tb->curr_count++; | ||
134 | if (tb->filled<MAX_TIMINGS) | ||
135 | tb->filled++; | ||
136 | /*fprintf(stderr, "added\n");*/ | ||
137 | } | ||
138 | |||
139 | /** Based on available data, this computes the optimal delay for the jitter buffer. | ||
140 | The optimised function is in timestamp units and is: | ||
141 | cost = delay + late_factor*[number of frames that would be late if we used that delay] | ||
142 | @param tb Array of buffers | ||
143 | @param late_factor Equivalent cost of a late frame (in timestamp units) | ||
144 | */ | ||
145 | static spx_int16_t tbs_get_opt_delay(struct TimingBuffer *tb, spx_int32_t late_factor) | ||
146 | { | ||
147 | int i; | ||
148 | spx_int16_t opt=0; | ||
149 | spx_int32_t best_cost=0x7fffffff; | ||
150 | int late = 0; | ||
151 | int pos[MAX_BUFFERS]; | ||
152 | |||
153 | /*fprintf(stderr, "tbs_get_opt_delay\n");*/ | ||
154 | for (i=0;i<MAX_BUFFERS;i++) | ||
155 | pos[i] = 0; | ||
156 | |||
157 | for (i=0;i<TOP_DELAY;i++) | ||
158 | { | ||
159 | int j; | ||
160 | int next=-1; | ||
161 | int latest = 32767; | ||
162 | for (j=0;j<MAX_BUFFERS;j++) | ||
163 | { | ||
164 | if (pos[j] < tb[j].filled && tb[j].timing[pos[j]] < latest) | ||
165 | { | ||
166 | next = j; | ||
167 | latest = tb[j].timing[pos[j]]; | ||
168 | } | ||
169 | } | ||
170 | late++; | ||
171 | if (next != -1) | ||
172 | { | ||
173 | spx_int32_t cost; | ||
174 | pos[next]++; | ||
175 | /* When considering reducing delay, "on-time" frames could twice (this provides hysteresis) */ | ||
176 | if (latest > 0) | ||
177 | late++; | ||
178 | cost = -latest + late_factor*late; | ||
179 | /*fprintf(stderr, "cost %d = -%d + %d * %d\n", cost, latest, late_factor, late);*/ | ||
180 | if (cost < best_cost) | ||
181 | { | ||
182 | best_cost = cost; | ||
183 | opt = latest; | ||
184 | } | ||
185 | } else { | ||
186 | break; | ||
187 | } | ||
188 | } | ||
189 | return opt; | ||
190 | } | ||
191 | |||
62 | /** Jitter buffer structure */ | 192 | /** Jitter buffer structure */ |
63 | struct JitterBuffer_ { | 193 | struct JitterBuffer_ { |
64 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ | 194 | spx_uint32_t pointer_timestamp; /**< Timestamp of what we will *get* next */ |
65 | spx_uint32_t current_timestamp; /**< Timestamp of the local clock (what we will *play* next) */ | 195 | spx_uint32_t last_returned_timestamp; |
66 | 196 | spx_uint32_t next_stop; | |
67 | char *buf[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Buffer of packets (NULL if slot is free) */ | 197 | |
68 | spx_uint32_t timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ | 198 | JitterBufferPacket packets[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packets stored in the buffer */ |
69 | int span[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Timestamp of packet */ | 199 | spx_uint32_t arrival[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Packet arrival time (0 means it was late, even though it's a valid timestamp) */ |
70 | int len[SPEEX_JITTER_MAX_BUFFER_SIZE]; /**< Number of bytes in packet */ | 200 | |
201 | void (*destroy) (void *); /**< Callback for destroying a packet */ | ||
71 | 202 | ||
72 | int tick_size; /**< Output granularity */ | 203 | int resolution; /**< Time resolution for histogram (timestamp units) */ |
204 | int delay_step; /**< Size of the steps when adjusting buffering (timestamp units) */ | ||
205 | int res_delay_step; /**< Size of the steps when adjusting buffering (resolution units) */ | ||
73 | int reset_state; /**< True if state was just reset */ | 206 | int reset_state; /**< True if state was just reset */ |
74 | int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ | 207 | int buffer_margin; /**< How many frames we want to keep in the buffer (lower bound) */ |
75 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ | 208 | int late_cutoff; /**< How late must a packet be for it not to be considered at all */ |
76 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ | 209 | int interp_requested; /**< An interpolation is requested by speex_jitter_update_delay() */ |
77 | 210 | ||
211 | struct TimingBuffer _tb[MAX_BUFFERS]; /**< Don't use those directly */ | ||
212 | struct TimingBuffer *timeBuffers[MAX_BUFFERS]; /**< Storing arrival time of latest frames so we can compute some stats */ | ||
213 | |||
214 | float late_ratio_short; | ||
215 | float late_ratio_long; | ||
216 | float ontime_ratio_short; | ||
217 | float ontime_ratio_long; | ||
218 | float early_ratio_short; | ||
219 | float early_ratio_long; | ||
220 | |||
78 | int lost_count; /**< Number of consecutive lost packets */ | 221 | int lost_count; /**< Number of consecutive lost packets */ |
79 | float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */ | 222 | float shortterm_margin[MAX_MARGIN]; /**< Short term margin histogram */ |
80 | float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */ | 223 | float longterm_margin[MAX_MARGIN]; /**< Long term margin histogram */ |
@@ -82,17 +225,21 @@ struct JitterBuffer_ { | |||
82 | }; | 225 | }; |
83 | 226 | ||
84 | /** Initialise jitter buffer */ | 227 | /** Initialise jitter buffer */ |
85 | JitterBuffer *jitter_buffer_init(int tick) | 228 | JitterBuffer *jitter_buffer_init(int resolution) |
86 | { | 229 | { |
87 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); | 230 | JitterBuffer *jitter = (JitterBuffer*)speex_alloc(sizeof(JitterBuffer)); |
88 | if (jitter) | 231 | if (jitter) |
89 | { | 232 | { |
90 | int i; | 233 | int i; |
91 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 234 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
92 | jitter->buf[i]=NULL; | 235 | jitter->packets[i].data=NULL; |
93 | jitter->tick_size = tick; | 236 | jitter->resolution = resolution; |
237 | jitter->delay_step = resolution; | ||
238 | jitter->res_delay_step = 1; | ||
239 | /*FIXME: Should this be 0 or 1?*/ | ||
94 | jitter->buffer_margin = 1; | 240 | jitter->buffer_margin = 1; |
95 | jitter->late_cutoff = 50; | 241 | jitter->late_cutoff = 50; |
242 | jitter->destroy = NULL; | ||
96 | jitter_buffer_reset(jitter); | 243 | jitter_buffer_reset(jitter); |
97 | } | 244 | } |
98 | return jitter; | 245 | return jitter; |
@@ -104,15 +251,18 @@ void jitter_buffer_reset(JitterBuffer *jitter) | |||
104 | int i; | 251 | int i; |
105 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 252 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
106 | { | 253 | { |
107 | if (jitter->buf[i]) | 254 | if (jitter->packets[i].data) |
108 | { | 255 | { |
109 | speex_free(jitter->buf[i]); | 256 | if (jitter->destroy) |
110 | jitter->buf[i] = NULL; | 257 | jitter->destroy(jitter->packets[i].data); |
258 | else | ||
259 | speex_free(jitter->packets[i].data); | ||
260 | jitter->packets[i].data = NULL; | ||
111 | } | 261 | } |
112 | } | 262 | } |
113 | /* Timestamp is actually undefined at this point */ | 263 | /* Timestamp is actually undefined at this point */ |
114 | jitter->pointer_timestamp = 0; | 264 | jitter->pointer_timestamp = 0; |
115 | jitter->current_timestamp = 0; | 265 | jitter->next_stop = 0; |
116 | jitter->reset_state = 1; | 266 | jitter->reset_state = 1; |
117 | jitter->lost_count = 0; | 267 | jitter->lost_count = 0; |
118 | jitter->loss_rate = 0; | 268 | jitter->loss_rate = 0; |
@@ -121,6 +271,12 @@ void jitter_buffer_reset(JitterBuffer *jitter) | |||
121 | jitter->shortterm_margin[i] = 0; | 271 | jitter->shortterm_margin[i] = 0; |
122 | jitter->longterm_margin[i] = 0; | 272 | jitter->longterm_margin[i] = 0; |
123 | } | 273 | } |
274 | |||
275 | for (i=0;i<MAX_BUFFERS;i++) | ||
276 | { | ||
277 | tb_init(&jitter->_tb[i]); | ||
278 | jitter->timeBuffers[i] = &jitter->_tb[i]; | ||
279 | } | ||
124 | /*fprintf (stderr, "reset\n");*/ | 280 | /*fprintf (stderr, "reset\n");*/ |
125 | } | 281 | } |
126 | 282 | ||
@@ -131,79 +287,45 @@ void jitter_buffer_destroy(JitterBuffer *jitter) | |||
131 | speex_free(jitter); | 287 | speex_free(jitter); |
132 | } | 288 | } |
133 | 289 | ||
134 | /** Put one packet into the jitter buffer */ | 290 | static void update_timings(JitterBuffer *jitter, spx_int32_t timing) |
135 | void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | ||
136 | { | 291 | { |
137 | int i,j; | 292 | if (timing < -32767) |
138 | spx_int32_t arrival_margin; | 293 | timing = -32767; |
139 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ | 294 | if (timing > 32767) |
140 | if (jitter->reset_state) | 295 | timing = 32767; |
141 | { | 296 | if (jitter->timeBuffers[0]->curr_count >= WINDOW_SIZE) |
142 | jitter->reset_state=0; | ||
143 | jitter->pointer_timestamp = packet->timestamp; | ||
144 | jitter->current_timestamp = packet->timestamp; | ||
145 | /*fprintf(stderr, "reset to %d\n", timestamp);*/ | ||
146 | } | ||
147 | |||
148 | /* Cleanup buffer (remove old packets that weren't played) */ | ||
149 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | ||
150 | { | 297 | { |
151 | /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ | 298 | int i; |
152 | if (jitter->buf[i] && LE32(jitter->timestamp[i] + jitter->span[i], jitter->pointer_timestamp)) | 299 | /*fprintf(stderr, "Rotate buffer\n");*/ |
153 | { | 300 | struct TimingBuffer *tmp = jitter->timeBuffers[MAX_BUFFERS-1]; |
154 | /*fprintf (stderr, "cleaned (not played)\n");*/ | 301 | for (i=MAX_BUFFERS-1;i>=1;i--) |
155 | speex_free(jitter->buf[i]); | 302 | jitter->timeBuffers[i] = jitter->timeBuffers[i-1]; |
156 | jitter->buf[i] = NULL; | 303 | jitter->timeBuffers[0] = tmp; |
157 | } | 304 | tb_init(jitter->timeBuffers[0]); |
158 | } | 305 | } |
306 | tb_add(jitter->timeBuffers[0], timing); | ||
307 | spx_int16_t opt = tbs_get_opt_delay(jitter->_tb, 2); | ||
308 | /*fprintf(stderr, "opt adjustment is %d\n", opt);*/ | ||
309 | } | ||
159 | 310 | ||
160 | /*Find an empty slot in the buffer*/ | 311 | static void shift_timings(JitterBuffer *jitter, spx_int16_t amount) |
161 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 312 | { |
313 | int i, j; | ||
314 | for (i=0;i<MAX_BUFFERS;i++) | ||
162 | { | 315 | { |
163 | if (jitter->buf[i]==NULL) | 316 | for (j=0;j<jitter->timeBuffers[i]->filled;i++) |
164 | break; | 317 | jitter->timeBuffers[i]->timing[j] += amount; |
165 | } | 318 | } |
319 | } | ||
166 | 320 | ||
167 | /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/ | 321 | static void update_histogram(JitterBuffer *jitter, spx_int32_t arrival_margin) |
168 | /*No place left in the buffer*/ | 322 | { |
169 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | 323 | int i; |
170 | { | ||
171 | int earliest=jitter->timestamp[0]; | ||
172 | i=0; | ||
173 | for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) | ||
174 | { | ||
175 | if (!jitter->buf[i] || LT32(jitter->timestamp[j],earliest)) | ||
176 | { | ||
177 | earliest = jitter->timestamp[j]; | ||
178 | i=j; | ||
179 | } | ||
180 | } | ||
181 | speex_free(jitter->buf[i]); | ||
182 | jitter->buf[i]=NULL; | ||
183 | if (jitter->lost_count>20) | ||
184 | { | ||
185 | jitter_buffer_reset(jitter); | ||
186 | } | ||
187 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ | ||
188 | } | ||
189 | |||
190 | /* Copy packet in buffer */ | ||
191 | jitter->buf[i]=(char*)speex_alloc(packet->len); | ||
192 | for (j=0;j<(int)packet->len;j++) | ||
193 | jitter->buf[i][j]=packet->data[j]; | ||
194 | jitter->timestamp[i]=packet->timestamp; | ||
195 | jitter->span[i]=packet->span; | ||
196 | jitter->len[i]=packet->len; | ||
197 | |||
198 | /* Adjust the buffer size depending on network conditions. | ||
199 | The arrival margin is how much in advance (or late) the packet it */ | ||
200 | arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->current_timestamp))/jitter->tick_size - jitter->buffer_margin; | ||
201 | |||
202 | if (arrival_margin >= -jitter->late_cutoff) | 324 | if (arrival_margin >= -jitter->late_cutoff) |
203 | { | 325 | { |
204 | /* Here we compute the histogram based on the time of arrival of the packet. | 326 | /* Here we compute the histogram based on the time of arrival of the packet. |
205 | This is based on a (first-order) recursive average. We keep both a short-term | 327 | This is based on a (first-order) recursive average. We keep both a short-term |
206 | histogram and a long-term histogram */ | 328 | histogram and a long-term histogram */ |
207 | spx_int32_t int_margin; | 329 | spx_int32_t int_margin; |
208 | /* First, apply the "damping" of the recursive average to all bins */ | 330 | /* First, apply the "damping" of the recursive average to all bins */ |
209 | for (i=0;i<MAX_MARGIN;i++) | 331 | for (i=0;i<MAX_MARGIN;i++) |
@@ -228,88 +350,215 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) | |||
228 | jitter_buffer_reset(jitter); | 350 | jitter_buffer_reset(jitter); |
229 | } | 351 | } |
230 | } | 352 | } |
231 | #if 0 /* Enable to check how much is being buffered */ | 353 | } |
232 | if (rand()%1000==0) | 354 | |
355 | static void shift_histogram(JitterBuffer *jitter, int amount) | ||
356 | { | ||
357 | int i, c; | ||
358 | if (amount == 0) | ||
359 | return; | ||
360 | if (amount > 0) | ||
233 | { | 361 | { |
234 | int count = 0; | 362 | /* FIXME: This is terribly inefficient */ |
235 | for (j=0;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) | 363 | for (c=0;c<amount;c++) |
236 | { | 364 | { |
237 | if (jitter->buf[j]) | 365 | jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; |
238 | count++; | 366 | jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; |
367 | for (i=MAX_MARGIN-3;i>=0;i--) | ||
368 | { | ||
369 | jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; | ||
370 | jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; | ||
371 | } | ||
372 | jitter->shortterm_margin[0] = 0; | ||
373 | jitter->longterm_margin[0] = 0; | ||
374 | } | ||
375 | } else { | ||
376 | /* FIXME: This is terribly inefficient */ | ||
377 | for (c=0;c<-amount;c++) | ||
378 | { | ||
379 | jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; | ||
380 | jitter->longterm_margin[0] += jitter->longterm_margin[1]; | ||
381 | for (i=1;i<MAX_MARGIN-1;i++) | ||
382 | { | ||
383 | jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1]; | ||
384 | jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; | ||
385 | } | ||
386 | jitter->shortterm_margin[MAX_MARGIN-1] = 0; | ||
387 | jitter->longterm_margin[MAX_MARGIN-1] = 0; | ||
239 | } | 388 | } |
240 | fprintf (stderr, "buffer_size = %d\n", count); | ||
241 | } | 389 | } |
242 | #endif | ||
243 | } | 390 | } |
244 | 391 | ||
245 | /** Get one packet from the jitter buffer */ | 392 | static void compute_statistics(JitterBuffer *jitter) |
246 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) | ||
247 | { | 393 | { |
248 | int i; | 394 | int i; |
249 | unsigned int j; | 395 | jitter->late_ratio_short = 0; |
250 | float late_ratio_short; | 396 | jitter->late_ratio_long = 0; |
251 | float late_ratio_long; | 397 | /* Count the proportion of packets that are late */ |
252 | float ontime_ratio_short; | 398 | for (i=0;i<LATE_BINS;i++) |
253 | float ontime_ratio_long; | ||
254 | float early_ratio_short; | ||
255 | float early_ratio_long; | ||
256 | int chunk_size; | ||
257 | int incomplete = 0; | ||
258 | |||
259 | if (jitter->interp_requested) | ||
260 | { | 399 | { |
261 | jitter->interp_requested = 0; | 400 | jitter->late_ratio_short += jitter->shortterm_margin[i]; |
262 | if (start_offset) | 401 | jitter->late_ratio_long += jitter->longterm_margin[i]; |
263 | *start_offset = 0; | ||
264 | packet->timestamp = jitter->pointer_timestamp; | ||
265 | packet->span = jitter->tick_size; | ||
266 | jitter->pointer_timestamp += jitter->tick_size; | ||
267 | packet->len = 0; | ||
268 | return JITTER_BUFFER_MISSING; | ||
269 | } | 402 | } |
270 | if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) | 403 | |
404 | /* Count the proportion of packets that are just on time */ | ||
405 | jitter->ontime_ratio_short = 0; | ||
406 | jitter->ontime_ratio_long = 0; | ||
407 | for (;i<LATE_BINS+jitter->res_delay_step;i++) | ||
271 | { | 408 | { |
272 | jitter->current_timestamp = jitter->pointer_timestamp; | 409 | jitter->ontime_ratio_short = jitter->shortterm_margin[i]; |
273 | speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); | 410 | jitter->ontime_ratio_long = jitter->longterm_margin[i]; |
274 | } | 411 | } |
275 | /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ | 412 | |
413 | jitter->early_ratio_short = 0; | ||
414 | jitter->early_ratio_long = 0; | ||
415 | /* Count the proportion of packets that are early */ | ||
416 | for (;i<MAX_MARGIN;i++) | ||
417 | { | ||
418 | jitter->early_ratio_short += jitter->shortterm_margin[i]; | ||
419 | jitter->early_ratio_long += jitter->longterm_margin[i]; | ||
420 | } | ||
421 | } | ||
276 | 422 | ||
277 | /* FIXME: This should be only what remaining of the current tick */ | 423 | /** Put one packet into the jitter buffer */ |
278 | chunk_size = jitter->tick_size; | 424 | void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet) |
425 | { | ||
426 | int i,j; | ||
427 | int late; | ||
428 | spx_int32_t arrival_margin; | ||
429 | spx_int32_t arrival_time; | ||
430 | /*fprintf (stderr, "put packet %d %d\n", timestamp, span);*/ | ||
279 | 431 | ||
280 | /* Compiling arrival statistics */ | 432 | /* Syncing on the first packet to arrive */ |
433 | if (jitter->reset_state) | ||
434 | { | ||
435 | jitter->reset_state=0; | ||
436 | jitter->pointer_timestamp = packet->timestamp; | ||
437 | jitter->next_stop = packet->timestamp; | ||
438 | /*fprintf(stderr, "reset to %d\n", timestamp);*/ | ||
439 | } | ||
281 | 440 | ||
282 | late_ratio_short = 0; | 441 | /* Cleanup buffer (remove old packets that weren't played) */ |
283 | late_ratio_long = 0; | 442 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
284 | /* Count the proportion of packets that are late */ | ||
285 | for (i=0;i<LATE_BINS;i++) | ||
286 | { | 443 | { |
287 | late_ratio_short += jitter->shortterm_margin[i]; | 444 | /* Make sure we don't discard a "just-late" packet in case we want to play it next (if we interpolate). */ |
288 | late_ratio_long += jitter->longterm_margin[i]; | 445 | if (jitter->packets[i].data && LE32(jitter->packets[i].timestamp + jitter->packets[i].span, jitter->pointer_timestamp)) |
446 | { | ||
447 | /*fprintf (stderr, "cleaned (not played)\n");*/ | ||
448 | if (jitter->destroy) | ||
449 | jitter->destroy(jitter->packets[i].data); | ||
450 | else | ||
451 | speex_free(jitter->packets[i].data); | ||
452 | jitter->packets[i].data = NULL; | ||
453 | } | ||
289 | } | 454 | } |
290 | /* Count the proportion of packets that are just on time */ | 455 | |
291 | ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; | 456 | /*fprintf(stderr, "arrival: %d %d %d\n", packet->timestamp, jitter->next_stop, jitter->pointer_timestamp);*/ |
292 | ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; | 457 | /* Check if packet is late (could still be useful though) */ |
293 | early_ratio_short = early_ratio_long = 0; | 458 | if (LT32(packet->timestamp, jitter->next_stop)) |
294 | /* Count the proportion of packets that are early */ | ||
295 | for (i=LATE_BINS+1;i<MAX_MARGIN;i++) | ||
296 | { | 459 | { |
297 | early_ratio_short += jitter->shortterm_margin[i]; | 460 | /*fprintf(stderr, "late by %d\n", jitter->next_stop - packet->timestamp);*/ |
298 | early_ratio_long += jitter->longterm_margin[i]; | 461 | |
462 | /* The arrival margin is how much in advance (or in this case late) the packet it (in resolution units) */ | ||
463 | arrival_margin = (((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop))/jitter->resolution - jitter->buffer_margin; | ||
464 | |||
465 | /*fprintf(stderr, "put arrival_margin = %d\n", arrival_margin);*/ | ||
466 | /*update_timings(jitter, ((spx_int32_t)packet->timestamp) - ((spx_int32_t)jitter->next_stop));*/ | ||
467 | update_histogram(jitter, arrival_margin); | ||
468 | late = 1; | ||
469 | } else { | ||
470 | late = 0; | ||
299 | } | 471 | } |
300 | if (0&&jitter->pointer_timestamp%1000==0) | 472 | |
473 | /* Only insert the packet if it's not hopelessly late (i.e. totally useless) */ | ||
474 | if (GE32(packet->timestamp+packet->span+jitter->delay_step, jitter->pointer_timestamp)) | ||
301 | { | 475 | { |
302 | /*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);*/ | 476 | |
303 | /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/ | 477 | /*Find an empty slot in the buffer*/ |
478 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | ||
479 | { | ||
480 | if (jitter->packets[i].data==NULL) | ||
481 | break; | ||
482 | } | ||
483 | |||
484 | /*No place left in the buffer, need to make room for it by discarding the oldest packet */ | ||
485 | if (i==SPEEX_JITTER_MAX_BUFFER_SIZE) | ||
486 | { | ||
487 | int earliest=jitter->packets[0].timestamp; | ||
488 | i=0; | ||
489 | for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++) | ||
490 | { | ||
491 | if (!jitter->packets[i].data || LT32(jitter->packets[j].timestamp,earliest)) | ||
492 | { | ||
493 | earliest = jitter->packets[j].timestamp; | ||
494 | i=j; | ||
495 | } | ||
496 | } | ||
497 | if (jitter->destroy) | ||
498 | jitter->destroy(jitter->packets[i].data); | ||
499 | else | ||
500 | speex_free(jitter->packets[i].data); | ||
501 | jitter->packets[i].data=NULL; | ||
502 | if (jitter->lost_count>20) | ||
503 | { | ||
504 | jitter_buffer_reset(jitter); | ||
505 | } | ||
506 | /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/ | ||
507 | } | ||
508 | |||
509 | /* Copy packet in buffer */ | ||
510 | if (jitter->destroy) | ||
511 | { | ||
512 | jitter->packets[i].data = packet->data; | ||
513 | } else { | ||
514 | jitter->packets[i].data=(char*)speex_alloc(packet->len); | ||
515 | for (j=0;j<packet->len;j++) | ||
516 | jitter->packets[i].data[j]=packet->data[j]; | ||
517 | } | ||
518 | jitter->packets[i].timestamp=packet->timestamp; | ||
519 | jitter->packets[i].span=packet->span; | ||
520 | jitter->packets[i].len=packet->len; | ||
521 | jitter->packets[i].user_data=packet->user_data; | ||
522 | if (late) | ||
523 | jitter->arrival[i] = 0; | ||
524 | else | ||
525 | jitter->arrival[i] = jitter->next_stop; | ||
304 | } | 526 | } |
305 | 527 | ||
306 | 528 | ||
529 | } | ||
530 | |||
531 | /** Get one packet from the jitter buffer */ | ||
532 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset) | ||
533 | { | ||
534 | int i; | ||
535 | unsigned int j; | ||
536 | int incomplete = 0; | ||
537 | |||
538 | jitter->last_returned_timestamp = jitter->pointer_timestamp; | ||
539 | |||
540 | if (jitter->interp_requested) | ||
541 | { | ||
542 | jitter->interp_requested = 0; | ||
543 | if (start_offset) | ||
544 | *start_offset = 0; | ||
545 | packet->timestamp = jitter->pointer_timestamp; | ||
546 | packet->span = jitter->delay_step; | ||
547 | |||
548 | /* Increment the pointer because it got decremented in the delay update */ | ||
549 | jitter->pointer_timestamp += jitter->delay_step; | ||
550 | packet->len = 0; | ||
551 | /*fprintf (stderr, "Deferred interpolate\n");*/ | ||
552 | |||
553 | return JITTER_BUFFER_MISSING; | ||
554 | } | ||
555 | |||
307 | /* Searching for the packet that fits best */ | 556 | /* Searching for the packet that fits best */ |
308 | 557 | ||
309 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ | 558 | /* Search the buffer for a packet with the right timestamp and spanning the whole current chunk */ |
310 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 559 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
311 | { | 560 | { |
312 | if (jitter->buf[i] && jitter->timestamp[i]==jitter->pointer_timestamp && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) | 561 | 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)) |
313 | break; | 562 | break; |
314 | } | 563 | } |
315 | 564 | ||
@@ -318,7 +567,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
318 | { | 567 | { |
319 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 568 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
320 | { | 569 | { |
321 | if (jitter->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GE32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp+chunk_size)) | 570 | 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)) |
322 | break; | 571 | break; |
323 | } | 572 | } |
324 | } | 573 | } |
@@ -328,7 +577,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
328 | { | 577 | { |
329 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 578 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
330 | { | 579 | { |
331 | if (jitter->buf[i] && LE32(jitter->timestamp[i], jitter->pointer_timestamp) && GT32(jitter->timestamp[i]+jitter->span[i],jitter->pointer_timestamp)) | 580 | 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)) |
332 | break; | 581 | break; |
333 | } | 582 | } |
334 | } | 583 | } |
@@ -343,12 +592,12 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
343 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 592 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
344 | { | 593 | { |
345 | /* check if packet starts within current chunk */ | 594 | /* check if packet starts within current chunk */ |
346 | if (jitter->buf[i] && LT32(jitter->timestamp[i],jitter->pointer_timestamp+chunk_size) && GE32(jitter->timestamp[i],jitter->pointer_timestamp)) | 595 | if (jitter->packets[i].data && LT32(jitter->packets[i].timestamp,jitter->pointer_timestamp+desired_span) && GE32(jitter->packets[i].timestamp,jitter->pointer_timestamp)) |
347 | { | 596 | { |
348 | if (!found || LT32(jitter->timestamp[i],best_time) || (jitter->timestamp[i]==best_time && GT32(jitter->span[i],best_span))) | 597 | if (!found || LT32(jitter->packets[i].timestamp,best_time) || (jitter->packets[i].timestamp==best_time && GT32(jitter->packets[i].span,best_span))) |
349 | { | 598 | { |
350 | best_time = jitter->timestamp[i]; | 599 | best_time = jitter->packets[i].timestamp; |
351 | best_span = jitter->span[i]; | 600 | best_span = jitter->packets[i].span; |
352 | besti = i; | 601 | besti = i; |
353 | found = 1; | 602 | found = 1; |
354 | } | 603 | } |
@@ -358,31 +607,62 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
358 | { | 607 | { |
359 | i=besti; | 608 | i=besti; |
360 | incomplete = 1; | 609 | incomplete = 1; |
361 | /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp, chunk_size, jitter->span[i]);*/ | 610 | /*fprintf (stderr, "incomplete: %d %d %d %d\n", jitter->packets[i].timestamp, jitter->pointer_timestamp, chunk_size, jitter->packets[i].span);*/ |
362 | } | 611 | } |
363 | } | 612 | } |
364 | 613 | ||
365 | /* If we find something */ | 614 | /* If we find something */ |
366 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) | 615 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) |
367 | { | 616 | { |
617 | |||
618 | |||
368 | /* We (obviously) haven't lost this packet */ | 619 | /* We (obviously) haven't lost this packet */ |
369 | jitter->lost_count = 0; | 620 | jitter->lost_count = 0; |
370 | jitter->loss_rate = .999*jitter->loss_rate; | 621 | jitter->loss_rate = .999*jitter->loss_rate; |
371 | /* Check for potential overflow */ | 622 | |
372 | packet->len = jitter->len[i]; | 623 | /* In this case, 0 isn't as a valid timestamp */ |
624 | if (jitter->arrival[i] != 0) | ||
625 | { | ||
626 | spx_int32_t arrival_margin; | ||
627 | /*fprintf(stderr, "early by %d\n", jitter->packets[i].timestamp - jitter->arrival[i]);*/ | ||
628 | |||
629 | /* The arrival margin is how much in advance (or in this case late) the packet it (in resolution units) */ | ||
630 | arrival_margin = (((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]))/jitter->resolution - jitter->buffer_margin; | ||
631 | |||
632 | /*fprintf(stderr, "get arrival_margin = %d\n", arrival_margin);*/ | ||
633 | |||
634 | /*update_timings(jitter, ((spx_int32_t)jitter->packets[i].timestamp) - ((spx_int32_t)jitter->arrival[i]));*/ | ||
635 | |||
636 | update_histogram(jitter, arrival_margin); | ||
637 | |||
638 | } | ||
639 | |||
640 | |||
641 | /* FIXME: Check for potential overflow */ | ||
642 | packet->len = jitter->packets[i].len; | ||
373 | /* Copy packet */ | 643 | /* Copy packet */ |
374 | for (j=0;j<packet->len;j++) | 644 | if (jitter->destroy) |
375 | packet->data[j] = jitter->buf[i][j]; | 645 | { |
376 | /* Remove packet */ | 646 | packet->data = jitter->packets[i].data; |
377 | speex_free(jitter->buf[i]); | 647 | } else { |
378 | jitter->buf[i] = NULL; | 648 | for (j=0;j<packet->len;j++) |
649 | packet->data[j] = jitter->packets[i].data[j]; | ||
650 | /* Remove packet */ | ||
651 | speex_free(jitter->packets[i].data); | ||
652 | } | ||
653 | jitter->packets[i].data = NULL; | ||
379 | /* Set timestamp and span (if requested) */ | 654 | /* Set timestamp and span (if requested) */ |
380 | if (start_offset) | 655 | if (start_offset) |
381 | *start_offset = (spx_int32_t)jitter->timestamp[i]-(spx_int32_t)jitter->pointer_timestamp; | 656 | *start_offset = (spx_int32_t)jitter->packets[i].timestamp-(spx_int32_t)jitter->pointer_timestamp; |
382 | packet->timestamp = jitter->timestamp[i]; | 657 | |
383 | packet->span = jitter->span[i]; | 658 | packet->timestamp = jitter->packets[i].timestamp; |
384 | /* Point at the end of the current packet */ | 659 | jitter->last_returned_timestamp = packet->timestamp; |
385 | jitter->pointer_timestamp = jitter->timestamp[i]+jitter->span[i]; | 660 | |
661 | packet->span = jitter->packets[i].span; | ||
662 | packet->user_data = jitter->packets[i].user_data; | ||
663 | /* Point to the end of the current packet */ | ||
664 | jitter->pointer_timestamp = jitter->packets[i].timestamp+jitter->packets[i].span; | ||
665 | |||
386 | if (incomplete) | 666 | if (incomplete) |
387 | return JITTER_BUFFER_INCOMPLETE; | 667 | return JITTER_BUFFER_INCOMPLETE; |
388 | else | 668 | else |
@@ -391,6 +671,7 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
391 | 671 | ||
392 | 672 | ||
393 | /* If we haven't found anything worth returning */ | 673 | /* If we haven't found anything worth returning */ |
674 | |||
394 | /*fprintf (stderr, "not found\n");*/ | 675 | /*fprintf (stderr, "not found\n");*/ |
395 | jitter->lost_count++; | 676 | jitter->lost_count++; |
396 | /*fprintf (stderr, "m");*/ | 677 | /*fprintf (stderr, "m");*/ |
@@ -398,34 +679,71 @@ int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int3 | |||
398 | jitter->loss_rate = .999*jitter->loss_rate + .001; | 679 | jitter->loss_rate = .999*jitter->loss_rate + .001; |
399 | if (start_offset) | 680 | if (start_offset) |
400 | *start_offset = 0; | 681 | *start_offset = 0; |
401 | packet->timestamp = jitter->pointer_timestamp; | ||
402 | packet->span = jitter->tick_size; | ||
403 | jitter->pointer_timestamp += chunk_size; | ||
404 | packet->len = 0; | ||
405 | 682 | ||
406 | /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ | 683 | compute_statistics(jitter); |
407 | if (late_ratio_short > .1 || late_ratio_long > .03) | 684 | |
685 | /* Should we force an increase in the buffer or just do normal interpolation? */ | ||
686 | if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03) | ||
408 | { | 687 | { |
409 | /* If too many packets are arriving late */ | 688 | /* Increase buffering */ |
410 | jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; | 689 | |
411 | jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; | 690 | /* Shift histogram to compensate */ |
412 | for (i=MAX_MARGIN-3;i>=0;i--) | 691 | shift_histogram(jitter, jitter->res_delay_step); |
413 | { | 692 | |
414 | jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; | 693 | packet->timestamp = jitter->pointer_timestamp; |
415 | jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; | 694 | packet->span = jitter->delay_step; |
416 | } | 695 | /* Don't move the pointer_timestamp forward */ |
417 | jitter->shortterm_margin[0] = 0; | 696 | packet->len = 0; |
418 | jitter->longterm_margin[0] = 0; | 697 | |
419 | jitter->pointer_timestamp -= jitter->tick_size; | 698 | /*jitter->pointer_timestamp -= jitter->delay_step;*/ |
420 | jitter->current_timestamp -= jitter->tick_size; | 699 | /*fprintf (stderr, "Forced to interpolate\n");*/ |
421 | /*fprintf (stderr, "i");*/ | 700 | } else { |
422 | /*fprintf (stderr, "interpolate (getting some slack)\n");*/ | 701 | /* Normal packet loss */ |
702 | packet->timestamp = jitter->pointer_timestamp; | ||
703 | packet->span = desired_span; | ||
704 | jitter->pointer_timestamp += desired_span; | ||
705 | packet->len = 0; | ||
706 | /*fprintf (stderr, "Normal loss\n");*/ | ||
423 | } | 707 | } |
424 | 708 | ||
425 | return JITTER_BUFFER_MISSING; | 709 | return JITTER_BUFFER_MISSING; |
426 | 710 | ||
427 | } | 711 | } |
428 | 712 | ||
713 | int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet) | ||
714 | { | ||
715 | int i, j; | ||
716 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | ||
717 | { | ||
718 | if (jitter->packets[i].data && jitter->packets[i].timestamp==jitter->last_returned_timestamp) | ||
719 | break; | ||
720 | } | ||
721 | if (i!=SPEEX_JITTER_MAX_BUFFER_SIZE) | ||
722 | { | ||
723 | /* Copy packet */ | ||
724 | packet->len = jitter->packets[i].len; | ||
725 | if (jitter->destroy) | ||
726 | { | ||
727 | packet->data = jitter->packets[i].data; | ||
728 | } else { | ||
729 | for (j=0;j<packet->len;j++) | ||
730 | packet->data[j] = jitter->packets[i].data[j]; | ||
731 | /* Remove packet */ | ||
732 | speex_free(jitter->packets[i].data); | ||
733 | } | ||
734 | jitter->packets[i].data = NULL; | ||
735 | packet->timestamp = jitter->packets[i].timestamp; | ||
736 | packet->span = jitter->packets[i].span; | ||
737 | packet->user_data = jitter->packets[i].user_data; | ||
738 | return JITTER_BUFFER_OK; | ||
739 | } else { | ||
740 | packet->data = NULL; | ||
741 | packet->len = 0; | ||
742 | packet->span = 0; | ||
743 | return JITTER_BUFFER_MISSING; | ||
744 | } | ||
745 | } | ||
746 | |||
429 | /** Get pointer timestamp of jitter buffer */ | 747 | /** Get pointer timestamp of jitter buffer */ |
430 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | 748 | int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) |
431 | { | 749 | { |
@@ -434,81 +752,39 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter) | |||
434 | 752 | ||
435 | void jitter_buffer_tick(JitterBuffer *jitter) | 753 | void jitter_buffer_tick(JitterBuffer *jitter) |
436 | { | 754 | { |
437 | jitter->current_timestamp += jitter->tick_size; | 755 | jitter->next_stop = jitter->pointer_timestamp; |
756 | } | ||
757 | |||
758 | void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem) | ||
759 | { | ||
760 | jitter->next_stop = jitter->pointer_timestamp - rem; | ||
438 | } | 761 | } |
439 | 762 | ||
440 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ | 763 | /* Let the jitter buffer know it's the right time to adjust the buffering delay to the network conditions */ |
441 | int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) | 764 | int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset) |
442 | { | 765 | { |
443 | int i; | 766 | int i; |
444 | float late_ratio_short; | ||
445 | float late_ratio_long; | ||
446 | float ontime_ratio_short; | ||
447 | float ontime_ratio_long; | ||
448 | float early_ratio_short; | ||
449 | float early_ratio_long; | ||
450 | 767 | ||
451 | if (LT32(jitter->current_timestamp+jitter->tick_size, jitter->pointer_timestamp)) | 768 | compute_statistics(jitter); |
452 | { | ||
453 | jitter->current_timestamp = jitter->pointer_timestamp; | ||
454 | speex_warning("did you forget to call jitter_buffer_tick() by any chance?"); | ||
455 | } | ||
456 | /*fprintf (stderr, "get packet %d %d\n", jitter->pointer_timestamp, jitter->current_timestamp);*/ | ||
457 | 769 | ||
458 | /* FIXME: This should be only what remaining of the current tick */ | ||
459 | late_ratio_short = 0; | ||
460 | late_ratio_long = 0; | ||
461 | /* Count the proportion of packets that are late */ | ||
462 | for (i=0;i<LATE_BINS;i++) | ||
463 | { | ||
464 | late_ratio_short += jitter->shortterm_margin[i]; | ||
465 | late_ratio_long += jitter->longterm_margin[i]; | ||
466 | } | ||
467 | /* Count the proportion of packets that are just on time */ | ||
468 | ontime_ratio_short = jitter->shortterm_margin[LATE_BINS]; | ||
469 | ontime_ratio_long = jitter->longterm_margin[LATE_BINS]; | ||
470 | early_ratio_short = early_ratio_long = 0; | ||
471 | /* Count the proportion of packets that are early */ | ||
472 | for (i=LATE_BINS+1;i<MAX_MARGIN;i++) | ||
473 | { | ||
474 | early_ratio_short += jitter->shortterm_margin[i]; | ||
475 | early_ratio_long += jitter->longterm_margin[i]; | ||
476 | } | ||
477 | |||
478 | /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ | 770 | /* Adjusting the buffering bssed on the amount of packets that are early/on time/late */ |
479 | if (late_ratio_short > .1 || late_ratio_long > .03) | 771 | if (jitter->late_ratio_short > .1 || jitter->late_ratio_long > .03) |
480 | { | 772 | { |
481 | /* If too many packets are arriving late */ | 773 | /* If too many packets are arriving late */ |
482 | jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2]; | 774 | shift_histogram(jitter, jitter->res_delay_step); |
483 | jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2]; | 775 | |
484 | for (i=MAX_MARGIN-3;i>=0;i--) | 776 | jitter->pointer_timestamp -= jitter->delay_step; |
485 | { | ||
486 | jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i]; | ||
487 | jitter->longterm_margin[i+1] = jitter->longterm_margin[i]; | ||
488 | } | ||
489 | jitter->shortterm_margin[0] = 0; | ||
490 | jitter->longterm_margin[0] = 0; | ||
491 | jitter->pointer_timestamp -= jitter->tick_size; | ||
492 | jitter->current_timestamp -= jitter->tick_size; | ||
493 | jitter->interp_requested = 1; | 777 | jitter->interp_requested = 1; |
778 | /*fprintf (stderr, "Decision to interpolate\n");*/ | ||
494 | return JITTER_BUFFER_ADJUST_INTERPOLATE; | 779 | return JITTER_BUFFER_ADJUST_INTERPOLATE; |
495 | 780 | ||
496 | } else if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8) | 781 | } 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) |
497 | { | 782 | { |
498 | /* Many frames arriving early */ | 783 | /* Many frames arriving early */ |
499 | jitter->shortterm_margin[0] += jitter->shortterm_margin[1]; | 784 | shift_histogram(jitter, -jitter->res_delay_step); |
500 | jitter->longterm_margin[0] += jitter->longterm_margin[1]; | 785 | |
501 | for (i=1;i<MAX_MARGIN-1;i++) | 786 | jitter->pointer_timestamp += jitter->delay_step; |
502 | { | 787 | /*fprintf (stderr, "Decision to drop\n");*/ |
503 | jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1]; | ||
504 | jitter->longterm_margin[i] = jitter->longterm_margin[i+1]; | ||
505 | } | ||
506 | jitter->shortterm_margin[MAX_MARGIN-1] = 0; | ||
507 | jitter->longterm_margin[MAX_MARGIN-1] = 0; | ||
508 | /*fprintf (stderr, "drop frame\n");*/ | ||
509 | /*fprintf (stderr, "d");*/ | ||
510 | jitter->pointer_timestamp += jitter->tick_size; | ||
511 | jitter->current_timestamp += jitter->tick_size; | ||
512 | return JITTER_BUFFER_ADJUST_DROP; | 788 | return JITTER_BUFFER_ADJUST_DROP; |
513 | } | 789 | } |
514 | 790 | ||
@@ -531,13 +807,26 @@ int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr) | |||
531 | count = 0; | 807 | count = 0; |
532 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) | 808 | for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++) |
533 | { | 809 | { |
534 | if (jitter->buf[i] && LE32(jitter->pointer_timestamp, jitter->timestamp[i])) | 810 | if (jitter->packets[i].data && LE32(jitter->pointer_timestamp, jitter->packets[i].timestamp)) |
535 | { | 811 | { |
536 | count++; | 812 | count++; |
537 | } | 813 | } |
538 | } | 814 | } |
539 | *(spx_int32_t*)ptr = count; | 815 | *(spx_int32_t*)ptr = count; |
540 | break; | 816 | break; |
817 | case JITTER_BUFFER_SET_DESTROY_CALLBACK: | ||
818 | jitter->destroy = (void (*) (void *))ptr; | ||
819 | break; | ||
820 | case JITTER_BUFFER_GET_DESTROY_CALLBACK: | ||
821 | *(void (**) (void *))ptr = jitter->destroy; | ||
822 | break; | ||
823 | case JITTER_BUFFER_SET_DELAY_STEP: | ||
824 | jitter->delay_step = *(spx_int32_t*)ptr; | ||
825 | jitter->res_delay_step = jitter->delay_step/jitter->resolution; | ||
826 | break; | ||
827 | case JITTER_BUFFER_GET_DELAY_STEP: | ||
828 | *(spx_int32_t*)ptr = jitter->delay_step; | ||
829 | break; | ||
541 | default: | 830 | default: |
542 | speex_warning_int("Unknown jitter_buffer_ctl request: ", request); | 831 | speex_warning_int("Unknown jitter_buffer_ctl request: ", request); |
543 | return -1; | 832 | return -1; |
diff --git a/apps/codecs/libspeex/kiss_fft.c b/apps/codecs/libspeex/kiss_fft.c index 599ba66845..775edfff36 100644 --- a/apps/codecs/libspeex/kiss_fft.c +++ b/apps/codecs/libspeex/kiss_fft.c | |||
@@ -19,7 +19,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | #include "_kiss_fft_guts.h" | 21 | #include "_kiss_fft_guts.h" |
22 | #include "misc.h" | 22 | #include "arch.h" |
23 | #include "os_support.h" | 23 | #include "os_support.h" |
24 | 24 | ||
25 | /* The guts header contains all the multiplication and addition macros that are defined for | 25 | /* The guts header contains all the multiplication and addition macros that are defined for |
diff --git a/apps/codecs/libspeex/kiss_fft.h b/apps/codecs/libspeex/kiss_fft.h index 54627e7da0..fa3f2c6042 100644 --- a/apps/codecs/libspeex/kiss_fft.h +++ b/apps/codecs/libspeex/kiss_fft.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | #include <math.h> | 5 | #include <math.h> |
6 | #include "misc.h" | 6 | #include "arch.h" |
7 | 7 | ||
8 | #ifdef __cplusplus | 8 | #ifdef __cplusplus |
9 | extern "C" { | 9 | extern "C" { |
@@ -32,7 +32,7 @@ extern "C" { | |||
32 | 32 | ||
33 | 33 | ||
34 | #ifdef FIXED_POINT | 34 | #ifdef FIXED_POINT |
35 | #include "misc.h" | 35 | #include "arch.h" |
36 | # define kiss_fft_scalar spx_int16_t | 36 | # define kiss_fft_scalar spx_int16_t |
37 | #else | 37 | #else |
38 | # ifndef kiss_fft_scalar | 38 | # ifndef kiss_fft_scalar |
diff --git a/apps/codecs/libspeex/lpc.h b/apps/codecs/libspeex/lpc.h index d64df96741..952ecdd933 100644 --- a/apps/codecs/libspeex/lpc.h +++ b/apps/codecs/libspeex/lpc.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #ifndef LPC_H | 35 | #ifndef LPC_H |
36 | #define LPC_H | 36 | #define LPC_H |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | 39 | ||
40 | void _spx_autocorr( | 40 | void _spx_autocorr( |
41 | const spx_word16_t * x, /* in: [0...n-1] samples x */ | 41 | const spx_word16_t * x, /* in: [0...n-1] samples x */ |
diff --git a/apps/codecs/libspeex/lsp.h b/apps/codecs/libspeex/lsp.h index 9d0345f426..648652fb9e 100644 --- a/apps/codecs/libspeex/lsp.h +++ b/apps/codecs/libspeex/lsp.h | |||
@@ -51,7 +51,7 @@ Modified by Jean-Marc Valin | |||
51 | #ifndef __AK2LSPD__ | 51 | #ifndef __AK2LSPD__ |
52 | #define __AK2LSPD__ | 52 | #define __AK2LSPD__ |
53 | 53 | ||
54 | #include "misc.h" | 54 | #include "arch.h" |
55 | 55 | ||
56 | int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); | 56 | int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack); |
57 | void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); | 57 | void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack); |
diff --git a/apps/codecs/libspeex/ltp.h b/apps/codecs/libspeex/ltp.h index bc050c6392..1e435bc36e 100644 --- a/apps/codecs/libspeex/ltp.h +++ b/apps/codecs/libspeex/ltp.h | |||
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <speex/speex_bits.h> | 35 | #include <speex/speex_bits.h> |
36 | #include "misc.h" | 36 | #include "arch.h" |
37 | 37 | ||
38 | /** LTP parameters. */ | 38 | /** LTP parameters. */ |
39 | typedef struct { | 39 | typedef struct { |
diff --git a/apps/codecs/libspeex/math.h b/apps/codecs/libspeex/math.h deleted file mode 100644 index 5c1781df52..0000000000 --- a/apps/codecs/libspeex/math.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2007 Dan Everton | ||
10 | * | ||
11 | * All files in this archive are subject to the GNU General Public License. | ||
12 | * See the file COPYING in the source tree root for full license agreement. | ||
13 | * | ||
14 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
15 | * KIND, either express or implied. | ||
16 | * | ||
17 | ***************************************************************************/ | ||
18 | |||
19 | #ifndef MATH_H | ||
20 | #define MATH_H | ||
21 | |||
22 | float floor(float); | ||
23 | float exp(float); | ||
24 | float sqrt(float); | ||
25 | float fabs(float); | ||
26 | float log(float); | ||
27 | float pow(float, float); | ||
28 | float sin(float); | ||
29 | float cos(float); | ||
30 | |||
31 | #endif | ||
32 | |||
diff --git a/apps/codecs/libspeex/math_approx.h b/apps/codecs/libspeex/math_approx.h index 4f61e8645a..9ca830755d 100644 --- a/apps/codecs/libspeex/math_approx.h +++ b/apps/codecs/libspeex/math_approx.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #ifndef MATH_APPROX_H | 35 | #ifndef MATH_APPROX_H |
36 | #define MATH_APPROX_H | 36 | #define MATH_APPROX_H |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | 39 | ||
40 | #ifndef FIXED_POINT | 40 | #ifndef FIXED_POINT |
41 | 41 | ||
diff --git a/apps/codecs/libspeex/mdf.c b/apps/codecs/libspeex/mdf.c index 8840c34e08..2e863cf274 100644 --- a/apps/codecs/libspeex/mdf.c +++ b/apps/codecs/libspeex/mdf.c | |||
@@ -69,7 +69,7 @@ | |||
69 | #include "config-speex.h" | 69 | #include "config-speex.h" |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #include "misc.h" | 72 | #include "arch.h" |
73 | #include "speex/speex_echo.h" | 73 | #include "speex/speex_echo.h" |
74 | #include "fftwrap.h" | 74 | #include "fftwrap.h" |
75 | #include "pseudofloat.h" | 75 | #include "pseudofloat.h" |
diff --git a/apps/codecs/libspeex/medfilter.c b/apps/codecs/libspeex/medfilter.c index e4bc1c6ce9..57f403f00a 100644 --- a/apps/codecs/libspeex/medfilter.c +++ b/apps/codecs/libspeex/medfilter.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | #include "medfilter.h" | 39 | #include "medfilter.h" |
40 | #include "misc.h" | 40 | #include "arch.h" |
41 | 41 | ||
42 | MedianFilter *median_filter_new(int N) | 42 | MedianFilter *median_filter_new(int N) |
43 | { | 43 | { |
diff --git a/apps/codecs/libspeex/misc.h b/apps/codecs/libspeex/misc.h deleted file mode 100644 index 7dcc4f25f9..0000000000 --- a/apps/codecs/libspeex/misc.h +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | /* Copyright (C) 2002 Jean-Marc Valin */ | ||
2 | /** | ||
3 | @file misc.h | ||
4 | @brief Various compatibility routines for Speex | ||
5 | */ | ||
6 | /* | ||
7 | Redistribution and use in source and binary forms, with or without | ||
8 | modification, are permitted provided that the following conditions | ||
9 | are met: | ||
10 | |||
11 | - Redistributions of source code must retain the above copyright | ||
12 | notice, this list of conditions and the following disclaimer. | ||
13 | |||
14 | - Redistributions in binary form must reproduce the above copyright | ||
15 | notice, this list of conditions and the following disclaimer in the | ||
16 | documentation and/or other materials provided with the distribution. | ||
17 | |||
18 | - Neither the name of the Xiph.org Foundation nor the names of its | ||
19 | contributors may be used to endorse or promote products derived from | ||
20 | this software without specific prior written permission. | ||
21 | |||
22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
23 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR | ||
26 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
27 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
29 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
30 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
31 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
33 | */ | ||
34 | |||
35 | #ifndef MISC_H | ||
36 | #define MISC_H | ||
37 | |||
38 | #include "config-speex.h" | ||
39 | |||
40 | #ifndef SPEEX_VERSION | ||
41 | #define SPEEX_MAJOR_VERSION 1 /**< Major Speex version. */ | ||
42 | #define SPEEX_MINOR_VERSION 1 /**< Minor Speex version. */ | ||
43 | #define SPEEX_MICRO_VERSION 15 /**< Micro Speex version. */ | ||
44 | #define SPEEX_EXTRA_VERSION "" /**< Extra Speex version. */ | ||
45 | #define SPEEX_VERSION "speex-1.2beta3" /**< Speex version string. */ | ||
46 | #endif | ||
47 | |||
48 | /* A couple test to catch stupid option combinations */ | ||
49 | #ifdef FIXED_POINT | ||
50 | |||
51 | #ifdef _USE_SSE | ||
52 | #error SSE is only for floating-point | ||
53 | #endif | ||
54 | #if ((defined (ARM4_ASM)||defined (ARM4_ASM)) && defined(BFIN_ASM)) || (defined (ARM4_ASM)&&defined(ARM5E_ASM)) | ||
55 | #error Make up your mind. What CPU do you have? | ||
56 | #endif | ||
57 | #ifdef VORBIS_PSYCHO | ||
58 | #error Vorbis-psy model currently not implemented in fixed-point | ||
59 | #endif | ||
60 | |||
61 | #else | ||
62 | |||
63 | #if defined (ARM4_ASM) || defined(ARM5E_ASM) || defined(BFIN_ASM) | ||
64 | #error I suppose you can have a [ARM4/ARM5E/Blackfin] that has float instructions? | ||
65 | #endif | ||
66 | #ifdef FIXED_POINT_DEBUG | ||
67 | #error "Don't you think enabling fixed-point is a good thing to do if you want to debug that?" | ||
68 | #endif | ||
69 | |||
70 | |||
71 | #endif | ||
72 | |||
73 | #include "arch.h" | ||
74 | |||
75 | /** Convert little endian */ | ||
76 | static inline spx_int32_t le_int(spx_int32_t i) | ||
77 | { | ||
78 | #if 1 | ||
79 | return letoh32(i); | ||
80 | #elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) | ||
81 | spx_uint32_t ui, ret; | ||
82 | ui = i; | ||
83 | ret = ui>>24; | ||
84 | ret |= (ui>>8)&0x0000ff00; | ||
85 | ret |= (ui<<8)&0x00ff0000; | ||
86 | ret |= (ui<<24); | ||
87 | return ret; | ||
88 | #else | ||
89 | return i; | ||
90 | #endif | ||
91 | } | ||
92 | |||
93 | |||
94 | #ifdef FIXED_DEBUG | ||
95 | long long spx_mips=0; | ||
96 | #endif | ||
97 | |||
98 | |||
99 | #endif | ||
diff --git a/apps/codecs/libspeex/modes.c b/apps/codecs/libspeex/modes.c index cf4ef3246c..20ea287344 100644 --- a/apps/codecs/libspeex/modes.c +++ b/apps/codecs/libspeex/modes.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "sb_celp.h" | 43 | #include "sb_celp.h" |
44 | #include "nb_celp.h" | 44 | #include "nb_celp.h" |
45 | #include "vbr.h" | 45 | #include "vbr.h" |
46 | #include "misc.h" | 46 | #include "arch.h" |
47 | #include <math.h> | 47 | #include <math.h> |
48 | 48 | ||
49 | #ifndef NULL | 49 | #ifndef NULL |
@@ -439,7 +439,6 @@ static const SpeexNBMode nb_mode = { | |||
439 | #else | 439 | #else |
440 | 0.9, 0.6, /* gamma1, gamma2 */ | 440 | 0.9, 0.6, /* gamma1, gamma2 */ |
441 | #endif | 441 | #endif |
442 | .012, /*lag_factor*/ | ||
443 | QCONST16(.0002,15), /*lpc_floor*/ | 442 | QCONST16(.0002,15), /*lpc_floor*/ |
444 | {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7, | 443 | {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7, |
445 | &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, | 444 | &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, |
diff --git a/apps/codecs/libspeex/modes.h b/apps/codecs/libspeex/modes.h index 9ce674a498..d0ff842ffa 100644 --- a/apps/codecs/libspeex/modes.h +++ b/apps/codecs/libspeex/modes.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #include <speex/speex.h> | 39 | #include <speex/speex.h> |
40 | #include <speex/speex_bits.h> | 40 | #include <speex/speex_bits.h> |
41 | #include "misc.h" | 41 | #include "arch.h" |
42 | 42 | ||
43 | #define NB_SUBMODES 16 | 43 | #define NB_SUBMODES 16 |
44 | #define NB_SUBMODE_BITS 4 | 44 | #define NB_SUBMODE_BITS 4 |
@@ -123,7 +123,6 @@ typedef struct SpeexNBMode { | |||
123 | 123 | ||
124 | spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ | 124 | spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ |
125 | spx_word16_t gamma2; /**< Perceptual filter parameter #2 */ | 125 | spx_word16_t gamma2; /**< Perceptual filter parameter #2 */ |
126 | float lag_factor; /**< Lag-windowing parameter */ | ||
127 | spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ | 126 | spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ |
128 | 127 | ||
129 | const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ | 128 | const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ |
@@ -140,7 +139,6 @@ typedef struct SpeexSBMode { | |||
140 | int lpcSize; /**< Order of LPC filter */ | 139 | int lpcSize; /**< Order of LPC filter */ |
141 | spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ | 140 | spx_word16_t gamma1; /**< Perceptual filter parameter #1 */ |
142 | spx_word16_t gamma2; /**< Perceptual filter parameter #1 */ | 141 | spx_word16_t gamma2; /**< Perceptual filter parameter #1 */ |
143 | float lag_factor; /**< Lag-windowing parameter */ | ||
144 | spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ | 142 | spx_word16_t lpc_floor; /**< Noise floor for LPC analysis */ |
145 | spx_word16_t folding_gain; | 143 | spx_word16_t folding_gain; |
146 | 144 | ||
diff --git a/apps/codecs/libspeex/modes_wb.c b/apps/codecs/libspeex/modes_wb.c index 1684ba6493..af16cdd775 100644 --- a/apps/codecs/libspeex/modes_wb.c +++ b/apps/codecs/libspeex/modes_wb.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "sb_celp.h" | 43 | #include "sb_celp.h" |
44 | #include "nb_celp.h" | 44 | #include "nb_celp.h" |
45 | #include "vbr.h" | 45 | #include "vbr.h" |
46 | #include "misc.h" | 46 | #include "arch.h" |
47 | #include <math.h> | 47 | #include <math.h> |
48 | #include "os_support.h" | 48 | #include "os_support.h" |
49 | 49 | ||
@@ -231,7 +231,6 @@ static const SpeexSBMode sb_wb_mode = { | |||
231 | #else | 231 | #else |
232 | 0.9, 0.6, /* gamma1, gamma2 */ | 232 | 0.9, 0.6, /* gamma1, gamma2 */ |
233 | #endif | 233 | #endif |
234 | .012, /*lag_factor*/ | ||
235 | QCONST16(.0002,15), /*lpc_floor*/ | 234 | QCONST16(.0002,15), /*lpc_floor*/ |
236 | QCONST16(0.9f,15), | 235 | QCONST16(0.9f,15), |
237 | {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL}, | 236 | {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL}, |
@@ -291,7 +290,6 @@ static const SpeexSBMode sb_uwb_mode = { | |||
291 | #else | 290 | #else |
292 | 0.9, 0.6, /* gamma1, gamma2 */ | 291 | 0.9, 0.6, /* gamma1, gamma2 */ |
293 | #endif | 292 | #endif |
294 | .012, /*lag_factor*/ | ||
295 | QCONST16(.0002,15), /*lpc_floor*/ | 293 | QCONST16(.0002,15), /*lpc_floor*/ |
296 | QCONST16(0.7f,15), | 294 | QCONST16(0.7f,15), |
297 | {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL}, | 295 | {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL}, |
diff --git a/apps/codecs/libspeex/nb_celp.c b/apps/codecs/libspeex/nb_celp.c index 7dc4920ede..49e2403d8b 100644 --- a/apps/codecs/libspeex/nb_celp.c +++ b/apps/codecs/libspeex/nb_celp.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include "vq.h" | 45 | #include "vq.h" |
46 | #include <speex/speex_bits.h> | 46 | #include <speex/speex_bits.h> |
47 | #include "vbr.h" | 47 | #include "vbr.h" |
48 | #include "misc.h" | 48 | #include "arch.h" |
49 | #include "math_approx.h" | 49 | #include "math_approx.h" |
50 | #include "os_support.h" | 50 | #include "os_support.h" |
51 | #include <speex/speex_callbacks.h> | 51 | #include <speex/speex_callbacks.h> |
@@ -108,6 +108,7 @@ const float exc_gain_quant_scal1[2]={0.70469f, 1.05127f}; | |||
108 | 108 | ||
109 | #define sqr(x) ((x)*(x)) | 109 | #define sqr(x) ((x)*(x)) |
110 | 110 | ||
111 | extern const spx_word16_t lag_window[]; | ||
111 | extern const spx_word16_t lpc_window[]; | 112 | extern const spx_word16_t lpc_window[]; |
112 | #ifndef SPEEX_DISABLE_ENCODER | 113 | #ifndef SPEEX_DISABLE_ENCODER |
113 | void *nb_encoder_init(const SpeexMode *m) | 114 | void *nb_encoder_init(const SpeexMode *m) |
@@ -137,7 +138,6 @@ void *nb_encoder_init(const SpeexMode *m) | |||
137 | st->gamma2=mode->gamma2; | 138 | st->gamma2=mode->gamma2; |
138 | st->min_pitch=mode->pitchStart; | 139 | st->min_pitch=mode->pitchStart; |
139 | st->max_pitch=mode->pitchEnd; | 140 | st->max_pitch=mode->pitchEnd; |
140 | st->lag_factor=mode->lag_factor; | ||
141 | st->lpc_floor = mode->lpc_floor; | 141 | st->lpc_floor = mode->lpc_floor; |
142 | 142 | ||
143 | st->submodes=mode->submodes; | 143 | st->submodes=mode->submodes; |
@@ -166,17 +166,13 @@ void *nb_encoder_init(const SpeexMode *m) | |||
166 | st->window= lpc_window; | 166 | st->window= lpc_window; |
167 | 167 | ||
168 | /* Create the window for autocorrelation (lag-windowing) */ | 168 | /* Create the window for autocorrelation (lag-windowing) */ |
169 | st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); | 169 | st->lagWindow = lag_window; |
170 | for (i=0;i<st->lpcSize+1;i++) | ||
171 | st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i)); | ||
172 | 170 | ||
173 | st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); | 171 | st->old_lsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); |
174 | st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); | 172 | st->old_qlsp = (spx_lsp_t*)speex_alloc((st->lpcSize)*sizeof(spx_lsp_t)); |
175 | st->first = 1; | 173 | st->first = 1; |
176 | for (i=0;i<st->lpcSize;i++) | 174 | for (i=0;i<st->lpcSize;i++) |
177 | { | 175 | st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); |
178 | st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1); | ||
179 | } | ||
180 | 176 | ||
181 | st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); | 177 | st->mem_sp = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); |
182 | st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); | 178 | st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); |
@@ -225,8 +221,6 @@ void nb_encoder_destroy(void *state) | |||
225 | speex_free (st->old_qlsp); | 221 | speex_free (st->old_qlsp); |
226 | speex_free (st->swBuf); | 222 | speex_free (st->swBuf); |
227 | 223 | ||
228 | speex_free (st->lagWindow); | ||
229 | |||
230 | speex_free (st->old_lsp); | 224 | speex_free (st->old_lsp); |
231 | speex_free (st->mem_sp); | 225 | speex_free (st->mem_sp); |
232 | speex_free (st->mem_sw); | 226 | speex_free (st->mem_sw); |
@@ -274,7 +268,7 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) | |||
274 | char *stack; | 268 | char *stack; |
275 | VARDECL(spx_word16_t *syn_resp); | 269 | VARDECL(spx_word16_t *syn_resp); |
276 | VARDECL(spx_word16_t *real_exc); | 270 | VARDECL(spx_word16_t *real_exc); |
277 | 271 | ||
278 | spx_word32_t ener=0; | 272 | spx_word32_t ener=0; |
279 | spx_word16_t fine_gain; | 273 | spx_word16_t fine_gain; |
280 | spx_word16_t *in = (spx_word16_t*)vin; | 274 | spx_word16_t *in = (spx_word16_t*)vin; |
@@ -591,6 +585,8 @@ int nb_encode(void *state, void *vin, SpeexBits *bits) | |||
591 | if (SUBMODE(forced_pitch_gain)) | 585 | if (SUBMODE(forced_pitch_gain)) |
592 | { | 586 | { |
593 | int quant; | 587 | int quant; |
588 | /* This just damps the pitch a bit, because it tends to be too aggressive when forced */ | ||
589 | ol_pitch_coef = MULT16_16_Q15(QCONST16(.9,15), ol_pitch_coef); | ||
594 | #ifdef FIXED_POINT | 590 | #ifdef FIXED_POINT |
595 | quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT); | 591 | quant = PSHR16(MULT16_16_16(15, ol_pitch_coef),GAIN_SHIFT); |
596 | #else | 592 | #else |
@@ -1120,7 +1116,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout) | |||
1120 | VARDECL(spx_coef_t *ak); | 1116 | VARDECL(spx_coef_t *ak); |
1121 | VARDECL(spx_lsp_t *qlsp); | 1117 | VARDECL(spx_lsp_t *qlsp); |
1122 | spx_word16_t pitch_average=0; | 1118 | spx_word16_t pitch_average=0; |
1123 | 1119 | ||
1124 | spx_word16_t *out = (spx_word16_t*)vout; | 1120 | spx_word16_t *out = (spx_word16_t*)vout; |
1125 | VARDECL(spx_lsp_t *interp_qlsp); | 1121 | VARDECL(spx_lsp_t *interp_qlsp); |
1126 | 1122 | ||
@@ -1724,7 +1720,7 @@ int nb_encoder_ctl(void *state, int request, void *ptr) | |||
1724 | st->bounded_pitch = 1; | 1720 | st->bounded_pitch = 1; |
1725 | st->first = 1; | 1721 | st->first = 1; |
1726 | for (i=0;i<st->lpcSize;i++) | 1722 | for (i=0;i<st->lpcSize;i++) |
1727 | st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); | 1723 | st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); |
1728 | for (i=0;i<st->lpcSize;i++) | 1724 | for (i=0;i<st->lpcSize;i++) |
1729 | st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; | 1725 | st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; |
1730 | for (i=0;i<st->frameSize+st->max_pitch+1;i++) | 1726 | for (i=0;i<st->frameSize+st->max_pitch+1;i++) |
diff --git a/apps/codecs/libspeex/nb_celp.h b/apps/codecs/libspeex/nb_celp.h index 28ee9325a1..7f90f7c05c 100644 --- a/apps/codecs/libspeex/nb_celp.h +++ b/apps/codecs/libspeex/nb_celp.h | |||
@@ -73,7 +73,6 @@ typedef struct EncState { | |||
73 | 73 | ||
74 | spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */ | 74 | spx_word16_t gamma1; /**< Perceptual filter: A(z/gamma1) */ |
75 | spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */ | 75 | spx_word16_t gamma2; /**< Perceptual filter: A(z/gamma2) */ |
76 | float lag_factor; /**< Lag windowing Gaussian width */ | ||
77 | spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ | 76 | spx_word16_t lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ |
78 | char *stack; /**< Pseudo-stack allocation for temporary memory */ | 77 | char *stack; /**< Pseudo-stack allocation for temporary memory */ |
79 | spx_word16_t *winBuf; /**< Input buffer (original signal) */ | 78 | spx_word16_t *winBuf; /**< Input buffer (original signal) */ |
@@ -82,7 +81,7 @@ typedef struct EncState { | |||
82 | spx_word16_t *swBuf; /**< Weighted signal buffer */ | 81 | spx_word16_t *swBuf; /**< Weighted signal buffer */ |
83 | spx_word16_t *sw; /**< Start of weighted signal frame */ | 82 | spx_word16_t *sw; /**< Start of weighted signal frame */ |
84 | const spx_word16_t *window; /**< Temporary (Hanning) window */ | 83 | const spx_word16_t *window; /**< Temporary (Hanning) window */ |
85 | spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ | 84 | const spx_word16_t *lagWindow; /**< Window applied to auto-correlation */ |
86 | spx_lsp_t *old_lsp; /**< LSPs for previous frame */ | 85 | spx_lsp_t *old_lsp; /**< LSPs for previous frame */ |
87 | spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */ | 86 | spx_lsp_t *old_qlsp; /**< Quantized LSPs for previous frame */ |
88 | spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */ | 87 | spx_mem_t *mem_sp; /**< Filter memory for signal synthesis */ |
diff --git a/apps/codecs/libspeex/oggframing.c b/apps/codecs/libspeex/oggframing.c index ab48de33c3..6a0ee21412 100644 --- a/apps/codecs/libspeex/oggframing.c +++ b/apps/codecs/libspeex/oggframing.c | |||
@@ -23,7 +23,7 @@ | |||
23 | //#include "config-tremor.h" | 23 | //#include "config-tremor.h" |
24 | #include <string.h> | 24 | #include <string.h> |
25 | #include "speex/ogg.h" | 25 | #include "speex/ogg.h" |
26 | #include "misc.h" | 26 | #include "arch.h" |
27 | 27 | ||
28 | /* A complete description of Ogg framing exists in docs/framing.html */ | 28 | /* A complete description of Ogg framing exists in docs/framing.html */ |
29 | 29 | ||
diff --git a/apps/codecs/libspeex/os_support.h b/apps/codecs/libspeex/os_support.h index 92262f1942..7e4b25b3d9 100644 --- a/apps/codecs/libspeex/os_support.h +++ b/apps/codecs/libspeex/os_support.h | |||
@@ -41,10 +41,14 @@ | |||
41 | #include <stdio.h> | 41 | #include <stdio.h> |
42 | #include <stdlib.h> | 42 | #include <stdlib.h> |
43 | 43 | ||
44 | /** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */ | 44 | /** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free |
45 | NOTE: speex_alloc needs to CLEAR THE MEMORY */ | ||
45 | #ifndef OVERRIDE_SPEEX_ALLOC | 46 | #ifndef OVERRIDE_SPEEX_ALLOC |
46 | static inline void *speex_alloc (int size) | 47 | static inline void *speex_alloc (int size) |
47 | { | 48 | { |
49 | /* WARNING: this is not equivalent to malloc(). If you want to use malloc() | ||
50 | or your own allocator, YOU NEED TO CLEAR THE MEMORY ALLOCATED. Otherwise | ||
51 | you will experience strange bugs */ | ||
48 | return calloc(size,1); | 52 | return calloc(size,1); |
49 | } | 53 | } |
50 | #endif | 54 | #endif |
@@ -53,6 +57,7 @@ static inline void *speex_alloc (int size) | |||
53 | #ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH | 57 | #ifndef OVERRIDE_SPEEX_ALLOC_SCRATCH |
54 | static inline void *speex_alloc_scratch (int size) | 58 | static inline void *speex_alloc_scratch (int size) |
55 | { | 59 | { |
60 | /* Scratch space doesn't need to be cleared */ | ||
56 | return calloc(size,1); | 61 | return calloc(size,1); |
57 | } | 62 | } |
58 | #endif | 63 | #endif |
diff --git a/apps/codecs/libspeex/preprocess.c b/apps/codecs/libspeex/preprocess.c index da2da4a599..5d5befe736 100644 --- a/apps/codecs/libspeex/preprocess.c +++ b/apps/codecs/libspeex/preprocess.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include <math.h> | 62 | #include <math.h> |
63 | #include "speex/speex_preprocess.h" | 63 | #include "speex/speex_preprocess.h" |
64 | #include "speex/speex_echo.h" | 64 | #include "speex/speex_echo.h" |
65 | #include "misc.h" | 65 | #include "arch.h" |
66 | #include "fftwrap.h" | 66 | #include "fftwrap.h" |
67 | #include "filterbank.h" | 67 | #include "filterbank.h" |
68 | #include "math_approx.h" | 68 | #include "math_approx.h" |
@@ -1127,16 +1127,16 @@ int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr) | |||
1127 | break; | 1127 | break; |
1128 | 1128 | ||
1129 | case SPEEX_PREPROCESS_SET_PROB_START: | 1129 | case SPEEX_PREPROCESS_SET_PROB_START: |
1130 | *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr)); | 1130 | *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); |
1131 | st->speech_prob_start = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100); | 1131 | st->speech_prob_start = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); |
1132 | break; | 1132 | break; |
1133 | case SPEEX_PREPROCESS_GET_PROB_START: | 1133 | case SPEEX_PREPROCESS_GET_PROB_START: |
1134 | (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); | 1134 | (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_start, 100); |
1135 | break; | 1135 | break; |
1136 | 1136 | ||
1137 | case SPEEX_PREPROCESS_SET_PROB_CONTINUE: | 1137 | case SPEEX_PREPROCESS_SET_PROB_CONTINUE: |
1138 | *(spx_int32_t*)ptr = MIN32(Q15_ONE,MAX32(0, *(spx_int32_t*)ptr)); | 1138 | *(spx_int32_t*)ptr = MIN32(100,MAX32(0, *(spx_int32_t*)ptr)); |
1139 | st->speech_prob_continue = DIV32_16(MULT16_16(32767,*(spx_int32_t*)ptr), 100); | 1139 | st->speech_prob_continue = DIV32_16(MULT16_16(Q15ONE,*(spx_int32_t*)ptr), 100); |
1140 | break; | 1140 | break; |
1141 | case SPEEX_PREPROCESS_GET_PROB_CONTINUE: | 1141 | case SPEEX_PREPROCESS_GET_PROB_CONTINUE: |
1142 | (*(spx_int32_t*)ptr) = MULT16_16_Q15(st->speech_prob_continue, 100); | 1142 | (*(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) | |||
1166 | case SPEEX_PREPROCESS_GET_ECHO_STATE: | 1166 | case SPEEX_PREPROCESS_GET_ECHO_STATE: |
1167 | ptr = (void*)st->echo_state; | 1167 | ptr = (void*)st->echo_state; |
1168 | break; | 1168 | break; |
1169 | #ifndef FIXED_POINT | ||
1170 | case SPEEX_PREPROCESS_GET_AGC_LOUDNESS: | ||
1171 | (*(spx_int32_t*)ptr) = pow(st->loudness, 1.0/LOUDNESS_EXP); | ||
1172 | break; | ||
1173 | #endif | ||
1169 | 1174 | ||
1170 | default: | 1175 | default: |
1171 | speex_warning_int("Unknown speex_preprocess_ctl request: ", request); | 1176 | speex_warning_int("Unknown speex_preprocess_ctl request: ", request); |
diff --git a/apps/codecs/libspeex/pseudofloat.h b/apps/codecs/libspeex/pseudofloat.h index a237e32620..448dd61ffe 100644 --- a/apps/codecs/libspeex/pseudofloat.h +++ b/apps/codecs/libspeex/pseudofloat.h | |||
@@ -44,7 +44,7 @@ | |||
44 | #ifndef PSEUDOFLOAT_H | 44 | #ifndef PSEUDOFLOAT_H |
45 | #define PSEUDOFLOAT_H | 45 | #define PSEUDOFLOAT_H |
46 | 46 | ||
47 | #include "misc.h" | 47 | #include "arch.h" |
48 | #include "os_support.h" | 48 | #include "os_support.h" |
49 | #include "math_approx.h" | 49 | #include "math_approx.h" |
50 | #include <math.h> | 50 | #include <math.h> |
diff --git a/apps/codecs/libspeex/quant_lsp.c b/apps/codecs/libspeex/quant_lsp.c index 10d5762017..441a257a49 100644 --- a/apps/codecs/libspeex/quant_lsp.c +++ b/apps/codecs/libspeex/quant_lsp.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #define M_PI 3.14159265358979323846 | 41 | #define M_PI 3.14159265358979323846 |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #include "misc.h" | 44 | #include "arch.h" |
45 | 45 | ||
46 | #ifdef BFIN_ASM | 46 | #ifdef BFIN_ASM |
47 | #include "quant_lsp_bfin.h" | 47 | #include "quant_lsp_bfin.h" |
diff --git a/apps/codecs/libspeex/quant_lsp.h b/apps/codecs/libspeex/quant_lsp.h index 828dffc4f5..3bf4d4021c 100644 --- a/apps/codecs/libspeex/quant_lsp.h +++ b/apps/codecs/libspeex/quant_lsp.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #define QUANT_LSP_H | 36 | #define QUANT_LSP_H |
37 | 37 | ||
38 | #include <speex/speex_bits.h> | 38 | #include <speex/speex_bits.h> |
39 | #include "misc.h" | 39 | #include "arch.h" |
40 | 40 | ||
41 | #define MAX_LSP_SIZE 20 | 41 | #define MAX_LSP_SIZE 20 |
42 | 42 | ||
diff --git a/apps/codecs/libspeex/resample.c b/apps/codecs/libspeex/resample.c index ae134ea783..82e85bef43 100644 --- a/apps/codecs/libspeex/resample.c +++ b/apps/codecs/libspeex/resample.c | |||
@@ -70,7 +70,7 @@ static void speex_free (void *ptr) {free(ptr);} | |||
70 | #else /* OUTSIDE_SPEEX */ | 70 | #else /* OUTSIDE_SPEEX */ |
71 | 71 | ||
72 | #include "speex/speex_resampler.h" | 72 | #include "speex/speex_resampler.h" |
73 | #include "misc.h" | 73 | #include "arch.h" |
74 | #include "os_support.h" | 74 | #include "os_support.h" |
75 | #endif /* OUTSIDE_SPEEX */ | 75 | #endif /* OUTSIDE_SPEEX */ |
76 | 76 | ||
diff --git a/apps/codecs/libspeex/sb_celp.c b/apps/codecs/libspeex/sb_celp.c index 3314f6b87e..192c873d9e 100644 --- a/apps/codecs/libspeex/sb_celp.c +++ b/apps/codecs/libspeex/sb_celp.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "quant_lsp.h" | 43 | #include "quant_lsp.h" |
44 | #include "vq.h" | 44 | #include "vq.h" |
45 | #include "ltp.h" | 45 | #include "ltp.h" |
46 | #include "misc.h" | 46 | #include "arch.h" |
47 | #include "math_approx.h" | 47 | #include "math_approx.h" |
48 | #include "os_support.h" | 48 | #include "os_support.h" |
49 | 49 | ||
@@ -183,6 +183,7 @@ static const float h0[64] = { | |||
183 | 183 | ||
184 | #endif | 184 | #endif |
185 | 185 | ||
186 | extern const spx_word16_t lag_window[]; | ||
186 | extern const spx_word16_t lpc_window[]; | 187 | extern const spx_word16_t lpc_window[]; |
187 | 188 | ||
188 | #ifndef SPEEX_DISABLE_ENCODER | 189 | #ifndef SPEEX_DISABLE_ENCODER |
@@ -224,7 +225,6 @@ void *sb_encoder_init(const SpeexMode *m) | |||
224 | tmp=1; | 225 | tmp=1; |
225 | speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp); | 226 | speex_encoder_ctl(st->st_low, SPEEX_SET_WIDEBAND, &tmp); |
226 | 227 | ||
227 | st->lag_factor = mode->lag_factor; | ||
228 | st->lpc_floor = mode->lpc_floor; | 228 | st->lpc_floor = mode->lpc_floor; |
229 | st->gamma1=mode->gamma1; | 229 | st->gamma1=mode->gamma1; |
230 | st->gamma2=mode->gamma2; | 230 | st->gamma2=mode->gamma2; |
@@ -237,9 +237,7 @@ void *sb_encoder_init(const SpeexMode *m) | |||
237 | 237 | ||
238 | st->window= lpc_window; | 238 | st->window= lpc_window; |
239 | 239 | ||
240 | st->lagWindow = (spx_word16_t*)speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t)); | 240 | st->lagWindow = lag_window; |
241 | for (i=0;i<st->lpcSize+1;i++) | ||
242 | st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i)); | ||
243 | 241 | ||
244 | st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); | 242 | st->old_lsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); |
245 | st->old_qlsp = (spx_lsp_t*)speex_alloc(st->lpcSize*sizeof(spx_lsp_t)); | 243 | 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) | |||
253 | st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); | 251 | st->mem_sw = (spx_mem_t*)speex_alloc((st->lpcSize)*sizeof(spx_mem_t)); |
254 | 252 | ||
255 | for (i=0;i<st->lpcSize;i++) | 253 | for (i=0;i<st->lpcSize;i++) |
256 | { | 254 | st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); |
257 | st->old_lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1); | ||
258 | } | ||
259 | 255 | ||
260 | st->vbr_quality = 8; | 256 | st->vbr_quality = 8; |
261 | st->vbr_enabled = 0; | 257 | st->vbr_enabled = 0; |
@@ -288,8 +284,6 @@ void sb_encoder_destroy(void *state) | |||
288 | speex_free(st->h0_mem); | 284 | speex_free(st->h0_mem); |
289 | speex_free(st->h1_mem); | 285 | speex_free(st->h1_mem); |
290 | 286 | ||
291 | speex_free(st->lagWindow); | ||
292 | |||
293 | speex_free(st->old_lsp); | 287 | speex_free(st->old_lsp); |
294 | speex_free(st->old_qlsp); | 288 | speex_free(st->old_qlsp); |
295 | speex_free(st->interp_qlpc); | 289 | speex_free(st->interp_qlpc); |
@@ -1271,7 +1265,7 @@ int sb_encoder_ctl(void *state, int request, void *ptr) | |||
1271 | int i; | 1265 | int i; |
1272 | st->first = 1; | 1266 | st->first = 1; |
1273 | for (i=0;i<st->lpcSize;i++) | 1267 | for (i=0;i<st->lpcSize;i++) |
1274 | st->old_lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); | 1268 | st->old_lsp[i]= DIV32(MULT16_16(QCONST16(3.1415927f, LSP_SHIFT), i+1), st->lpcSize+1); |
1275 | for (i=0;i<st->lpcSize;i++) | 1269 | for (i=0;i<st->lpcSize;i++) |
1276 | st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; | 1270 | st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; |
1277 | for (i=0;i<QMF_ORDER;i++) | 1271 | for (i=0;i<QMF_ORDER;i++) |
diff --git a/apps/codecs/libspeex/sb_celp.h b/apps/codecs/libspeex/sb_celp.h index c4c8160a55..0d171b3f8b 100644 --- a/apps/codecs/libspeex/sb_celp.h +++ b/apps/codecs/libspeex/sb_celp.h | |||
@@ -51,7 +51,6 @@ typedef struct SBEncState { | |||
51 | int windowSize; /**< Length of high-band LPC window*/ | 51 | int windowSize; /**< Length of high-band LPC window*/ |
52 | int lpcSize; /**< Order of high-band LPC analysis */ | 52 | int lpcSize; /**< Order of high-band LPC analysis */ |
53 | int first; /**< First frame? */ | 53 | int first; /**< First frame? */ |
54 | float lag_factor; /**< Lag-windowing control parameter */ | ||
55 | spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */ | 54 | spx_word16_t lpc_floor; /**< Controls LPC analysis noise floor */ |
56 | spx_word16_t gamma1; /**< Perceptual weighting coef 1 */ | 55 | spx_word16_t gamma1; /**< Perceptual weighting coef 1 */ |
57 | spx_word16_t gamma2; /**< Perceptual weighting coef 2 */ | 56 | spx_word16_t gamma2; /**< Perceptual weighting coef 2 */ |
@@ -61,7 +60,7 @@ typedef struct SBEncState { | |||
61 | spx_word16_t *h0_mem, *h1_mem; | 60 | spx_word16_t *h0_mem, *h1_mem; |
62 | 61 | ||
63 | const spx_word16_t *window; /**< LPC analysis window */ | 62 | const spx_word16_t *window; /**< LPC analysis window */ |
64 | spx_word16_t *lagWindow; /**< Auto-correlation window */ | 63 | const spx_word16_t *lagWindow; /**< Auto-correlation window */ |
65 | spx_lsp_t *old_lsp; /**< LSPs of previous frame */ | 64 | spx_lsp_t *old_lsp; /**< LSPs of previous frame */ |
66 | spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */ | 65 | spx_lsp_t *old_qlsp; /**< Quantized LSPs of previous frame */ |
67 | spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ | 66 | spx_coef_t *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ |
diff --git a/apps/codecs/libspeex/smallft.c b/apps/codecs/libspeex/smallft.c index 980b7ac735..6ff46a8445 100644 --- a/apps/codecs/libspeex/smallft.c +++ b/apps/codecs/libspeex/smallft.c | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | #include <math.h> | 35 | #include <math.h> |
36 | #include "smallft.h" | 36 | #include "smallft.h" |
37 | #include "misc.h" | 37 | #include "arch.h" |
38 | #include "os_support.h" | 38 | #include "os_support.h" |
39 | 39 | ||
40 | static void drfti1(int n, float *wa, int *ifac){ | 40 | static void drfti1(int n, float *wa, int *ifac){ |
diff --git a/apps/codecs/libspeex/speex/speex_jitter.h b/apps/codecs/libspeex/speex/speex_jitter.h index 3f3a43c240..7c948d474e 100644 --- a/apps/codecs/libspeex/speex/speex_jitter.h +++ b/apps/codecs/libspeex/speex/speex_jitter.h | |||
@@ -41,8 +41,7 @@ | |||
41 | * @{ | 41 | * @{ |
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "speex.h" | 44 | #include "speex_types.h" |
45 | #include "speex_bits.h" | ||
46 | 45 | ||
47 | #ifdef __cplusplus | 46 | #ifdef __cplusplus |
48 | extern "C" { | 47 | extern "C" { |
@@ -63,6 +62,7 @@ struct _JitterBufferPacket { | |||
63 | spx_uint32_t len; /**< Length of the packet in bytes */ | 62 | spx_uint32_t len; /**< Length of the packet in bytes */ |
64 | spx_uint32_t timestamp; /**< Timestamp for the packet */ | 63 | spx_uint32_t timestamp; /**< Timestamp for the packet */ |
65 | spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ | 64 | spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ |
65 | spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ | ||
66 | }; | 66 | }; |
67 | 67 | ||
68 | /** Packet has been retrieved */ | 68 | /** Packet has been retrieved */ |
@@ -82,11 +82,21 @@ struct _JitterBufferPacket { | |||
82 | /** Get minimum amount of extra buffering required (margin) */ | 82 | /** Get minimum amount of extra buffering required (margin) */ |
83 | #define JITTER_BUFFER_GET_MARGIN 1 | 83 | #define JITTER_BUFFER_GET_MARGIN 1 |
84 | /* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ | 84 | /* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ |
85 | |||
85 | /** Get the amount of available packets currently buffered */ | 86 | /** Get the amount of available packets currently buffered */ |
86 | #define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 | 87 | #define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 |
87 | /** Included because of an early misspelling (will remove in next release) */ | 88 | /** Included because of an early misspelling (will remove in next release) */ |
88 | #define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 | 89 | #define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 |
89 | 90 | ||
91 | /** */ | ||
92 | #define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 | ||
93 | /** */ | ||
94 | #define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 | ||
95 | |||
96 | /** */ | ||
97 | #define JITTER_BUFFER_SET_DELAY_STEP 6 | ||
98 | /** */ | ||
99 | #define JITTER_BUFFER_GET_DELAY_STEP 7 | ||
90 | 100 | ||
91 | 101 | ||
92 | #define JITTER_BUFFER_ADJUST_INTERPOLATE -1 | 102 | #define JITTER_BUFFER_ADJUST_INTERPOLATE -1 |
@@ -123,9 +133,18 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); | |||
123 | * | 133 | * |
124 | * @param jitter Jitter buffer state | 134 | * @param jitter Jitter buffer state |
125 | * @param packet Returned packet | 135 | * @param packet Returned packet |
136 | * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) | ||
126 | * @param current_timestamp Timestamp for the returned packet | 137 | * @param current_timestamp Timestamp for the returned packet |
127 | */ | 138 | */ |
128 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); | 139 | int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); |
140 | |||
141 | /** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. | ||
142 | * This is mainly useful for media where a single "frame" can be split into several packets. | ||
143 | * | ||
144 | * @param jitter Jitter buffer state | ||
145 | * @param packet Returned packet | ||
146 | */ | ||
147 | int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); | ||
129 | 148 | ||
130 | /** Get pointer timestamp of jitter buffer | 149 | /** Get pointer timestamp of jitter buffer |
131 | * | 150 | * |
@@ -139,6 +158,12 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); | |||
139 | */ | 158 | */ |
140 | void jitter_buffer_tick(JitterBuffer *jitter); | 159 | void jitter_buffer_tick(JitterBuffer *jitter); |
141 | 160 | ||
161 | /** Telling the jitter buffer about the remaining data in the application buffer | ||
162 | * @param jitter Jitter buffer state | ||
163 | * @param rem Amount of data buffered by the application (timestamp units) | ||
164 | */ | ||
165 | void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); | ||
166 | |||
142 | /** Used like the ioctl function to control the jitter buffer parameters | 167 | /** Used like the ioctl function to control the jitter buffer parameters |
143 | * | 168 | * |
144 | * @param jitter Jitter buffer state | 169 | * @param jitter Jitter buffer state |
@@ -152,45 +177,8 @@ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, | |||
152 | 177 | ||
153 | /* @} */ | 178 | /* @} */ |
154 | 179 | ||
155 | /** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex | ||
156 | * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size | ||
157 | * to maintain good quality and low latency. This is a simplified version that works only | ||
158 | * with Speex, but is much easier to use. | ||
159 | * @{ | ||
160 | */ | ||
161 | |||
162 | /** Speex jitter-buffer state. Never use it directly! */ | ||
163 | typedef struct SpeexJitter { | ||
164 | SpeexBits current_packet; /**< Current Speex packet */ | ||
165 | int valid_bits; /**< True if Speex bits are valid */ | ||
166 | JitterBuffer *packets; /**< Generic jitter buffer state */ | ||
167 | void *dec; /**< Pointer to Speex decoder */ | ||
168 | spx_int32_t frame_size; /**< Frame size of Speex decoder */ | ||
169 | } SpeexJitter; | ||
170 | |||
171 | /** Initialise jitter buffer | ||
172 | * | ||
173 | * @param jitter State of the Speex jitter buffer | ||
174 | * @param decoder Speex decoder to call | ||
175 | * @param sampling_rate Sampling rate used by the decoder | ||
176 | */ | ||
177 | void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate); | ||
178 | |||
179 | /** Destroy jitter buffer */ | ||
180 | void speex_jitter_destroy(SpeexJitter *jitter); | ||
181 | |||
182 | /** Put one packet into the jitter buffer */ | ||
183 | void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp); | ||
184 | |||
185 | /** Get one packet from the jitter buffer */ | ||
186 | void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset); | ||
187 | |||
188 | /** Get pointer timestamp of jitter buffer */ | ||
189 | int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); | ||
190 | |||
191 | #ifdef __cplusplus | 180 | #ifdef __cplusplus |
192 | } | 181 | } |
193 | #endif | 182 | #endif |
194 | 183 | ||
195 | /* @} */ | ||
196 | #endif | 184 | #endif |
diff --git a/apps/codecs/libspeex/speex/speex_preprocess.h b/apps/codecs/libspeex/speex/speex_preprocess.h index 863b83fe14..273efaff79 100644 --- a/apps/codecs/libspeex/speex/speex_preprocess.h +++ b/apps/codecs/libspeex/speex/speex_preprocess.h | |||
@@ -178,6 +178,10 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); | |||
178 | /** Get maximal gain in dB (int32) */ | 178 | /** Get maximal gain in dB (int32) */ |
179 | #define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 | 179 | #define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 |
180 | 180 | ||
181 | /* Can't set loudness */ | ||
182 | /** Get loudness */ | ||
183 | #define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 | ||
184 | |||
181 | #ifdef __cplusplus | 185 | #ifdef __cplusplus |
182 | } | 186 | } |
183 | #endif | 187 | #endif |
diff --git a/apps/codecs/libspeex/speex/speex_stereo.h b/apps/codecs/libspeex/speex/speex_stereo.h index b817a5535e..67e2a8d4e0 100644 --- a/apps/codecs/libspeex/speex/speex_stereo.h +++ b/apps/codecs/libspeex/speex/speex_stereo.h | |||
@@ -60,7 +60,7 @@ typedef struct SpeexStereoState { | |||
60 | #define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} | 60 | #define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} |
61 | 61 | ||
62 | /** Initialise/create a stereo stereo state */ | 62 | /** Initialise/create a stereo stereo state */ |
63 | SpeexStereoState *speex_stereo_state_init(); | 63 | SpeexStereoState *speex_stereo_state_init(void); |
64 | 64 | ||
65 | /** Reset/re-initialise an already allocated stereo state */ | 65 | /** Reset/re-initialise an already allocated stereo state */ |
66 | void speex_stereo_state_reset(SpeexStereoState *stereo); | 66 | void speex_stereo_state_reset(SpeexStereoState *stereo); |
diff --git a/apps/codecs/libspeex/speex_callbacks.c b/apps/codecs/libspeex/speex_callbacks.c index ca29e1b32b..252bc90f6f 100644 --- a/apps/codecs/libspeex/speex_callbacks.c +++ b/apps/codecs/libspeex/speex_callbacks.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | #include <speex/speex_callbacks.h> | 39 | #include <speex/speex_callbacks.h> |
40 | #include "misc.h" | 40 | #include "arch.h" |
41 | #include "os_support.h" | 41 | #include "os_support.h" |
42 | 42 | ||
43 | int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) | 43 | int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) |
diff --git a/apps/codecs/libspeex/speex_header.c b/apps/codecs/libspeex/speex_header.c index 6d1e010828..eb4c199d46 100644 --- a/apps/codecs/libspeex/speex_header.c +++ b/apps/codecs/libspeex/speex_header.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "config-speex.h" | 35 | #include "config-speex.h" |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | #include <speex/speex_header.h> | 39 | #include <speex/speex_header.h> |
40 | #include <speex/speex.h> | 40 | #include <speex/speex.h> |
41 | #include "os_support.h" | 41 | #include "os_support.h" |
@@ -44,6 +44,24 @@ | |||
44 | #define NULL 0 | 44 | #define NULL 0 |
45 | #endif | 45 | #endif |
46 | 46 | ||
47 | /** Convert little endian */ | ||
48 | static inline spx_int32_t le_int(spx_int32_t i) | ||
49 | { | ||
50 | #if 1 | ||
51 | return letoh32(i); | ||
52 | #elif !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) | ||
53 | spx_uint32_t ui, ret; | ||
54 | ui = i; | ||
55 | ret = ui>>24; | ||
56 | ret |= (ui>>8)&0x0000ff00; | ||
57 | ret |= (ui<<8)&0x00ff0000; | ||
58 | ret |= (ui<<24); | ||
59 | return ret; | ||
60 | #else | ||
61 | return i; | ||
62 | #endif | ||
63 | } | ||
64 | |||
47 | #define ENDIAN_SWITCH(x) {x=le_int(x);} | 65 | #define ENDIAN_SWITCH(x) {x=le_int(x);} |
48 | 66 | ||
49 | 67 | ||
diff --git a/apps/codecs/libspeex/stereo.c b/apps/codecs/libspeex/stereo.c index c63c974798..9fa812dd72 100644 --- a/apps/codecs/libspeex/stereo.c +++ b/apps/codecs/libspeex/stereo.c | |||
@@ -213,7 +213,7 @@ void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState | |||
213 | spx_word16_t e_left, e_right, e_ratio; | 213 | spx_word16_t e_left, e_right, e_ratio; |
214 | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; | 214 | RealSpeexStereoState *stereo = (RealSpeexStereoState*)_stereo; |
215 | 215 | ||
216 | COMPATIBILITY_HACK(stereo); | 216 | /* COMPATIBILITY_HACK(stereo); */ |
217 | 217 | ||
218 | balance=stereo->balance; | 218 | balance=stereo->balance; |
219 | e_ratio=stereo->e_ratio; | 219 | e_ratio=stereo->e_ratio; |
@@ -240,7 +240,7 @@ int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) | |||
240 | 240 | ||
241 | stereo = (RealSpeexStereoState*)data; | 241 | stereo = (RealSpeexStereoState*)data; |
242 | 242 | ||
243 | COMPATIBILITY_HACK(stereo); | 243 | /* COMPATIBILITY_HACK(stereo); */ |
244 | 244 | ||
245 | if (speex_bits_unpack_unsigned(bits, 1)) | 245 | if (speex_bits_unpack_unsigned(bits, 1)) |
246 | sign=-1; | 246 | sign=-1; |
diff --git a/apps/codecs/libspeex/vbr.h b/apps/codecs/libspeex/vbr.h index 34e1d4c358..ff1e3e46f2 100644 --- a/apps/codecs/libspeex/vbr.h +++ b/apps/codecs/libspeex/vbr.h | |||
@@ -37,7 +37,7 @@ | |||
37 | #ifndef VBR_H | 37 | #ifndef VBR_H |
38 | #define VBR_H | 38 | #define VBR_H |
39 | 39 | ||
40 | #include "misc.h" | 40 | #include "arch.h" |
41 | 41 | ||
42 | #define VBR_MEMORY_SIZE 5 | 42 | #define VBR_MEMORY_SIZE 5 |
43 | 43 | ||
diff --git a/apps/codecs/libspeex/vorbis_psy.c b/apps/codecs/libspeex/vorbis_psy.c index fe01af145f..91cf49c69c 100644 --- a/apps/codecs/libspeex/vorbis_psy.c +++ b/apps/codecs/libspeex/vorbis_psy.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #ifdef VORBIS_PSYCHO | 36 | #ifdef VORBIS_PSYCHO |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | #include "smallft.h" | 39 | #include "smallft.h" |
40 | #include "lpc.h" | 40 | #include "lpc.h" |
41 | #include "vorbis_psy.h" | 41 | #include "vorbis_psy.h" |
diff --git a/apps/codecs/libspeex/vq.c b/apps/codecs/libspeex/vq.c index f9ee3b4a86..1c66b32b16 100644 --- a/apps/codecs/libspeex/vq.c +++ b/apps/codecs/libspeex/vq.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | #include "vq.h" | 37 | #include "vq.h" |
38 | #include "stack_alloc.h" | 38 | #include "stack_alloc.h" |
39 | #include "misc.h" | 39 | #include "arch.h" |
40 | 40 | ||
41 | #ifdef _USE_SSE | 41 | #ifdef _USE_SSE |
42 | #include <xmmintrin.h> | 42 | #include <xmmintrin.h> |
diff --git a/apps/codecs/libspeex/vq.h b/apps/codecs/libspeex/vq.h index 7ca81975c6..478d8696bd 100644 --- a/apps/codecs/libspeex/vq.h +++ b/apps/codecs/libspeex/vq.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #ifndef VQ_H | 35 | #ifndef VQ_H |
36 | #define VQ_H | 36 | #define VQ_H |
37 | 37 | ||
38 | #include "misc.h" | 38 | #include "arch.h" |
39 | 39 | ||
40 | int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries); | 40 | int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries); |
41 | int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries); | 41 | int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries); |
diff --git a/apps/codecs/libspeex/window.c b/apps/codecs/libspeex/window.c index 41757ff0d0..84ed4916cf 100644 --- a/apps/codecs/libspeex/window.c +++ b/apps/codecs/libspeex/window.c | |||
@@ -33,9 +33,13 @@ | |||
33 | #include "config-speex.h" | 33 | #include "config-speex.h" |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #include "misc.h" | 36 | #include "arch.h" |
37 | 37 | ||
38 | #ifdef FIXED_POINT | 38 | #ifdef FIXED_POINT |
39 | const spx_word16_t lag_window[11] ICONST_ATTR = { | ||
40 | 16384, 16337, 16199, 15970, 15656, 15260, 14790, 14254, 13659, 13015, 12330 | ||
41 | }; | ||
42 | |||
39 | const spx_word16_t lpc_window[200] ICONST_ATTR = { | 43 | const spx_word16_t lpc_window[200] ICONST_ATTR = { |
40 | 1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436, | 44 | 1310, 1313, 1321, 1333, 1352, 1375, 1403, 1436, |
41 | 1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884, | 45 | 1475, 1518, 1567, 1621, 1679, 1743, 1811, 1884, |
@@ -64,6 +68,10 @@ const spx_word16_t lpc_window[200] ICONST_ATTR = { | |||
64 | 6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696 | 68 | 6797, 6028, 5251, 4470, 3695, 2943, 2248, 1696 |
65 | }; | 69 | }; |
66 | #else | 70 | #else |
71 | const spx_word16_t lag_window[11] = { | ||
72 | 1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998, 0.83367, 0.79434, 0.75258 | ||
73 | }; | ||
74 | |||
67 | const spx_word16_t lpc_window[200] = { | 75 | const spx_word16_t lpc_window[200] = { |
68 | 0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f, | 76 | 0.080000f, 0.080158f, 0.080630f, 0.081418f, 0.082520f, 0.083935f, 0.085663f, 0.087703f, |
69 | 0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f, | 77 | 0.090052f, 0.092710f, 0.095674f, 0.098943f, 0.102514f, 0.106385f, 0.110553f, 0.115015f, |