annotate tremor/codebook.c @ 24362:93d5f228ff82

synced with r24381
author Gabrov
date Sun, 09 Sep 2007 12:19:57 +0000
parents cd6b211be811
children e83eef58b30a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
1 /********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
2 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
3 * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
4 * *
19251
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
5 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
6 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
7 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
cd6b211be811 Replace tremor files that had old headers saying "ALL REDISTRIBUTION
uau
parents: 14280
diff changeset
8 * *
14280
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
9 * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
10 * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
11 * *
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
12 ********************************************************************
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
13
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
14 function: basic codebook pack/unpack/code/decode operations
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
15
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
16 ********************************************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
17
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
18 #include <stdlib.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
19 #include <string.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
20 #include <math.h>
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
21 #include "ogg.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
22 #include "ivorbiscodec.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
23 #include "codebook.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
24 #include "misc.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
25 #include "os.h"
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
26
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
27 /* unpacks a codebook from the packet buffer into the codebook struct,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
28 readies the codebook auxiliary structures for decode *************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
29 int vorbis_staticbook_unpack(oggpack_buffer *opb,static_codebook *s){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
30 long i,j;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
31 memset(s,0,sizeof(*s));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
32
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
33 /* make sure alignment is correct */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
34 if(oggpack_read(opb,24)!=0x564342)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
35
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
36 /* first the basic parameters */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
37 s->dim=oggpack_read(opb,16);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
38 s->entries=oggpack_read(opb,24);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
39 if(s->entries==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
40
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
41 /* codeword ordering.... length ordered or unordered? */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
42 switch((int)oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
43 case 0:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
44 /* unordered */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
45 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
46
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
47 /* allocated but unused entries? */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
48 if(oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
49 /* yes, unused entries */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
50
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
51 for(i=0;i<s->entries;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
52 if(oggpack_read(opb,1)){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
53 long num=oggpack_read(opb,5);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
54 if(num==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
55 s->lengthlist[i]=num+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
56 }else
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
57 s->lengthlist[i]=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
58 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
59 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
60 /* all entries used; no tagging */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
61 for(i=0;i<s->entries;i++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
62 long num=oggpack_read(opb,5);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
63 if(num==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
64 s->lengthlist[i]=num+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
65 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
66 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
67
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
68 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
69 case 1:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
70 /* ordered */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
71 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
72 long length=oggpack_read(opb,5)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
73 s->lengthlist=(long *)_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
74
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
75 for(i=0;i<s->entries;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
76 long num=oggpack_read(opb,_ilog(s->entries-i));
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
77 if(num==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
78 for(j=0;j<num && i<s->entries;j++,i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
79 s->lengthlist[i]=length;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
80 length++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
81 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
82 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
83 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
84 default:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
85 /* EOF */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
86 return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
87 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
88
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
89 /* Do we have a mapping to unpack? */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
90 switch((s->maptype=oggpack_read(opb,4))){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
91 case 0:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
92 /* no mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
93 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
94 case 1: case 2:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
95 /* implicitly populated value mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
96 /* explicitly populated value mapping */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
97
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
98 s->q_min=oggpack_read(opb,32);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
99 s->q_delta=oggpack_read(opb,32);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
100 s->q_quant=oggpack_read(opb,4)+1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
101 s->q_sequencep=oggpack_read(opb,1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
102
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
103 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
104 int quantvals=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
105 switch(s->maptype){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
106 case 1:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
107 quantvals=_book_maptype1_quantvals(s);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
108 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
109 case 2:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
110 quantvals=s->entries*s->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
111 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
112 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
113
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
114 /* quantized values */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
115 s->quantlist=(long *)_ogg_malloc(sizeof(*s->quantlist)*quantvals);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
116 for(i=0;i<quantvals;i++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
117 s->quantlist[i]=oggpack_read(opb,s->q_quant);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
118
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
119 if(quantvals&&s->quantlist[quantvals-1]==-1)goto _eofout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
120 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
121 break;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
122 default:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
123 goto _errout;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
124 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
125
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
126 /* all set */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
127 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
128
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
129 _errout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
130 _eofout:
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
131 vorbis_staticbook_clear(s);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
132 return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
133 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
134
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
135 /* the 'eliminate the decode tree' optimization actually requires the
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
136 codewords to be MSb first, not LSb. This is an annoying inelegancy
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
137 (and one of the first places where carefully thought out design
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
138 turned out to be wrong; Vorbis II and future Ogg codecs should go
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
139 to an MSb bitpacker), but not actually the huge hit it appears to
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
140 be. The first-stage decode table catches most words so that
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
141 bitreverse is not in the main execution path. */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
142
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
143 static ogg_uint32_t bitreverse(ogg_uint32_t x){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
144 x= ((x>>16)&0x0000ffff) | ((x<<16)&0xffff0000);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
145 x= ((x>> 8)&0x00ff00ff) | ((x<< 8)&0xff00ff00);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
146 x= ((x>> 4)&0x0f0f0f0f) | ((x<< 4)&0xf0f0f0f0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
147 x= ((x>> 2)&0x33333333) | ((x<< 2)&0xcccccccc);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
148 return((x>> 1)&0x55555555) | ((x<< 1)&0xaaaaaaaa);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
149 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
150
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
151 static inline long decode_packed_entry_number(codebook *book,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
152 oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
153 int read=book->dec_maxlength;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
154 long lo,hi;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
155 long lok = oggpack_look(b,book->dec_firsttablen);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
156
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
157 if (lok >= 0) {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
158 long entry = book->dec_firsttable[lok];
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
159 if(entry&0x80000000UL){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
160 lo=(entry>>15)&0x7fff;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
161 hi=book->used_entries-(entry&0x7fff);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
162 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
163 oggpack_adv(b, book->dec_codelengths[entry-1]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
164 return(entry-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
165 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
166 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
167 lo=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
168 hi=book->used_entries;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
169 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
170
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
171 lok = oggpack_look(b, read);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
172
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
173 while(lok<0 && read>1)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
174 lok = oggpack_look(b, --read);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
175 if(lok<0)return -1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
176
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
177 /* bisect search for the codeword in the ordered list */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
178 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
179 ogg_uint32_t testword=bitreverse((ogg_uint32_t)lok);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
180
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
181 while(hi-lo>1){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
182 long p=(hi-lo)>>1;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
183 long test=book->codelist[lo+p]>testword;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
184 lo+=p&(test-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
185 hi-=p&(-test);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
186 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
187
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
188 if(book->dec_codelengths[lo]<=read){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
189 oggpack_adv(b, book->dec_codelengths[lo]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
190 return(lo);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
191 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
192 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
193
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
194 oggpack_adv(b, read);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
195 return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
196 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
197
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
198 /* Decode side is specced and easier, because we don't need to find
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
199 matches using different criteria; we simply read and map. There are
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
200 two things we need to do 'depending':
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
201
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
202 We may need to support interleave. We don't really, but it's
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
203 convenient to do it here rather than rebuild the vector later.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
204
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
205 Cascades may be additive or multiplicitive; this is not inherent in
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
206 the codebook, but set in the code using the codebook. Like
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
207 interleaving, it's easiest to do it here.
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
208 addmul==0 -> declarative (set the value)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
209 addmul==1 -> additive
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
210 addmul==2 -> multiplicitive */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
211
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
212 /* returns the [original, not compacted] entry number or -1 on eof *********/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
213 long vorbis_book_decode(codebook *book, oggpack_buffer *b){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
214 long packed_entry=decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
215 if(packed_entry>=0)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
216 return(book->dec_index[packed_entry]);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
217
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
218 /* if there's no dec_index, the codebook unpacking isn't collapsed */
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
219 return(packed_entry);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
220 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
221
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
222 /* returns 0 on OK or -1 on eof *************************************/
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
223 long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
224 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
225 int step=n/book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
226 long *entry = (long *)alloca(sizeof(*entry)*step);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
227 ogg_int32_t **t = (ogg_int32_t **)alloca(sizeof(*t)*step);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
228 int i,j,o;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
229 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
230
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
231 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
232 for (i = 0; i < step; i++) {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
233 entry[i]=decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
234 if(entry[i]==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
235 t[i] = book->valuelist+entry[i]*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
236 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
237 for(i=0,o=0;i<book->dim;i++,o+=step)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
238 for (j=0;j<step;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
239 a[o+j]+=t[j][i]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
240 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
241 for (i = 0; i < step; i++) {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
242 entry[i]=decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
243 if(entry[i]==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
244 t[i] = book->valuelist+entry[i]*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
245 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
246 for(i=0,o=0;i<book->dim;i++,o+=step)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
247 for (j=0;j<step;j++)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
248 a[o+j]+=t[j][i]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
249 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
250 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
251 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
252
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
253 long vorbis_book_decodev_add(codebook *book,ogg_int32_t *a,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
254 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
255 int i,j,entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
256 ogg_int32_t *t;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
257 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
258
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
259 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
260 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
261 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
262 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
263 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
264 for (j=0;j<book->dim;)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
265 a[i++]+=t[j++]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
266 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
267 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
268 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
269 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
270 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
271 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
272 for (j=0;j<book->dim;)
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
273 a[i++]+=t[j++]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
274 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
275 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
276 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
277 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
278
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
279 long vorbis_book_decodev_set(codebook *book,ogg_int32_t *a,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
280 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
281 int i,j,entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
282 ogg_int32_t *t;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
283 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
284
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
285 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
286
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
287 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
288 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
289 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
290 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
291 for (j=0;j<book->dim;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
292 a[i++]=t[j++]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
293 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
294 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
295 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
296
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
297 for(i=0;i<n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
298 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
299 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
300 t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
301 for (j=0;j<book->dim;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
302 a[i++]=t[j++]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
303 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
304 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
305 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
306 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
307 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
308
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
309 long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a,\
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
310 long offset,int ch,
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
311 oggpack_buffer *b,int n,int point){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
312 long i,j,entry;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
313 int chptr=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
314 int shift=point-book->binarypoint;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
315
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
316 if(shift>=0){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
317
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
318 for(i=offset;i<offset+n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
319 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
320 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
321 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
322 const ogg_int32_t *t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
323 for (j=0;j<book->dim;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
324 a[chptr++][i]+=t[j]>>shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
325 if(chptr==ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
326 chptr=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
327 i++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
328 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
329 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
330 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
331 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
332 }else{
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
333
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
334 for(i=offset;i<offset+n;){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
335 entry = decode_packed_entry_number(book,b);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
336 if(entry==-1)return(-1);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
337 {
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
338 const ogg_int32_t *t = book->valuelist+entry*book->dim;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
339 for (j=0;j<book->dim;j++){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
340 a[chptr++][i]+=t[j]<<-shift;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
341 if(chptr==ch){
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
342 chptr=0;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
343 i++;
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
344 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
345 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
346 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
347 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
348 }
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
349 return(0);
8631a3803289 internal Tremor decoder for Ogg/Vorbis
henry
parents:
diff changeset
350 }