summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2000-03-29 03:49:29 +0000
committerMonty <xiphmont@xiph.org>2000-03-29 03:49:29 +0000
commit9bb072dc5a541ffb4f724b9d215ba67fef01af0d (patch)
tree248dab6beb8044b0b09b0852cf1521b70b252db9
parentc210a7decc824c3f11256d78da06c7a62326bda0 (diff)
downloadlibvorbis-git-9bb072dc5a541ffb4f724b9d215ba67fef01af0d.tar.gz
Don't want to lose anything while I'm integrating (also don;t want to
disturb mainline till I'm done) Monty svn path=/branches/unlabeled-1.1.2/vorbis/; revision=286
-rw-r--r--lib/masking.h149
-rw-r--r--lib/psytune.c360
-rw-r--r--lib/scales.h54
3 files changed, 563 insertions, 0 deletions
diff --git a/lib/masking.h b/lib/masking.h
new file mode 100644
index 00000000..18aeac47
--- /dev/null
+++ b/lib/masking.h
@@ -0,0 +1,149 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: masking curve data for psychoacoustics
+ last mod: $Id: masking.h,v 1.1.2.1 2000/03/29 03:49:28 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_MASKING_H_
+#define _V_MASKING_H_
+
+double ATH_Bark_dB[]={
+ 70, 25, 15, 11, 9, 8, 7.5, 7, 7, 7,
+ 6, 4, 2, 0, -3, -5, -6, -6, -4.5, 2.5,
+ 11, 18, 21, 17, 25, 80, 120};
+
+/* The below masking curves are straight from the R. Ehmer
+ (J. Acoustical Society of America) papers ca 1958-59. I modified
+ them slightly as Ehmer does not correct for the Absolute Threshold
+ of Hearing, and the low dB portions of the curves are thus highly
+ suspect. */
+
+/* Let's all do the Trek thing and just call them 'Ehmer curves' ;-)
+ Note these are octaves, not Bark scale. */
+
+#define EHMER_OFFSET 16
+#define EHMER_MAX 56
+
+double tone_250_40dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -19, -13, -7, -1, 4, 9, 15, 20,
+ 22, 23, 22, 19, 18, 18, 16, 13, 9, 7, 3, 1, -1, -3, -6, -8,
+ -10, -13, -16, -19, -21, -24, -28, -32, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_250_60dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -5, 1, 7, 13, 19, 25, 30, 33,
+ 36, 39, 38, 37, 38, 39, 39, 40, 38, 36, 35, 34, 33, 31, 29, 28,
+ 28, 28, 25, 20, 14, 10, 5, 0, -5,-10,-15,-20,-25,-30,-35,-40,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_250_80dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, 10, 17, 24, 30, 37, 41, 48, 49,
+ 60, 58, 54, 53, 53, 54, 55, 57, 57, 57, 58, 59, 60, 58, 57, 58,
+ 59, 58, 57, 54, 52, 50, 49, 47, 46, 47, 46, 44, 43, 42, 41, 40,
+ 38, 32, 27, 22, 17, 11, 6, 0};
+
+double tone_500_40dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -26, -20, -14, -8, -2, 4, 10, 17,
+ 23, 16, 12, 9, 6, 3, 0, -3, -7, -10, -13, -16, -20, -23, -26, -30,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_500_60dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -18, -12, -6, 0, 6, 13, 20, 30,
+ 39, 34, 31, 29, 29, 27, 24, 21, 18, 16, 13, 8, 6, 3, 1, -1,
+ -5, -2, -5, -8, -12, -15, -18, -22, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_500_80dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -22,-16,-10, 0, 10, 20, 32, 43,
+ 60, 55, 52, 50, 49, 50, 52, 55, 55, 54, 51, 49, 46, 44, 44, 42,
+ 38, 34, 32, 29, 29, 28, 25, 23, 20, 16, 10, 7, 4, 2, -1, -4,
+ -7, -10, -15, -20, -25, -30, -35, -40};
+double tone_500_100dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -7, 2, 10, 19, 27, 35, 55, 56,
+ 80, 70, 60, 58, 57, 57, 59, 63, 65, 66, 62, 60, 57, 57, 58, 58,
+ 57, 56, 56, 56, 57, 57, 56, 57, 57, 54, 47, 41, 37, 28, 21, 16,
+ 10, 3, -3, -8, -13, -18, -23, -28};
+
+double tone_1000_40dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -55, -45, -35, -25, -15, -5, 5, 15,
+ 25, 20, 13, 8, 3, -3, -9, -15, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_1000_60dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -40,-30,-20,-10, 0, 10, 20, 30,
+ 40, 33, 24, 23, 21, 17, 13, 8, 3, -2, -8,-13,-18, -23, -28, -33,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_1000_80dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -40,-30,-20,-10, 0, 10, 24, 42,
+ 60, 57, 46, 41, 39, 37, 41, 46, 45, 41, 39, 35, 35, 34, 33, 31,
+ 28, 22, 15, 10, 5, -2, -10, -18, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_1000_100dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -34,-24,-14, -4, 6, 16, 33, 53,
+ 80, 72, 55, 49, 43, 40, 44, 54, 59, 58, 49, 43, 52, 57, 57, 58,
+ 58, 54, 49, 47, 42, 39, 33, 28, 20, 15, 5, 0, -5,-15,-20,-25,
+-900,-900,-900,-900,-900,-900,-900,-900};
+
+double tone_2000_40dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -3, 5, 12, 20,
+ 25, 21, 15, 5, -5, -15, -25, -35, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_2000_60dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -2, 8, 19, 32,
+ 40, 35, 25, 17, 14, 13, 11, 7, 3, -2, -6, -10, -14, -20, -26, -32,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_2000_80dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -12, -2, 13, 28, 41,
+ 60, 55, 43, 35, 28, 29, 35, 37, 37, 35, 31, 28, 25, 22, 19, 15,
+ 11, 8, 6, 2, -6, -14, -22, -30, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_2000_100dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -40, -30, -21, -10, 6, 25, 42, 60,
+ 80, 68, 53, 43, 35, 31, 34, 47, 58, 51, 43, 45, 54, 59, 59, 56,
+ 54, 51, 40, 29, 20, 11, 2, -8, -17, -26, -35,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+
+double tone_4000_40dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -70, -56, -43, -30, -17, -5, 7, 15,
+ 21, 13, 5, -2, -10, -17, -24, -31, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_4000_60dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -70, -56, -43, -30, -17, -5, 10, 27,
+ 40, 33, 20, 16, 10, 5, -5, -15, -20, -25, -30, -35, -40,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_4000_80dB_SL[EHMER_MAX]={
+-900,-900,-900,-900,-900,-900,-900,-900, -60, -50, -40, -29, -12, 5, 19, 37,
+ 60, 53, 35, 33, 36, 36, 36, 31, 27, 17, 8, 0, -8, -16, -24, -32,
+-900,-900,-900,-900,-900,-900,-900,-900, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+double tone_4000_100dB_SL[EHMER_MAX]={
+ -20, -12, -8, -4, 0, 4, 8, 11, 15, 22, 26, 28, 32, 36, 43, 54,
+ 80, 70, 45, 41, 48, 49, 40, 26, 40, 40, 33, 29, 24, 19, 14, 9,
+ 4, -1, -6, -11, -16, -21, -26, -31, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+
+double tone_8000_100dB_SL[EHMER_MAX]={
+ -18, -12, -7, -3, 0, 2, 6, 9, 12, 19, 22, 21, 19, 21, 40, 40,
+ 80, 60,
+ /* educated guessing from here on out */
+ 35, 31, 38, 39, 30, 16, 30, 30, 23, 19, 14, 9, 4, -1,
+ -6, -11, -16, -21, -26, -31, -36, -41, -900,-900,-900,-900,-900,-900,-900,-900,
+-900,-900,-900,-900,-900,-900,-900,-900};
+
+#endif
+
+
diff --git a/lib/psytune.c b/lib/psytune.c
new file mode 100644
index 00000000..95b8815e
--- /dev/null
+++ b/lib/psytune.c
@@ -0,0 +1,360 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: simple utility that runs audio through the psychoacoustics
+ without encoding
+ last mod: $Id: psytune.c,v 1.1.2.1 2000/03/29 03:49:28 xiphmont Exp $
+
+ ********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "vorbis/codec.h"
+#include "psy.h"
+#include "mdct.h"
+#include "window.h"
+#include "scales.h"
+#include "lpc.h"
+
+/*
+ 0 1 2 3 4 5 6 7 8 9
+ 0, 100, 200, 300, 400, 510, 630, 770, 920, 1080,
+
+ 10 11 12 13 14 15 16 17 18 19
+ 1270, 1480, 1720, 2000, 2320, 2700, 3150, 3700, 4400, 5300,
+
+ 20 21 22 23 24 25 26 Bark
+ 6400, 7700, 9500, 12000, 15500, 20500, 27000 Hz */
+
+static vorbis_info_psy _psy_set0={
+ /* ATH */
+ { 70, 25, 15, 11, 9, 8, 7.5, 7, 7, 7,
+ 6, 4, 2, 0, -3, -5, -6, -6,-4.5, 2.5,
+ 11, 18, 21, 17, 25, 80,120},
+ /* master attenuation */
+ 120.,
+
+ /* mask1 attenuation proportion */
+ { .7, .75, .80, .83, .84, .85, .85, .85, .85, .85,
+ .00, .00, .00, .00, .00, .00, .00, .00, .00, .00,
+ /* .85, .85, .85, .85, .00, .00, .00, .00, .00, .00,*/
+ .00, .00, .00, .00, .00, .00, .00},
+ /* mask1 slope */
+ {-40, -24, -12, -8., -4., -4, -4, -4, -4, -4,
+ -99, -99, -99, -99, -99,-99,-99,-99,-99,-99,
+ -99,-99,-99,-99,-99,-99,-99},
+
+ /* mask2 attenuation proportion */
+ { .60, .60, .60, .60, .55, .55, .50, .50, .50, .50,
+ .50, .50, .50, .50, .50, .50, .50, .50, .50, .55,
+ .60, .65, .66, .67, .68, .7, .7},
+ /* mask2 slope */
+ {-40.,-24.,-11., -8., -6., -5.,-3.,-1.8, -1.8,-1.8,
+ -1.8,-1.8,-1.9,-1.9,-2, -2, -2, -2,-2,-1.8,
+ -1.7,-1.7,-1.6,-1.6,-1.6,-1.6,-1.6},
+
+ -33., /* backward masking rolloff */
+
+ .9998, .9997 /* attack/decay control */
+};
+
+static int noisy=0;
+void analysis(char *base,int i,double *v,int n,int bark,int dB){
+ if(noisy){
+ int j;
+ FILE *of;
+ char buffer[80];
+ sprintf(buffer,"%s_%d.m",base,i);
+ of=fopen(buffer,"w");
+
+ for(j=0;j<n;j++){
+ if(dB && v[j]==0)
+ fprintf(of,"\n\n");
+ else{
+ if(bark)
+ fprintf(of,"%g ",toBARK(22050.*j/n));
+ else
+ fprintf(of,"%g ",(double)j);
+
+ if(dB){
+ fprintf(of,"%g\n",todB(fabs(v[j])));
+ }else{
+ fprintf(of,"%g\n",v[j]);
+ }
+ }
+ }
+ fclose(of);
+ }
+}
+
+long frameno=0;
+
+int main(int argc,char *argv[]){
+ int eos=0;
+ double nonz=0.;
+ double acc=0.;
+ double tot=0.;
+
+ int framesize=2048;
+ int order=32;
+
+ double *pcm[2],*out[2],*window,*mask,*maskwindow,*decay[2],*lpc,*floor;
+ signed char *buffer,*buffer2;
+ mdct_lookup m_look;
+ vorbis_look_psy p_look;
+ long i,j,k;
+
+ drft_lookup fft_look;
+ lpc_lookup lpc_look;
+
+ int ath=0;
+ int mask1p=0;
+ int mask2p=0;
+ int mask3p=0;
+ int backp=0;
+ int decayp=0;
+
+ argv++;
+ while(*argv){
+ if(*argv[0]=='-'){
+ /* option */
+ if(argv[0][1]=='v'){
+ noisy=0;
+ }
+ if(argv[0][1]=='A'){
+ ath=0;
+ }
+ if(argv[0][1]=='1'){
+ mask1p=0;
+ }
+ if(argv[0][1]=='2'){
+ mask2p=0;
+ }
+ if(argv[0][1]=='3'){
+ mask3p=0;
+ }
+ if(argv[0][1]=='B'){
+ backp=0;
+ }
+ if(argv[0][1]=='D'){
+ decayp=0;
+ }
+ if(argv[0][1]=='X'){
+ ath=0;
+ mask1p=0;
+ mask2p=0;
+ mask3p=0;
+ decayp=0;
+ backp=0;
+ }
+ }else
+ if(*argv[0]=='+'){
+ /* option */
+ if(argv[0][1]=='v'){
+ noisy=1;
+ }
+ if(argv[0][1]=='A'){
+ ath=1;
+ }
+ if(argv[0][1]=='1'){
+ mask1p=1;
+ }
+ if(argv[0][1]=='2'){
+ mask2p=1;
+ }
+ if(argv[0][1]=='3'){
+ mask3p=1;
+ }
+ if(argv[0][1]=='B'){
+ backp=1;
+ }
+ if(argv[0][1]=='D'){
+ decayp=1;
+ }
+ if(argv[0][1]=='X'){
+ ath=1;
+ mask1p=1;
+ mask2p=1;
+ mask3p=1;
+ decayp=1;
+ backp=1;
+ }
+ }else
+ framesize=atoi(argv[0]);
+ argv++;
+ }
+
+ pcm[0]=malloc(framesize*sizeof(double));
+ pcm[1]=malloc(framesize*sizeof(double));
+ out[0]=calloc(framesize/2,sizeof(double));
+ out[1]=calloc(framesize/2,sizeof(double));
+ decay[0]=calloc(framesize/2,sizeof(double));
+ decay[1]=calloc(framesize/2,sizeof(double));
+ mask=malloc(framesize*sizeof(double));
+ floor=malloc(framesize*sizeof(double));
+ lpc=malloc(order*sizeof(double));
+ buffer=malloc(framesize*4);
+ buffer2=buffer+framesize*2;
+ window=_vorbis_window(0,framesize,framesize/2,framesize/2);
+ maskwindow=_vorbis_window(0,framesize,framesize/2,framesize/2);
+ mdct_init(&m_look,framesize);
+ _vp_psy_init(&p_look,&_psy_set0,framesize/2,44100);
+ lpc_init(&lpc_look,framesize/2,256,44100,order);
+
+ for(j=0;j<framesize;j++)
+ maskwindow[j]*=maskwindow[j];
+
+ /* we cheat on the WAV header; we just bypass 44 bytes and never
+ verify that it matches 16bit/stereo/44.1kHz. */
+
+ fread(buffer,1,44,stdin);
+ fwrite(buffer,1,44,stdout);
+ memset(buffer,0,framesize*2);
+
+ analysis("window",0,window,framesize,0,0);
+
+ fprintf(stderr,"Processing for frame size %d...\n",framesize);
+
+ while(!eos){
+ long s;
+ long bytes=fread(buffer2,1,framesize*2,stdin);
+ if(bytes<framesize*2)
+ memset(buffer2+bytes,0,framesize*2-bytes);
+
+ if(bytes!=0){
+
+ /* uninterleave samples */
+ for(i=0;i<framesize;i++){
+ pcm[0][i]=((buffer[i*4+1]<<8)|
+ (0x00ff&(int)buffer[i*4]))/32768.;
+ pcm[1][i]=((buffer[i*4+3]<<8)|
+ (0x00ff&(int)buffer[i*4+2]))/32768.;
+ }
+
+ for(i=0;i<2;i++){
+
+ analysis("pre",frameno,pcm[i],framesize,0,0);
+
+ /* do the psychacoustics */
+ memset(mask,0,sizeof(double)*framesize/2);
+ for(j=0;j<framesize;j++)
+ mask[j]=pcm[i][j]*maskwindow[j];
+
+ mdct_forward(&m_look,mask,mask);
+
+ analysis("maskmdct",frameno,mask,framesize/2,1,1);
+ _vp_tone_tone_mask(&p_look,mask,mask,
+ 1,1,decayp,decay[i]);
+ analysis("mask",frameno,mask,framesize/2,1,0);
+ analysis("lmask",frameno,mask,framesize/2,0,0);
+ analysis("decay",frameno,decay[i],framesize/2,1,1);
+ analysis("ldecay",frameno,decay[i],framesize/2,0,1);
+
+ for(j=0;j<framesize;j++)
+ pcm[i][j]=pcm[i][j]*window[j];
+ analysis("pcm",frameno,pcm[i],framesize,0,0);
+
+ mdct_forward(&m_look,pcm[i],pcm[i]);
+ analysis("mdct",frameno,pcm[i],framesize/2,1,1);
+ analysis("lmdct",frameno,pcm[i],framesize/2,0,1);
+
+ /* floor */
+ {
+ double amp;
+
+ for(j=0;j<framesize/2;j++)floor[j]=mask[j]+DYNAMIC_RANGE_dB;
+ amp=sqrt(vorbis_curve_to_lpc(floor,lpc,&lpc_look));
+ fprintf(stderr,"amp=%g\n",amp);
+ vorbis_lpc_to_curve(floor,lpc,amp,&lpc_look);
+ for(j=0;j<framesize/2;j++)floor[j]-=DYNAMIC_RANGE_dB;
+ analysis("floor",frameno,floor,framesize/2,1,0);
+
+ }
+
+
+ /* quantize according to masking */
+ for(j=0;j<framesize/2;j++){
+ double val;
+ if(mask[j]==0)
+ val=0;
+ else{
+ val=todB(pcm[i][j])-floor[j]-3.;
+ if(val<-6.){
+ val=0;
+ }else{
+ nonz+=1;
+ if(val<1.5){
+ val=1;
+ }else{
+ val=rint(val/3.)+1;
+ }
+ }
+ if(pcm[i][j]<0)val= -val;
+ }
+
+ acc+=log(fabs(val)*2.+1.)/log(2);
+ tot++;
+ if(val==0)
+ pcm[i][j]=0.;
+ else{
+ if(val>0)
+ pcm[i][j]=fromdB(val*3.+floor[j]-3.);
+ else
+ pcm[i][j]=-fromdB(floor[j]-val*3.-3.);
+ }
+ }
+
+ analysis("final",frameno,pcm[i],framesize/2,1,1);
+
+ /* take it back to time */
+ mdct_backward(&m_look,pcm[i],pcm[i]);
+ for(j=0;j<framesize/2;j++)
+ out[i][j]+=pcm[i][j]*window[j];
+
+ frameno++;
+ }
+
+ /* write data. Use the part of buffer we're about to shift out */
+ for(i=0;i<2;i++){
+ char *ptr=buffer+i*2;
+ double *mono=out[i];
+ for(j=0;j<framesize/2;j++){
+ int val=mono[j]*32767.;
+ /* might as well guard against clipping */
+ if(val>32767)val=32767;
+ if(val<-32768)val=-32768;
+ ptr[0]=val&0xff;
+ ptr[1]=(val>>8)&0xff;
+ ptr+=4;
+ }
+ }
+
+ fwrite(buffer,1,framesize*2,stdout);
+ memmove(buffer,buffer2,framesize*2);
+
+ for(i=0;i<2;i++){
+ for(j=0,k=framesize/2;j<framesize/2;j++,k++)
+ out[i][j]=pcm[i][k]*window[k];
+ }
+ }else
+ eos=1;
+ }
+ fprintf(stderr,"average raw bits of entropy: %.03g/sample\n",acc/tot);
+ fprintf(stderr,"average nonzero samples: %.03g/%d\n",nonz/tot*framesize/2,
+ framesize/2);
+ fprintf(stderr,"Done\n\n");
+ return 0;
+}
diff --git a/lib/scales.h b/lib/scales.h
new file mode 100644
index 00000000..39e7f6ab
--- /dev/null
+++ b/lib/scales.h
@@ -0,0 +1,54 @@
+/********************************************************************
+ * *
+ * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
+ * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
+ * PLEASE READ THESE TERMS DISTRIBUTING. *
+ * *
+ * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
+ * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
+ * http://www.xiph.org/ *
+ * *
+ ********************************************************************
+
+ function: linear scale -> dB, Bark and Mel scales
+ last mod: $Id: scales.h,v 1.1.2.1 2000/03/29 03:49:29 xiphmont Exp $
+
+ ********************************************************************/
+
+#ifndef _V_SCALE_H_
+#define _V_SCALES_H_
+
+#include <math.h>
+
+#define min(x,y) ((x)>(y)?(y):(x))
+#define max(x,y) ((x)<(y)?(y):(x))
+
+/* 20log10(x) */
+#define DYNAMIC_RANGE_dB 200.
+#define todB(x) ((x)==0?-9.e40:log(fabs(x))*8.6858896)
+#define fromdB(x) (exp((x)*.11512925))
+
+
+/* The bark scale equations are approximations, since the original
+ table was somewhat hand rolled. The below are chosen to have the
+ best possible fit to the rolled tables, thus their somewhat odd
+ appearance (these are more accurate and over a longer range than
+ the oft-quoted bark equations found in the texts I have). The
+ approximations are valid from 0 - 30kHz (nyquist) or so.
+
+ all f in Hz, z in Bark */
+
+#define toBARK(f) (13.1*atan(.00074*(f))+2.24*atan((f)*(f)*1.85e-8)+1e-4*(f))
+#define fromBARK(z) (102.*(z)-2.*pow(z,2.)+.4*pow(z,3)+pow(1.46,z)-1.)
+#define toMEL(f) (log(1.+(f)*.001)*1442.695)
+#define fromMEL(m) (1000.*exp((m)/1442.695)-1000.)
+
+/* Frequency to octave. We arbitrarily declare 250.0 Hz to be octave
+ 0.0 */
+
+#define toOC(f) (log(f)*1.442695-7.965784)
+#define fromOC(o) (exp(((o)+7.965784)*.693147))
+
+#endif
+