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: psychoacoustics not including preecho
15 last mod: $Id: psy.c,v 1.15 2000/02/06 13:39:44 xiphmont Exp $
17 ********************************************************************/
23 #include "vorbis/codec.h"
30 /* Set up decibel threshhold slopes on a Bark frequency scale */
32 static void set_curve(double *ref,double *c,int n, double crate){
35 for(i=0;i<MAX_BARK-1;i++){
36 int endpos=rint(fromBARK(i+1)*2*n/crate);
38 double delta=(ref[i+1]-base)/(endpos-j);
39 for(;j<endpos && j<n;j++){
46 void _vp_psy_init(vorbis_look_psy *p,vorbis_info_psy *vi,int n,long rate){
48 memset(p,0,sizeof(vorbis_look_psy));
49 p->maskthresh=malloc(n*sizeof(double));
50 p->barknum=malloc(n*sizeof(double));
54 /* set up the lookups for a given blocksize and sample rate */
55 /* Vorbis max sample rate is limited by 26 Bark (54kHz) */
56 set_curve(vi->maskthresh, p->maskthresh, n,rate);
59 p->barknum[i]=toBARK(rate/2.*i/n);
67 sprintf(buffer,"mask_threshhold_%d.m",n);
68 out=fopen(buffer,"w+");
70 fprintf(out,"%g\n",p->maskthresh[j]);
77 void _vp_psy_clear(vorbis_look_psy *p){
79 if(p->maskthresh)free(p->maskthresh);
80 if(p->barknum)free(p->barknum);
81 memset(p,0,sizeof(vorbis_look_psy));
85 /* Masking curve: linear rolloff on a Bark/dB scale, attenuated by
87 /* right now, floor==mask */
88 void _vp_mask_floor(vorbis_look_psy *p,double *f, double *mask,double *floor){
90 double hroll=p->vi->hrolldB;
91 double lroll=p->vi->lrolldB;
92 double curmask=todB(f[0])+p->maskthresh[0];
96 /* run mask forward then backward */
98 double newmask=todB(f[i])+p->maskthresh[i];
99 double newoc=p->barknum[i];
100 double roll=curmask-(newoc-curoc)*hroll;
103 roll=curmask=newmask;
107 if(mask[i]<troll)mask[i]=troll;
108 if(floor[i]<troll)floor[i]=troll;
111 curmask=todB(f[n-1])+p->maskthresh[n-1];
112 curoc=p->barknum[n-1];
114 double newmask=todB(f[i])+p->maskthresh[i];
115 double newoc=p->barknum[i];
116 double roll=curmask-(curoc-newoc)*lroll;
119 roll=curmask=newmask;
123 if(mask[i]<troll)mask[i]=troll;
124 if(floor[i]<troll)floor[i]=troll;
128 /* take a masking curve and raw residue; eliminate the inaduble and
129 quantize to the final form handed to the VQ. All and any tricks to
130 squeeze out bits given knowledge of the encoding mode should go
133 /* modifies the pcm vector, returns book membership in aux */
135 void _vp_quantize(vorbis_look_psy *p, double *pcm, double *mask,
136 double *floor,int *aux,long begin, long n,long subn){
138 /* for now, we're not worrying about subvector, but the idea is
139 that we normal blocks not have zeroes; zeroes only exist as an
142 for(i=begin;i<n;i++){
143 double value=rint(pcm[i]/floor[i]);
144 if(value>15)value=15;
145 if(value<-15)value=-15;
151 /* s must be padded at the end with m-1 zeroes */
152 static void time_convolve(double *s,double *r,int n,int m){
160 acc+=s[i+j]*r[m-j-1];
166 void _vi_psy_free(vorbis_info_psy *i){
168 memset(i,0,sizeof(vorbis_info_psy));