floor0.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  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-2003 *
  10. * BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: floor backend 0 implementation
  14. ********************************************************************/
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <math.h>
  18. #include "ogg.h"
  19. #include "ivorbiscodec.h"
  20. #include "codec_internal.h"
  21. #include "codebook.h"
  22. #include "misc.h"
  23. #include "os.h"
  24. #define LSP_FRACBITS 14
  25. extern const ogg_int32_t FLOOR_fromdB_LOOKUP[];
  26. /*************** LSP decode ********************/
  27. #include "lsp_lookup.h"
  28. /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
  29. 16.16 format
  30. returns in m.8 format */
  31. static long ADJUST_SQRT2[2]={8192,5792};
  32. static inline ogg_int32_t vorbis_invsqlook_i(long a,long e){
  33. long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1);
  34. long d=a&INVSQ_LOOKUP_I_MASK; /* 0.10 */
  35. long val=INVSQ_LOOKUP_I[i]- /* 1.16 */
  36. ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT); /* result 1.16 */
  37. val*=ADJUST_SQRT2[e&1];
  38. e=(e>>1)+21;
  39. return(val>>e);
  40. }
  41. /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
  42. /* a is in n.12 format */
  43. #ifdef _LOW_ACCURACY_
  44. static inline ogg_int32_t vorbis_fromdBlook_i(long a){
  45. if(a>0) return 0x7fffffff;
  46. if(a<(-140<<12)) return 0;
  47. return FLOOR_fromdB_LOOKUP[((a+140)*467)>>20]<<9;
  48. }
  49. #else
  50. static inline ogg_int32_t vorbis_fromdBlook_i(long a){
  51. if(a>0) return 0x7fffffff;
  52. if(a<(-140<<12)) return 0;
  53. return FLOOR_fromdB_LOOKUP[((a+(140<<12))*467)>>20];
  54. }
  55. #endif
  56. /* interpolated lookup based cos function, domain 0 to PI only */
  57. /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
  58. static inline ogg_int32_t vorbis_coslook_i(long a){
  59. int i=a>>COS_LOOKUP_I_SHIFT;
  60. int d=a&COS_LOOKUP_I_MASK;
  61. return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
  62. COS_LOOKUP_I_SHIFT);
  63. }
  64. /* interpolated half-wave lookup based cos function */
  65. /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
  66. static inline ogg_int32_t vorbis_coslook2_i(long a){
  67. int i=a>>COS_LOOKUP_I_SHIFT;
  68. int d=a&COS_LOOKUP_I_MASK;
  69. return ((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
  70. d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
  71. (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
  72. }
  73. static const ogg_uint16_t barklook[54]={
  74. 0,51,102,154, 206,258,311,365,
  75. 420,477,535,594, 656,719,785,854,
  76. 926,1002,1082,1166, 1256,1352,1454,1564,
  77. 1683,1812,1953,2107, 2276,2463,2670,2900,
  78. 3155,3440,3756,4106, 4493,4919,5387,5901,
  79. 6466,7094,7798,8599, 9528,10623,11935,13524,
  80. 15453,17775,20517,23667, 27183,31004
  81. };
  82. /* used in init only; interpolate the long way */
  83. static inline ogg_int32_t toBARK(int n){
  84. int i;
  85. for(i=0;i<54;i++)
  86. if(n>=barklook[i] && n<barklook[i+1])break;
  87. if(i==54){
  88. return 54<<14;
  89. }else{
  90. return (i<<14)+(((n-barklook[i])*
  91. ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17);
  92. }
  93. }
  94. static const unsigned char MLOOP_1[64]={
  95. 0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
  96. 14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
  97. 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
  98. 15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
  99. };
  100. static const unsigned char MLOOP_2[64]={
  101. 0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
  102. 8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
  103. 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
  104. 9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
  105. };
  106. static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
  107. void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
  108. ogg_int32_t *lsp,int m,
  109. ogg_int32_t amp,
  110. ogg_int32_t ampoffset,
  111. ogg_int32_t nyq){
  112. /* 0 <= m < 256 */
  113. /* set up for using all int later */
  114. int i;
  115. int ampoffseti=ampoffset*4096;
  116. int ampi=amp;
  117. ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
  118. ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq);
  119. ogg_uint32_t imap= (1UL<<31) / ln;
  120. ogg_uint32_t tBnyq1 = toBARK(nyq)<<1;
  121. /* Besenham for frequency scale to avoid a division */
  122. int f=0;
  123. int fdx=n;
  124. int fbase=nyq/fdx;
  125. int ferr=0;
  126. int fdy=nyq-fbase*fdx;
  127. int map=0;
  128. #ifdef _LOW_ACCURACY_
  129. ogg_uint32_t nextbark=((tBnyq1<<11)/ln)>>12;
  130. #else
  131. ogg_uint32_t nextbark=MULT31(imap>>1,tBnyq1);
  132. #endif
  133. int nextf=barklook[nextbark>>14]+(((nextbark&0x3fff)*
  134. (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
  135. /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
  136. for(i=0;i<m;i++){
  137. #ifndef _LOW_ACCURACY_
  138. ogg_int32_t val=MULT32(lsp[i],0x517cc2);
  139. #else
  140. ogg_int32_t val=((lsp[i]>>10)*0x517d)>>14;
  141. #endif
  142. /* safeguard against a malicious stream */
  143. if(val<0 || (val>>COS_LOOKUP_I_SHIFT)>=COS_LOOKUP_I_SZ){
  144. memset(curve,0,sizeof(*curve)*n);
  145. return;
  146. }
  147. ilsp[i]=vorbis_coslook_i(val);
  148. }
  149. i=0;
  150. while(i<n){
  151. int j;
  152. ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
  153. ogg_uint32_t qi=46341;
  154. ogg_int32_t qexp=0,shift;
  155. ogg_int32_t wi;
  156. wi=vorbis_coslook2_i((map*imap)>>15);
  157. #ifdef _V_LSP_MATH_ASM
  158. lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
  159. pi=((pi*pi)>>16);
  160. qi=((qi*qi)>>16);
  161. if(m&1){
  162. qexp= qexp*2-28*((m+1)>>1)+m;
  163. pi*=(1<<14)-((wi*wi)>>14);
  164. qi+=pi>>14;
  165. }else{
  166. qexp= qexp*2-13*m;
  167. pi*=(1<<14)-wi;
  168. qi*=(1<<14)+wi;
  169. qi=(qi+pi)>>14;
  170. }
  171. if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
  172. qi>>=1; qexp++;
  173. }else
  174. lsp_norm_asm(&qi,&qexp);
  175. #else
  176. qi*=labs(ilsp[0]-wi);
  177. pi*=labs(ilsp[1]-wi);
  178. for(j=3;j<m;j+=2){
  179. if(!(shift=MLOOP_1[(pi|qi)>>25]))
  180. if(!(shift=MLOOP_2[(pi|qi)>>19]))
  181. shift=MLOOP_3[(pi|qi)>>16];
  182. qi=(qi>>shift)*labs(ilsp[j-1]-wi);
  183. pi=(pi>>shift)*labs(ilsp[j]-wi);
  184. qexp+=shift;
  185. }
  186. if(!(shift=MLOOP_1[(pi|qi)>>25]))
  187. if(!(shift=MLOOP_2[(pi|qi)>>19]))
  188. shift=MLOOP_3[(pi|qi)>>16];
  189. /* pi,qi normalized collectively, both tracked using qexp */
  190. if(m&1){
  191. /* odd order filter; slightly assymetric */
  192. /* the last coefficient */
  193. qi=(qi>>shift)*labs(ilsp[j-1]-wi);
  194. pi=(pi>>shift)<<14;
  195. qexp+=shift;
  196. if(!(shift=MLOOP_1[(pi|qi)>>25]))
  197. if(!(shift=MLOOP_2[(pi|qi)>>19]))
  198. shift=MLOOP_3[(pi|qi)>>16];
  199. pi>>=shift;
  200. qi>>=shift;
  201. qexp+=shift-14*((m+1)>>1);
  202. pi=((pi*pi)>>16);
  203. qi=((qi*qi)>>16);
  204. qexp=qexp*2+m;
  205. pi*=(1<<14)-((wi*wi)>>14);
  206. qi+=pi>>14;
  207. }else{
  208. /* even order filter; still symmetric */
  209. /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
  210. worth tracking step by step */
  211. pi>>=shift;
  212. qi>>=shift;
  213. qexp+=shift-7*m;
  214. pi=((pi*pi)>>16);
  215. qi=((qi*qi)>>16);
  216. qexp=qexp*2+m;
  217. pi*=(1<<14)-wi;
  218. qi*=(1<<14)+wi;
  219. qi=(qi+pi)>>14;
  220. }
  221. /* we've let the normalization drift because it wasn't important;
  222. however, for the lookup, things must be normalized again. We
  223. need at most one right shift or a number of left shifts */
  224. if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
  225. qi>>=1; qexp++;
  226. }else
  227. while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
  228. qi<<=1; qexp--;
  229. }
  230. #endif
  231. amp=vorbis_fromdBlook_i(ampi* /* n.4 */
  232. vorbis_invsqlook_i(qi,qexp)-
  233. /* m.8, m+n<=8 */
  234. ampoffseti); /* 8.12[0] */
  235. #ifdef _LOW_ACCURACY_
  236. amp>>=9;
  237. #endif
  238. curve[i]= MULT31_SHIFT15(curve[i],amp);
  239. while(++i<n){
  240. /* line plot to get new f */
  241. ferr+=fdy;
  242. if(ferr>=fdx){
  243. ferr-=fdx;
  244. f++;
  245. }
  246. f+=fbase;
  247. if(f>=nextf)break;
  248. curve[i]= MULT31_SHIFT15(curve[i],amp);
  249. }
  250. while(1){
  251. map++;
  252. if(map+1<ln){
  253. #ifdef _LOW_ACCURACY_
  254. nextbark=((tBnyq1<<11)/ln*(map+1))>>12;
  255. #else
  256. nextbark=MULT31((map+1)*(imap>>1),tBnyq1);
  257. #endif
  258. nextf=barklook[nextbark>>14]+
  259. (((nextbark&0x3fff)*
  260. (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
  261. if(f<=nextf)break;
  262. }else{
  263. nextf=9999999;
  264. break;
  265. }
  266. }
  267. if(map>=ln){
  268. map=ln-1; /* guard against the approximation */
  269. nextf=9999999;
  270. }
  271. }
  272. }
  273. /*************** vorbis decode glue ************/
  274. void floor0_free_info(vorbis_info_floor *i){
  275. vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
  276. if(info)_ogg_free(info);
  277. }
  278. vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
  279. codec_setup_info *ci=(codec_setup_info *)vi->codec_setup;
  280. int j;
  281. vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
  282. info->order=oggpack_read(opb,8);
  283. info->rate=oggpack_read(opb,16);
  284. info->barkmap=oggpack_read(opb,16);
  285. info->ampbits=oggpack_read(opb,6);
  286. info->ampdB=oggpack_read(opb,8);
  287. info->numbooks=oggpack_read(opb,4)+1;
  288. if(info->order<1)goto err_out;
  289. if(info->rate<1)goto err_out;
  290. if(info->barkmap<1)goto err_out;
  291. for(j=0;j<info->numbooks;j++){
  292. info->books[j]=oggpack_read(opb,8);
  293. if(info->books[j]>=ci->books)goto err_out;
  294. }
  295. if(oggpack_eop(opb))goto err_out;
  296. return(info);
  297. err_out:
  298. floor0_free_info(info);
  299. return(NULL);
  300. }
  301. int floor0_memosize(vorbis_info_floor *i){
  302. vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
  303. return info->order+1;
  304. }
  305. ogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i,
  306. ogg_int32_t *lsp){
  307. vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
  308. int j,k;
  309. int ampraw=oggpack_read(&vd->opb,info->ampbits);
  310. if(ampraw>0){ /* also handles the -1 out of data case */
  311. long maxval=(1<<info->ampbits)-1;
  312. int amp=((ampraw*info->ampdB)<<4)/maxval;
  313. int booknum=oggpack_read(&vd->opb,_ilog(info->numbooks));
  314. if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
  315. codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
  316. codebook *b=ci->book_param+info->books[booknum];
  317. ogg_int32_t last=0;
  318. if(vorbis_book_decodev_set(b,lsp,&vd->opb,info->order,-24)==-1)goto eop;
  319. for(j=0;j<info->order;){
  320. for(k=0;j<info->order && k<b->dim;k++,j++)lsp[j]+=last;
  321. last=lsp[j-1];
  322. }
  323. lsp[info->order]=amp;
  324. return(lsp);
  325. }
  326. }
  327. eop:
  328. return(NULL);
  329. }
  330. int floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i,
  331. ogg_int32_t *lsp,ogg_int32_t *out){
  332. vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
  333. codec_setup_info *ci=(codec_setup_info *)vd->vi->codec_setup;
  334. if(lsp){
  335. ogg_int32_t amp=lsp[info->order];
  336. /* take the coefficients back to a spectral envelope curve */
  337. vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap,
  338. lsp,info->order,amp,info->ampdB,
  339. info->rate>>1);
  340. return(1);
  341. }
  342. memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2);
  343. return(0);
  344. }