psytune.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
  6. * PLEASE READ THESE TERMS DISTRIBUTING. *
  7. * *
  8. * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
  9. * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
  10. * http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: simple utility that runs audio through the psychoacoustics
  14. without encoding
  15. last mod: $Id: psytune.c,v 1.1.2.2.2.9 2000/05/08 08:25:43 xiphmont Exp $
  16. ********************************************************************/
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <math.h>
  21. #include "vorbis/codec.h"
  22. #include "os.h"
  23. #include "psy.h"
  24. #include "mdct.h"
  25. #include "window.h"
  26. #include "scales.h"
  27. #include "lpc.h"
  28. static vorbis_info_psy _psy_set0={
  29. 1,/*athp*/
  30. 1,/*decayp*/
  31. 1,/*smoothp*/
  32. 1,8,0.,
  33. -130.,
  34. 1,/* tonemaskp*/
  35. {-35.,-40.,-60.,-80.,-80.}, /* remember that el 4 is an 80 dB curve, not 100 */
  36. {-35.,-40.,-60.,-80.,-95.},
  37. {-35.,-40.,-60.,-80.,-95.},
  38. {-35.,-40.,-60.,-80.,-95.},
  39. {-35.,-40.,-60.,-80.,-95.},
  40. {-65.,-60.,-60.,-80.,-90.}, /* remember that el 1 is a 60 dB curve, not 40 */
  41. 1,/*noisemaskp*/
  42. {-100.,-100.,-100.,-200.,-200.}, /* this is the 500 Hz curve, which
  43. is too wrong to work */
  44. {-60.,-60.,-60.,-80.,-80.},
  45. {-60.,-60.,-60.,-80.,-80.},
  46. {-60.,-60.,-60.,-80.,-80.},
  47. {-60.,-60.,-60.,-80.,-80.},
  48. {-50.,-55.,-60.,-80.,-80.},
  49. 110.,
  50. .9998, .9997 /* attack/decay control */
  51. };
  52. static int noisy=0;
  53. void analysis(char *base,int i,double *v,int n,int bark,int dB){
  54. if(noisy){
  55. int j;
  56. FILE *of;
  57. char buffer[80];
  58. sprintf(buffer,"%s_%d.m",base,i);
  59. of=fopen(buffer,"w");
  60. for(j=0;j<n;j++){
  61. if(dB && v[j]==0)
  62. fprintf(of,"\n\n");
  63. else{
  64. if(bark)
  65. fprintf(of,"%g ",toBARK(22050.*j/n));
  66. else
  67. fprintf(of,"%g ",(double)j);
  68. if(dB){
  69. fprintf(of,"%g\n",todB(fabs(v[j])));
  70. }else{
  71. fprintf(of,"%g\n",v[j]);
  72. }
  73. }
  74. }
  75. fclose(of);
  76. }
  77. }
  78. typedef struct {
  79. long n;
  80. int ln;
  81. int m;
  82. int *linearmap;
  83. vorbis_info_floor0 *vi;
  84. lpc_lookup lpclook;
  85. } vorbis_look_floor0;
  86. extern double _curve_to_lpc(double *curve,double *lpc,vorbis_look_floor0 *l,
  87. long frameno);
  88. extern void _lpc_to_curve(double *curve,double *lpc,double amp,
  89. vorbis_look_floor0 *l,char *name,long frameno);
  90. long frameno=0;
  91. /* hacked from floor0.c */
  92. static void floorinit(vorbis_look_floor0 *look,int n,int m,int ln){
  93. int j;
  94. double scale;
  95. look->m=m;
  96. look->n=n;
  97. look->ln=ln;
  98. lpc_init(&look->lpclook,look->ln,look->m);
  99. scale=look->ln/toBARK(22050.);
  100. look->linearmap=malloc(look->n*sizeof(int));
  101. for(j=0;j<look->n;j++){
  102. int val=floor( toBARK(22050./n*j) *scale);
  103. if(val>look->ln)val=look->ln;
  104. look->linearmap[j]=val;
  105. }
  106. }
  107. int main(int argc,char *argv[]){
  108. int eos=0;
  109. double nonz=0.;
  110. double acc=0.;
  111. double tot=0.;
  112. int framesize=2048;
  113. int order=32;
  114. double *pcm[2],*out[2],*window,*decay[2],*lpc,*floor,*mask;
  115. signed char *buffer,*buffer2;
  116. mdct_lookup m_look;
  117. vorbis_look_psy p_look;
  118. long i,j,k;
  119. vorbis_look_floor0 floorlook;
  120. int ath=0;
  121. int decayp=0;
  122. argv++;
  123. while(*argv){
  124. if(*argv[0]=='-'){
  125. /* option */
  126. if(argv[0][1]=='v'){
  127. noisy=0;
  128. }
  129. if(argv[0][1]=='A'){
  130. ath=0;
  131. }
  132. if(argv[0][1]=='D'){
  133. decayp=0;
  134. }
  135. if(argv[0][1]=='X'){
  136. ath=0;
  137. decayp=0;
  138. }
  139. }else
  140. if(*argv[0]=='+'){
  141. /* option */
  142. if(argv[0][1]=='v'){
  143. noisy=1;
  144. }
  145. if(argv[0][1]=='A'){
  146. ath=1;
  147. }
  148. if(argv[0][1]=='D'){
  149. decayp=1;
  150. }
  151. if(argv[0][1]=='X'){
  152. ath=1;
  153. decayp=1;
  154. }
  155. }else
  156. framesize=atoi(argv[0]);
  157. argv++;
  158. }
  159. pcm[0]=malloc(framesize*sizeof(double));
  160. pcm[1]=malloc(framesize*sizeof(double));
  161. out[0]=calloc(framesize/2,sizeof(double));
  162. out[1]=calloc(framesize/2,sizeof(double));
  163. decay[0]=calloc(framesize/2,sizeof(double));
  164. decay[1]=calloc(framesize/2,sizeof(double));
  165. floor=malloc(framesize*sizeof(double));
  166. mask=malloc(framesize*sizeof(double));
  167. lpc=malloc(order*sizeof(double));
  168. buffer=malloc(framesize*4);
  169. buffer2=buffer+framesize*2;
  170. window=_vorbis_window(0,framesize,framesize/2,framesize/2);
  171. mdct_init(&m_look,framesize);
  172. _vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
  173. floorinit(&floorlook,framesize/2,order,framesize/8);
  174. for(i=0;i<11;i++)
  175. for(j=0;j<9;j++)
  176. analysis("Ptonecurve",i*10+j,p_look.tonecurves[i][j],EHMER_MAX,0,1);
  177. for(i=0;i<11;i++)
  178. for(j=0;j<9;j++)
  179. analysis("Pnoisecurve",i*10+j,p_look.noisecurves[i][j],EHMER_MAX,0,1);
  180. /* we cheat on the WAV header; we just bypass 44 bytes and never
  181. verify that it matches 16bit/stereo/44.1kHz. */
  182. fread(buffer,1,44,stdin);
  183. fwrite(buffer,1,44,stdout);
  184. memset(buffer,0,framesize*2);
  185. analysis("window",0,window,framesize,0,0);
  186. fprintf(stderr,"Processing for frame size %d...\n",framesize);
  187. while(!eos){
  188. long bytes=fread(buffer2,1,framesize*2,stdin);
  189. if(bytes<framesize*2)
  190. memset(buffer2+bytes,0,framesize*2-bytes);
  191. if(bytes!=0){
  192. /* uninterleave samples */
  193. for(i=0;i<framesize;i++){
  194. pcm[0][i]=((buffer[i*4+1]<<8)|
  195. (0x00ff&(int)buffer[i*4]))/32768.;
  196. pcm[1][i]=((buffer[i*4+3]<<8)|
  197. (0x00ff&(int)buffer[i*4+2]))/32768.;
  198. }
  199. for(i=0;i<2;i++){
  200. double amp;
  201. analysis("pre",frameno,pcm[i],framesize,0,0);
  202. /* do the psychacoustics */
  203. for(j=0;j<framesize;j++)
  204. pcm[i][j]*=window[j];
  205. mdct_forward(&m_look,pcm[i],pcm[i]);
  206. analysis("mdct",frameno,pcm[i],framesize/2,1,1);
  207. _vp_compute_mask(&p_look,pcm[i],floor,mask,decay[i]);
  208. analysis("prefloor",frameno,floor,framesize/2,1,1);
  209. analysis("mask",frameno,mask,framesize/2,1,1);
  210. analysis("decay",frameno,decay[i],framesize/2,1,1);
  211. amp=_curve_to_lpc(floor,lpc,&floorlook,frameno);
  212. _lpc_to_curve(floor,lpc,sqrt(amp),&floorlook,"Ffloor",frameno);
  213. analysis("floor",frameno,floor,framesize/2,1,1);
  214. _vp_apply_floor(&p_look,pcm[i],floor,mask);
  215. analysis("quant",frameno,pcm[i],framesize/2,1,1);
  216. /* re-add floor */
  217. for(j=0;j<framesize/2;j++){
  218. double val=rint(pcm[i][j]);
  219. tot++;
  220. if(val){
  221. nonz++;
  222. acc+=log(fabs(val)*2.+1.)/log(2);
  223. pcm[i][j]=val*floor[j];
  224. }else{
  225. pcm[i][j]=0;
  226. }
  227. }
  228. analysis("final",frameno,pcm[i],framesize/2,1,1);
  229. /* take it back to time */
  230. mdct_backward(&m_look,pcm[i],pcm[i]);
  231. for(j=0;j<framesize/2;j++)
  232. out[i][j]+=pcm[i][j]*window[j];
  233. frameno++;
  234. }
  235. /* write data. Use the part of buffer we're about to shift out */
  236. for(i=0;i<2;i++){
  237. char *ptr=buffer+i*2;
  238. double *mono=out[i];
  239. for(j=0;j<framesize/2;j++){
  240. int val=mono[j]*32767.;
  241. /* might as well guard against clipping */
  242. if(val>32767)val=32767;
  243. if(val<-32768)val=-32768;
  244. ptr[0]=val&0xff;
  245. ptr[1]=(val>>8)&0xff;
  246. ptr+=4;
  247. }
  248. }
  249. fwrite(buffer,1,framesize*2,stdout);
  250. memmove(buffer,buffer2,framesize*2);
  251. for(i=0;i<2;i++){
  252. for(j=0,k=framesize/2;j<framesize/2;j++,k++)
  253. out[i][j]=pcm[i][k]*window[k];
  254. }
  255. }else
  256. eos=1;
  257. }
  258. fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
  259. fprintf(stderr,"average nonzero samples: %.03g/%d\n",nonz/tot*framesize/2,
  260. framesize/2);
  261. fprintf(stderr,"Done\n\n");
  262. return 0;
  263. }