void Test::test_PolyMult_works() { srand(time(0)); int n = 4; int randMin = -100, randMax = 100; Vector<Complex> P(n), Q(n); for(int i = 0; i < n; ++i) { double real = rand()%(randMax-randMin)+randMin; double imaginary = rand()%(randMax-randMin)+randMin; P[i] = Complex(real, imaginary); Q[i] = Complex(real, imaginary); } FFT fft; fft.preComputeOmega(n); Vector<Complex> resultsR = fft.polyMultR(P, Q, n); fft.preComputeRBS(n); Vector<Complex> resultsD = fft.polyMultD(P, Q, n); for(int i = 0; i < n; ++i) { if(resultsD[i] != resultsR[i]) std::cout << "*** Failed ***" << std::endl; std::cout << resultsR[i] << " " << resultsD[i] << std::endl; } }
void ofApp::audioIn(float * input, int bufferSize, int nChannels){ if( !processAudio ) return; for (int i=0; i<bufferSize; i++) { trainingSample[i][0] = input[i]; } if( record ){ trainingData.addSample( trainingClassLabel, trainingSample ); } if( pipeline.getTrained() ){ //Run the prediction using the matrix of audio data pipeline.predict( trainingSample ); //Update the FFT plot FFT *fft = pipeline.getFeatureExtractionModule< FFT >( 0 ); if( fft ){ vector< FastFourierTransform > &results = fft->getFFTResultsPtr(); magnitudePlot.setData( results[0].getMagnitudeData() ); } //Update the likelihood plot classLikelihoodsPlot.update( pipeline.getClassLikelihoods() ); } }
bool test3() { FFT fft; vector<complex<double> > in, out, expected, temp; in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(1.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); expected.push_back(complex<double>( 0.125, 0.0)); expected.push_back(complex<double>( 0.088, -0.088)); expected.push_back(complex<double>( 0.000, -0.125)); expected.push_back(complex<double>(-0.088, -0.088)); expected.push_back(complex<double>(-0.125, 0.0)); expected.push_back(complex<double>(-0.088, 0.088)); expected.push_back(complex<double>( 0.000, 0.125)); expected.push_back(complex<double>( 0.088, 0.088)); fft.FT(in,out); if (!checkEqual(expected,out)) { printError(expected,out); cout << __FILE__ << ": " << __LINE__ << endl; return false; } fft.inverseFT(out, temp); return true; }
//-------------------------------------------------------------- void ofApp::setup(){ ofSetFrameRate(60); //Setup the FFT FFT fft; fft.init(FFT_WINDOW_SIZE,FFT_HOP_SIZE,1,FFT::RECTANGULAR_WINDOW,true,false,DATA_TYPE_MATRIX); //Setup the classifier RandomForests forest; forest.setForestSize( 10 ); forest.setNumRandomSplits( 100 ); forest.setMaxDepth( 10 ); forest.setMinNumSamplesPerNode( 10 ); //Add the feature extraction and classifier to the pipeline pipeline.addFeatureExtractionModule( fft ); pipeline.setClassifier( forest ); trainingClassLabel = 1; record = false; processAudio = true; trainingData.setNumDimensions( 1 ); //We are only going to use the data from one microphone channel, so the dimensions are 1 trainingSample.resize( AUDIO_BUFFER_SIZE, 1 ); //We will set the training matrix to match the audio buffer size //Setup the audio card ofSoundStreamSetup(2, 1, this, AUDIO_SAMPLE_RATE, AUDIO_BUFFER_SIZE, 4); }
void test_scalar_generic(int nfft) { typedef typename FFT<T>::Complex Complex; typedef typename FFT<T>::Scalar Scalar; typedef typename VectorType<Container, Scalar>::type ScalarVector; typedef typename VectorType<Container, Complex>::type ComplexVector; FFT<T> fft; ScalarVector tbuf(nfft); ComplexVector freqBuf; for (int k = 0; k < nfft; ++k) tbuf[k] = (T)(rand() / (double)RAND_MAX - .5); // make sure it DOESN'T give the right full spectrum answer // if we've asked for half-spectrum fft.SetFlag(fft.HalfSpectrum); fft.fwd(freqBuf, tbuf); VERIFY((size_t)freqBuf.size() == (size_t)((nfft >> 1) + 1)); VERIFY(fft_rmse(freqBuf, tbuf) < test_precision<T>()); // gross check fft.ClearFlag(fft.HalfSpectrum); fft.fwd(freqBuf, tbuf); VERIFY((size_t)freqBuf.size() == (size_t)nfft); VERIFY(fft_rmse(freqBuf, tbuf) < test_precision<T>()); // gross check if (nfft & 1) return; // odd FFTs get the wrong size inverse FFT ScalarVector tbuf2; fft.inv(tbuf2, freqBuf); VERIFY(dif_rmse(tbuf, tbuf2) < test_precision<T>()); // gross check // verify that the Unscaled flag takes effect ScalarVector tbuf3; fft.SetFlag(fft.Unscaled); fft.inv(tbuf3, freqBuf); for (int k = 0; k < nfft; ++k) tbuf3[k] *= T(1. / nfft); // for (size_t i=0;i<(size_t) tbuf.size();++i) // cout << "freqBuf=" << freqBuf[i] << " in2=" << tbuf3[i] << " - in=" << tbuf[i] << " => " << (tbuf3[i] - tbuf[i] ) << endl; VERIFY(dif_rmse(tbuf, tbuf3) < test_precision<T>()); // gross check // verify that ClearFlag works fft.ClearFlag(fft.Unscaled); fft.inv(tbuf2, freqBuf); VERIFY(dif_rmse(tbuf, tbuf2) < test_precision<T>()); // gross check }
void fft_Y(MultiArray<complex<float>, 3> &a) { FFT<float> fft; int ny = a.dims()[1]; for (int z = 0; z < a.dims()[2]; z++) { for (int x = 0; x < a.dims()[0]; x++) { VectorXcf fft_in = a.slice<1>({x,0,z},{0,ny,0}).asArray(); VectorXcf fft_out(ny); fft.fwd(fft_out, fft_in); a.slice<1>({x,0,z},{0,ny,0}).asArray() = fft_out; } } }
void fft_Z(MultiArray<complex<float>, 3> &a) { FFT<float> fft; int nz = a.dims()[2]; for (int x = 0; x < a.dims()[0]; x++) { for (int y = 0; y < a.dims()[1]; y++) { VectorXcf fft_in = a.slice<1>({x,y,0},{0,0,nz}).asArray(); VectorXcf fft_out(nz); fft.fwd(fft_out, fft_in); a.slice<1>({x,y,0},{0,0,nz}).asArray() = fft_out; } } }
void fft_X(MultiArray<complex<float>, 3> &a) { FFT<float> fft; int nx = a.dims()[0]; for (int z = 0; z < a.dims()[2]; z++) { for (int y = 0; y < a.dims()[1]; y++) { VectorXcf fft_in = a.slice<1>({0,y,z},{nx,0,0}).asArray(); VectorXcf fft_out(nx); fft.fwd(fft_out, fft_in); a.slice<1>({0,y,z},{nx,0,0}).asArray() = fft_out; } } }
void test_return_by_value(int len) { VectorXf in; VectorXf in1; in.setRandom( len ); VectorXcf out1,out2; FFT<float> fft; fft.SetFlag(fft.HalfSpectrum ); fft.fwd(out1,in); out2 = fft.fwd(in); VERIFY( (out1-out2).norm() < test_precision<float>() ); in1 = fft.inv(out1); VERIFY( (in1-in).norm() < test_precision<float>() ); }
void fwd_inv(size_t nfft) { typedef typename NumTraits<T_freq>::Real Scalar; vector<T_time> timebuf(nfft); RandomFill(timebuf); vector<T_freq> freqbuf; static FFT<Scalar> fft; fft.fwd(freqbuf,timebuf); vector<T_time> timebuf2; fft.inv(timebuf2,freqbuf); long double rmse = mag2(timebuf - timebuf2) / mag2(timebuf); cout << "roundtrip rmse: " << rmse << endl; }
void test_complex_generic(int nfft) { typedef typename FFT<T>::Complex Complex; typedef typename VectorType<Container,Complex>::type ComplexVector; FFT<T> fft; ComplexVector inbuf(nfft); ComplexVector outbuf; ComplexVector buf3; for (int k=0;k<nfft;++k) inbuf[k]= Complex( (T)(rand()/(double)RAND_MAX - .5), (T)(rand()/(double)RAND_MAX - .5) ); fft.fwd( outbuf , inbuf); VERIFY( fft_rmse(outbuf,inbuf) < test_precision<T>() );// gross check fft.inv( buf3 , outbuf); VERIFY( dif_rmse(inbuf,buf3) < test_precision<T>() );// gross check // verify that the Unscaled flag takes effect ComplexVector buf4; fft.SetFlag(fft.Unscaled); fft.inv( buf4 , outbuf); for (int k=0;k<nfft;++k) buf4[k] *= T(1./nfft); VERIFY( dif_rmse(inbuf,buf4) < test_precision<T>() );// gross check // verify that ClearFlag works fft.ClearFlag(fft.Unscaled); fft.inv( buf3 , outbuf); VERIFY( dif_rmse(inbuf,buf3) < test_precision<T>() );// gross check }
int main() { int n; scanf("%d", &n); while(n--) { string a, b; cin>>a>>b; if(a == "0" || b == "0") { cout<<"0\n"; continue; } vector<int> ai; vector<int> bi; vector<int> res; for(int i = a.size()-1; i >= 0; --i) { ai.pb((a[i]-'0')); } for(int i = b.size()-1; i >= 0; --i) { bi.pb((b[i]-'0')); } FFT f; f.multiply(ai, bi, res); int carry=0; for(size_t i = 0; i < res.size(); i++) { res[i] += carry; carry = res[i]/10; res[i] %= 10; } int i = res.size()-1; while(res[i] == 0) i--; while(i >= 0) { cout<<res[i]; --i; } cout<<endl; } return 0; }
void Test::test_PolyMult_recursive() { int n = 2; Vector<Complex> P(n),Q(n); P[0] = Complex(2,0); P[1] = Complex(2,0); Q[0] = Complex(2,0); Q[1] = Complex(2,0); FFT fft; fft.preComputeOmega(n); Vector<Complex> results = fft.polyMultR(P, Q, n); for(Complex c : results) { std::cout << c << std::endl; } }
vector<vector<double> > compute(vector<double> sound) { FFT fft; vector<vector<double> > res; vector<complex<double> > tmp; while(sound.size()%SMPLS_PR_BLCK) sound.push_back(0); for(int i=0;i<sound.size();i+=SMPLS_PR_BLCK) { vector<complex<double> > t; for(int j=0;j<SMPLS_PR_BLCK;j++) t.push_back(complex<double>(sound[i+j],0)); tmp = fft.compute(t); vector<double> tmp2; for(int i=0;i<tmp.size();i++) tmp2.push_back(tmp[i].real()); res.push_back(transform(tmp2)); } return res; }
void Test::test_FFT_works() { srand(time(0)); int n = 4; Vector<Complex> P(n); int randMin = -100, randMax = 100; for(int i = 0; i < n; ++i) { double real = rand()%(randMax-randMin)+randMin; double imaginary = rand()%(randMax-randMin)+randMin; P[i] = Complex(real, imaginary); } // P[0] = Complex(2,0); // P[1] = Complex(2,0); // P[2] = Complex(2,0); // P[3] = Complex(2,0); Vector<Complex> x = Vector<Complex> (n); for(int i = 0; i < n; i++) { x[i] = Complex(cos(2*PI/n * i), sin(2*PI/n * i)); } FFT fft; fft.preComputeRBS(n); Vector<Complex> algebraic = fft.algebraic(P, n, x); Vector<Complex> recursive = fft.recursive(P, n, x, 1); Vector<Complex> dynamic = fft.dynamic(P, n, x); for(int i = 0; i < n; ++i) { std::cout << "A(" << i << "): " << algebraic[i] << std::endl; std::cout << "R(" << i << "): " << recursive[i] << std::endl; std::cout << "D(" << i << "): " << dynamic[i] << std::endl; std::cout << std::endl; } }
int main(int argc, char*argv[]) { // create FFT class implementation // each implementation has its own plan map. FFT<double> fft; // create some data size_t N = 1024 * 1024; std::vector<complex<double>,fftalloc<complex<double> > > data(N); std::vector<complex<double>,fftalloc<complex<double> > > dataFourier(N); std::vector<complex<double>,fftalloc<complex<double> > > dataCalc(N); std::cout << "1) --- original data ---" << endl; for(std::vector<complex<double> >::size_type i = 0; i != data.size(); i++) { data[i] = polar(sin(double(i)/N * M_PI * 2), 0.0); // std::cout << i << data[i] << endl; } // fft std::cout << "2) --- fft data ---" << endl; fft.fwd(dataFourier, data); std::cout << "speed / ms: " << fft.speed()/1000 << endl; // for(std::vector<complex<double> >::size_type i = 0; i != dataFourier.size(); i++) { // std::cout << i << dataFourier[i] << endl; // } // ifft std::cout << "3) --- ifft data ---" << endl; fft.inv(dataCalc, dataFourier); std::cout << "speed / ms: " << fft.speed()/1000 << endl; // for(std::vector<complex<double> >::size_type i = 0; i != dataCalc.size(); i++) { // std::cout << i << dataCalc[i] << endl; // } // std::cout << "4) --- comparison data ---" << endl; // for(std::vector<complex<double> >::size_type i = 0; i != dataCalc.size(); i++) { // std::cout << i << data[i] - dataCalc[i] << endl; // } std::getchar(); return 0; }
bool test1() { FFT fft; vector<complex<double> > in, out, expected, temp; in.push_back(complex<double>(1.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); in.push_back(complex<double>(0.0,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); expected.push_back(complex<double>(0.125,0.0)); fft.FT(in,out); if (!checkEqual(expected,out)) { printError(expected,out); return false; } fft.inverseFT(out, temp); if (!checkEqual(in,temp)) { printError(in,temp); return false; } return true; }
int main() { int N = 32768; double Temp = 1.0/8192.0; printf("N: %d, Temp: %.15le\n",N, Temp); IAGRID iagrid(N,N,Temp); double* omega; double* tau; iagrid.GetGrid(omega,tau); complex<double>* G_f = new complex<double>[N]; complex<double>* G_t = new complex<double>[N]; iagrid.InitG(G_f,0.3,0.5,0); PrintFunc("gfin",N,G_f,omega); //-----------------glavni deo koda----------------// FFT fft; //pravimo objekat fft fft.Initialize(&iagrid); //inicijalizujemo ga za temperaturu 0.05 i broj tachaka N for (int n=0; n<20; n++) //ovde staviti koliko puta da uradi FFT u oba smera { char str_fn_f[20]; //priprema naziva fajlova za ispis char str_fn_t[20]; sprintf(str_fn_f, "gfout.dat.%d", n); sprintf(str_fn_t, "gtout.dat.%d", n); fft.FtoT(G_f, G_t); //FFT freq to time fft.TtoF(G_t, G_f); //FFT time to freq //ispis rezultata u fajl PrintFunc(str_fn_f,N,G_f,omega); PrintFunc(str_fn_t,N,G_t,tau); } //-------------------------------------------------// return 0; }
void Test::run_FFT_recursive() { int minN = 32, maxN = 20000000; std::cout << "FFT recursive" << std::endl << "N" << '\t' << "Time" << std::endl; for(int n = minN; n <= maxN; n*=2) { FFT fft; fft.preComputeOmega(n); int runTime = averageRuntime([&](){ Vector<Complex> P = fft.makeRandomVector(n, -1, 1); Vector<Complex> Q = fft.makeRandomVector(n, -1, 1); Vector<Complex> result = fft.polyMultR(P, Q, n); }, RUNS); std::cout << n << '\t' << runTime << std::endl; } }
void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false) { typedef typename NumTraits<T>::Real Scalar; typedef typename std::complex<Scalar> Complex; int nits = NDATA/nfft; vector<T> inbuf(nfft); vector<Complex > outbuf(nfft); FFT< Scalar > fft; if (unscaled) { fft.SetFlag(fft.Unscaled); cout << "unscaled "; } if (halfspec) { fft.SetFlag(fft.HalfSpectrum); cout << "halfspec "; } std::fill(inbuf.begin(),inbuf.end(),0); fft.fwd( outbuf , inbuf); BenchTimer timer; timer.reset(); for (int k=0;k<8;++k) { timer.start(); if (fwd) for(int i = 0; i < nits; i++) fft.fwd( outbuf , inbuf); else for(int i = 0; i < nits; i++) fft.inv(inbuf,outbuf); timer.stop(); } cout << nameof<Scalar>() << " "; double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits ); if ( NumTraits<T>::IsComplex ) { cout << "complex"; }else{ cout << "real "; mflops /= 2; } if (fwd) cout << " fwd"; else cout << " inv"; cout << " NFFT=" << nfft << " " << (double(1e-6*nfft*nits)/timer.value()) << " MS/s " << mflops << "MFLOPS\n"; }
virtual void DoProcess() { Int complexsize = ComplexSize();//(UInt)(this->PeriodSize() / 2) + 1; //asdf++; //if(asdf>1) //{ //fftw_execute(p1); //cout << this->PeriodSize() << endl; fft.Forward(this->tmpbuffer,this->PeriodSize()); memcpy(lastSpectrum,fft.Data_c,ComplexSize()*sizeof(fftw_complex)); #ifdef CEPSTRUM for(UInt i=0;i<complexsize;i++) { auto sine=fft.Data_c[i][1]; auto cosine=fft.Data_c[i][0]; double amplitude=sqrt(sine*sine+cosine*cosine); //double phase=atan2(cosine,sine); if(amplitude<0.00001) //10^-5 fft2.Data[i]=-5; else fft2.Data[i]=logf(amplitude)/M_LN10; //fft2.Data[i]=amplitude; } fft2.Forward(); for(UInt i=0;i<ComplexSize2();i++) { fft2.Data_c[i][0] = fft2.Data_c[i][0]*coefficients2[i]; fft2.Data_c[i][1] = fft2.Data_c[i][1]*coefficients2[i]; } fft2.Reverse(); for(UInt i=0;i<complexsize;i++) { auto sine=fft.Data_c[i][1]; auto cosine=fft.Data_c[i][0]; double amplitude=pow(10,fft2.Data[i]/fft2.size); double phase=atan2(cosine,sine); fft.Data_c[i][1] = cos(phase)*amplitude; fft.Data_c[i][0] = sin(phase)*amplitude; } #endif //int shift=21; /*for(UInt i=0;i<complexsize;i++) { tmpcomplex[i][0] = tmpcomplex[i][0]*coefficients[i]; tmpcomplex[i][1] = tmpcomplex[i][1]*coefficients[i]; }*/ //asdf=0; //} //tmpcomplex[0][0]=0; //tmpcomplex[0][1]=0; /*for(UInt i=(complexsize-1)/2+1;i<complexsize;i++) { tmpcomplex[i][0]=0; tmpcomplex[i][1]=0; }*/ //memcpy(tmpcomplex,fft.Data_c,complexsize*sizeof(fftw_complex)); if(freq_scale==1.) { for(UInt i=0;i<complexsize;i++) { fft.Data_c[i][0] = fft.Data_c[i][0]*coefficients[i]; fft.Data_c[i][1] = fft.Data_c[i][1]*coefficients[i]; } goto trolled; } /*Int skip=this->BuffersPerPeriod/this->overlapcount; if(skip<1)skip=1; UInt overlapcount=this->BuffersPerPeriod/skip; Int skip_samples=this->PeriodSize()/overlapcount;*/ //for(Int i=complexsize-1;i>=0;i--) bool rev; rev=freq_scale>1.; for(Int i=rev?Int(complexsize)-1:0;rev?(i>=0):(i<Int(complexsize));rev?i--:i++) { int i2; //if(i>50) double asdf=((double)i)/freq_scale; //source frequency i2=(int)asdf; if(i2==0 || i==0) //prevent division by zero continue; if(i2+1>=(int)complexsize) { fft.Data_c[i][0]=fft.Data_c[i][1]=0.; continue; } double trololo=asdf-i2; //double freq1=(asdf/(double)(complexsize-1))*0.5; double period1=(double)fft.size/(double)asdf; //double freq2=(double)i/(double)(complexsize-1)*0.5; double period2=(double)fft.size/(double)i; double sine=(tmpcomplex[i2][1]*(1.0-trololo) + tmpcomplex[i2+1][1]*trololo); double cosine=(tmpcomplex[i2][0]*(1.0-trololo) + tmpcomplex[i2+1][0]*trololo); double amplitude=sqrt(sine*sine+cosine*cosine); double phase=atan2(cosine,sine); //radians; [-pi,pi] //double phase_delta1=(skip_samples%period1)/period1*(2*M_PI); phase=phase*((double)period1); //phase=phase/((double)(M_PI*2)); //phase=phase*((double)(M_PI*2)); phase=phase/((double)period2); //double phase=atan2(tmpcomplex[i][0],tmpcomplex[i][1]); //phase*=1.5; //if(i==100)cout << phase << endl; //else i2=i; //fft.Data_c[i][0] = (fft.Data_c[i2][0]*(1.0-trololo) + fft.Data_c[i2+1][0]*trololo)*coefficients[i]; //fft.Data_c[i][1] = (fft.Data_c[i2][1]*(1.0-trololo) + fft.Data_c[i2+1][1]*trololo)*coefficients[i]; amplitude*=coefficients[i]; fft.Data_c[i][1] = cos(phase)*amplitude; fft.Data_c[i][0] = sin(phase)*amplitude; } trolled: //fftw_execute(p2); /*int shift=50; for(Int i=complexsize-1-shift;i>=0;i--) { fft.Data_c[i+shift][0]=fft.Data_c[i][0]*coefficients[i+shift]; fft.Data_c[i+shift][1]=fft.Data_c[i][1]*coefficients[i+shift]; }*/ double* d=fft.Reverse(this->PeriodSize()); memcpy(this->tmpbuffer,d,sizeof(double)*this->PeriodSize()); Int ps=this->PeriodSize(); for(Int i=0;i<ps;i++) this->tmpbuffer[i] /= fft.size; }
boolean CAlgorithmHilbertTransform::process(void) { uint32 l_ui32ChannelCount = ip_pMatrix->getDimensionSize(0); uint32 l_ui32SamplesPerChannel = ip_pMatrix->getDimensionSize(1); IMatrix* l_pInputMatrix = ip_pMatrix; IMatrix* l_pOutputEnvelopeMatrix = op_pEnvelopeMatrix; IMatrix* l_pOutputPhaseMatrix = op_pPhaseMatrix; FFT< double, internal::kissfft_impl<double > > fft; if(this->isInputTriggerActive(OVP_Algorithm_HilbertTransform_InputTriggerId_Process)) { //Computing Hilbert transform for all channels for(uint32 channel=0; channel<l_ui32ChannelCount; channel++) { //Initialization of buffer vectors m_vecXcdSignalBuffer = RowVectorXcd::Zero(l_ui32SamplesPerChannel); m_vecXcdSignalFourier = RowVectorXcd::Zero(l_ui32SamplesPerChannel); //Initialization of vector h used to compute analytic signal m_vecXdHilbert.resize(l_ui32SamplesPerChannel); m_vecXdHilbert(0) = 1.0; if(l_ui32SamplesPerChannel%2 == 0) { m_vecXdHilbert(l_ui32SamplesPerChannel/2) = 1.0; for(uint32 i=1; i<l_ui32SamplesPerChannel/2; i++) { m_vecXdHilbert(i) = 2.0; } for(uint32 i=(l_ui32SamplesPerChannel/2)+1; i<l_ui32SamplesPerChannel; i++) { m_vecXdHilbert(i) = 0.0; } } else { m_vecXdHilbert((l_ui32SamplesPerChannel/2)+1) = 1.0; for(uint32 i=1; i<(l_ui32SamplesPerChannel/2)+1; i++) { m_vecXdHilbert(i) = 2.0; } for(uint32 i=(l_ui32SamplesPerChannel/2)+2; i<l_ui32SamplesPerChannel; i++) { m_vecXdHilbert(i) = 0.0; } } //Copy input signal chunk on buffer for(uint32 samples=0; samples<l_ui32SamplesPerChannel;samples++) { m_vecXcdSignalBuffer(samples).real(l_pInputMatrix->getBuffer()[samples + channel * (l_ui32SamplesPerChannel)]); m_vecXcdSignalBuffer(samples).imag(0.0); } //Fast Fourier Transform of input signal fft.fwd(m_vecXcdSignalFourier, m_vecXcdSignalBuffer); //Apply Hilbert transform by element-wise multiplying fft vector by h m_vecXcdSignalFourier = m_vecXcdSignalFourier * m_vecXdHilbert; //Inverse Fast Fourier transform fft.inv(m_vecXcdSignalBuffer, m_vecXcdSignalFourier); //m_vecXcdSignalBuffer is now the analytical signal of the initial input signal //Compute envelope and phase and pass it to the corresponding output for(uint32 samples=0; samples<l_ui32SamplesPerChannel;samples++) { l_pOutputEnvelopeMatrix->getBuffer()[samples + channel*samples] = abs(m_vecXcdSignalBuffer(samples)); l_pOutputPhaseMatrix->getBuffer()[samples + channel*samples] = arg(m_vecXcdSignalBuffer(samples)); } } } return true; }
void process(int input_fd, int output_fd) { off_t current_offset = 0; std::complex<float> *frame_data = NULL; std::complex<float> *last_frame_data = NULL; size_t count = 0; size_t frame_count = 0, hop_factor = 8; FFT<float> *ifft = NULL; std::complex<float> *ifft_result = NULL; int16_t *samples = NULL; float scale_factor = 1.0; for (;;) { BlockSet blkset; try { blkset.begin_read(input_fd, current_offset); delete [] last_frame_data; last_frame_data = frame_data; frame_data = blkset.load_alloc_block<std::complex<float> >(REPLAY_PVOC_BLOCK, count); if (ifft == NULL) { ifft = new FFT<float>(count, FFT<float>::INVERSE); ifft_result = new std::complex<float>[count]; samples = new int16_t[count]; scale_factor = float(count) * float(hop_factor); } } catch (...) { /* * if it bombs out we are probably past end of file but who knows * so we just close the output_fd and rethrow. This is really ugly * but will make sure that any really bad errors get printed * rather than ignored. */ close(input_fd); close(output_fd); throw; } /* * phase information is stored as a delta from last_frame_data. * If last_frame_data is not NULL, we add the phase values into * those in frame_data. */ if (last_frame_data != NULL) { for (size_t i = 0; i < count; i++) { frame_data[i] = std::polar( std::abs(frame_data[i]), std::arg(frame_data[i]) + std::arg(last_frame_data[i]) ); } } /* * now if frame_count % hop_factor == 0, take the IFFT. * This should yield a block of (approximately) original * audio data. */ if (frame_count % hop_factor == 0) { ifft->compute(ifft_result, frame_data); /* take real part and scale as needed */ for (size_t i = 0; i < count; i++) { samples[i] = std::real(ifft_result[i]) / scale_factor; } write_all(output_fd, samples, count * sizeof(*samples)); } frame_count++; current_offset = blkset.end_offset( ); } }
void UnbiasedSquaredPhaseLagIndex::compute(ConnectivitySettings::IntermediateTrialData& inputData, QVector<QPair<int,MatrixXcd> >& vecPairCsdSum, QVector<QPair<int,MatrixXd> >& vecPairCsdImagSignSum, QMutex& mutex, int iNRows, int iNFreqs, int iNfft, const QPair<MatrixXd, VectorXd>& tapers) { if(inputData.vecPairCsdImagSign.size() == iNRows) { //qDebug() << "UnbiasedSquaredPhaseLagIndex::compute - vecPairCsdImagSign was already computed for this trial."; return; } inputData.vecPairCsdImagSign.clear(); int i,j; // Calculate tapered spectra if not available already // This code was copied and changed modified Utils/Spectra since we do not want to call the function due to time loss. if(inputData.vecTapSpectra.size() != iNRows) { inputData.vecTapSpectra.clear(); RowVectorXd vecInputFFT, rowData; RowVectorXcd vecTmpFreq; MatrixXcd matTapSpectrum(tapers.first.rows(), iNFreqs); QVector<Eigen::MatrixXcd> vecTapSpectra; FFT<double> fft; fft.SetFlag(fft.HalfSpectrum); for (i = 0; i < iNRows; ++i) { // Substract mean rowData.array() = inputData.matData.row(i).array() - inputData.matData.row(i).mean(); // Calculate tapered spectra if not available already for(j = 0; j < tapers.first.rows(); j++) { vecInputFFT = rowData.cwiseProduct(tapers.first.row(j)); // FFT for freq domain returning the half spectrum and multiply taper weights fft.fwd(vecTmpFreq, vecInputFFT, iNfft); matTapSpectrum.row(j) = vecTmpFreq * tapers.second(j); } inputData.vecTapSpectra.append(matTapSpectrum); } } // Compute CSD if(inputData.vecPairCsd.isEmpty()) { double denomCSD = sqrt(tapers.second.cwiseAbs2().sum()) * sqrt(tapers.second.cwiseAbs2().sum()) / 2.0; bool bNfftEven = false; if (iNfft % 2 == 0){ bNfftEven = true; } MatrixXcd matCsd = MatrixXcd(iNRows, iNFreqs); for (i = 0; i < iNRows; ++i) { for (j = i; j < iNRows; ++j) { // Compute CSD (average over tapers if necessary) matCsd.row(j) = inputData.vecTapSpectra.at(i).cwiseProduct(inputData.vecTapSpectra.at(j).conjugate()).colwise().sum() / denomCSD; // Divide first and last element by 2 due to half spectrum matCsd.row(j)(0) /= 2.0; if(bNfftEven) { matCsd.row(j).tail(1) /= 2.0; } } inputData.vecPairCsd.append(QPair<int,MatrixXcd>(i,matCsd)); inputData.vecPairCsdImagSign.append(QPair<int,MatrixXd>(i,matCsd.imag().cwiseSign())); } mutex.lock(); if(vecPairCsdSum.isEmpty()) { vecPairCsdSum = inputData.vecPairCsd; vecPairCsdImagSignSum = inputData.vecPairCsdImagSign; } else { for (int j = 0; j < vecPairCsdSum.size(); ++j) { vecPairCsdSum[j].second += inputData.vecPairCsd.at(j).second; vecPairCsdImagSignSum[j].second += inputData.vecPairCsdImagSign.at(j).second; } } mutex.unlock(); } else { if(inputData.vecPairCsdImagSign.isEmpty()) { for (i = 0; i < inputData.vecPairCsd.size(); ++i) { inputData.vecPairCsdImagSign.append(QPair<int,MatrixXd>(i,inputData.vecPairCsd.at(i).second.imag().cwiseSign())); } mutex.lock(); if(vecPairCsdImagSignSum.isEmpty()) { vecPairCsdImagSignSum = inputData.vecPairCsdImagSign; } else { for (int j = 0; j < vecPairCsdImagSignSum.size(); ++j) { vecPairCsdImagSignSum[j].second += inputData.vecPairCsdImagSign.at(j).second; } } mutex.unlock(); } } }
void TMSI::run() { while(m_bIsRunning) { //std::cout<<"TMSI::run(s)"<<std::endl; //pop matrix only if the producer thread is running if(m_pTMSIProducer->isRunning()) { MatrixXf matValue = m_pRawMatrixBuffer_In->pop(); // Set Beep trigger (if activated) if(m_bBeepTrigger && m_qTimerTrigger.elapsed() >= m_iTriggerInterval) { QFuture<void> future = QtConcurrent::run(Beep, 450, 700); //Set trigger in received data samples - just for one sample, so that this event is easy to detect matValue(136, m_iSamplesPerBlock-1) = 252; m_qTimerTrigger.restart(); Q_UNUSED(future); } // Set keyboard trigger (if activated and !=0) if(m_bUseKeyboardTrigger && m_iTriggerType!=0) matValue(136, m_iSamplesPerBlock-1) = m_iTriggerType; //Write raw data to fif file if(m_bWriteToFile) m_pOutfid->write_raw_buffer(matValue.cast<double>(), m_cals); // TODO: Use preprocessing if wanted by the user if(m_bUseFiltering) { MatrixXf temp = matValue; matValue = matValue - m_matOldMatrix; m_matOldMatrix = temp; // //Check filter class - will be removed in the future - testing purpose only! // FilterTools* filterObject = new FilterTools(); // //kaiser window testing // qint32 numberCoeff = 51; // QVector<float> impulseResponse(numberCoeff); // filterObject->createDynamicFilter(QString('LP'), numberCoeff, (float)0.3, impulseResponse); // ofstream outputFileStream("mne_x_plugins/resources/tmsi/filterToolsTest.txt", ios::out); // outputFileStream << "impulseResponse:\n"; // for(int i=0; i<impulseResponse.size(); i++) // outputFileStream << impulseResponse[i] << " "; // outputFileStream << endl; // //convolution testing // QVector<float> in (12, 2); // QVector<float> kernel (4, 2); // QVector<float> out = filterObject->convolve(in, kernel); // outputFileStream << "convolution result:\n"; // for(int i=0; i<out.size(); i++) // outputFileStream << out[i] << " "; // outputFileStream << endl; } // TODO: Perform a fft if wanted by the user if(m_bUseFFT) { QElapsedTimer timer; timer.start(); FFT<float> fft; Matrix<complex<float>, 138, 16> freq; for(qint32 i = 0; i < matValue.rows(); ++i) fft.fwd(freq.row(i), matValue.row(i)); // cout<<"FFT postprocessing done in "<<timer.nsecsElapsed()<<" nanosec"<<endl; // cout<<"matValue before FFT:"<<endl<<matValue<<endl; // cout<<"freq after FFT:"<<endl<<freq<<endl; // matValue = freq.cwiseAbs(); // cout<<"matValue after FFT:"<<endl<<matValue<<endl; } //Change values of the trigger channel for better plotting - this change is not saved in the produced fif file if(m_iNumberOfChannels>137) { for(int i = 0; i<matValue.row(137).cols(); i++) { // Left keyboard or capacitive if(matValue.row(136)[i] == 254) matValue.row(136)[i] = 4000; // Right keyboard if(matValue.row(136)[i] == 253) matValue.row(136)[i] = 8000; // Beep if(matValue.row(136)[i] == 252) matValue.row(136)[i] = 2000; } } //emit values to real time multi sample array for(qint32 i = 0; i < matValue.cols(); ++i) m_pRMTSA_TMSI->data()->setValue(matValue.col(i).cast<double>()); // Reset keyboard trigger m_iTriggerType = 0; } } //Close the fif output stream if(m_bWriteToFile) m_pOutfid->finish_writing_raw(); //std::cout<<"EXITING - TMSI::run()"<<std::endl; }
void Test::test_FFT_vs_previous_approaches() { std::cout << "Simple Test" << std::endl; { int n = 2; double p[] = {3,5}; double q[] = {2,1}; Vector<double> P(p, p+n); Vector<double> Q(q, q+n); Vector<Complex> PFFT (P.begin(), P.end()); Vector<Complex> QFFT (Q.begin(), Q.end()); PolyMult polyMultSB; Vector<double> pqActualSB = polyMultSB.schoolBook(n, P, Q); PolyMult polyMultDnC4; std::vector<double> pqActualDnC4 = polyMultDnC4.divideAndConquer4(n, P, Q); PolyMult polyMultDnC3; std::vector<double> pqActualDnC3 = polyMultDnC3.divideAndConquer3(n, P, Q); FFT fft; fft.preComputeOmega(n); Vector<Complex> pqActualFFTR = fft.polyMultR(PFFT, QFFT, n); fft.preComputeRBS(n); Vector<Complex> pqActualFFTD = fft.polyMultD(PFFT, QFFT, n); double pqExpected[] = {6,13,5}; int w1 = 10; std::cout << std::setw(w1) << "Expected" << std::setw(w1) << "SB" << std::setw(w1) << "DnC 4" << std::setw(w1) << "DnC 3" << std::setw(w1) << "FFT R" << std::setw(w1) << "FFT D" << std::endl; std::cout << std::right; for(int index = 0; index < 2*n-1; ++index) { std::cout << std::setw(w1) << pqExpected[index] << std::setw(w1) << pqActualSB[index] << std::setw(w1) << pqActualDnC4[index] << std::setw(w1) << pqActualDnC3[index] << std::setw(w1) << pqActualFFTR[index].real() << std::setw(w1) << pqActualFFTD[index].real() << std::endl; } } std::cout << std::endl << "Random Test" << std::endl; { srand(time(0)); int n = 8; int randMin = 0, randMax = 100; Vector<double> P(n), Q(n); Vector<Complex> PFFT(n), QFFT(n); for(int i = 0; i < n; ++i) { double randomP = rand()%(randMax-randMin)+randMin; double randomQ = rand()%(randMax-randMin)+randMin; P[i] = randomP; Q[i] = randomQ; PFFT[i] = Complex(randomP, 0); QFFT[i] = Complex(randomQ, 0); } PolyMult polyMultSB; Vector<double> pqActualSB = polyMultSB.schoolBook(n, P, Q); PolyMult polyMultDnC4; std::vector<double> pqActualDnC4 = polyMultDnC4.divideAndConquer4(n, P, Q); PolyMult polyMultDnC3; std::vector<double> pqActualDnC3 = polyMultDnC3.divideAndConquer3(n, P, Q); FFT fft; fft.preComputeOmega(n); Vector<Complex> pqActualFFTR = fft.polyMultR(PFFT, QFFT, n); fft.preComputeRBS(n); Vector<Complex> pqActualFFTD = fft.polyMultD(PFFT, QFFT, n); int w1 = 10; std::cout << std::setw(w1) << "SB" << std::setw(w1) << "DnC 4" << std::setw(w1) << "DnC 3" << std::setw(w1) << "FFT R" << std::setw(w1) << "FFT D" << std::endl; std::cout << std::right << std::fixed; for(int index = 0; index < 2*n-1; ++index) { std::cout << std::setprecision(0) << std::setw(w1) << pqActualSB[index] << std::setprecision(0) << std::setw(w1) << pqActualDnC4[index] << std::setprecision(0) << std::setw(w1) << pqActualDnC3[index] << std::setprecision(0) << std::setw(w1) << pqActualFFTR[index].real() << std::setprecision(0) << std::setw(w1) << pqActualFFTD[index].real() << std::endl; } } }
int main(int argc, char **argv) { if(argc != 2) exit(0); if(!glfwInit()) { fprintf(stderr, "Failed to initialize GLFW\n"); return -1; } glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); window = glfwCreateWindow(1920, 1080, "Audio Visualization", glfwGetPrimaryMonitor(), NULL); if(window == NULL) { fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n"); glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glewExperimental = true; //Needed for core profile if(glewInit() != GLEW_OK) { fprintf(stderr, "Failed to initialize GLEW\n"); return -1; } glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); glfwSetInputMode(window, GLFW_CURSOR_DISABLED, GL_TRUE); // glClearColor(0.f / 255.f, 63.f / 255.f, 0.f / 255.f, 1.0f); glClearColor(0.1, 0.1, 0.1, 1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); GLuint VertexArrayID; glGenVertexArrays(1, &VertexArrayID); glBindVertexArray(VertexArrayID); /* ShaderInfo shaders[] = { {GL_VERTEX_SHADER, "VertexShader.vert"}, {GL_FRAGMENT_SHADER, "FragmentShader.frag"}, {GL_GEOMETRY_SHADER, "GeometryShader.geom"}, {GL_NONE, NULL}}; GLuint programID = LoadShaders(shaders);*/ GLuint programID = LoadShaders("shaders/VertexShader.vert", "shaders/FragmentShader.frag", NULL);//"shaders/GeometryShader.geom"); GLuint MatrixID = glGetUniformLocation(programID, "MVP"); GLuint objectID = glGetUniformLocation(programID, "object"); GLuint topID = glGetUniformLocation(programID, "top"); glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 View = glm::lookAt( glm::vec3(10,15,20), //Camera is at (4,3,-3), in World Space glm::vec3(0,0,0), //and looks at the origin glm::vec3(0,1,0)); //Head is up (set to 0,-1,0 to look upside-down) glm::mat4 Model = glm::mat4(1.0f); glm::mat4 PV = Projection * View; glm::mat4 MVP = PV * Model; static const GLfloat g_vertex_buffer_data1[] = { -1.0f,-1.0f,-1.0f, //left -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, //right 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, //front 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, //top 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,-1.0f,-1.0f, //back 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, //bottom 1.0f,-1.0f,-1.0f, 1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f }; static const GLfloat g_vertex_buffer_data2[] = { -1.0f,-1.0f,-1.0f, //left -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, //right 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, //front 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, //top 1.0f, 1.0f,-1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,-1.0f,-1.0f, //back 1.0f,-1.0f,-1.0f, 1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, -1.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f, -1.0f,-1.0f,-1.0f, //bottom 1.0f,-1.0f,-1.0f, 1.0f,-1.0f, 1.0f, -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f }; static const GLfloat g_color_buffer_data1[] = { 1.0f, 0.2f, 0.2f, //left 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, //right 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, //front 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, //top 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, //back 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.5f, 0.5f, 1.0f, 0.2f, 0.2f, //bottom 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.5f, 0.5f }; static const GLfloat g_color_buffer_data2[] = { 0.2f, 0.2f, 1.0f, //left 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, 1.0f, //right 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, //front 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, //top 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.2f, 0.2f, 1.0f, //back 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.5f, 0.5f, 1.0f, 0.2f, 0.2f, 1.0f, //bottom 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.2f, 0.2f, 1.0f, 0.5f, 0.5f, 1.0f, 0.5f, 0.5f, 1.0f }; GLuint vertexbuffer1; //left column glGenBuffers(1, &vertexbuffer1); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer1); glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data1), g_vertex_buffer_data1, GL_STATIC_DRAW); GLuint vertexbuffer2; //right column glGenBuffers(1, &vertexbuffer2); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2); glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data2), g_vertex_buffer_data2, GL_STATIC_DRAW); GLuint vertexbuffer3; //waveform glGenBuffers(1, &vertexbuffer3); GLuint vertexbuffer4; //z glGenBuffers(1, &vertexbuffer4); GLuint vertexbuffer5; //spectrum glGenBuffers(1, &vertexbuffer5); GLuint colorbuffer1; glGenBuffers(1, &colorbuffer1); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer1); glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data1), g_color_buffer_data1, GL_STATIC_DRAW); GLuint colorbuffer2; glGenBuffers(1, &colorbuffer2); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer2); glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data2), g_color_buffer_data2, GL_STATIC_DRAW); audio_data data = get_audio_data(argv[1]); int bpf = data.sampling_rate / fps; int data_index = 0; double current_time; double last_time; double total_time = data.size / data.sampling_rate / 4; float z[bpf * 2]; for(int i = 0; i < bpf; i++) z[i * 2] = z[i * 2 + 1] = waveform_length / bpf * i - waveform_length / 2; glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer4); glBufferData(GL_ARRAY_BUFFER, bpf * 8, z, GL_STATIC_DRAW); int res; pthread_t a_thread; void *thread_result; res = pthread_create(&a_thread, NULL, play_wav_d, argv[1]); if(res != 0) { perror("Thread creation failed!"); exit(EXIT_FAILURE); } FFT fft; fft.setDataSize(bpf); fft.setSampleRate(data.sampling_rate); float max_l = 0, max_r = 0; glfwSetTime(0); do { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programID); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); computeMatricesFromInputs(); glm::mat4 Projection = getProjectionMatrix(); glm::mat4 View = getViewMatrix(); glm::mat4 ModelMatrix = glm::mat4(1.0); PV = Projection * View; MVP = PV * ModelMatrix; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); float *FFTdata = fft.calculateFFT((short *)data.data + data_index); int spectrum_interval = fps / 2; for(int i = 0; i < bpf; i++) { for(int j = 1; j < spectrum_interval; j++) FFTdata[i * spectrum_interval] += FFTdata[i * spectrum_interval + j]; FFTdata[i * spectrum_interval] /= spectrum_interval * 10; FFTdata[i * spectrum_interval + spectrum_interval / 2] = 0; } glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer4); //z glVertexAttribPointer( 2, //attribute. No particular reason for 0, but must match the layout in the shader. 1, //size GL_FLOAT, //type GL_FALSE, //normalized? 0, //stride (void *)0 //array buffer offset ); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer5); //spectrum glBufferData(GL_ARRAY_BUFFER, spectrum_interval * bpf * 4, FFTdata, GL_STATIC_DRAW); glVertexAttribPointer( 0, //attribute. No particular reason for 0, but must match the layout in the shader. 1, //size GL_FLOAT, //type GL_FALSE, //normalized? spectrum_interval * 2, //stride (void *)0 //array buffer offset ); glUniform1i(objectID, 6); glDrawArrays(GL_LINES, 0, bpf * 2); //draw spectrum glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer4); //z glVertexAttribPointer( 2, //attribute. No particular reason for 0, but must match the layout in the shader. 1, //size GL_FLOAT, //type GL_FALSE, //normalized? (waveform_interval + 1) * 4, //stride (void *)0 //array buffer offset ); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer3); //waveform glBufferData(GL_ARRAY_BUFFER, bpf * 4, (short *)data.data + data_index, GL_DYNAMIC_DRAW); glVertexAttribPointer( 0, //attribute. No particular reason for 0, but must match the layout in the shader. 1, //size GL_SHORT, //type GL_FALSE, //normalized? waveform_interval * 4, //stride (void *)0 //array buffer offset ); glUniform1i(objectID, 2); glDrawArrays(GL_LINE_STRIP, 0, bpf / waveform_interval); //draw left waveform glVertexAttribPointer( 0, //attribute. No particular reason for 0, but must match the layout in the shader. 1, //size GL_SHORT, //type GL_FALSE, //normalized? waveform_interval * 4, //stride (void *)2 //array buffer offset ); glUniform1i(objectID, 3); glDrawArrays(GL_LINE_STRIP, 0, bpf / waveform_interval); //draw right waveform float sum_l = 0, sum_r = 0; for(int i = 0; i < bpf; i++) { sum_l = max(sum_l, abs(((short*)data.data)[data_index++])); //max sum_r = max(sum_r, abs(((short*)data.data)[data_index++])); // sum_l += abs(((short*)data.data)[data_index++]); //avg // sum_r += abs(((short*)data.data)[data_index++]); } // sum_l /= bpf; //avg // sum_r /= bpf; float scale_l = sum_l / 32768 * column_height; Model = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.0, 1.0, 0.0, 1.0); glm::mat4 scale1 = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, scale_l, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); MVP = PV * scale1 * Model; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer1); //left column vertex glVertexAttribPointer( 0, // attribute. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void *)0 // array buffer offset ); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer1); //left column color glVertexAttribPointer( 1, // attribute. No particular reason for 1, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void *)0 // array buffer offset ); glUniform1i(objectID, 0); glDrawArrays(GL_TRIANGLES, 0, 12*3); //draw left column if(scale_l> max_l) max_l = scale_l; else max_l -= top_speed; glm::mat4 translate1 = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.0, max_l * 2, 0.0, 1.0); scale1 = glm::mat4( max_l / 2, 0.0, 0.0, 0.0, 0.0, max_l / 2 * top_height, 0.0, 0.0, 0.0, 0.0, max_l / 2, 0.0, 0.0, 0.0, 0.0, 1.0); MVP = PV * translate1 * scale1; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniform1i(objectID, 4); glUniform1f(topID, max_l); glDrawArrays(GL_TRIANGLES, 0, 12*3); //draw left upper top translate1 = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.0, scale_l * 2, 0.0, 1.0); scale1 = glm::mat4( scale_l / 2, 0.0, 0.0, 0.0, 0.0, scale_l / 2 * top_height, 0.0, 0.0, 0.0, 0.0, scale_l / 2, 0.0, 0.0, 0.0, 0.0, 1.0); MVP = PV * translate1 * scale1; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniform1i(objectID, 4); glUniform1f(topID, scale_l); glDrawArrays(GL_TRIANGLES, 0, 12*3); //draw left lower top float scale_r = sum_r / 32768 * column_height; Model = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, 1.0, 0.0, 1.0); glm::mat4 scale2 = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, scale_r, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); MVP = PV * scale2 * Model; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer2); //right column vertex glVertexAttribPointer( 0, // attribute. No particular reason for 0, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer2); //right column vertex glVertexAttribPointer( 1, // attribute. No particular reason for 1, but must match the layout in the shader. 3, // size GL_FLOAT, // type GL_FALSE, // normalized? 0, // stride (void*)0 // array buffer offset ); glUniform1i(objectID, 1); glDrawArrays(GL_TRIANGLES, 0, 12*3); //draw right column if(scale_r > max_r) max_r = scale_r; else max_r -= top_speed; glm::mat4 translate2 = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, max_r * 2, 0.0, 1.0); scale2 = glm::mat4( max_r / 2, 0.0, 0.0, 0.0, 0.0, max_r / 2 * top_height, 0.0, 0.0, 0.0, 0.0, max_r / 2, 0.0, 0.0, 0.0, 0.0, 1.0);//0.25 / max_r);//(4.0 - max_r) * (4.0 - max_r)); MVP = PV * translate2 * scale2; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniform1i(objectID, 5); glUniform1f(topID, max_r); glDrawArrays(GL_TRIANGLES, 0, 12*3); //draw right upper top translate2 = glm::mat4( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.0, scale_r * 2, 0.0, 1.0); scale2 = glm::mat4( scale_r / 2, 0.0, 0.0, 0.0, 0.0, scale_r / 2 * top_height, 0.0, 0.0, 0.0, 0.0, scale_r / 2, 0.0, 0.0, 0.0, 0.0, 1.0);//0.25 / max_r);//(4.0 - max_r) * (4.0 - max_r)); MVP = PV * translate2 * scale2; glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]); glUniform1i(objectID, 5); glUniform1f(topID, scale_r); glDrawArrays(GL_TRIANGLES, 0, 12*3); //draw right lower top glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDisableVertexAttribArray(2); if(data_index >= data.size / 2) break; current_time = glfwGetTime(); double left_time = total_time - current_time; if(left_time <= 0) break; double accurate_time = data_index / 2.0 / bpf / fps; double delta = accurate_time - current_time; printf("%lf %lf %lf %lf %lf\n", current_time - last_time, accurate_time, current_time, delta, left_time); delta = delta > 0 ? delta : 0; last_time = current_time; usleep(delta * 1000000); glfwSwapBuffers(window); glfwPollEvents(); } while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window)); pthread_cancel(a_thread); res = pthread_join(a_thread, &thread_result); if(res != 0) { perror("Thread join failed!"); exit(EXIT_FAILURE); } glDeleteBuffers(1, &vertexbuffer1); glDeleteBuffers(1, &vertexbuffer2); glDeleteBuffers(1, &vertexbuffer3); glDeleteBuffers(1, &vertexbuffer4); glDeleteBuffers(1, &vertexbuffer5); glDeleteBuffers(1, &colorbuffer1); glDeleteBuffers(1, &colorbuffer2); glDeleteProgram(programID); glDeleteVertexArrays(1, &VertexArrayID); glfwTerminate(); return 0; }
boolean CAlgorithmHilbertTransform::process(void) { uint32 l_ui32ChannelCount = ip_pMatrix->getDimensionSize(0); uint32 l_ui32SamplesPerChannel = ip_pMatrix->getDimensionSize(1); IMatrix* l_pInputMatrix = ip_pMatrix; IMatrix* l_pOutputHilbertMatrix = op_pHilbertMatrix; IMatrix* l_pOutputEnvelopeMatrix = op_pEnvelopeMatrix; IMatrix* l_pOutputPhaseMatrix = op_pPhaseMatrix; FFT< double, internal::kissfft_impl<double > > fft; //create instance of fft transform if(this->isInputTriggerActive(OVP_Algorithm_HilbertTransform_InputTriggerId_Initialize)) //Check if the input is correct { if( l_pInputMatrix->getDimensionCount() != 2) { this->getLogManager() << LogLevel_Error << "The input matrix must have 2 dimensions, here the dimension is "; std::cout<<l_pInputMatrix->getDimensionCount()<<std::endl; return false; } //Setting size of outputs l_pOutputHilbertMatrix->setDimensionCount(2); l_pOutputHilbertMatrix->setDimensionSize(0,l_ui32ChannelCount); l_pOutputHilbertMatrix->setDimensionSize(1,l_ui32SamplesPerChannel); l_pOutputEnvelopeMatrix->setDimensionCount(2); l_pOutputEnvelopeMatrix->setDimensionSize(0,l_ui32ChannelCount); l_pOutputEnvelopeMatrix->setDimensionSize(1,l_ui32SamplesPerChannel); l_pOutputPhaseMatrix->setDimensionCount(2); l_pOutputPhaseMatrix->setDimensionSize(0,l_ui32ChannelCount); l_pOutputPhaseMatrix->setDimensionSize(1,l_ui32SamplesPerChannel); } if(this->isInputTriggerActive(OVP_Algorithm_HilbertTransform_InputTriggerId_Process)) { //Computing Hilbert transform for all channels for(uint32 channel=0; channel<l_ui32ChannelCount; channel++) { //Initialization of buffer vectors m_vecXcdSignalBuffer = VectorXcd::Zero(l_ui32SamplesPerChannel); m_vecXcdSignalFourier = VectorXcd::Zero(l_ui32SamplesPerChannel); //Initialization of vector h used to compute analytic signal m_vecXdHilbert.resize(l_ui32SamplesPerChannel); m_vecXdHilbert(0) = 1.0; if(l_ui32SamplesPerChannel%2 == 0) { m_vecXdHilbert(l_ui32SamplesPerChannel/2) = 1.0; for(uint32 i=1; i<l_ui32SamplesPerChannel/2; i++) { m_vecXdHilbert(i) = 2.0; } for(uint32 i=(l_ui32SamplesPerChannel/2)+1; i<l_ui32SamplesPerChannel; i++) { m_vecXdHilbert(i) = 0.0; } } else { m_vecXdHilbert((l_ui32SamplesPerChannel+1)/2) = 1.0; for(uint32 i=1; i<(l_ui32SamplesPerChannel+1); i++) { m_vecXdHilbert(i) = 2.0; } for(uint32 i=(l_ui32SamplesPerChannel+1)/2+1; i<l_ui32SamplesPerChannel; i++) { m_vecXdHilbert(i) = 0.0; } } //Copy input signal chunk on buffer for(uint32 samples=0; samples<l_ui32SamplesPerChannel;samples++) { m_vecXcdSignalBuffer(samples).real(l_pInputMatrix->getBuffer()[samples + channel * (l_ui32SamplesPerChannel)]); m_vecXcdSignalBuffer(samples).imag(0.0); } //Fast Fourier Transform of input signal fft.fwd(m_vecXcdSignalFourier, m_vecXcdSignalBuffer); //Apply Hilbert transform by element-wise multiplying fft vector by h for(uint32 samples=0; samples<l_ui32SamplesPerChannel;samples++) { m_vecXcdSignalFourier(samples) = m_vecXcdSignalFourier(samples)*m_vecXdHilbert(samples); } //Inverse Fast Fourier transform fft.inv(m_vecXcdSignalBuffer, m_vecXcdSignalFourier); // m_vecXcdSignalBuffer is now the analytical signal of the initial input signal //Compute envelope and phase and pass it to the corresponding output for(uint32 samples=0; samples<l_ui32SamplesPerChannel;samples++) { l_pOutputHilbertMatrix->getBuffer()[samples + channel*l_ui32SamplesPerChannel] = m_vecXcdSignalBuffer(samples).imag(); l_pOutputEnvelopeMatrix->getBuffer()[samples + channel*l_ui32SamplesPerChannel] = abs(m_vecXcdSignalBuffer(samples)); l_pOutputPhaseMatrix->getBuffer()[samples + channel*l_ui32SamplesPerChannel] = arg(m_vecXcdSignalBuffer(samples)); } } } return true; }