Mercurial > pygar
view tools/audio_processor_test/shift_up/checker/checker.cpp @ 59:92041177735c pygar svn.60
[svn r60] LUTRAMing
author | punk |
---|---|
date | Mon, 10 May 2010 13:50:40 -0400 |
parents | 90197e3375e2 |
children |
line wrap: on
line source
1 #include <stdio.h>2 #include <stdlib.h>3 #include <math.h>4 #include <assert.h>5 #include <string.h>6 #include "SndfileWavUtil.h"8 const int Taps = 9;9 const int Points = 8;10 const int log_Points = 3;11 static int newest;12 static short int x[Taps] = {0,0,0,0,0,0,0,0,0};13 static short int fir(short int);15 // foreward declaration. This is defined in DFT.cpp16 int DFT(int dir,int m,double *x1,double *y1);19 static int x_to_y(int x, int y)20 {21 assert(y>0);22 int rv = x;23 while(y-->1)24 x *= x;25 return rv;26 }28 // function implemented in LinearWindowingFunction.bsv29 static double windowing_fn(int index)30 {31 double i = (double)index;32 double divisor = Points/2; //(double) (x_to_y(2,log_Points-1));33 double rv = (index < Points/2) ? (i / divisor) : ((((double)Points)-i) / divisor);34 return rv;35 }37 // lifted from the bluespec code38 static double h[Taps] = {-0.0124,39 0.0,40 -0.0133,41 0.0,42 0.8181,43 0.0,44 -0.0133,45 0.0,46 -0.0124};49 short int50 fir(short int sample)51 {52 x[newest] = sample;53 double y = 0;54 for (int k = 0; k < Taps; k++) {55 short int bits = x[(newest+k)%Taps];56 double x = (double)bits;57 y += h[k] * x;58 }59 newest = (newest == 0) ? (Taps-1) : (newest-1);60 short int rv = ((short int)y)&0x0000FFFF;61 return rv;62 }65 int66 main (int argc, char * argv [])67 {68 const char* inputWavFileName;69 const char* outputWavFileName;71 FILE *inputPcmFile;72 FILE *firPcmFile;73 FILE *ifftPcmFile;74 FILE *outputPcmFile;76 short int sample;77 short int samples[Points];78 const unsigned int short_sz = sizeof(short int);80 inputWavFileName = argv[1];81 outputWavFileName = argv[2];83 // Convert input wav to pcm84 generate_pcm(inputWavFileName, "input.pcm");86 inputPcmFile = fopen("input.pcm", "r");87 firPcmFile = fopen("fir.pcm", "w");89 assert(inputPcmFile);90 assert(firPcmFile);92 newest = 0;93 memset(x, 0, sizeof(x));95 while(fread(&sample, short_sz, 1, inputPcmFile)) {96 sample = fir(sample);97 assert(fwrite(&sample,short_sz, 1, firPcmFile));98 }100 fclose(inputPcmFile);101 fclose(firPcmFile);103 firPcmFile = fopen("fir.pcm", "r");104 ifftPcmFile = fopen("ifft.pcm", "w");106 assert(firPcmFile);107 assert(ifftPcmFile);109 int read = 0;111 // read in half a frame112 for(int i = 0; i < Points/2; i++)113 read += fread(&samples[(Points/2)+i], short_sz, 1, firPcmFile);115 if(read > 0)116 assert(read==Points/2);118 // we will do an 'Points' point fft, and then undo it119 while(true) {121 read = 0;123 // shift last half frame to head124 for(int i = 0; i < Points/2; i++)125 samples[i] = samples[(Points/2)+i];127 // read in another half frame128 for(int i = 0; i < Points/2; i++)129 read += fread(&samples[(Points/2)+i], short_sz, 1, firPcmFile);131 if(read == 0)132 break;134 // pad out the135 if(read < Points/2){136 for(int i = read; i < Points/2; i++)137 samples[Points/2+i] = 0;138 }140 double dsamples[Points];141 double dimag[Points];143 // this shift is performed in the Bluespec144 for(int i = 0; i < Points; i++){145 dsamples[i] = (double)(samples[i]>>log_Points);146 dimag[i] = 0.0;147 }150 //for(int i = 0; i < Points; i++)151 // printf("%d ", (int)dsamples[i]);152 //printf("\n");154 DFT(1,Points,dsamples,dimag);156 // shift up by 'shift' (in)157 int shift = 2;159 for(int i = 0; i < Points/2; i++){161 dsamples[Points/2-1-i] = dsamples[Points/2-1-i-shift];162 dimag[Points/2-1-i] = dimag[Points/2-1-i-shift];165 dsamples[Points/2+i] = dsamples[Points/2+i+shift];166 dimag[Points/2+i] = dimag[Points/2+i+shift];168 }170 // fill in the lower points171 for(int i = 0; i < shift; i++){173 dsamples[i] = 0.0;174 dimag[i] = 0.0;176 dsamples[Points-1-i] = 0.0;177 dimag[Points-1-i] = 0.0;178 }180 DFT(-1,Points,dsamples,dimag);182 short int ifftResult[Points];183 for(int i = 0; i < Points; i++)184 ifftResult[i] = (int)dsamples[i];186 // strip off the padding187 int write = (read < Points/2) ? read+(Points/2) : Points;188 for(int i = 0; i < write; i++)189 assert(fwrite(&ifftResult[i],short_sz,1,ifftPcmFile));191 // break out if we're at the end192 if(read < Points/2){193 break;194 }195 }197 fclose(firPcmFile);198 fclose(ifftPcmFile);200 // do the windowing202 ifftPcmFile = fopen("ifft.pcm", "r");203 outputPcmFile = fopen("output.pcm", "w");205 assert(ifftPcmFile);206 assert(outputPcmFile);208 short int samplesA[Points];209 short int samplesB[Points];211 bool valid_stream = true;212 // write out the first half frame213 for(int i = 0; i < Points/2; i++){214 valid_stream &= fread(samplesA, short_sz, 1,ifftPcmFile);215 valid_stream &= fwrite(samplesA, short_sz,1,outputPcmFile);216 }218 while(valid_stream){220 for(int i = 0; i < Points/2; i++)221 valid_stream &= fread(&samplesA[i], short_sz, 1,ifftPcmFile);223 for(int i = 0; i < Points; i++)224 valid_stream &= fread(&samplesB[i], short_sz, 1,ifftPcmFile);226 for(int i = 0; i < Points/2; i++)227 valid_stream &= fread(&samplesA[(Points/2)+i], short_sz, 1,ifftPcmFile);230 // this isn't quite right231 if(!valid_stream)232 break;234 for(int i = 0; i < Points; i++){235 double window = windowing_fn(i);236 short int rv = (short int)(((double)samplesA[i])*(1.0-window) + window*((double)samplesB[i]));237 assert(fwrite(&rv,short_sz,1,outputPcmFile));238 }240 }242 fclose(ifftPcmFile);243 fclose(outputPcmFile);245 generate_wav("output.pcm", inputWavFileName, outputWavFileName);247 }