decoder excitation now in 16-bit precision (was 32), which saves quite a bit
[speexdsp.git] / libspeex / bits.c
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.h"
37 #endif
38
39 #include <speex/speex_bits.h>
40 #include "misc.h"
41
42 /* Maximum size of the bit-stream (for fixed-size allocation) */
43 #ifndef MAX_CHARS_PER_FRAME
44 #define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
45 #endif
46
47 void speex_bits_init(SpeexBits *bits)
48 {
49    bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
50    if (!bits->chars)
51       return;
52
53    bits->buf_size = MAX_CHARS_PER_FRAME;
54
55    bits->owner=1;
56
57    speex_bits_reset(bits);
58 }
59
60 void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
61 {
62    bits->chars = (char*)buff;
63    bits->buf_size = buf_size;
64
65    bits->owner=0;
66
67    speex_bits_reset(bits);
68 }
69
70 void speex_bits_destroy(SpeexBits *bits)
71 {
72    if (bits->owner)
73       speex_free(bits->chars);
74    /* Will do something once the allocation is dynamic */
75 }
76
77 void speex_bits_reset(SpeexBits *bits)
78 {
79    bits->chars[0]=0;
80    bits->nbBits=0;
81    bits->charPtr=0;
82    bits->bitPtr=0;
83    bits->overflow=0;
84 }
85
86 void speex_bits_rewind(SpeexBits *bits)
87 {
88    bits->charPtr=0;
89    bits->bitPtr=0;
90    bits->overflow=0;
91 }
92
93 void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
94 {
95    int i;
96    int nchars = len / BYTES_PER_CHAR;
97    if (nchars > bits->buf_size)
98    {
99       speex_warning_int("Packet is larger than allocated buffer: ", len);
100       if (bits->owner)
101       {
102          char *tmp = (char*)speex_realloc(bits->chars, nchars);
103          if (tmp)
104          {
105             bits->buf_size=nchars;
106             bits->chars=tmp;
107          } else {
108             nchars=bits->buf_size;
109             speex_warning("Could not resize input buffer: truncating input");
110          }
111       } else {
112          speex_warning("Do not own input buffer: truncating input");
113          nchars=bits->buf_size;
114       }
115    }
116 #if (BYTES_PER_CHAR==2)
117 /* Swap bytes to proper endian order (could be done externally) */
118 #define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
119 #else
120 #define HTOLS(A) (A)
121 #endif
122    for (i=0;i<nchars;i++)
123       bits->chars[i]=HTOLS(chars[i]);
124
125    bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;
126    bits->charPtr=0;
127    bits->bitPtr=0;
128    bits->overflow=0;
129 }
130
131 static void speex_bits_flush(SpeexBits *bits)
132 {
133    int i;
134    int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
135    if (bits->charPtr>0)
136    {
137      for (i=bits->charPtr;i<nchars; i++) 
138        bits->chars[i-bits->charPtr]=bits->chars[i];
139    }
140    bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
141    bits->charPtr=0;
142 }
143
144 void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
145 {
146    int i,pos;
147    int nchars = nbytes/BYTES_PER_CHAR;
148
149    if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
150    {
151       /* Packet is larger than allocated buffer */
152       if (bits->owner)
153       {
154          char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
155          if (tmp)
156          {
157             bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
158             bits->chars=tmp;
159          } else {
160             nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
161             speex_warning("Could not resize input buffer: truncating input");
162          }
163       } else {
164          speex_warning("Do not own input buffer: truncating input");
165          nchars=bits->buf_size;
166       }
167    }
168
169    speex_bits_flush(bits);
170    pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
171    for (i=0;i<nchars;i++)
172       bits->chars[pos+i]=HTOLS(chars[i]);
173    bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
174 }
175
176 int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
177 {
178    int i;
179    int max_nchars = max_nbytes/BYTES_PER_CHAR;
180    int charPtr, bitPtr, nbBits;
181
182    /* Insert terminator, but save the data so we can put it back after */
183    bitPtr=bits->bitPtr;
184    charPtr=bits->charPtr;
185    nbBits=bits->nbBits;
186    speex_bits_insert_terminator(bits);
187    bits->bitPtr=bitPtr;
188    bits->charPtr=charPtr;
189    bits->nbBits=nbBits;
190
191    if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
192       max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
193
194    for (i=0;i<max_nchars;i++)
195       chars[i]=HTOLS(bits->chars[i]);
196    return max_nchars*BYTES_PER_CHAR;
197 }
198
199 int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
200 {
201    int max_nchars = max_nbytes/BYTES_PER_CHAR;
202    int i;
203    if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
204       max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
205    for (i=0;i<max_nchars;i++)
206       chars[i]=HTOLS(bits->chars[i]);
207
208    if (bits->bitPtr>0)
209       bits->chars[0]=bits->chars[max_nchars];
210    else
211       bits->chars[0]=0;
212    for (i=1;i<((bits->nbBits)>>LOG2_BITS_PER_CHAR)+1;i++)
213       bits->chars[i]=0;
214    bits->charPtr=0;
215    bits->nbBits &= (BITS_PER_CHAR-1);
216    return max_nchars*BYTES_PER_CHAR;
217 }
218
219 void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
220 {
221    unsigned int d=data;
222
223    if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
224    {
225       speex_warning("Buffer too small to pack bits");
226       if (bits->owner)
227       {
228         int new_nchars = ((bits->buf_size+5)*3)>>1;
229          char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
230          if (tmp)
231          {
232             speex_memset_bytes(tmp, 0, new_nchars);
233             bits->buf_size=new_nchars;
234             bits->chars=tmp;
235          } else {
236             speex_warning("Could not resize input buffer: not packing");
237             return;
238          }
239       } else {
240          speex_warning("Do not own input buffer: not packing");
241          return;
242       }
243    }
244
245    while(nbBits)
246    {
247       int bit;
248       bit = (d>>(nbBits-1))&1;
249       bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
250       bits->bitPtr++;
251
252       if (bits->bitPtr==BITS_PER_CHAR)
253       {
254          bits->bitPtr=0;
255          bits->charPtr++;
256          bits->chars[bits->charPtr] = 0;
257       }
258       bits->nbBits++;
259       nbBits--;
260    }
261 }
262
263 int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
264 {
265    unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
266    /* If number is negative */
267    if (d>>(nbBits-1))
268    {
269       d |= (-1)<<nbBits;
270    }
271    return d;
272 }
273
274 unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
275 {
276    unsigned int d=0;
277    if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
278       bits->overflow=1;
279    if (bits->overflow)
280       return 0;
281    while(nbBits)
282    {
283       d<<=1;
284       d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
285       bits->bitPtr++;
286       if (bits->bitPtr==BITS_PER_CHAR)
287       {
288          bits->bitPtr=0;
289          bits->charPtr++;
290       }
291       nbBits--;
292    }
293    return d;
294 }
295
296 unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
297 {
298    unsigned int d=0;
299    int bitPtr, charPtr;
300    char *chars;
301
302    if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
303      bits->overflow=1;
304    if (bits->overflow)
305       return 0;
306
307    bitPtr=bits->bitPtr;
308    charPtr=bits->charPtr;
309    chars = bits->chars;
310    while(nbBits)
311    {
312       d<<=1;
313       d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
314       bitPtr++;
315       if (bitPtr==BITS_PER_CHAR)
316       {
317          bitPtr=0;
318          charPtr++;
319       }
320       nbBits--;
321    }
322    return d;
323 }
324
325 int speex_bits_peek(SpeexBits *bits)
326 {
327    if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
328       bits->overflow=1;
329    if (bits->overflow)
330       return 0;
331    return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
332 }
333
334 void speex_bits_advance(SpeexBits *bits, int n)
335 {
336     if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
337       bits->overflow=1;
338       return;
339     }
340    bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
341    bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1);       /* modulo by BITS_PER_CHAR */
342 }
343
344 int speex_bits_remaining(SpeexBits *bits)
345 {
346    if (bits->overflow)
347       return -1;
348    else
349       return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
350 }
351
352 int speex_bits_nbytes(SpeexBits *bits)
353 {
354    return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
355 }
356
357 void speex_bits_insert_terminator(SpeexBits *bits)
358 {
359    if (bits->bitPtr)
360       speex_bits_pack(bits, 0, 1);
361    while (bits->bitPtr)
362       speex_bits_pack(bits, 1, 1);
363 }