comparison tremor/codebook.c @ 14280:8631a3803289

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