1 /********************************************************************
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. *
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/ *
12 ********************************************************************
14 function: simple utility that runs audio through the psychoacoustics
16 last mod: $Id: psytune.c,v 1.2 2000/04/03 08:30:49 xiphmont Exp $
18 ********************************************************************/
25 #include "vorbis/codec.h"
31 static vorbis_info_psy _psy_set0={
32 {-20, -20, -14, -14, -14, -14, -14, -14, -14, -14,
33 -14, -14, -16, -16, -16, -16, -18, -18, -16, -16,
34 -12, -10, -6, -3, -1, -1, -0}, 0., (.6/1024), 10,4
37 int main(int argc,char *argv[]){
41 int framesize=argv[1]?atoi(argv[1]):2048;
42 double *pcm[2],*out[2],*window,*mask,*decay[2];
43 signed char *buffer,*buffer2;
45 vorbis_look_psy p_look;
47 pcm[0]=malloc(framesize*sizeof(double));
48 pcm[1]=malloc(framesize*sizeof(double));
49 out[0]=calloc(framesize/2,sizeof(double));
50 out[1]=calloc(framesize/2,sizeof(double));
51 decay[0]=calloc(framesize/2,sizeof(double));
52 decay[1]=calloc(framesize/2,sizeof(double));
53 mask=malloc(framesize/2*sizeof(double));
54 buffer=malloc(framesize*4);
55 buffer2=buffer+framesize*2;
56 window=_vorbis_window(0,framesize,framesize/2,framesize/2);
57 mdct_init(&m_look,framesize);
58 _vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
60 /* we cheat on the WAV header; we just bypass 44 bytes and never
61 verify that it matches 16bit/stereo/44.1kHz. */
63 fread(buffer,1,44,stdin);
64 fwrite(buffer,1,44,stdout);
65 memset(buffer,0,framesize*2);
67 fprintf(stderr,"Processing for frame size %d...\n",framesize);
71 long bytes=fread(buffer2,1,framesize*2,stdin);
73 memset(buffer2+bytes,0,framesize*2-bytes);
77 /* uninterleave samples */
78 for(i=0;i<framesize;i++){
79 pcm[0][i]=((buffer[i*4+1]<<8)|
80 (0x00ff&(int)buffer[i*4]))/32768.;
81 pcm[1][i]=((buffer[i*4+3]<<8)|
82 (0x00ff&(int)buffer[i*4+2]))/32768.;
86 for(j=0;j<framesize;j++)
89 mdct_forward(&m_look,pcm[i],pcm[i]);
91 /* do the psychacoustics */
93 memset(mask,0,sizeof(double)*framesize/2);
94 _vp_mask_floor(&p_look,pcm[i],mask,decay[i],1);
96 /* quantize according to masking */
97 for(j=0;j<framesize/2;j++){
102 val=rint(pcm[i][j]/mask[j]);
103 acc+=log(fabs(val)*2.+1.)/log(2);
105 pcm[i][j]=val*mask[j];
108 /* take it back to time */
109 mdct_backward(&m_look,pcm[i],pcm[i]);
110 for(j=0;j<framesize/2;j++)
111 out[i][j]+=pcm[i][j]*window[j];
114 /* write data. Use the part of buffer we're about to shift out */
116 char *ptr=buffer+i*2;
118 for(j=0;j<framesize/2;j++){
119 int val=mono[j]*32767.;
120 /* might as well guard against clipping */
121 if(val>32767)val=32767;
122 if(val<-32768)val=-32768;
124 ptr[1]=(val>>8)&0xff;
129 fwrite(buffer,1,framesize*2,stdout);
130 memmove(buffer,buffer2,framesize*2);
133 for(j=0,k=framesize/2;j<framesize/2;j++,k++)
134 out[i][j]=pcm[i][k]*window[k];
139 fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
140 fprintf(stderr,"Done\n\n");