134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)/* Copyright (C) 2002 Jean-Marc Valin
234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   File: speex_bits.c
334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   Handles bit packing/unpacking
534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   Redistribution and use in source and binary forms, with or without
734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   modification, are permitted provided that the following conditions
834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   are met:
934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
1034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   - Redistributions of source code must retain the above copyright
1134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   notice, this list of conditions and the following disclaimer.
1234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
1334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   - Redistributions in binary form must reproduce the above copyright
1434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   notice, this list of conditions and the following disclaimer in the
1534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   documentation and/or other materials provided with the distribution.
1634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
1734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   - Neither the name of the Xiph.org Foundation nor the names of its
1834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   contributors may be used to endorse or promote products derived from
1934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   this software without specific prior written permission.
2034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
2134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
2534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
3334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)*/
3434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
3534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#ifdef HAVE_CONFIG_H
3634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "config.h"
3734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#endif
3834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
3934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include <speex/speex_bits.h>
4034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "arch.h"
4134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#include "os_support.h"
4234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
4334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)/* Maximum size of the bit-stream (for fixed-size allocation) */
4434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#ifndef MAX_CHARS_PER_FRAME
4534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#define MAX_CHARS_PER_FRAME (2000/BYTES_PER_CHAR)
4634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#endif
4734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
4834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_init(SpeexBits *bits)
4934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
5034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->chars = (char*)speex_alloc(MAX_CHARS_PER_FRAME);
5134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (!bits->chars)
5234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return;
5334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
5434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->buf_size = MAX_CHARS_PER_FRAME;
5534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
5634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->owner=1;
5734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
5834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   speex_bits_reset(bits);
5934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
6034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
6134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
6234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
6334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->chars = (char*)buff;
6434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->buf_size = buf_size;
6534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
6634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->owner=0;
6734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
6834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   speex_bits_reset(bits);
6934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
7034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
7134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size)
7234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
7334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->chars = (char*)buff;
7434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->buf_size = buf_size;
7534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
7634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->owner=0;
7734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
7834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits=buf_size<<LOG2_BITS_PER_CHAR;
7934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=0;
8034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->bitPtr=0;
8134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->overflow=0;
8234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
8334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
8434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
8534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_destroy(SpeexBits *bits)
8634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
8734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->owner)
8834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      speex_free(bits->chars);
8934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   /* Will do something once the allocation is dynamic */
9034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
9134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
9234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_reset(SpeexBits *bits)
9334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
9434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   /* We only need to clear the first byte now */
9534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->chars[0]=0;
9634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits=0;
9734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=0;
9834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->bitPtr=0;
9934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->overflow=0;
10034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
10134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
10234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_rewind(SpeexBits *bits)
10334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
10434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=0;
10534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->bitPtr=0;
10634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->overflow=0;
10734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
10834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
10934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
11034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
11134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int i;
11234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int nchars = len / BYTES_PER_CHAR;
11334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (nchars > bits->buf_size)
11434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
11534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      speex_notify("Packet is larger than allocated buffer");
11634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (bits->owner)
11734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      {
11834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         char *tmp = (char*)speex_realloc(bits->chars, nchars);
11934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         if (tmp)
12034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         {
12134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            bits->buf_size=nchars;
12234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            bits->chars=tmp;
12334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         } else {
12434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            nchars=bits->buf_size;
12534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            speex_warning("Could not resize input buffer: truncating input");
12634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         }
12734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      } else {
12834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         speex_warning("Do not own input buffer: truncating oversize input");
12934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         nchars=bits->buf_size;
13034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      }
13134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
13234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#if (BYTES_PER_CHAR==2)
13334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)/* Swap bytes to proper endian order (could be done externally) */
13434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
13534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#else
13634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#define HTOLS(A) (A)
13734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)#endif
13834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   for (i=0;i<nchars;i++)
13934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->chars[i]=HTOLS(chars[i]);
14034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
14134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits=nchars<<LOG2_BITS_PER_CHAR;
14234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=0;
14334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->bitPtr=0;
14434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->overflow=0;
14534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
14634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
14734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)static void speex_bits_flush(SpeexBits *bits)
14834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
14934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
15034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->charPtr>0)
15134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      SPEEX_MOVE(bits->chars, &bits->chars[bits->charPtr], nchars-bits->charPtr);
15234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
15334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=0;
15434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
15534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
15634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
15734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
15834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int i,pos;
15934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int nchars = nbytes/BYTES_PER_CHAR;
16034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
16134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
16234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
16334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      /* Packet is larger than allocated buffer */
16434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (bits->owner)
16534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      {
16634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
16734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         if (tmp)
16834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         {
16934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
17034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            bits->chars=tmp;
17134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         } else {
17234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
17334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            speex_warning("Could not resize input buffer: truncating oversize input");
17434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         }
17534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      } else {
17634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         speex_warning("Do not own input buffer: truncating oversize input");
17734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         nchars=bits->buf_size;
17834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      }
17934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
18034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
18134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   speex_bits_flush(bits);
18234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
18334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   for (i=0;i<nchars;i++)
18434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->chars[pos+i]=HTOLS(chars[i]);
18534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
18634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
18734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
18834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
18934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
19034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int i;
19134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int max_nchars = max_nbytes/BYTES_PER_CHAR;
19234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int charPtr, bitPtr, nbBits;
19334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
19434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   /* Insert terminator, but save the data so we can put it back after */
19534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bitPtr=bits->bitPtr;
19634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   charPtr=bits->charPtr;
19734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   nbBits=bits->nbBits;
19834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   speex_bits_insert_terminator(bits);
19934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->bitPtr=bitPtr;
20034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=charPtr;
20134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits=nbBits;
20234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
20334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
20434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
20534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
20634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   for (i=0;i<max_nchars;i++)
20734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      chars[i]=HTOLS(bits->chars[i]);
20834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return max_nchars*BYTES_PER_CHAR;
20934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
21034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
21134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
21234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
21334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int max_nchars = max_nbytes/BYTES_PER_CHAR;
21434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int i;
21534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
21634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
21734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   for (i=0;i<max_nchars;i++)
21834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      chars[i]=HTOLS(bits->chars[i]);
21934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
22034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->bitPtr>0)
22134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->chars[0]=bits->chars[max_nchars];
22234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   else
22334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->chars[0]=0;
22434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr=0;
22534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->nbBits &= (BITS_PER_CHAR-1);
22634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return max_nchars*BYTES_PER_CHAR;
22734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
22834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
22934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
23034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
23134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   unsigned int d=data;
23234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
23334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
23434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
23534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      speex_notify("Buffer too small to pack bits");
23634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (bits->owner)
23734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      {
23834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         int new_nchars = ((bits->buf_size+5)*3)>>1;
23934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
24034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         if (tmp)
24134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         {
24234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            bits->buf_size=new_nchars;
24334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            bits->chars=tmp;
24434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         } else {
24534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            speex_warning("Could not resize input buffer: not packing");
24634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)            return;
24734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         }
24834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      } else {
24934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         speex_warning("Do not own input buffer: not packing");
25034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         return;
25134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      }
25234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
25334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
25434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   while(nbBits)
25534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
25634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      int bit;
25734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bit = (d>>(nbBits-1))&1;
25834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->chars[bits->charPtr] |= bit<<(BITS_PER_CHAR-1-bits->bitPtr);
25934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->bitPtr++;
26034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
26134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (bits->bitPtr==BITS_PER_CHAR)
26234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      {
26334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         bits->bitPtr=0;
26434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         bits->charPtr++;
26534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         bits->chars[bits->charPtr] = 0;
26634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      }
26734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->nbBits++;
26834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      nbBits--;
26934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
27034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
27134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
27234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
27334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
27434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
27534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   /* If number is negative */
27634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (d>>(nbBits-1))
27734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
27834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      d |= (-1)<<nbBits;
27934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
28034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return d;
28134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
28234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
28334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
28434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
28534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   unsigned int d=0;
28634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
28734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->overflow=1;
28834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->overflow)
28934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return 0;
29034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   while(nbBits)
29134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
29234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      d<<=1;
29334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
29434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->bitPtr++;
29534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (bits->bitPtr==BITS_PER_CHAR)
29634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      {
29734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         bits->bitPtr=0;
29834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         bits->charPtr++;
29934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      }
30034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      nbBits--;
30134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
30234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return d;
30334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
30434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
30534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
30634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
30734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   unsigned int d=0;
30834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   int bitPtr, charPtr;
30934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   char *chars;
31034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
31134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
31234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)     bits->overflow=1;
31334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->overflow)
31434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return 0;
31534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
31634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bitPtr=bits->bitPtr;
31734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   charPtr=bits->charPtr;
31834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   chars = bits->chars;
31934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   while(nbBits)
32034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   {
32134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      d<<=1;
32234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
32334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bitPtr++;
32434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      if (bitPtr==BITS_PER_CHAR)
32534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      {
32634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         bitPtr=0;
32734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)         charPtr++;
32834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      }
32934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      nbBits--;
33034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   }
33134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return d;
33234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
33334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
33434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT int speex_bits_peek(SpeexBits *bits)
33534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
33634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
33734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->overflow=1;
33834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->overflow)
33934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return 0;
34034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
34134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
34234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
34334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_advance(SpeexBits *bits, int n)
34434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
34534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
34634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      bits->overflow=1;
34734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return;
34834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)    }
34934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
35034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1);       /* modulo by BITS_PER_CHAR */
35134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
35234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
35334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT int speex_bits_remaining(SpeexBits *bits)
35434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
35534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->overflow)
35634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return -1;
35734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   else
35834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
35934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
36034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
36134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT int speex_bits_nbytes(SpeexBits *bits)
36234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
36334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
36434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
36534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
36634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)EXPORT void speex_bits_insert_terminator(SpeexBits *bits)
36734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles){
36834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   if (bits->bitPtr)
36934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      speex_bits_pack(bits, 0, 1);
37034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)   while (bits->bitPtr)
37134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      speex_bits_pack(bits, 1, 1);
37234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)}
373