1
/********************************************************************
3
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
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. *
9
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
10
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
12
********************************************************************
14
function: floor backend 1 implementation
16
********************************************************************/
22
#include "ivorbiscodec.h"
23
#include "codec_internal.h"
29
#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
32
int forward_index[VIF_POSIT+2];
34
int hineighbor[VIF_POSIT];
35
int loneighbor[VIF_POSIT];
40
vorbis_info_floor1 *vi;
44
/***********************************************/
46
static void floor1_free_info(vorbis_info_floor *i){
47
vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
49
memset(info,0,sizeof(*info));
54
static void floor1_free_look(vorbis_look_floor *i){
55
vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
57
memset(look,0,sizeof(*look));
62
static int ilog(unsigned int v){
71
static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
72
codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
73
int j,k,count=0,maxclass=-1,rangebits;
75
vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
77
info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
78
for(j=0;j<info->partitions;j++){
79
info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
80
if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
83
/* read partition classes */
84
for(j=0;j<maxclass+1;j++){
85
info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
86
info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
87
if(info->class_subs[j]<0)
89
if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
90
if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
92
for(k=0;k<(1<<info->class_subs[j]);k++){
93
info->class_subbook[j][k]=oggpack_read(opb,8)-1;
94
if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
99
/* read the post list */
100
info->mult=oggpack_read(opb,2)+1; /* only 1,2,3,4 legal now */
101
rangebits=oggpack_read(opb,4);
103
for(j=0,k=0;j<info->partitions;j++){
104
count+=info->class_dim[info->partitionclass[j]];
106
int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
107
if(t<0 || t>=(1<<rangebits))
112
info->postlist[1]=1<<rangebits;
117
floor1_free_info(info);
121
static int icomp(const void *a,const void *b){
122
return(**(int **)a-**(int **)b);
125
static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
126
vorbis_info_floor *in){
128
int *sortpointer[VIF_POSIT+2];
129
vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
130
vorbis_look_floor1 *look=(vorbis_look_floor1 *)_ogg_calloc(1,sizeof(*look));
134
look->n=info->postlist[1];
136
/* we drop each position value in-between already decoded values,
137
and use linear interpolation to predict each new value past the
138
edges. The positions are read in the order of the position
139
list... we precompute the bounding positions in the lookup. Of
140
course, the neighbors can change (if a position is declined), but
141
this is an initial mapping */
143
for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
147
/* also store a sorted position index */
148
for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
149
qsort(sortpointer,n,sizeof(*sortpointer),icomp);
151
/* points from sort order back to range number */
152
for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
154
/* quantize values to multiplier spec */
156
case 1: /* 1024 -> 256 */
159
case 2: /* 1024 -> 128 */
162
case 3: /* 1024 -> 86 */
165
case 4: /* 1024 -> 64 */
170
/* discover our neighbors for decode where we don't use fit flags
171
(that would push the neighbors outward) */
177
int currentx=info->postlist[i+2];
179
int x=info->postlist[j];
180
if(x>lx && x<currentx){
184
if(x<hx && x>currentx){
189
look->loneighbor[i]=lo;
190
look->hineighbor[i]=hi;
196
static int render_point(int x0,int x1,int y0,int y1,int x){
197
y0&=0x7fff; /* mask off flag */
207
if(dy<0)return(y0-off);
212
#ifdef _LOW_ACCURACY_
213
# define XdB(n) ((((n)>>8)+1)>>1)
218
static const ogg_int32_t FLOOR_fromdB_LOOKUP[256]={
219
XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114),
220
XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163),
221
XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9),
222
XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c),
223
XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4),
224
XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd),
225
XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4),
226
XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a),
227
XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818),
228
XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69),
229
XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64),
230
XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a),
231
XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629),
232
XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82),
233
XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac),
234
XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c),
235
XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf),
236
XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10),
237
XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b),
238
XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e),
239
XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d),
240
XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4),
241
XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd),
242
XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf),
243
XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e),
244
XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962),
245
XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109),
246
XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4),
247
XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23),
248
XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306),
249
XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20),
250
XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6),
251
XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471),
252
XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1),
253
XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7),
254
XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d),
255
XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1),
256
XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc),
257
XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2),
258
XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488),
259
XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0),
260
XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f),
261
XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41),
262
XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17),
263
XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e),
264
XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7),
265
XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf),
266
XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea),
267
XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793),
268
XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2),
269
XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013),
270
XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204),
271
XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299),
272
XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e),
273
XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca),
274
XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea),
275
XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1),
276
XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1),
277
XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870),
278
XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6),
279
XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44),
280
XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e),
281
XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298),
282
XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff),
285
static void render_line(int n, int x0,int x1,int y0,int y1,ogg_int32_t *d){
290
int sy=(dy<0?base-1:base+1);
299
d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
309
d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
313
static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
314
vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
315
vorbis_info_floor1 *info=look->vi;
316
codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
319
codebook *books=ci->fullbooks;
321
/* unpack wrapped/predicted values from stream */
322
if(oggpack_read(&vb->opb,1)==1){
323
int *fit_value=(int *)_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
325
fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
326
fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
328
/* partition by partition */
329
/* partition by partition */
330
for(i=0,j=2;i<info->partitions;i++){
331
int classv=info->partitionclass[i];
332
int cdim=info->class_dim[classv];
333
int csubbits=info->class_subs[classv];
334
int csub=1<<csubbits;
337
/* decode the partition's first stage cascade value */
339
cval=vorbis_book_decode(books+info->class_book[classv],&vb->opb);
341
if(cval==-1)goto eop;
345
int book=info->class_subbook[classv][cval&(csub-1)];
348
if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
357
/* unwrap positive values and reconsitute via linear interpolation */
358
for(i=2;i<look->posts;i++){
359
int predicted=render_point(info->postlist[look->loneighbor[i-2]],
360
info->postlist[look->hineighbor[i-2]],
361
fit_value[look->loneighbor[i-2]],
362
fit_value[look->hineighbor[i-2]],
364
int hiroom=look->quant_q-predicted;
365
int loroom=predicted;
366
int room=(hiroom<loroom?hiroom:loroom)<<1;
367
int val=fit_value[i];
374
val = -1-(val-hiroom);
384
fit_value[i]=val+predicted;
385
fit_value[look->loneighbor[i-2]]&=0x7fff;
386
fit_value[look->hineighbor[i-2]]&=0x7fff;
389
fit_value[i]=predicted|0x8000;
400
static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
402
vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
403
vorbis_info_floor1 *info=look->vi;
405
codec_setup_info *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
406
int n=ci->blocksizes[vb->W]/2;
410
/* render the lines */
411
int *fit_value=(int *)memo;
414
int ly=fit_value[0]*info->mult;
415
for(j=1;j<look->posts;j++){
416
int current=look->forward_index[j];
417
int hy=fit_value[current]&0x7fff;
418
if(hy==fit_value[current]){
421
hx=info->postlist[current];
423
render_line(n,lx,hx,ly,hy,out);
429
for(j=hx;j<n;j++)out[j]*=ly; /* be certain */
432
memset(out,0,sizeof(*out)*n);
437
vorbis_func_floor floor1_exportbundle={
438
&floor1_unpack,&floor1_look,&floor1_free_info,
439
&floor1_free_look,&floor1_inverse1,&floor1_inverse2