psy.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
  5. * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6. * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
  9. * by the XIPHOPHORUS Company http://www.xiph.org/ *
  10. ********************************************************************
  11. function: psychoacoustics not including preecho
  12. last mod: $Id: psy.c,v 1.47 2001/06/18 09:07:31 xiphmont Exp $
  13. ********************************************************************/
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include <string.h>
  17. #include "vorbis/codec.h"
  18. #include "codec_internal.h"
  19. #include "masking.h"
  20. #include "psy.h"
  21. #include "os.h"
  22. #include "lpc.h"
  23. #include "smallft.h"
  24. #include "scales.h"
  25. #include "misc.h"
  26. #define NEGINF -9999.f
  27. /* Why Bark scale for encoding but not masking computation? Because
  28. masking has a strong harmonic dependancy */
  29. /* the beginnings of real psychoacoustic infrastructure. This is
  30. still not tightly tuned */
  31. void _vi_psy_free(vorbis_info_psy *i){
  32. if(i){
  33. memset(i,0,sizeof(vorbis_info_psy));
  34. _ogg_free(i);
  35. }
  36. }
  37. vorbis_info_psy *_vi_psy_copy(vorbis_info_psy *i){
  38. vorbis_info_psy *ret=_ogg_malloc(sizeof(vorbis_info_psy));
  39. memcpy(ret,i,sizeof(vorbis_info_psy));
  40. return(ret);
  41. }
  42. /* Set up decibel threshold slopes on a Bark frequency scale */
  43. /* ATH is the only bit left on a Bark scale. No reason to change it
  44. right now */
  45. static void set_curve(float *ref,float *c,int n, float crate){
  46. int i,j=0;
  47. for(i=0;i<MAX_BARK-1;i++){
  48. int endpos=rint(fromBARK(i+1)*2*n/crate);
  49. float base=ref[i];
  50. if(j<endpos){
  51. float delta=(ref[i+1]-base)/(endpos-j);
  52. for(;j<endpos && j<n;j++){
  53. c[j]=base;
  54. base+=delta;
  55. }
  56. }
  57. }
  58. }
  59. static void min_curve(float *c,
  60. float *c2){
  61. int i;
  62. for(i=0;i<EHMER_MAX;i++)if(c2[i]<c[i])c[i]=c2[i];
  63. }
  64. static void max_curve(float *c,
  65. float *c2){
  66. int i;
  67. for(i=0;i<EHMER_MAX;i++)if(c2[i]>c[i])c[i]=c2[i];
  68. }
  69. static void attenuate_curve(float *c,float att){
  70. int i;
  71. for(i=0;i<EHMER_MAX;i++)
  72. c[i]+=att;
  73. }
  74. static void interp_curve(float *c,float *c1,float *c2,float del){
  75. int i;
  76. for(i=0;i<EHMER_MAX;i++)
  77. c[i]=c2[i]*del+c1[i]*(1.f-del);
  78. }
  79. static void setup_curve(float **c,
  80. int band,
  81. float *curveatt_dB){
  82. int i,j;
  83. float ath[EHMER_MAX];
  84. float tempc[P_LEVELS][EHMER_MAX];
  85. float *ATH=ATH_Bark_dB_lspconservative; /* just for limiting here */
  86. memcpy(c[0]+2,c[4]+2,sizeof(float)*EHMER_MAX);
  87. memcpy(c[2]+2,c[4]+2,sizeof(float)*EHMER_MAX);
  88. /* we add back in the ATH to avoid low level curves falling off to
  89. -infinity and unneccessarily cutting off high level curves in the
  90. curve limiting (last step). But again, remember... a half-band's
  91. settings must be valid over the whole band, and it's better to
  92. mask too little than too much, so be pessimal. */
  93. for(i=0;i<EHMER_MAX;i++){
  94. float oc_min=band*.5+(i-EHMER_OFFSET)*.125;
  95. float oc_max=band*.5+(i-EHMER_OFFSET+1)*.125;
  96. float bark=toBARK(fromOC(oc_min));
  97. int ibark=floor(bark);
  98. float del=bark-ibark;
  99. float ath_min,ath_max;
  100. if(ibark<26)
  101. ath_min=ATH[ibark]*(1.f-del)+ATH[ibark+1]*del;
  102. else
  103. ath_min=ATH[25];
  104. bark=toBARK(fromOC(oc_max));
  105. ibark=floor(bark);
  106. del=bark-ibark;
  107. if(ibark<26)
  108. ath_max=ATH[ibark]*(1.f-del)+ATH[ibark+1]*del;
  109. else
  110. ath_max=ATH[25];
  111. ath[i]=min(ath_min,ath_max);
  112. }
  113. /* The c array is comes in as dB curves at 20 40 60 80 100 dB.
  114. interpolate intermediate dB curves */
  115. for(i=1;i<P_LEVELS;i+=2){
  116. interp_curve(c[i]+2,c[i-1]+2,c[i+1]+2,.5);
  117. }
  118. /* normalize curves so the driving amplitude is 0dB */
  119. /* make temp curves with the ATH overlayed */
  120. for(i=0;i<P_LEVELS;i++){
  121. attenuate_curve(c[i]+2,curveatt_dB[i]);
  122. memcpy(tempc[i],ath,EHMER_MAX*sizeof(float));
  123. attenuate_curve(tempc[i],-i*10.f);
  124. max_curve(tempc[i],c[i]+2);
  125. }
  126. /* Now limit the louder curves.
  127. the idea is this: We don't know what the playback attenuation
  128. will be; 0dB SL moves every time the user twiddles the volume
  129. knob. So that means we have to use a single 'most pessimal' curve
  130. for all masking amplitudes, right? Wrong. The *loudest* sound
  131. can be in (we assume) a range of ...+100dB] SL. However, sounds
  132. 20dB down will be in a range ...+80], 40dB down is from ...+60],
  133. etc... */
  134. for(j=1;j<P_LEVELS;j++){
  135. min_curve(tempc[j],tempc[j-1]);
  136. min_curve(c[j]+2,tempc[j]);
  137. }
  138. /* add fenceposts */
  139. for(j=0;j<P_LEVELS;j++){
  140. for(i=0;i<EHMER_MAX;i++)
  141. if(c[j][i+2]>-200.f)break;
  142. c[j][0]=i;
  143. for(i=EHMER_MAX-1;i>=0;i--)
  144. if(c[j][i+2]>-200.f)
  145. break;
  146. c[j][1]=i;
  147. }
  148. }
  149. void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
  150. long i,j,lo=0,hi=0;
  151. long maxoc;
  152. memset(p,0,sizeof(vorbis_look_psy));
  153. p->eighth_octave_lines=vi->eighth_octave_lines;
  154. p->shiftoc=rint(log(vi->eighth_octave_lines*8)/log(2))-1;
  155. p->firstoc=toOC(.25f*rate/n)*(1<<(p->shiftoc+1))-vi->eighth_octave_lines;
  156. maxoc=toOC((n*.5f-.25f)*rate/n)*(1<<(p->shiftoc+1))+.5f;
  157. p->total_octave_lines=maxoc-p->firstoc+1;
  158. if(vi->ath)
  159. p->ath=_ogg_malloc(n*sizeof(float));
  160. p->octave=_ogg_malloc(n*sizeof(long));
  161. p->bark=_ogg_malloc(n*sizeof(unsigned long));
  162. p->vi=vi;
  163. p->n=n;
  164. /* set up the lookups for a given blocksize and sample rate */
  165. /* Vorbis max sample rate is currently limited by 26 Bark (54kHz) */
  166. if(vi->ath)
  167. set_curve(vi->ath, p->ath,n,rate);
  168. for(i=0;i<n;i++){
  169. float bark=toBARK(rate/(2*n)*i);
  170. for(;lo+vi->noisewindowlomin<i &&
  171. toBARK(rate/(2*n)*lo)<(bark-vi->noisewindowlo);lo++);
  172. for(;hi<n && (hi<i+vi->noisewindowhimin ||
  173. toBARK(rate/(2*n)*hi)<(bark+vi->noisewindowhi));hi++);
  174. p->bark[i]=(hi<<16)+lo;
  175. }
  176. for(i=0;i<n;i++)
  177. p->octave[i]=toOC((i*.5f+.25f)*rate/n)*(1<<(p->shiftoc+1))+.5f;
  178. p->tonecurves=_ogg_malloc(P_BANDS*sizeof(float **));
  179. p->noisemedian=_ogg_malloc(n*sizeof(int));
  180. p->noiseoffset=_ogg_malloc(n*sizeof(float));
  181. p->peakatt=_ogg_malloc(P_BANDS*sizeof(float *));
  182. for(i=0;i<P_BANDS;i++){
  183. p->tonecurves[i]=_ogg_malloc(P_LEVELS*sizeof(float *));
  184. p->peakatt[i]=_ogg_malloc(P_LEVELS*sizeof(float));
  185. }
  186. for(i=0;i<P_BANDS;i++)
  187. for(j=0;j<P_LEVELS;j++){
  188. p->tonecurves[i][j]=_ogg_malloc((EHMER_MAX+2)*sizeof(float));
  189. }
  190. /* OK, yeah, this was a silly way to do it */
  191. memcpy(p->tonecurves[0][4]+2,tone_125_40dB_SL,sizeof(float)*EHMER_MAX);
  192. memcpy(p->tonecurves[0][6]+2,tone_125_60dB_SL,sizeof(float)*EHMER_MAX);
  193. memcpy(p->tonecurves[0][8]+2,tone_125_80dB_SL,sizeof(float)*EHMER_MAX);
  194. memcpy(p->tonecurves[0][10]+2,tone_125_100dB_SL,sizeof(float)*EHMER_MAX);
  195. memcpy(p->tonecurves[2][4]+2,tone_125_40dB_SL,sizeof(float)*EHMER_MAX);
  196. memcpy(p->tonecurves[2][6]+2,tone_125_60dB_SL,sizeof(float)*EHMER_MAX);
  197. memcpy(p->tonecurves[2][8]+2,tone_125_80dB_SL,sizeof(float)*EHMER_MAX);
  198. memcpy(p->tonecurves[2][10]+2,tone_125_100dB_SL,sizeof(float)*EHMER_MAX);
  199. memcpy(p->tonecurves[4][4]+2,tone_250_40dB_SL,sizeof(float)*EHMER_MAX);
  200. memcpy(p->tonecurves[4][6]+2,tone_250_60dB_SL,sizeof(float)*EHMER_MAX);
  201. memcpy(p->tonecurves[4][8]+2,tone_250_80dB_SL,sizeof(float)*EHMER_MAX);
  202. memcpy(p->tonecurves[4][10]+2,tone_250_100dB_SL,sizeof(float)*EHMER_MAX);
  203. memcpy(p->tonecurves[6][4]+2,tone_500_40dB_SL,sizeof(float)*EHMER_MAX);
  204. memcpy(p->tonecurves[6][6]+2,tone_500_60dB_SL,sizeof(float)*EHMER_MAX);
  205. memcpy(p->tonecurves[6][8]+2,tone_500_80dB_SL,sizeof(float)*EHMER_MAX);
  206. memcpy(p->tonecurves[6][10]+2,tone_500_100dB_SL,sizeof(float)*EHMER_MAX);
  207. memcpy(p->tonecurves[8][4]+2,tone_1000_40dB_SL,sizeof(float)*EHMER_MAX);
  208. memcpy(p->tonecurves[8][6]+2,tone_1000_60dB_SL,sizeof(float)*EHMER_MAX);
  209. memcpy(p->tonecurves[8][8]+2,tone_1000_80dB_SL,sizeof(float)*EHMER_MAX);
  210. memcpy(p->tonecurves[8][10]+2,tone_1000_100dB_SL,sizeof(float)*EHMER_MAX);
  211. memcpy(p->tonecurves[10][4]+2,tone_2000_40dB_SL,sizeof(float)*EHMER_MAX);
  212. memcpy(p->tonecurves[10][6]+2,tone_2000_60dB_SL,sizeof(float)*EHMER_MAX);
  213. memcpy(p->tonecurves[10][8]+2,tone_2000_80dB_SL,sizeof(float)*EHMER_MAX);
  214. memcpy(p->tonecurves[10][10]+2,tone_2000_100dB_SL,sizeof(float)*EHMER_MAX);
  215. memcpy(p->tonecurves[12][4]+2,tone_4000_40dB_SL,sizeof(float)*EHMER_MAX);
  216. memcpy(p->tonecurves[12][6]+2,tone_4000_60dB_SL,sizeof(float)*EHMER_MAX);
  217. memcpy(p->tonecurves[12][8]+2,tone_4000_80dB_SL,sizeof(float)*EHMER_MAX);
  218. memcpy(p->tonecurves[12][10]+2,tone_4000_100dB_SL,sizeof(float)*EHMER_MAX);
  219. memcpy(p->tonecurves[14][4]+2,tone_8000_40dB_SL,sizeof(float)*EHMER_MAX);
  220. memcpy(p->tonecurves[14][6]+2,tone_8000_60dB_SL,sizeof(float)*EHMER_MAX);
  221. memcpy(p->tonecurves[14][8]+2,tone_8000_80dB_SL,sizeof(float)*EHMER_MAX);
  222. memcpy(p->tonecurves[14][10]+2,tone_8000_100dB_SL,sizeof(float)*EHMER_MAX);
  223. memcpy(p->tonecurves[16][4]+2,tone_8000_40dB_SL,sizeof(float)*EHMER_MAX);
  224. memcpy(p->tonecurves[16][6]+2,tone_8000_60dB_SL,sizeof(float)*EHMER_MAX);
  225. memcpy(p->tonecurves[16][8]+2,tone_8000_80dB_SL,sizeof(float)*EHMER_MAX);
  226. memcpy(p->tonecurves[16][10]+2,tone_8000_100dB_SL,sizeof(float)*EHMER_MAX);
  227. /* interpolate curves between */
  228. for(i=1;i<P_BANDS;i+=2)
  229. for(j=4;j<P_LEVELS;j+=2){
  230. memcpy(p->tonecurves[i][j]+2,p->tonecurves[i-1][j]+2,EHMER_MAX*sizeof(float));
  231. /*interp_curve(p->tonecurves[i][j],
  232. p->tonecurves[i-1][j],
  233. p->tonecurves[i+1][j],.5);*/
  234. min_curve(p->tonecurves[i][j]+2,p->tonecurves[i+1][j]+2);
  235. }
  236. /* set up the final curves */
  237. for(i=0;i<P_BANDS;i++)
  238. setup_curve(p->tonecurves[i],i,vi->toneatt[i]);
  239. /* set up attenuation levels */
  240. for(i=0;i<P_BANDS;i++)
  241. for(j=0;j<P_LEVELS;j++){
  242. p->peakatt[i][j]=p->vi->peakatt[i][j];
  243. }
  244. /* set up rolling noise median */
  245. for(i=0;i<n;i++){
  246. float halfoc=toOC((i+.5)*rate/(2.*n))*2.+2.;
  247. int inthalfoc;
  248. float del;
  249. if(halfoc<0)halfoc=0;
  250. if(halfoc>=P_BANDS-1)halfoc=P_BANDS-1;
  251. inthalfoc=(int)halfoc;
  252. del=halfoc-inthalfoc;
  253. p->noisemedian[i]=rint(
  254. (p->vi->noisemedian[inthalfoc*2]*(1.-del) +
  255. p->vi->noisemedian[inthalfoc*2+2]*del)*1024.f);
  256. p->noiseoffset[i]=
  257. p->vi->noisemedian[inthalfoc*2+1]*(1.-del) +
  258. p->vi->noisemedian[inthalfoc*2+3]*del -
  259. 140.f;
  260. }
  261. /*_analysis_output("mediancurve",0,p->noisemedian,n,0,0);*/
  262. }
  263. void _vp_psy_clear(vorbis_look_psy *p){
  264. int i,j;
  265. if(p){
  266. if(p->ath)_ogg_free(p->ath);
  267. if(p->octave)_ogg_free(p->octave);
  268. if(p->bark)_ogg_free(p->bark);
  269. if(p->tonecurves){
  270. for(i=0;i<P_BANDS;i++){
  271. for(j=0;j<P_LEVELS;j++){
  272. _ogg_free(p->tonecurves[i][j]);
  273. }
  274. _ogg_free(p->tonecurves[i]);
  275. _ogg_free(p->peakatt[i]);
  276. }
  277. _ogg_free(p->tonecurves);
  278. _ogg_free(p->noisemedian);
  279. _ogg_free(p->noiseoffset);
  280. _ogg_free(p->peakatt);
  281. }
  282. memset(p,0,sizeof(vorbis_look_psy));
  283. }
  284. }
  285. /* octave/(8*eighth_octave_lines) x scale and dB y scale */
  286. static void seed_curve(float *seed,
  287. const float **curves,
  288. float amp,
  289. int oc, int n,
  290. int linesper,float dBoffset){
  291. int i,post1;
  292. int seedptr;
  293. const float *posts,*curve;
  294. int choice=(int)((amp+dBoffset)*.1f);
  295. choice=max(choice,0);
  296. choice=min(choice,P_LEVELS-1);
  297. posts=curves[choice];
  298. curve=posts+2;
  299. post1=(int)posts[1];
  300. seedptr=oc+(posts[0]-16)*linesper-(linesper>>1);
  301. for(i=posts[0];i<post1;i++){
  302. if(seedptr>0){
  303. float lin=amp+curve[i];
  304. if(seed[seedptr]<lin)seed[seedptr]=lin;
  305. }
  306. seedptr+=linesper;
  307. if(seedptr>=n)break;
  308. }
  309. }
  310. static void seed_peak(float *seed,
  311. const float *att,
  312. float amp,
  313. int oc,
  314. int linesper,
  315. float dBoffset){
  316. long seedptr;
  317. int choice=(int)((amp+dBoffset)*.1f);
  318. choice=max(choice,0);
  319. choice=min(choice,P_LEVELS-1);
  320. seedptr=oc-(linesper>>1);
  321. amp+=att[choice];
  322. if(seed[seedptr]<amp)seed[seedptr]=amp;
  323. }
  324. static void seed_loop(vorbis_look_psy *p,
  325. const float ***curves,
  326. const float **att,
  327. const float *f,
  328. const float *flr,
  329. float *minseed,
  330. float *maxseed,
  331. float specmax){
  332. vorbis_info_psy *vi=p->vi;
  333. long n=p->n,i;
  334. float dBoffset=vi->max_curve_dB-specmax;
  335. /* prime the working vector with peak values */
  336. for(i=0;i<n;i++){
  337. float max=f[i];
  338. long oc=p->octave[i];
  339. while(i+1<n && p->octave[i+1]==oc){
  340. i++;
  341. if(f[i]>max)max=f[i];
  342. }
  343. if(max>flr[i]){
  344. oc=oc>>p->shiftoc;
  345. if(oc>=P_BANDS)oc=P_BANDS-1;
  346. if(oc<0)oc=0;
  347. if(vi->tonemaskp)
  348. seed_curve(minseed,
  349. curves[oc],
  350. max,
  351. p->octave[i]-p->firstoc,
  352. p->total_octave_lines,
  353. p->eighth_octave_lines,
  354. dBoffset);
  355. if(vi->peakattp)
  356. seed_peak(maxseed,
  357. att[oc],
  358. max,
  359. p->octave[i]-p->firstoc,
  360. p->eighth_octave_lines,
  361. dBoffset);
  362. }
  363. }
  364. }
  365. static void bound_loop(vorbis_look_psy *p,
  366. float *f,
  367. float *seeds,
  368. float *flr,
  369. float att){
  370. long n=p->n,i;
  371. long off=(p->eighth_octave_lines>>1)+p->firstoc;
  372. long *ocp=p->octave;
  373. for(i=0;i<n;i++){
  374. long oc=ocp[i]-off;
  375. float v=f[i]+att;
  376. if(seeds[oc]<v)seeds[oc]=v;
  377. }
  378. }
  379. static void seed_chase(float *seeds, int linesper, long n){
  380. long *posstack=alloca(n*sizeof(long));
  381. float *ampstack=alloca(n*sizeof(float));
  382. long stack=0;
  383. long pos=0;
  384. long i;
  385. for(i=0;i<n;i++){
  386. if(stack<2){
  387. posstack[stack]=i;
  388. ampstack[stack++]=seeds[i];
  389. }else{
  390. while(1){
  391. if(seeds[i]<ampstack[stack-1]){
  392. posstack[stack]=i;
  393. ampstack[stack++]=seeds[i];
  394. break;
  395. }else{
  396. if(i<posstack[stack-1]+linesper){
  397. if(stack>1 && ampstack[stack-1]<=ampstack[stack-2] &&
  398. i<posstack[stack-2]+linesper){
  399. /* we completely overlap, making stack-1 irrelevant. pop it */
  400. stack--;
  401. continue;
  402. }
  403. }
  404. posstack[stack]=i;
  405. ampstack[stack++]=seeds[i];
  406. break;
  407. }
  408. }
  409. }
  410. }
  411. /* the stack now contains only the positions that are relevant. Scan
  412. 'em straight through */
  413. for(i=0;i<stack;i++){
  414. long endpos;
  415. if(i<stack-1 && ampstack[i+1]>ampstack[i]){
  416. endpos=posstack[i+1];
  417. }else{
  418. endpos=posstack[i]+linesper+1; /* +1 is important, else bin 0 is
  419. discarded in short frames */
  420. }
  421. if(endpos>n)endpos=n;
  422. for(;pos<endpos;pos++)
  423. seeds[pos]=ampstack[i];
  424. }
  425. /* there. Linear time. I now remember this was on a problem set I
  426. had in Grad Skool... I didn't solve it at the time ;-) */
  427. }
  428. /* bleaugh, this is more complicated than it needs to be */
  429. static void max_seeds(vorbis_look_psy *p,float *minseed,float *maxseed,
  430. float *flr){
  431. long n=p->total_octave_lines;
  432. int linesper=p->eighth_octave_lines;
  433. long linpos=0;
  434. long pos;
  435. seed_chase(minseed,linesper,n); /* for masking */
  436. seed_chase(maxseed,linesper,n); /* for peak att */
  437. pos=p->octave[0]-p->firstoc-(linesper>>1);
  438. while(linpos+1<p->n){
  439. float min=minseed[pos];
  440. float max=maxseed[pos];
  441. long end=((p->octave[linpos]+p->octave[linpos+1])>>1)-p->firstoc;
  442. while(pos+1<=end){
  443. pos++;
  444. if((minseed[pos]>NEGINF && minseed[pos]<min) || min==NEGINF)
  445. min=minseed[pos];
  446. if(maxseed[pos]>max)max=maxseed[pos];
  447. }
  448. if(max<min)max=min;
  449. /* seed scale is log. Floor is linear. Map back to it */
  450. end=pos+p->firstoc;
  451. for(;linpos<p->n && p->octave[linpos]<=end;linpos++)
  452. if(flr[linpos]<max)flr[linpos]=max;
  453. }
  454. {
  455. float min=minseed[p->total_octave_lines-1];
  456. float max=maxseed[p->total_octave_lines-1];
  457. if(max<min)max=min;
  458. for(;linpos<p->n;linpos++)
  459. if(flr[linpos]<max)flr[linpos]=max;
  460. }
  461. }
  462. /* set to match vorbis_quantdblook.h */
  463. #define BINCOUNT 280
  464. #define LASTBIN (BINCOUNT-1)
  465. static int psy_dBquant(const float *x){
  466. int i= *x*2.f+279.5f;
  467. if(i>279)return(279);
  468. if(i<0)return(0);
  469. return i;
  470. }
  471. static void bark_noise_median(int n,const long *b,const float *f,
  472. float *noise,
  473. float lowidth,float hiwidth,
  474. int lomin,int himin,
  475. const int *thresh,const float *off,
  476. int fixed){
  477. int i=0,lo=-1,hi=-1,fixedc=0;
  478. int median=LASTBIN>>1;
  479. int barkradix[BINCOUNT];
  480. int barkcountbelow=0;
  481. int fixedradix[BINCOUNT];
  482. int fixedcountbelow=0;
  483. memset(barkradix,0,sizeof(barkradix));
  484. if(fixed>0){
  485. memset(fixedradix,0,sizeof(fixedradix));
  486. /* bootstrap the fixed window case seperately */
  487. for(i=0;i<(fixed>>1);i++){
  488. int bin=psy_dBquant(f+i);
  489. fixedradix[bin]++;
  490. fixedc++;
  491. if(bin<=median)
  492. fixedcountbelow++;
  493. }
  494. }
  495. for(i=0;i<n;i++){
  496. /* find new lo/hi */
  497. int bi=b[i]>>16;
  498. for(;hi<bi;hi++){
  499. int bin=psy_dBquant(f+hi);
  500. barkradix[bin]++;
  501. if(bin<=median)
  502. barkcountbelow++;
  503. }
  504. bi=b[i]&0xffff;
  505. for(;lo<bi;lo++){
  506. int bin=psy_dBquant(f+lo);
  507. barkradix[bin]--;
  508. if(bin<=median)
  509. barkcountbelow--;
  510. }
  511. if(fixed>0){
  512. bi=i+(fixed>>1);
  513. if(bi<n){
  514. int bin=psy_dBquant(f+bi);
  515. fixedradix[bin]++;
  516. fixedc++;
  517. if(bin<=median)
  518. fixedcountbelow++;
  519. }
  520. bi-=fixed;
  521. if(bi>=0){
  522. int bin=psy_dBquant(f+bi);
  523. fixedradix[bin]--;
  524. fixedc--;
  525. if(bin<=median)
  526. fixedcountbelow--;
  527. }
  528. }
  529. /* move the median if needed */
  530. {
  531. int bark_th = (thresh[i]*(hi-lo)+512)/1024;
  532. if(fixed>0){
  533. int fixed_th = (thresh[i]*(fixedc)+512)/1024;
  534. while(bark_th>=barkcountbelow &&
  535. fixed_th>=fixedcountbelow /* && median<LASTBIN by rep invariant */
  536. ){
  537. median++;
  538. barkcountbelow+=barkradix[median];
  539. fixedcountbelow+=fixedradix[median];
  540. }
  541. while(bark_th<barkcountbelow ||
  542. fixed_th<fixedcountbelow /* && median>=0 by rep invariant */
  543. ){
  544. barkcountbelow-=barkradix[median];
  545. fixedcountbelow-=fixedradix[median];
  546. median--;
  547. }
  548. }else{
  549. while(bark_th>=barkcountbelow){
  550. median++;
  551. barkcountbelow+=barkradix[median];
  552. }
  553. while(bark_th<barkcountbelow){
  554. barkcountbelow-=barkradix[median];
  555. median--;
  556. }
  557. }
  558. }
  559. noise[i]= (median+1)*.5f+off[i];
  560. }
  561. }
  562. float _vp_compute_mask(vorbis_look_psy *p,
  563. float *fft,
  564. float *mdct,
  565. float *mask,
  566. float specmax){
  567. int i,n=p->n;
  568. float localmax=NEGINF;
  569. static int seq=0;
  570. float *minseed=alloca(sizeof(float)*p->total_octave_lines);
  571. float *maxseed=alloca(sizeof(float)*p->total_octave_lines);
  572. for(i=0;i<p->total_octave_lines;i++)minseed[i]=maxseed[i]=NEGINF;
  573. /* Find the highest peak so we know the limits */
  574. for(i=0;i<n;i++)
  575. if(fft[i]>localmax)localmax=fft[i];
  576. if(specmax<localmax)specmax=localmax;
  577. /* noise masking */
  578. if(p->vi->noisemaskp){
  579. bark_noise_median(n,p->bark,mdct,mask,
  580. p->vi->noisewindowlo,
  581. p->vi->noisewindowhi,
  582. p->vi->noisewindowlomin,
  583. p->vi->noisewindowhimin,
  584. p->noisemedian,
  585. p->noiseoffset,
  586. p->vi->noisewindowfixed);
  587. /* suppress any noise curve > specmax+p->vi->noisemaxsupp */
  588. for(i=0;i<n;i++)
  589. if(mask[i]>specmax+p->vi->noisemaxsupp)
  590. mask[i]=specmax+p->vi->noisemaxsupp;
  591. _analysis_output("noise",seq,mask,n,0,0);
  592. }else{
  593. for(i=0;i<n;i++)mask[i]=NEGINF;
  594. }
  595. /* set the ATH (floating below localmax, not global max by a
  596. specified att) */
  597. if(p->vi->ath){
  598. float att=localmax+p->vi->ath_adjatt;
  599. if(att<p->vi->ath_maxatt)att=p->vi->ath_maxatt;
  600. for(i=0;i<n;i++){
  601. float av=p->ath[i]+att;
  602. if(av>mask[i])mask[i]=av;
  603. }
  604. }
  605. /* tone/peak masking */
  606. /* XXX apply decay to the fft here */
  607. seed_loop(p,
  608. (const float ***)p->tonecurves,
  609. (const float **)p->peakatt,fft,mask,minseed,maxseed,specmax);
  610. bound_loop(p,mdct,maxseed,mask,p->vi->bound_att_dB);
  611. max_seeds(p,minseed,maxseed,mask);
  612. /* doing this here is clean, but we need to find a faster way to do
  613. it than to just tack it on */
  614. for(i=0;i<n;i++)if(mdct[i]>=mask[i])break;
  615. if(i==n)
  616. for(i=0;i<n;i++)mask[i]=NEGINF;
  617. else
  618. for(i=0;i<n;i++)fft[i]=max(mdct[i],fft[i]);
  619. seq++;
  620. return(specmax);
  621. }
  622. float _vp_ampmax_decay(float amp,vorbis_dsp_state *vd){
  623. vorbis_info *vi=vd->vi;
  624. codec_setup_info *ci=vi->codec_setup;
  625. int n=ci->blocksizes[vd->W]/2;
  626. float secs=(float)n/vi->rate;
  627. amp+=secs*ci->ampmax_att_per_sec;
  628. if(amp<-9999)amp=-9999;
  629. return(amp);
  630. }