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