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.1 2000/02/25 11:05:32 xiphmont Exp $
18 ********************************************************************/
25 #include "vorbis/codec.h"
30 static vorbis_info_psy _psy_set0={
31 {-20, -20, -14, -14, -14, -14, -14, -14, -14, -14,
32 -14, -14, -16, -16, -16, -16, -18, -18, -16, -16,
33 -12, -10, -6, -3, -1, -1, -0}, 0., (.6/1024), 10,4
36 int main(int argc,char *argv[]){
40 int framesize=argv[1]?atoi(argv[1]):2048;
41 double *pcm[2],*out[2],*window,*mask,*decay[2];
42 signed char *buffer,*buffer2;
44 vorbis_look_psy p_look;
46 pcm[0]=malloc(framesize*sizeof(double));
47 pcm[1]=malloc(framesize*sizeof(double));
48 out[0]=calloc(framesize/2,sizeof(double));
49 out[1]=calloc(framesize/2,sizeof(double));
50 decay[0]=calloc(framesize/2,sizeof(double));
51 decay[1]=calloc(framesize/2,sizeof(double));
52 mask=malloc(framesize/2*sizeof(double));
53 buffer=malloc(framesize*4);
54 buffer2=buffer+framesize*2;
55 window=_vorbis_window(0,framesize,framesize/2,framesize/2);
56 mdct_init(&m_look,framesize);
57 _vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
59 /* we cheat on the WAV header; we just bypass 44 bytes and never
60 verify that it matches 16bit/stereo/44.1kHz. */
62 fread(buffer,1,44,stdin);
63 fwrite(buffer,1,44,stdout);
64 memset(buffer,0,framesize*2);
66 fprintf(stderr,"Processing for frame size %d...\n",framesize);
70 long bytes=fread(buffer2,1,framesize*2,stdin);
72 memset(buffer2+bytes,0,framesize*2-bytes);
76 /* uninterleave samples */
77 for(i=0;i<framesize;i++){
78 pcm[0][i]=((buffer[i*4+1]<<8)|
79 (0x00ff&(int)buffer[i*4]))/32768.;
80 pcm[1][i]=((buffer[i*4+3]<<8)|
81 (0x00ff&(int)buffer[i*4+2]))/32768.;
85 for(j=0;j<framesize;j++)
88 mdct_forward(&m_look,pcm[i],pcm[i]);
90 /* do the psychacoustics */
92 memset(mask,0,sizeof(double)*framesize/2);
93 _vp_mask_floor(&p_look,pcm[i],mask,decay[i],1);
95 /* quantize according to masking */
96 for(j=0;j<framesize/2;j++){
101 val=rint(pcm[i][j]/mask[j]);
102 acc+=log(fabs(val)*2.+1.)/log(2);
104 pcm[i][j]=val*mask[j];
107 /* take it back to time */
108 mdct_backward(&m_look,pcm[i],pcm[i]);
109 for(j=0;j<framesize/2;j++)
110 out[i][j]+=pcm[i][j]*window[j];
113 /* write data. Use the part of buffer we're about to shift out */
115 char *ptr=buffer+i*2;
117 for(j=0;j<framesize/2;j++){
118 int val=mono[j]*32767.;
119 /* might as well guard against clipping */
120 if(val>32767)val=32767;
121 if(val<-32768)val=-32768;
123 ptr[1]=(val>>8)&0xff;
128 fwrite(buffer,1,framesize*2,stdout);
129 memmove(buffer,buffer2,framesize*2);
132 for(j=0,k=framesize/2;j<framesize/2;j++,k++)
133 out[i][j]=pcm[i][k]*window[k];
138 fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
139 fprintf(stderr,"Done\n\n");