summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libspeex/bits.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libspeex/bits.c')
-rw-r--r--lib/rbcodec/codecs/libspeex/bits.c399
1 files changed, 399 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libspeex/bits.c b/lib/rbcodec/codecs/libspeex/bits.c
new file mode 100644
index 0000000000..c7a5c14ede
--- /dev/null
+++ b/lib/rbcodec/codecs/libspeex/bits.c
@@ -0,0 +1,399 @@
1/* Copyright (C) 2002 Jean-Marc Valin
2 File: speex_bits.c
3
4 Handles bit packing/unpacking
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33*/
34
35#ifdef HAVE_CONFIG_H
36#include "config-speex.h"
37#endif
38
39#include "speex/speex_bits.h"
40#include "arch.h"
41#include "os_support.h"
42
43/* Maximum size of the bit-stream (for fixed-size allocation) */
44#ifndef MAX_CHARS_PER_FRAME
45#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
46#endif
47
48#ifdef ROCKBOX_VOICE_ENCODER
49void speex_bits_init(SpeexBits *bits)
50{
51 bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
52 if (!bits->chars)
53 return;
54
55 bits->buf_size = MAX_CHARS_PER_FRAME;
56
57 bits->owner=1;
58
59 speex_bits_reset(bits);
60}
61#endif
62
63#if 0
64/* Rockbox: unused */
65void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
66{
67 bits->chars = (char*)buff;
68 bits->buf_size = buf_size;
69
70 bits->owner=0;
71
72 speex_bits_reset(bits);
73}
74#endif
75
76void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
77{
78 bits->chars = (char*)buff;
79 bits->buf_size = buf_size;
80
81 bits->owner=0;
82
83 bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
84 bits->charPtr=0;
85 bits->bitPtr=0;
86 bits->overflow=0;
87
88}
89
90#ifndef ROCKBOX_VOICE_CODEC
91void speex_bits_destroy(SpeexBits *bits)
92{
93 if (bits->owner)
94 speex_free(bits->chars);
95 /* Will do something once the allocation is dynamic */
96}
97#endif
98
99#ifdef ROCKBOX_VOICE_ENCODER
100void speex_bits_reset(SpeexBits *bits)
101{
102 /* We only need to clear the first byte now */
103 bits->chars[0]=0;
104 bits->nbBits=0;
105 bits->charPtr=0;
106 bits->bitPtr=0;
107 bits->overflow=0;
108}
109#endif
110
111#if 0
112/* Rockbox: unused */
113void speex_bits_rewind(SpeexBits *bits)
114{
115 bits->charPtr=0;
116 bits->bitPtr=0;
117 bits->overflow=0;
118}
119#endif
120
121#if !defined(SPEEX_VOICE_ENCODER) && !defined(ROCKBOX_VOICE_CODEC)
122void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
123{
124 int i;
125 int nchars = len / BYTES_PER_CHAR;
126 if (nchars > bits->buf_size)
127 {
128 speex_notify("Packet is larger than allocated buffer");
129 if (bits->owner)
130 {
131 char *tmp = (char*)speex_realloc(bits->chars, nchars);
132 if (tmp)
133 {
134 bits->buf_size=nchars;
135 bits->chars=tmp;
136 } else {
137 nchars=bits->buf_size;
138 speex_warning("Could not resize input buffer: truncating input");
139 }
140 } else {
141 speex_warning("Do not own input buffer: truncating oversize input");
142 nchars=bits->buf_size;
143 }
144 }
145#if (BYTES_PER_CHAR==2)
146/* Swap bytes to proper endian order (could be done externally) */
147#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
148#else
149#define HTOLS(A) (A)
150#endif
151 for (i=0;i<nchars;i++)
152 bits->chars[i]=HTOLS(chars[i]);
153
154 bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;
155 bits->charPtr=0;
156 bits->bitPtr=0;
157 bits->overflow=0;
158}
159
160static void speex_bits_flush(SpeexBits *bits)
161{
162 int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
163 if (bits->charPtr>0)
164 SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
165 bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
166 bits->charPtr=0;
167}
168
169void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
170{
171 int i,pos;
172 int nchars = nbytes/BYTES_PER_CHAR;
173
174 if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
175 {
176 /* Packet is larger than allocated buffer */
177 if (bits->owner)
178 {
179 char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
180 if (tmp)
181 {
182 bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
183 bits->chars=tmp;
184 } else {
185 nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
186 speex_warning("Could not resize input buffer: truncating oversize input");
187 }
188 } else {
189 speex_warning("Do not own input buffer: truncating oversize input");
190 nchars=bits->buf_size;
191 }
192 }
193
194 speex_bits_flush(bits);
195 pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
196 for (i=0;i<nchars;i++)
197 bits->chars[pos+i]=HTOLS(chars[i]);
198 bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
199}
200#endif
201
202#ifndef SPEEX_DISABLE_ENCODER
203int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
204{
205 int i;
206 int max_nchars = max_nbytes/BYTES_PER_CHAR;
207 int charPtr, bitPtr, nbBits;
208
209 /* Insert terminator, but save the data so we can put it back after */
210 bitPtr=bits->bitPtr;
211 charPtr=bits->charPtr;
212 nbBits=bits->nbBits;
213 speex_bits_insert_terminator(bits);
214 bits->bitPtr=bitPtr;
215 bits->charPtr=charPtr;
216 bits->nbBits=nbBits;
217
218 if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
219 max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
220
221 for (i=0;i<max_nchars;i++)
222 chars[i]=HTOLS(bits->chars[i]);
223 return max_nchars*BYTES_PER_CHAR;
224}
225
226int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
227{
228 int max_nchars = max_nbytes/BYTES_PER_CHAR;
229 int i;
230 if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
231 max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
232 for (i=0;i<max_nchars;i++)
233 chars[i]=HTOLS(bits->chars[i]);
234
235 if (bits->bitPtr>0)
236 bits->chars[0]=bits->chars[max_nchars];
237 else
238 bits->chars[0]=0;
239 bits->charPtr=0;
240 bits->nbBits &= (BITS_PER_CHAR-1);
241 return max_nchars*BYTES_PER_CHAR;
242}
243
244void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
245{
246 unsigned int d=data;
247
248 if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
249 {
250 speex_notify("Buffer too small to pack bits");
251 if (bits->owner)
252 {
253 int new_nchars = ((bits->buf_size+5)*3)>>1;
254 char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
255 if (tmp)
256 {
257 bits->buf_size=new_nchars;
258 bits->chars=tmp;
259 } else {
260 speex_warning("Could not resize input buffer: not packing");
261 return;
262 }
263 } else {
264 speex_warning("Do not own input buffer: not packing");
265 return;
266 }
267 }
268
269 while(nbBits)
270 {
271 int bit;
272 bit = (d>>(nbBits-1))&1;
273 bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
274 bits->bitPtr++;
275
276 if (bits->bitPtr==BITS_PER_CHAR)
277 {
278 bits->bitPtr=0;
279 bits->charPtr++;
280 bits->chars[bits->charPtr] = 0;
281 }
282 bits->nbBits++;
283 nbBits--;
284 }
285}
286#endif /* SPEEX_DISABLE_ENCODER */
287
288#if 0
289/* Rockbox: unused */
290int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
291{
292 unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
293 /* If number is negative */
294 if (d>>(nbBits-1))
295 {
296 d |= (-1)<<nbBits;
297 }
298 return d;
299}
300#endif
301
302unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
303{
304 unsigned int d=0;
305 if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
306 bits->overflow=1;
307 if (bits->overflow)
308 return 0;
309 while(nbBits)
310 {
311 d<<=1;
312 d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
313 bits->bitPtr++;
314 if (bits->bitPtr==BITS_PER_CHAR)
315 {
316 bits->bitPtr=0;
317 bits->charPtr++;
318 }
319 nbBits--;
320 }
321 return d;
322}
323
324#if 0
325/* Rockbox: unused */
326unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
327{
328 unsigned int d=0;
329 int bitPtr, charPtr;
330 char *chars;
331
332 if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
333 bits->overflow=1;
334 if (bits->overflow)
335 return 0;
336
337 bitPtr=bits->bitPtr;
338 charPtr=bits->charPtr;
339 chars = bits->chars;
340 while(nbBits)
341 {
342 d<<=1;
343 d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
344 bitPtr++;
345 if (bitPtr==BITS_PER_CHAR)
346 {
347 bitPtr=0;
348 charPtr++;
349 }
350 nbBits--;
351 }
352 return d;
353}
354#endif
355
356int speex_bits_peek(SpeexBits *bits)
357{
358 if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
359 bits->overflow=1;
360 if (bits->overflow)
361 return 0;
362 return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
363}
364
365void speex_bits_advance(SpeexBits *bits, int n)
366{
367 if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
368 bits->overflow=1;
369 return;
370 }
371 bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
372 bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1); /* modulo by BITS_PER_CHAR */
373}
374
375int speex_bits_remaining(SpeexBits *bits)
376{
377 if (bits->overflow)
378 return -1;
379 else
380 return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
381}
382
383#if 0
384/* Rockbox: unused */
385int speex_bits_nbytes(SpeexBits *bits)
386{
387 return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
388}
389#endif
390
391#ifndef SPEEX_DISABLE_ENCODER
392void speex_bits_insert_terminator(SpeexBits *bits)
393{
394 if (bits->bitPtr)
395 speex_bits_pack(bits, 0, 1);
396 while (bits->bitPtr)
397 speex_bits_pack(bits, 1, 1);
398}
399#endif /* SPEEX_DISABLE_ENCODER */