Mercurial > hg > easaier-soundaccess
view sv/filter/DSP.cpp @ 282:d9319859a4cf tip
(none)
author | benoitrigolleau |
---|---|
date | Fri, 31 Oct 2008 11:00:24 +0000 |
parents | 8b0f142fa8d2 |
children |
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ /* Sound Access EASAIER client application. Dublin Institute of Technology - Audio Research Group 2007 www.audioresearchgroup.com Author: Dan Barry This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. See the file COPYING included with this distribution for more information. */ //#include "stdafx.h" #include "DSP.h" #include "math.h" #include <cassert> #include <cmath> extern int currentposition; extern float lastfactor; extern float hopfactor; //These variables are only required for find peaks...the same variables are passed in to other functions extern int numpeaks; extern float *peak_locations; extern float *L_mags; ///CURRENT FRAME MAGNITUDES extern float *R_mags; ///CURRENT FRAME MAGNITUDES extern float *pL_mags; ///PREVIOUS FRAME MAGNITUDES extern float *pR_mags; ///PREVIOUS FRAME MAGNITUDES void intobyte(int num, char* pbyte1 ,char* pbyte2) { char firstByte = (num & 0xff); int secondByteInt = (num & 0xff00); secondByteInt = secondByteInt>>8; char secondByte = secondByteInt; /*int thirdByteInt = (array[i] & 0xff0000); thirdByteInt = thirdByteInt>>16; char thirdByte = thirdByteInt; int fourthByteInt = (array[i] & 0xff000000); fourthByteInt = fourthByteInt>>24; char fourthByte = fourthByteInt;*/ *pbyte1 = firstByte; *pbyte2 = secondByte; } void cart2pol(float* cart, float* mags, float* phases, int framesize) { int length=framesize/2; for (int f = 0; f<length; f++) { mags[f]=sqrt((cart[f]*cart[f])+(cart[length+f]*cart[length+f])); phases[f]=atan2((float)(-1*cart[f+length]),(float)(cart[f])); } } void pol2cart(float* cart, float* mags, float* phases, int framesize) { int length=framesize/2; for (int f = 0; f<length; f++) { cart[f]=mags[f]*cos(phases[f]); cart[length+f]=-(mags[f]*sin(phases[f])); } } void hanning(float* window, int framesize) { for (int f = 0; f<framesize; f++) { window[f]= (float) (0.5*(1-cos(2*PI*(f+1)/(framesize+1)))); } } void updatephases(float* c_phase,float* p_phase,float* c_synthphase,float* p_synthphase, int framesize,float hopfactor,float interpfactor) { float synth_hopsize=((float) framesize) /4; float actual_anhop=floor(hopfactor*synth_hopsize); float anhop = floor((hopfactor*synth_hopsize)/interpfactor); float inst_freq; float omega_k; float delta_phi; float a, k; for (int f = 0; f<(framesize/2); f++) { //float bin = (f/(float)framesize); interpfactor; omega_k=(float) ((2*PI*f)/float(framesize)); //This is the predicted angular freqency rads/sec of the centre frequency delta_phi=(c_phase[f]-p_phase[f])-(anhop*omega_k); a = (float) (delta_phi/(2*PI)); k = (float) (floor(a+0.5)); delta_phi = (float) (delta_phi-k*2*PI); inst_freq=omega_k+delta_phi/anhop; c_synthphase[f] = p_synthphase[f]+(inst_freq*synth_hopsize); if (currentposition<actual_anhop){c_synthphase[f] = c_phase[f];} p_synthphase[f] = c_synthphase[f]; p_phase[f] = c_phase[f]; } } void updatephases2(float* c_phase,float* p_phase,float* c_synthphase,float* p_synthphase, int framesize,float hopfactor,float interpfactor) { float synth_hopsize=((float) framesize)/4; float actual_anhop=actual_anhop=floor(hopfactor*synth_hopsize); float anhop = floor((hopfactor*synth_hopsize)/interpfactor); float inst_freq; float omega_k; float delta_phi; float a, k; for (int f = 0; f<(framesize/2); f++) { //float bin = (f/(float)framesize); interpfactor; omega_k=(float) ((2*PI*f)/float(framesize)); //This is the predicted angular freqency rads/sec of the centre frequency delta_phi=(c_phase[f]-p_phase[f])-(anhop*omega_k); a = (float) (delta_phi/(2*PI)); k = (float) (floor(a+0.5)); delta_phi = (float) (delta_phi-k*2*PI); inst_freq=omega_k+delta_phi/anhop; c_synthphase[f] = p_synthphase[f]+(inst_freq*synth_hopsize); if (currentposition<actual_anhop){c_synthphase[f] = c_phase[f];} if (!(anhop==lastfactor)){c_synthphase[f]=c_phase[f];} p_synthphase[f] = c_synthphase[f]; p_phase[f] = c_phase[f]; } lastfactor=anhop; } void rotatephases(float* c_phase, float* p_phase, float* c_synthphase, float* p_synthphase, int framesize, float interpfactor) { float phase_diff; int diffhop = framesize/4; float anhop = floor((diffhop)/interpfactor); float inst_freq; float omega_k; float delta_phi; float a, k; //findpeaks(c_mags, p_mags, framesize, peak_locations, numpeaks); for (int i=0; i<framesize/2; i++) { phase_diff=(c_phase[i]-p_phase[i]); omega_k=(float) ((2*PI*i)/float(framesize)); delta_phi=(phase_diff)-(anhop*omega_k); a = (float) (delta_phi/(2*PI)); k = (float) (floor(a+0.5)); delta_phi = (float) (delta_phi-k*2*PI); inst_freq=omega_k+delta_phi/anhop; c_synthphase[i]=p_synthphase[i]+(inst_freq*diffhop); //c_synthphase[i]=p_synthphase[i]+(phase_diff); //c_synthphase[i]=p_synthphase[i]+((phase_diff*diffhop)*interpfactor); //if (currentposition<framesize/2 || (!(lastfactor==hopfactor))){c_synthphase[i] = c_phase[i];} if (currentposition<framesize/2){c_synthphase[i] = c_phase[i];} p_synthphase[i]=c_synthphase[i]; } lastfactor=hopfactor; } void rotatephases_peaklocked(float* c_phase, float* p_phase, float* c_synthphase, float* p_synthphase, float* c_mags, int framesize, float interpfactor) { float phase_diff; int diffhop = framesize/4; float anhop = floor((diffhop)/interpfactor); float inst_freq; float omega_k; float delta_phi; float a, k; int start, end, i; float original_peak_phase; float cutoff; cutoff = 10000; cutoff = floor(cutoff/(44100/framesize)); numpeaks = findpeaks(c_mags, pL_mags,(float) framesize, peak_locations); int p=1; //while(peak_locations[p]<cutoff) while(p<=numpeaks) { i=(int) peak_locations[p]; original_peak_phase=c_phase[i]; //start=i-2; //end=i+2; if (p==1){ start=0; end=(int) floor(peak_locations[p]+((peak_locations[p+1]-peak_locations[p])/2)); } else{ if (p==numpeaks){ start=(int) floor(peak_locations[p-1]+((peak_locations[p]-peak_locations[p-1])/2)); end=(framesize/2); } else { start=(int) floor(peak_locations[p-1]+((peak_locations[p]-peak_locations[p-1])/2)); end=(int) floor(peak_locations[p]+((peak_locations[p+1]-peak_locations[p])/2)); } } phase_diff=(c_phase[i]-p_phase[i]); omega_k=(float) ((2*PI*i)/float(framesize)); delta_phi=(phase_diff)-(anhop*omega_k); a = (float) (delta_phi/(2*PI)); k = (float) (floor(a+0.5)); delta_phi = (float) (delta_phi-k*2*PI); inst_freq=omega_k+delta_phi/anhop; c_synthphase[i]=p_synthphase[i]+(inst_freq*diffhop); //c_synthphase[i]=p_synthphase[i]+(phase_diff); //c_synthphase[i]=p_synthphase[i]+((phase_diff*diffhop)*interpfactor); //if (currentposition<framesize/2 || (!(lastfactor==hopfactor))){c_synthphase[i] = c_phase[i];} if (currentposition<framesize/2){c_synthphase[i] = c_phase[i];} p_synthphase[i]=c_synthphase[i]; int j; for (j=start; j<i; j++) { c_synthphase[j]=c_synthphase[i]-(original_peak_phase-c_phase[j]); p_synthphase[j]=c_synthphase[j]; } for (j=i+1; j<end; j++) { c_synthphase[j]=c_synthphase[i]-(original_peak_phase-c_phase[j]); p_synthphase[j]=c_synthphase[j]; } p++; } /*for (i=peak_locations[p]+1; i<(framesize/2); i++) { phase_diff=(c_phase[i]-p_phase[i]); omega_k=(2*PI*i)/float(framesize); delta_phi=(phase_diff)-(anhop*omega_k); a = delta_phi/(2*PI); k = floor(a+0.5); delta_phi = delta_phi-k*2*PI; inst_freq=omega_k+delta_phi/anhop; c_synthphase[i]=p_synthphase[i]+(inst_freq*diffhop); p_synthphase[i]=c_synthphase[i]; } */ lastfactor=hopfactor; } void cur2last(float* c_phase, float* c_synthphase, float* p_synthphase, int framesize) { for (int i=0; i<framesize/2; i++) { c_synthphase[i]=c_phase[i]; p_synthphase[i]=c_synthphase[i]; } } int findpeaks(float* c_mags, float* p_mags, float framesize, float* peak_locations) { numpeaks=0; peak_locations[0]=0; float peakthreshold=0; for (int i=2; i<(framesize/4)-10; i++) { if(c_mags[i]>c_mags[i-1] && c_mags[i]>c_mags[i+1] && c_mags[i]>c_mags[i-2] && c_mags[i]>c_mags[i+2] && c_mags[i]>peakthreshold) { numpeaks++; peak_locations[numpeaks]=(float) i; } } return numpeaks; } bool transient_detect(float* L_mags, float* R_mags, float* pL_mags, float* pR_mags, float drumthresh, float framesize) { extern float *L_phase, *R_phase; int trans = 0; for (int f = 0; f<(framesize/2); f++) { if ((R_mags[f]-pR_mags[f])>0 || (L_mags[f]-pL_mags[f])>0){trans++;} pR_mags[f]=R_mags[f]; pL_mags[f]=L_mags[f]; } drumthresh=(drumthresh/100)*(framesize/2); if (trans>=drumthresh) { return true; } else{return false;} } void log10plot(float* L_mags, float* plotFFTarray, int framesize, int plotsize) { float interpfactor1 = 10/100; //1 - 100hz bin 1 - 10 float interpfactor2 = 90/100; //100 - 1000hz bin 10 - 100 float interpfactor3 = 900/100; //1000 - 10000hz bin 100 - 1000 float interpfactor4 = 1048/100; //10000 - 20000hz bin 1000 - 2048 int temp; int i; float p; float ratio,dec; for (i=0 ; i<plotsize/4; i++) { p=(float) i; temp=(int) floor((((1+p)/100)*9)+1); ratio=((((1+p)/100)*9)+1)-floor((float) temp); plotFFTarray[i]=log((((L_mags[temp+1]-L_mags[temp])*ratio)+L_mags[temp])/1000); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log((((L_mags[temp+1]-L_mags[temp])*ratio)+L_mags[temp])/1000); } for (i=plotsize/4 ; i<(plotsize/4)*2; i++) { p=(float) i; temp= (int) floor((((1+p-plotsize/4)/100)*90)+10); plotFFTarray[i]=log(L_mags[temp]/1000); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log(L_mags[temp]/1000); } for (i=(plotsize/4)*2 ; i<(plotsize/4)*3; i++) { p=(float) i; temp=(int) floor((((1+p-(plotsize/4)*2)/100)*900)+100); plotFFTarray[i]=log(L_mags[temp]/1000); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log(L_mags[temp]/1000); } for (i=(plotsize/4)*3 ; i<(plotsize/4)*4; i++) { p=(float) i; temp=(int) floor((((1+p-(plotsize/4)*3)/100)*1048)+1000); plotFFTarray[i]=log(L_mags[temp]/1000); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log(L_mags[temp]/1000); } } void log10plot2(QVector<float>& L_mags, float* plotFFTarray, int framesize, int plotsize) { float interpfactor1 = 10/100; //1 - 100hz bin 1 - 10 float interpfactor2 = 90/100; //100 - 1000hz bin 10 - 100 float interpfactor3 = 900/100; //1000 - 10000hz bin 100 - 1000 float interpfactor4 = 1048/100; //10000 - 20000hz bin 1000 - 2048 int temp; int i; float p; float ratio,dec; for (i=0 ; i<plotsize/4; i++) { p=(float) i; temp=(int) floor((((1+p)/100)*9)+1); ratio=((((1+p)/100)*9)+1)-floor((float) temp); plotFFTarray[i]=((((L_mags.at(temp+1)-L_mags.at(temp))*ratio)+L_mags.at(temp))); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log((((L_mags[temp+1]-L_mags[temp])*ratio)+L_mags[temp])/1000); } for (i=plotsize/4 ; i<(plotsize/4)*2; i++) { p=i; temp=floor((((1+p-plotsize/4)/100)*90)+10); plotFFTarray[i]=(L_mags.at(temp)); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log(L_mags[temp]/1000); } for (i=(plotsize/4)*2 ; i<(plotsize/4)*3; i++) { p=i; temp=floor((((1+p-(plotsize/4)*2)/100)*900)+100); plotFFTarray[i]=(L_mags.at(temp)); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log(L_mags[temp]/1000); } for (i=(plotsize/4)*3 ; i<(plotsize/4)*4-1; i++) { p=i; temp=floor((((1+p-(plotsize/4)*3)/100)*1048)+1000); plotFFTarray[i]=(L_mags.at(temp)); //plotFFTarray[i]=dec*plotFFTarray[i]+0.5*log(L_mags[temp]/1000); } } void applyEQ(float* L_mags, float* R_mags, int framesize, int plotsize, QVector<float>& eqcurve) { //(80,85,400,120,0) Screen Coordinates float gain, interpfactor, p,result; int i, ind; for(i=0; i<10; i++) { gain=(119-(eqcurve.at(i*10)))/120; // eqcurve is the array filled when the user draws on the canvas if (gain < 0){gain=0;} L_mags[i]*=gain; R_mags[i]*=gain; } for(i=10; i<100; i++) { p=i; interpfactor=1.1; result=100+((interpfactor*(p-10))); ind=int(result); gain=(119-(eqcurve.at(ind)))/120; //gain=(110-(eqcurve[i+90]-85))/120; if (gain < 0){gain=0;} L_mags[i]*=gain; R_mags[i]*=gain; } for(i=100; i<1000; i++) { p=i; interpfactor=0.11; result=200+((interpfactor*(p-100))); ind=int(result); gain=(119-(eqcurve.at(ind)))/120; if (gain < 0){gain=0;} L_mags[i]*=gain; R_mags[i]*=gain; } for(i=1000; i<2048; i++) { p=i; interpfactor=.09; result=300+((interpfactor*(p-1000))); ind=int(result); gain=(119-(eqcurve.at(ind)))/120; if (gain < 0){gain=0;} L_mags[i]*=gain; R_mags[i]*=gain; } } void stereo2ms(float* left, float* right, int framesize) { float m, s; for (int i=0;i<framesize;i++) { m=(left[i]+right[i])/2; s=(left[i]-right[i])/2; left[i]=m; right[i]=s; } } void ms2stereo(float* left, float* right, int framesize) { float m, s; for (int i=0;i<framesize;i++) { m=(left[i]+right[i]); s=(left[i]-right[i]); left[i]=m; right[i]=s; } } void bandeq(float* L_mags, float* R_mags, QVector<float>& eqcurve, int framesize) { for (int i=0;i<framesize/2;i++) { L_mags[i] *= eqcurve.at(i); R_mags[i] *= eqcurve.at(i); } }