annotate tremor/codebook.c @ 24588:8eb1ef462d29

codecs.conf: Change Monkey's Audio decoder status to "working" The FFmpeg issue that broke decoding of some files has been fixed and no other problems are known, so there's no need to mark it "buggy" any more.
author uau
date Mon, 24 Sep 2007 21:49:53 +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 }