annotate tools/audio_processor_test/transform/checker/checker.cpp @ 44:9b0dfce52c29 pygar svn.45

[svn r45] adding mixer
author punk
date Wed, 05 May 2010 12:30:18 -0400
parents 90197e3375e2
children
rev   line source
rlm@23 1 #include <stdio.h>
rlm@23 2 #include <stdlib.h>
rlm@23 3 #include <math.h>
rlm@23 4 #include <assert.h>
rlm@23 5 #include <string.h>
rlm@23 6 #include "SndfileWavUtil.h"
rlm@23 7
rlm@23 8 const int Taps = 9;
rlm@23 9 const int Points = 8;
rlm@23 10 const int log_Points = 3;
rlm@23 11 static int newest;
rlm@23 12 static short int x[Taps] = {0,0,0,0,0,0,0,0,0};
rlm@23 13 static short int fir(short int);
rlm@23 14
rlm@23 15 // foreward declaration. This is defined in DFT.cpp
rlm@23 16 int DFT(int dir,int m,double *x1,double *y1);
rlm@23 17
rlm@23 18
rlm@23 19 static int x_to_y(int x, int y)
rlm@23 20 {
rlm@23 21 assert(y>0);
rlm@23 22 int rv = x;
rlm@23 23 while(y-->1)
rlm@23 24 x *= x;
rlm@23 25 return rv;
rlm@23 26 }
rlm@23 27
rlm@23 28 // function implemented in LinearWindowingFunction.bsv
rlm@23 29 static double windowing_fn(int index)
rlm@23 30 {
rlm@23 31 double i = (double)index;
rlm@23 32 double divisor = Points/2; //(double) (x_to_y(2,log_Points-1));
rlm@23 33 double rv = (index < Points/2) ? (i / divisor) : ((((double)Points)-i) / divisor);
rlm@23 34 return rv;
rlm@23 35 }
rlm@23 36
rlm@23 37 // lifted from the bluespec code
rlm@23 38 static double h[Taps] = {-0.0124,
rlm@23 39 0.0,
rlm@23 40 -0.0133,
rlm@23 41 0.0,
rlm@23 42 0.8181,
rlm@23 43 0.0,
rlm@23 44 -0.0133,
rlm@23 45 0.0,
rlm@23 46 -0.0124};
rlm@23 47
rlm@23 48
rlm@23 49 short int
rlm@23 50 fir(short int sample)
rlm@23 51 {
rlm@23 52 x[newest] = sample;
rlm@23 53 double y = 0;
rlm@23 54 for (int k = 0; k < Taps; k++) {
rlm@23 55 short int bits = x[(newest+k)%Taps];
rlm@23 56 double x = (double)bits;
rlm@23 57 y += h[k] * x;
rlm@23 58 }
rlm@23 59 newest = (newest == 0) ? (Taps-1) : (newest-1);
rlm@23 60 short int rv = ((short int)y)&0x0000FFFF;
rlm@23 61 return rv;
rlm@23 62 }
rlm@23 63
rlm@23 64
rlm@23 65 int
rlm@23 66 main (int argc, char * argv [])
rlm@23 67 {
rlm@23 68 const char* inputWavFileName;
rlm@23 69 const char* outputWavFileName;
rlm@23 70
rlm@23 71 FILE *inputPcmFile;
rlm@23 72 FILE *firPcmFile;
rlm@23 73 FILE *ifftPcmFile;
rlm@23 74 FILE *outputPcmFile;
rlm@23 75
rlm@23 76 short int sample;
rlm@23 77 short int samples[Points];
rlm@23 78 const unsigned int short_sz = sizeof(short int);
rlm@23 79
rlm@23 80 inputWavFileName = argv[1];
rlm@23 81 outputWavFileName = argv[2];
rlm@23 82
rlm@23 83 // Convert input wav to pcm
rlm@23 84 generate_pcm(inputWavFileName, "input.pcm");
rlm@23 85
rlm@23 86 inputPcmFile = fopen("input.pcm", "r");
rlm@23 87 firPcmFile = fopen("fir.pcm", "w");
rlm@23 88
rlm@23 89 assert(inputPcmFile);
rlm@23 90 assert(firPcmFile);
rlm@23 91
rlm@23 92 newest = 0;
rlm@23 93 memset(x, 0, sizeof(x));
rlm@23 94
rlm@23 95 while(fread(&sample, short_sz, 1, inputPcmFile)) {
rlm@23 96 sample = fir(sample);
rlm@23 97 assert(fwrite(&sample,short_sz, 1, firPcmFile));
rlm@23 98 }
rlm@23 99
rlm@23 100 fclose(inputPcmFile);
rlm@23 101 fclose(firPcmFile);
rlm@23 102
rlm@23 103 firPcmFile = fopen("fir.pcm", "r");
rlm@23 104 ifftPcmFile = fopen("ifft.pcm", "w");
rlm@23 105
rlm@23 106 assert(firPcmFile);
rlm@23 107 assert(ifftPcmFile);
rlm@23 108
rlm@23 109 int read = 0;
rlm@23 110
rlm@23 111 // read in half a frame
rlm@23 112 for(int i = 0; i < Points/2; i++)
rlm@23 113 read += fread(&samples[(Points/2)+i], short_sz, 1, firPcmFile);
rlm@23 114
rlm@23 115 if(read > 0)
rlm@23 116 assert(read==Points/2);
rlm@23 117
rlm@23 118 // we will do an 'Points' point fft, and then undo it
rlm@23 119 while(true) {
rlm@23 120
rlm@23 121 read = 0;
rlm@23 122
rlm@23 123 // shift last half frame to head
rlm@23 124 for(int i = 0; i < Points/2; i++)
rlm@23 125 samples[i] = samples[(Points/2)+i];
rlm@23 126
rlm@23 127 // read in another half frame
rlm@23 128 for(int i = 0; i < Points/2; i++)
rlm@23 129 read += fread(&samples[(Points/2)+i], short_sz, 1, firPcmFile);
rlm@23 130
rlm@23 131 if(read == 0)
rlm@23 132 break;
rlm@23 133
rlm@23 134 // pad out the
rlm@23 135 if(read < Points/2){
rlm@23 136 for(int i = read; i < Points/2; i++)
rlm@23 137 samples[Points/2+i] = 0;
rlm@23 138 }
rlm@23 139
rlm@23 140 double dsamples[Points];
rlm@23 141 double dimag[Points];
rlm@23 142
rlm@23 143 // this shift is performed in the Bluespec
rlm@23 144 for(int i = 0; i < Points; i++){
rlm@23 145 dsamples[i] = (double)(samples[i]>>log_Points);
rlm@23 146 dimag[i] = 0.0;
rlm@23 147 }
rlm@23 148
rlm@23 149
rlm@23 150 DFT(1,Points,dsamples,dimag);
rlm@23 151 DFT(-1,Points,dsamples,dimag);
rlm@23 152
rlm@23 153 short int ifftResult[Points];
rlm@23 154 for(int i = 0; i < Points; i++)
rlm@23 155 ifftResult[i] = (int)dsamples[i]; //)>>log_Points;
rlm@23 156
rlm@23 157 // strip off the padding
rlm@23 158 int write = (read < Points/2) ? read+(Points/2) : Points;
rlm@23 159 for(int i = 0; i < write; i++)
rlm@23 160 assert(fwrite(&ifftResult[i],short_sz,1,ifftPcmFile));
rlm@23 161
rlm@23 162 // break out if we're at the end
rlm@23 163 if(read < Points/2){
rlm@23 164 break;
rlm@23 165 }
rlm@23 166 }
rlm@23 167
rlm@23 168 fclose(firPcmFile);
rlm@23 169 fclose(ifftPcmFile);
rlm@23 170
rlm@23 171 // do the windowing
rlm@23 172
rlm@23 173 ifftPcmFile = fopen("ifft.pcm", "r");
rlm@23 174 outputPcmFile = fopen("output.pcm", "w");
rlm@23 175
rlm@23 176 assert(ifftPcmFile);
rlm@23 177 assert(outputPcmFile);
rlm@23 178
rlm@23 179 short int samplesA[Points];
rlm@23 180 short int samplesB[Points];
rlm@23 181
rlm@23 182 bool valid_stream = true;
rlm@23 183 // write out the first half frame
rlm@23 184 for(int i = 0; i < Points/2; i++){
rlm@23 185 valid_stream &= fread(samplesA, short_sz, 1,ifftPcmFile);
rlm@23 186 valid_stream &= fwrite(samplesA, short_sz,1,outputPcmFile);
rlm@23 187 }
rlm@23 188
rlm@23 189 while(valid_stream){
rlm@23 190
rlm@23 191 for(int i = 0; i < Points/2; i++)
rlm@23 192 valid_stream &= fread(&samplesA[i], short_sz, 1,ifftPcmFile);
rlm@23 193
rlm@23 194 for(int i = 0; i < Points; i++)
rlm@23 195 valid_stream &= fread(&samplesB[i], short_sz, 1,ifftPcmFile);
rlm@23 196
rlm@23 197 for(int i = 0; i < Points/2; i++)
rlm@23 198 valid_stream &= fread(&samplesA[(Points/2)+i], short_sz, 1,ifftPcmFile);
rlm@23 199
rlm@23 200
rlm@23 201 // this isn't quite right
rlm@23 202 if(!valid_stream)
rlm@23 203 break;
rlm@23 204
rlm@23 205 for(int i = 0; i < Points; i++){
rlm@23 206 double window = windowing_fn(i);
rlm@23 207 short int rv = samplesA[i]*(1-window) + window*samplesB[i];
rlm@23 208 assert(fwrite(&rv,short_sz,1,outputPcmFile));
rlm@23 209 }
rlm@23 210
rlm@23 211 }
rlm@23 212
rlm@23 213 fclose(ifftPcmFile);
rlm@23 214 fclose(outputPcmFile);
rlm@23 215
rlm@23 216 generate_wav("output.pcm", inputWavFileName, outputWavFileName);
rlm@23 217
rlm@23 218 }
rlm@23 219