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 ********************************************************************/
18 #include "config-tremor.h"
22 #include "ivorbiscodec.h"
23 #include "codec_internal.h"
28 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
31 int forward_index
[VIF_POSIT
+2];
33 int hineighbor
[VIF_POSIT
];
34 int loneighbor
[VIF_POSIT
];
39 vorbis_info_floor1
*vi
;
43 /***********************************************/
45 static void floor1_free_info(vorbis_info_floor
*i
){
46 vorbis_info_floor1
*info
=(vorbis_info_floor1
*)i
;
48 //memset(info,0,sizeof(*info));
53 static void floor1_free_look(vorbis_look_floor
*i
){
54 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)i
;
56 //memset(look,0,sizeof(*look));
61 static inline int ilog(register unsigned int v
){
70 static vorbis_info_floor
*floor1_unpack (vorbis_info
*vi
,oggpack_buffer
*opb
){
71 codec_setup_info
*ci
=(codec_setup_info
*)vi
->codec_setup
;
72 int j
,k
,count
=0,maxclass
=-1,rangebits
;
74 vorbis_info_floor1
*info
=(vorbis_info_floor1
*)_ogg_calloc(1,sizeof(*info
));
76 info
->partitions
=oggpack_read(opb
,5); /* only 0 to 31 legal */
77 for(j
=0;j
<info
->partitions
;j
++){
78 info
->partitionclass
[j
]=oggpack_read(opb
,4); /* only 0 to 15 legal */
79 if(maxclass
<info
->partitionclass
[j
])maxclass
=info
->partitionclass
[j
];
82 /* read partition classes */
83 for(j
=0;j
<maxclass
+1;j
++){
84 info
->class_dim
[j
]=oggpack_read(opb
,3)+1; /* 1 to 8 */
85 info
->class_subs
[j
]=oggpack_read(opb
,2); /* 0,1,2,3 bits */
86 if(info
->class_subs
[j
]<0)
88 if(info
->class_subs
[j
])info
->class_book
[j
]=oggpack_read(opb
,8);
89 if(info
->class_book
[j
]<0 || info
->class_book
[j
]>=ci
->books
)
91 for(k
=0;k
<(1<<info
->class_subs
[j
]);k
++){
92 info
->class_subbook
[j
][k
]=oggpack_read(opb
,8)-1;
93 if(info
->class_subbook
[j
][k
]<-1 || info
->class_subbook
[j
][k
]>=ci
->books
)
98 /* read the post list */
99 info
->mult
=oggpack_read(opb
,2)+1; /* only 1,2,3,4 legal now */
100 rangebits
=oggpack_read(opb
,4);
102 for(j
=0,k
=0;j
<info
->partitions
;j
++){
103 count
+=info
->class_dim
[info
->partitionclass
[j
]];
105 int t
=info
->postlist
[k
+2]=oggpack_read(opb
,rangebits
);
106 if(t
<0 || t
>=(1<<rangebits
))
111 info
->postlist
[1]=1<<rangebits
;
116 floor1_free_info(info
);
120 static int icomp(const void *a
,const void *b
){
121 return(**(int **)a
-**(int **)b
);
124 static vorbis_look_floor
*floor1_look(vorbis_dsp_state
*vd
,vorbis_info_mode
*mi
,
125 vorbis_info_floor
*in
){
127 int *sortpointer
[VIF_POSIT
+2];
128 vorbis_info_floor1
*info
=(vorbis_info_floor1
*)in
;
129 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)_ogg_calloc(1,sizeof(*look
));
135 look
->n
=info
->postlist
[1];
137 /* we drop each position value in-between already decoded values,
138 and use linear interpolation to predict each new value past the
139 edges. The positions are read in the order of the position
140 list... we precompute the bounding positions in the lookup. Of
141 course, the neighbors can change (if a position is declined), but
142 this is an initial mapping */
144 for(i
=0;i
<info
->partitions
;i
++)n
+=info
->class_dim
[info
->partitionclass
[i
]];
148 /* also store a sorted position index */
149 for(i
=0;i
<n
;i
++)sortpointer
[i
]=info
->postlist
+i
;
150 qsort(sortpointer
,n
,sizeof(*sortpointer
),icomp
);
152 /* points from sort order back to range number */
153 for(i
=0;i
<n
;i
++)look
->forward_index
[i
]=sortpointer
[i
]-info
->postlist
;
155 /* quantize values to multiplier spec */
157 case 1: /* 1024 -> 256 */
160 case 2: /* 1024 -> 128 */
163 case 3: /* 1024 -> 86 */
166 case 4: /* 1024 -> 64 */
171 /* discover our neighbors for decode where we don't use fit flags
172 (that would push the neighbors outward) */
178 int currentx
=info
->postlist
[i
+2];
180 int x
=info
->postlist
[j
];
181 if(x
>lx
&& x
<currentx
){
185 if(x
<hx
&& x
>currentx
){
190 look
->loneighbor
[i
]=lo
;
191 look
->hineighbor
[i
]=hi
;
197 static int render_point(int x0
,int x1
,int y0
,int y1
,int x
){
198 y0
&=0x7fff; /* mask off flag */
200 return y0
+((y1
-y0
)*(x
-x0
))/(x1
-x0
);
203 #ifdef _LOW_ACCURACY_
204 # define XdB(n) ((((n)>>8)+1)>>1)
209 /* keep the floor lookup table in fast IRAM */
210 static const ogg_int32_t FLOOR_fromdB_LOOKUP
[256] ICONST_ATTR
= {
211 XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114),
212 XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163),
213 XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9),
214 XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c),
215 XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4),
216 XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd),
217 XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4),
218 XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a),
219 XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818),
220 XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69),
221 XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64),
222 XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a),
223 XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629),
224 XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82),
225 XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac),
226 XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c),
227 XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf),
228 XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10),
229 XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b),
230 XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e),
231 XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d),
232 XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4),
233 XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd),
234 XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf),
235 XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e),
236 XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962),
237 XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109),
238 XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4),
239 XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23),
240 XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306),
241 XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20),
242 XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6),
243 XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471),
244 XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1),
245 XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7),
246 XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d),
247 XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1),
248 XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc),
249 XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2),
250 XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488),
251 XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0),
252 XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f),
253 XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41),
254 XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17),
255 XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e),
256 XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7),
257 XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf),
258 XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea),
259 XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793),
260 XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2),
261 XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013),
262 XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204),
263 XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299),
264 XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e),
265 XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca),
266 XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea),
267 XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1),
268 XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1),
269 XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870),
270 XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6),
271 XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44),
272 XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e),
273 XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298),
274 XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff),
277 static void render_line(int n
, int x0
,register int x1
,int y0
,int y1
,ogg_int32_t
*d
){
281 register int adx
=x1
-x0
;
282 register int ady
=abs(dy
);
283 register int base
=dy
/adx
;
284 register int sy
=(dy
<0?base
-1:base
+1);
291 d
[x
]= MULT31_SHIFT15(d
[x
],FLOOR_fromdB_LOOKUP
[y
]);
301 d
[x
]= MULT31_SHIFT15(d
[x
],FLOOR_fromdB_LOOKUP
[y
]);
305 static void *floor1_inverse1(vorbis_block
*vb
,vorbis_look_floor
*in
)
306 ICODE_ATTR_TREMOR_NOT_MDCT
;
307 static void *floor1_inverse1(vorbis_block
*vb
,vorbis_look_floor
*in
){
308 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)in
;
309 vorbis_info_floor1
*info
=look
->vi
;
310 codec_setup_info
*ci
=(codec_setup_info
*)vb
->vd
->vi
->codec_setup
;
312 codebook
*books
=ci
->fullbooks
;
314 /* unpack wrapped/predicted values from stream */
315 if(oggpack_read(&vb
->opb
,1)==1){
316 int *fit_value
=(int *)_vorbis_block_alloc(vb
,(look
->posts
)*sizeof(*fit_value
));
317 int ilg
= ilog(look
->quant_q
-1);
318 fit_value
[0]=oggpack_read(&vb
->opb
,ilg
);
319 fit_value
[1]=oggpack_read(&vb
->opb
,ilg
);
321 /* partition by partition */
322 /* partition by partition */
323 for(i
=0,j
=2;i
<info
->partitions
;i
++){
324 int classv
=info
->partitionclass
[i
];
325 int cdim
=info
->class_dim
[classv
];
326 int csubbits
=info
->class_subs
[classv
];
327 int csub
=1<<csubbits
;
330 /* decode the partition's first stage cascade value */
332 cval
=vorbis_book_decode(books
+info
->class_book
[classv
],&vb
->opb
);
334 if(cval
==-1)goto eop
;
338 int book
=info
->class_subbook
[classv
][cval
&(csub
-1)];
341 if((fit_value
[j
+k
]=vorbis_book_decode(books
+book
,&vb
->opb
))==-1)
350 /* unwrap positive values and reconsitute via linear interpolation */
351 for(i
=2;i
<look
->posts
;i
++){
352 int predicted
=render_point(info
->postlist
[look
->loneighbor
[i
-2]],
353 info
->postlist
[look
->hineighbor
[i
-2]],
354 fit_value
[look
->loneighbor
[i
-2]],
355 fit_value
[look
->hineighbor
[i
-2]],
357 int hiroom
=look
->quant_q
-predicted
;
358 int loroom
=predicted
;
359 int room
=(hiroom
<loroom
?hiroom
:loroom
)<<1;
360 int val
=fit_value
[i
];
367 val
= -1-(val
-hiroom
);
377 fit_value
[i
]=val
+predicted
;
378 fit_value
[look
->loneighbor
[i
-2]]&=0x7fff;
379 fit_value
[look
->hineighbor
[i
-2]]&=0x7fff;
382 fit_value
[i
]=predicted
|0x8000;
392 static int floor1_inverse2(vorbis_block
*vb
,vorbis_look_floor
*in
,void *memo
,
393 ogg_int32_t
*out
) ICODE_ATTR_TREMOR_NOT_MDCT
;
394 static int floor1_inverse2(vorbis_block
*vb
,vorbis_look_floor
*in
,void *memo
,
396 vorbis_look_floor1
*look
=(vorbis_look_floor1
*)in
;
397 vorbis_info_floor1
*info
=look
->vi
;
399 codec_setup_info
*ci
=(codec_setup_info
*)vb
->vd
->vi
->codec_setup
;
400 int n
=ci
->blocksizes
[vb
->W
]/2;
404 /* render the lines */
405 int *fit_value
=(int *)memo
;
408 int ly
=fit_value
[0]*info
->mult
;
409 for(j
=1;j
<look
->posts
;j
++){
410 int current
=look
->forward_index
[j
];
411 int hy
=fit_value
[current
]&0x7fff;
412 if(hy
==fit_value
[current
]){
415 hx
=info
->postlist
[current
];
417 render_line(n
,lx
,hx
,ly
,hy
,out
);
423 for(j
=hx
;j
<n
;j
++)out
[j
]*=ly
; /* be certain */
426 memset(out
,0,sizeof(*out
)*n
);
431 const vorbis_func_floor floor1_exportbundle ICONST_ATTR
= {
432 &floor1_unpack
,&floor1_look
,&floor1_free_info
,
433 &floor1_free_look
,&floor1_inverse1
,&floor1_inverse2