speex.[ch] renamed to nb_celp.[ch] for consistency
[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    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10    
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 */
21
22 #include "speex_bits.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 void speex_bits_init(FrameBits *bits)
27 {
28    int i;
29    for (i=0;i<MAX_BYTES_PER_FRAME;i++)
30       bits->bytes[i]=0;
31    bits->nbBits=0;
32    bits->bytePtr=0;
33    bits->bitPtr=0;
34 }
35
36 void speex_bits_destroy(FrameBits *bits)
37 {
38    /* Will do something once the allocation is dynamic */
39 }
40
41 void speex_bits_reset(FrameBits *bits)
42 {
43    int i;
44    for (i=0;i<MAX_BYTES_PER_FRAME;i++)
45       bits->bytes[i]=0;
46    bits->nbBits=0;
47    bits->bytePtr=0;
48    bits->bitPtr=0;
49 }
50
51 void speex_bits_rewind(FrameBits *bits)
52 {
53    bits->bytePtr=0;
54    bits->bitPtr=0;
55 }
56
57 void speex_bits_init_from(FrameBits *bits, char *bytes, int len)
58 {
59    int i;
60    if (len > MAX_BYTES_PER_FRAME)
61    {
62       fprintf (stderr, "Trying to init frame with too many bits");
63       exit(1);
64    }
65    for (i=0;i<len;i++)
66       bits->bytes[i]=bytes[i];
67    bits->nbBits=len<<3;
68    bits->bytePtr=0;
69    bits->bitPtr=0;
70 }
71
72 void speex_bits_flush(FrameBits *bits)
73 {
74    int i;
75    if (bits->bytePtr>0)
76    {
77       for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++)
78          bits->bytes[i-bits->bytePtr]=bits->bytes[i];
79    }
80    bits->nbBits -= bits->bytePtr<<3;
81    bits->bytePtr=0;
82 }
83
84 void speex_bits_read_whole_bytes(FrameBits *bits, char *bytes, int len)
85 {
86    int i,pos;
87    speex_bits_flush(bits);
88    pos=bits->nbBits>>3;
89    for (i=0;i<len;i++)
90       bits->bytes[pos+i]=bytes[i];
91    bits->nbBits+=len<<3;
92 }
93
94 int speex_bits_write(FrameBits *bits, char *bytes, int max_len)
95 {
96    int i;
97    if (max_len > ((bits->nbBits+7)>>3))
98       max_len = ((bits->nbBits+7)>>3);
99    for (i=0;i<max_len;i++)
100       bytes[i]=bits->bytes[i];
101    return max_len;
102 }
103
104 int speex_bits_write_whole_bytes(FrameBits *bits, char *bytes, int max_len)
105 {
106    int i;
107    if (max_len > ((bits->nbBits)>>3))
108       max_len = ((bits->nbBits)>>3);
109    for (i=0;i<max_len;i++)
110       bytes[i]=bits->bytes[i];
111    
112    if (bits->bitPtr>0)
113       bits->bytes[0]=bits->bytes[max_len];
114    else
115       bits->bytes[0]=0;
116    for (i=1;i<((bits->nbBits)>>3)+1;i++)
117       bits->bytes[i]=0;
118    bits->bytePtr=0;
119    bits->nbBits &= 7;
120    return max_len;
121 }
122
123
124 void speex_bits_pack(FrameBits *bits, int data, int nbBits)
125 {
126    unsigned int d=data;
127    while(nbBits)
128    {
129       int bit;
130       bit = (d>>(nbBits-1))&1;
131       bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr);
132       bits->bitPtr++;
133       /*fprintf(stderr, "%d %d\n", nbBits, bit);*/
134       if (bits->bitPtr==8)
135       {
136          bits->bitPtr=0;
137          bits->bytePtr++;
138       }
139       bits->nbBits++;
140       nbBits--;
141    }
142 }
143
144 int speex_bits_unpack_signed(FrameBits *bits, int nbBits)
145 {
146    unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
147    /* If number is negative */
148    if (d>>(nbBits-1))
149    {
150       d |= (-1)<<nbBits;
151    }
152    return d;
153 }
154
155 unsigned int speex_bits_unpack_unsigned(FrameBits *bits, int nbBits)
156 {
157    unsigned int d=0;
158    while(nbBits)
159    {
160       d<<=1;
161       d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1;
162       bits->bitPtr++;
163       if (bits->bitPtr==8)
164       {
165          bits->bitPtr=0;
166          bits->bytePtr++;
167       }
168       nbBits--;
169    }
170    return d;
171 }