LV2_Handle PitchShifter::instantiate(const LV2_Descriptor* descriptor, double samplerate, const char* bundle_path, const LV2_Feature* const* features) { PitchShifter *plugin = new PitchShifter(); plugin->nBuffers = 20; plugin->Qcolumn = plugin->nBuffers; plugin->hopa = TAMANHO_DO_BUFFER; plugin->N = plugin->nBuffers*plugin->hopa; plugin->cont = 0; plugin->s = 0; plugin->g = 1; plugin->Hops = (int*)calloc(plugin->Qcolumn,sizeof(int)); memset(plugin->Hops, plugin->hopa, plugin->Qcolumn ); plugin->frames = (double*)calloc(plugin->N,sizeof(double)); plugin->ysaida = (double*)calloc(2*(plugin->N + 2*(plugin->Qcolumn-1)*plugin->hopa),sizeof(double)); plugin->yshift = (double*)calloc(plugin->hopa,sizeof(double)); plugin->b = (double**)calloc(plugin->hopa,sizeof(double*)); plugin->frames2 = fftwf_alloc_real(plugin->N); plugin->q = fftwf_alloc_real(plugin->N); plugin->fXa = fftwf_alloc_complex(plugin->N/2 + 1); plugin->fXs = fftwf_alloc_complex(plugin->N/2 + 1); plugin->Xa.zeros(plugin->N/2 + 1); plugin->Xs.zeros(plugin->N/2 + 1); plugin->XaPrevious.zeros(plugin->N/2 + 1); plugin->Xa_arg.zeros(plugin->N/2 + 1); plugin->XaPrevious_arg.zeros(plugin->N/2 + 1); plugin->Phi.zeros(plugin->N/2 + 1); plugin->PhiPrevious.zeros(plugin->N/2 + 1); plugin->d_phi.zeros(plugin->N/2 + 1); plugin->d_phi_prime.zeros(plugin->N/2 + 1); plugin->d_phi_wrapped.zeros(plugin->N/2 + 1); plugin->omega_true_sobre_fs.zeros(plugin->N/2 + 1); plugin->AUX.zeros(plugin->N/2 + 1); plugin->Xa_abs.zeros(plugin->N/2 + 1); plugin->w.zeros(plugin->N); hann(plugin->N,&plugin->w); plugin->I.zeros(plugin->N/2 + 1); plugin->I = linspace(0, plugin->N/2,plugin->N/2 + 1); for (int i=1 ; i<= (plugin->nBuffers); i++) { plugin->b[i-1] = &plugin->frames[(i-1)*plugin->hopa]; } plugin->p = fftwf_plan_dft_r2c_1d(plugin->N, plugin->frames2, plugin->fXa, FFTW_ESTIMATE); plugin->p2 = fftwf_plan_dft_c2r_1d(plugin->N, plugin->fXs, plugin->q, FFTW_ESTIMATE); return (LV2_Handle)plugin; }
fftwf_complex* FFTW::alloc_complex<float>(size_t n) { assert(n > 0); fftwf_complex* p = fftwf_alloc_complex(n); if (p == nullptr) THROW_EXCEPTION(FFTWException, "Error in fftw_alloc_complex (float, n = " << n << ")."); return p; }
PSSinthesis::PSSinthesis(PSAnalysis *obj, const char* wisdomFile) //Construtor { Qcolumn = obj->Qcolumn; hopa = obj->hopa; N = obj->N; omega_true_sobre_fs = &obj->omega_true_sobre_fs; Xa_abs = &obj->Xa_abs; w = &obj->w; first = true; hops = new int[Qcolumn]; fill_n(hops,Qcolumn,hopa); ysaida = new double[2*N + 4*(Qcolumn-1)*hopa]; fill_n(ysaida,2*N + 4*(Qcolumn-1)*hopa,0); yshift = new double[hopa]; fill_n(yshift,hopa,0); q = fftwf_alloc_real(N); fXs = fftwf_alloc_complex(N/2 + 1); Xs.zeros(N/2 + 1); Phi.zeros(N/2 + 1); PhiPrevious.zeros(N/2 + 1); if (fftwf_import_wisdom_from_filename(wisdomFile) != 0) { p2 = fftwf_plan_dft_c2r_1d(N, fXs, q, FFTW_WISDOM_ONLY); } else { p2 = NULL; printf("PSSinthesis: failed to import wisdom file '%s'\n", wisdomFile); } }
ProcessSamples::ProcessSamples(uint32_t numSamples, uint32_t sampleRate, uint32_t enob, float threshold, gr::fft::window::win_type windowType, Mode mode, uint32_t threadCount, std::string fileNameBase, double useBandWidth, double dcIgnoreWidth, uint32_t preTrigger, uint32_t postTrigger) : m_sampleCount(numSamples), m_sampleRate(sampleRate), m_enob(enob), m_fileCounter(0), m_threshold(threshold), m_fftWindow(windowType, numSamples), m_correctDCOffset(false), m_useWindow(uint32_t(useBandWidth * numSamples / 2.0)), // This is only for hackRF. m_dcIgnoreWindow(4), // m_dcIgnoreWindow(uint32_t(dcIgnoreWidth * numSamples / 2.0)), m_fft(numSamples), m_mode(mode), m_sampleQueue(nullptr), m_fileNameBase(fileNameBase), m_preTrigger(preTrigger), m_postTrigger(postTrigger), m_writing(false), m_endSequenceId(0), m_threadCount(threadCount) { assert(mode > Illegal && mode <= FrequencyDomain); assert(threadCount <= MAX_THREADS); for (uint32_t threadId = 0; threadId < threadCount; threadId++) { this->m_inputSamples[threadId] = reinterpret_cast<fftwf_complex *>(fftwf_alloc_complex(numSamples)); this->m_fftOutputBuffer[threadId] = reinterpret_cast<fftwf_complex *>(fftwf_alloc_complex(numSamples)); this->m_threads[threadId] = nullptr; } }
int main(){ int nthreads = 4; omp_set_num_threads(nthreads); #pragma omp parallel fprintf(stderr,"nthreads %d \n", omp_get_num_threads()); int n3 = 128; int n2 = 128; int n1 = 128; // float ***array = sf_floatalloc3(n1,n2,n3); float *array = fftwf_alloc_real(n3*n2*n1); fftwf_complex* cout = fftwf_alloc_complex(n3*n2*n1); int err = fftwf_init_threads(); if (err == 0) { fprintf(stderr,"something went wrong with fftw\n"); } fprintf(stderr,"Got here\n"); double start,end; start = omp_get_wtime()*omp_get_wtick(); fftwf_plan_with_nthreads(nthreads); fftwf_plan plan = fftwf_plan_dft_r2c_3d( n1,n2,n3, array,cout, FFTW_MEASURE); end = omp_get_wtime()*omp_get_wtick(); fprintf(stderr,"elapsed time: %f %f %f\n",end,start,end-start); for(int i = 0; i < n3*n2*n1; ++i) array[i] = rand()/RAND_MAX; //float start = clock()/CLOCKS_PER_SEC; start = omp_get_wtime(); for(int i=0; i < 1001; ++i) fftwf_execute(plan); //float end = clock()/CLOCKS_PER_SEC; end = omp_get_wtime(); fprintf(stderr,"elapsed time: %f time/calc %f\n", end-start,(end-start)/100.0); fftwf_cleanup_threads(); fftwf_cleanup(); fftwf_destroy_plan(plan); fftwf_free(cout); fftwf_free(array); //free(**array); free(*array); free(array); return 0; }
int main(int argc, char **argv) { fftwf_plan plan; fftwf_complex *data; ptrdiff_t alloc_local, local_n0, local_0_start, i, j; if (argc != 2) { printf("usage: ./fft_mpi MATRIX_SIZE\n"); exit(1); } const ptrdiff_t N0 = atoi(argv[1]); const ptrdiff_t N1 = N0; int id; double startTime, totalTime; totalTime = 0; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &id); fftwf_mpi_init(); /* get local data size and allocate */ alloc_local = fftwf_mpi_local_size_2d(N0, N1, MPI_COMM_WORLD, &local_n0, &local_0_start); data = fftwf_alloc_complex(alloc_local);//(fftwf_complex *) fftwf_malloc(sizeof(fftw_complex) * alloc_local); /* create plan for in-place forward DFT */ plan = fftwf_mpi_plan_dft_2d(N0, N1, data, data, MPI_COMM_WORLD, FFTW_FORWARD, FFTW_ESTIMATE); /* initialize data to some function my_function(x,y) */ for (i = 0; i < local_n0; ++i) for (j = 0; j < N1; ++j){ data[i*N1 + j][0] = local_0_start;;//my_function(local_0_start + i, j); data[i*N1 + j][1]=i; } /* compute transforms, in-place, as many times as desired */ MPI_Barrier(MPI_COMM_WORLD); if (id == 0) { startTime = getTime(); } fftwf_execute(plan); MPI_Barrier(MPI_COMM_WORLD); if (id == 0) { totalTime += getTime() - startTime; } fftwf_destroy_plan(plan); fftwf_mpi_cleanup(); if (id == 0) { printf("%.5f\n", totalTime); } MPI_Finalize(); return 0; }
PitchDetection::PitchDetection(uint32_t n_samples, int nBuffers, double SampleRate, const char* wisdomFile) //Constructor { hopa = n_samples; N = nBuffers*n_samples; fs = SampleRate; frames = fftwf_alloc_real(2*N); memset(frames, 0, 2*N ); b = new float*[hopa]; for (int i=0 ; i< nBuffers; i++) { b[i] = &frames[i*hopa]; } q = fftwf_alloc_real(2*N); fXa = fftwf_alloc_complex(N + 1); fXs = fftwf_alloc_complex(N + 1); Xa.zeros(N + 1); Xs.zeros(N + 1); R.zeros(N); NORM.zeros(N); F.zeros(N); AUTO.zeros(N); if (fftwf_import_wisdom_from_filename(wisdomFile) != 0) { p = fftwf_plan_dft_r2c_1d(2*N, frames, fXa, FFTW_WISDOM_ONLY); p2 = fftwf_plan_dft_c2r_1d(2*N, fXs, q, FFTW_WISDOM_ONLY); } else { p = fftwf_plan_dft_r2c_1d(2*N, frames, fXa, FFTW_ESTIMATE); p2 = fftwf_plan_dft_c2r_1d(2*N, fXs, q, FFTW_ESTIMATE); printf("PitchDetection: failed to import wisdom file '%s', using estimate instead\n", wisdomFile); } }
PSAnalysis::PSAnalysis(uint32_t n_samples, int nBuffers, const char* wisdomFile) //Construtor { Qcolumn = nBuffers; hopa = n_samples; N = nBuffers*n_samples; frames = new double[N]; fill_n(frames,N,0); b = new double*[hopa]; for (int i=0 ; i< nBuffers; i++) b[i] = &frames[i*hopa]; frames2 = fftwf_alloc_real(N); fXa = fftwf_alloc_complex(N/2 + 1); Xa.zeros(N/2 + 1); XaPrevious.zeros(N/2 + 1); Xa_arg.zeros(N/2 + 1); XaPrevious_arg.zeros(N/2 + 1); d_phi.zeros(N/2 + 1); d_phi_prime.zeros(N/2 + 1); d_phi_wrapped.zeros(N/2 + 1); omega_true_sobre_fs.zeros(N/2 + 1); AUX.zeros(N/2 + 1); Xa_abs.zeros(N/2 + 1); w.zeros(N); hann(N,&w); I.zeros(N/2 + 1); I = linspace(0, N/2, N/2 + 1); if (fftwf_import_wisdom_from_filename(wisdomFile) != 0) { p = fftwf_plan_dft_r2c_1d(N, frames2, fXa, FFTW_WISDOM_ONLY); } else { p = NULL; printf("PSAnalysis: failed to import wisdom file '%s'\n", wisdomFile); } }
float _Complex* malloc_vector_c(size_t n) { return fftwf_alloc_complex(n); }
void PitchShifter::run(LV2_Handle instance, uint32_t n_samples) { PitchShifter *plugin; plugin = (PitchShifter *) instance; float media = 0; for (uint32_t i=1; i<n_samples; i++) { media = media + abs(plugin->in[i-1]); } if (media == 0) { for (uint32_t i=1; i<n_samples; i++) { plugin->out_1[i-1] = 0; } } else { int hops; double g_before = plugin->g; plugin->g = pow(10, (float)(*(plugin->gain))/20.0); plugin->s = (double)(*(plugin->step)); hops = round(plugin->hopa*(pow(2,(plugin->s/12)))); for (int k=1; k<= plugin->Qcolumn-1; k++) { plugin->Hops[k-1] = plugin->Hops[k]; } plugin->Hops[plugin->Qcolumn-1] = hops; if ( ((plugin->hopa) != (int)n_samples) ) { plugin->hopa = n_samples; plugin->N = plugin->nBuffers*plugin->hopa; plugin->frames = (double*)realloc(plugin->frames,plugin->N*sizeof(double)); memset(plugin->frames, 0, plugin->N ); plugin->ysaida = (double*)realloc(plugin->ysaida,2*(plugin->N + 2*(plugin->Qcolumn-1)*plugin->hopa)*sizeof(double)); memset(plugin->ysaida, 0, 2*(plugin->N + 2*(plugin->Qcolumn-1)*plugin->hopa) ); plugin->yshift = (double*)realloc(plugin->yshift,plugin->hopa*sizeof(double)); memset(plugin->yshift, 0, plugin->hopa ); plugin->b = (double**)realloc(plugin->b,plugin->hopa*sizeof(double*)); fftwf_free(plugin->frames2); plugin->frames2 = fftwf_alloc_real(plugin->N); fftwf_free(plugin->q); plugin->q = fftwf_alloc_real(plugin->N); fftwf_free(plugin->fXa); plugin->fXa = fftwf_alloc_complex(plugin->N/2 + 1); fftwf_free(plugin->fXs); plugin->fXs = fftwf_alloc_complex(plugin->N/2 + 1); plugin->Xa.zeros(plugin->N/2 + 1); plugin->Xs.zeros(plugin->N/2 + 1); plugin->XaPrevious.zeros(plugin->N/2 + 1); plugin->Xa_arg.zeros(plugin->N/2 + 1); plugin->XaPrevious_arg.zeros(plugin->N/2 + 1); plugin->Phi.zeros(plugin->N/2 + 1); plugin->PhiPrevious.zeros(plugin->N/2 + 1); plugin->d_phi.zeros(plugin->N/2 + 1); plugin->d_phi_prime.zeros(plugin->N/2 + 1); plugin->d_phi_wrapped.zeros(plugin->N/2 + 1); plugin->omega_true_sobre_fs.zeros(plugin->N/2 + 1); plugin->AUX.zeros(plugin->N/2 + 1); plugin->Xa_abs.zeros(plugin->N/2 + 1); plugin->w.zeros(plugin->N); hann(plugin->N,&plugin->w); plugin->I.zeros(plugin->N/2 + 1); plugin->I = linspace(0, plugin->N/2,plugin->N/2 + 1); for (int i=1 ; i<= plugin->nBuffers; i++) { plugin->b[i-1] = &plugin->frames[(i-1)*plugin->hopa]; } fftwf_destroy_plan(plugin->p); plugin->p = fftwf_plan_dft_r2c_1d(plugin->N, plugin->frames2, plugin->fXa, FFTW_ESTIMATE); fftwf_destroy_plan(plugin->p2); plugin->p2 = fftwf_plan_dft_c2r_1d(plugin->N, plugin->fXs, plugin->q, FFTW_ESTIMATE); return; } for (int i=1; i<=plugin->hopa; i++) { for (int j=1; j<=(plugin->nBuffers-1); j++) { plugin->b[j-1][i-1] = plugin->b[j][i-1]; } plugin->b[plugin->nBuffers-1][i-1] = plugin->in[i-1]; } if ( plugin->cont < plugin->nBuffers-1) { plugin->cont = plugin->cont + 1; } else { shift(plugin->N, plugin->hopa, plugin->Hops, plugin->frames, plugin->frames2, &plugin->w, &plugin->XaPrevious, &plugin->Xa_arg, &plugin->Xa_abs, &plugin->XaPrevious_arg, &plugin->PhiPrevious, plugin->yshift, &plugin->Xa, &plugin->Xs, plugin->q, &plugin->Phi, plugin->ysaida, plugin->ysaida2, plugin->Qcolumn, &plugin->d_phi, &plugin->d_phi_prime, &plugin->d_phi_wrapped, &plugin->omega_true_sobre_fs, &plugin->I, &plugin->AUX, plugin->p, plugin->p2, plugin->fXa, plugin->fXs); for (int i=1; i<=plugin->hopa; i++) { plugin->out_1[i-1] = (g_before + ((plugin->g - g_before)/(plugin->hopa - 1))*(i-1) )*(float)plugin->yshift[i-1]; } } } }
// Setup variables for 2LPT initial condition void lpt_init(const int nc, const void* mem, const size_t size) { // nc: number of mesh per dimension ptrdiff_t local_nx, local_x_start; ptrdiff_t total_size= fftwf_mpi_local_size_3d(nc, nc, nc/2+1, MPI_COMM_WORLD, &local_nx, &local_x_start); Local_nx= local_nx; Local_x_start= local_x_start; // // Allocate memory // if(mem == 0) { // allocate memory here size_t bytes= sizeof(fftwf_complex)*total_size; int allocation_failed= 0; // 1&2 displacement for(int axes=0; axes < 3; axes++) { cdisp[axes]= fftwf_alloc_complex(total_size); disp[axes] = (float*) cdisp[axes]; cdisp2[axes]= fftwf_alloc_complex(total_size); disp2[axes] = (float*) cdisp2[axes]; bytes += 2*sizeof(fftwf_complex)*total_size; allocation_failed = allocation_failed || (cdisp[axes] == 0) || (cdisp2[axes] == 0); } // 2LPT for(int i=0; i<6; i++) { cdigrad[i] = (fftwf_complex *) fftwf_alloc_complex(total_size); digrad[i] = (float*) cdigrad[i]; bytes += sizeof(fftwf_complex)*total_size; allocation_failed = allocation_failed || (digrad[i] == 0); } if(allocation_failed) msg_abort(2003, "Error: Failed to allocate memory for 2LPT." "Tried to allocate %d Mbytes\n", (int)(bytes/(1024*1024))); msg_printf(info, "%d Mbytes allocated for LPT\n", (int)(bytes/(1024*1024))); } else { size_t bytes= 0; fftwf_complex* p= (fftwf_complex*) mem; for(int axes=0; axes<3; axes++) { cdisp[axes]= p; disp[axes]= (float*) p; bytes += sizeof(fftwf_complex)*total_size*2; p += total_size; } for(int i=0; i<6; i++) { cdigrad[i]= p; digrad[i]= (float*) p; bytes += sizeof(fftwf_complex)*total_size; p += total_size; } assert(bytes <= size); } // // FFTW3 plans // for(int i=0; i<6; ++i) Inverse_plan[i]= fftwf_mpi_plan_dft_c2r_3d(nc, nc, nc, cdigrad[i], digrad[i], MPI_COMM_WORLD, FFTW_ESTIMATE); Forward_plan= fftwf_mpi_plan_dft_r2c_3d(nc, nc, nc, digrad[3], cdigrad[3], MPI_COMM_WORLD, FFTW_ESTIMATE); for(int i=0; i<3; ++i) { Disp_plan[i]= fftwf_mpi_plan_dft_c2r_3d(nc, nc, nc, cdisp[i], disp[i], MPI_COMM_WORLD, FFTW_ESTIMATE); Disp2_plan[i]= fftwf_mpi_plan_dft_c2r_3d(nc, nc, nc, cdisp2[i], disp2[i], MPI_COMM_WORLD, FFTW_ESTIMATE); } // FFTW_MPI_TRANSPOSED_IN/FFTW_MPI_TRANSPOSED_OUT would be faster // FFTW_MEASURE is probably better for multiple realization // misc data Nmesh= nc; Nsample= nc; seedtable = malloc(Nmesh * Nmesh * sizeof(unsigned int)); assert(seedtable); }
int shrinkWrap ( float * const & rIntensity, const std::vector<unsigned> & rSize, unsigned rnCycles, float rTargetError, float rHioBeta, float rIntensityCutOffAutoCorel, float rIntensityCutOff, float rSigma0, float rSigmaChange, unsigned rnHioCycles ) { if ( rSize.size() != 2 ) return 1; const unsigned & Ny = rSize[1]; const unsigned & Nx = rSize[0]; /* Evaluate input parameters and fill with default values if necessary */ if ( rIntensity == NULL ) return 1; if ( rTargetError <= 0 ) rTargetError = 1e-5; if ( rnHioCycles == 0 ) rnHioCycles = 20; if ( rHioBeta <= 0 ) rHioBeta = 0.9; if ( rIntensityCutOffAutoCorel <= 0 ) rIntensityCutOffAutoCorel = 0.04; if ( rIntensityCutOff <= 0 ) rIntensityCutOff = 0.2; if ( rSigma0 <= 0 ) rSigma0 = 3.0; if ( rSigmaChange <= 0 ) rSigmaChange = 0.01; float sigma = rSigma0; /* calculate this (length of array) often needed value */ unsigned nElements = 1; for ( unsigned i = 0; i < rSize.size(); ++i ) { assert( rSize[i] > 0 ); nElements *= rSize[i]; } /* allocate needed memory so that HIO doesn't need to allocate and * deallocate on each call */ fftwf_complex * const curData = fftwf_alloc_complex( nElements ); fftwf_complex * const gPrevious = fftwf_alloc_complex( nElements ); auto const isMasked = new float[nElements]; /* create fft plans G' to g' and g to G */ auto toRealSpace = fftwf_plan_dft( rSize.size(), (int*) &rSize[0], curData, curData, FFTW_BACKWARD, FFTW_ESTIMATE ); auto toFreqSpace = fftwf_plan_dft( rSize.size(), (int*) &rSize[0], gPrevious, curData, FFTW_FORWARD, FFTW_ESTIMATE ); /* create first guess for mask from autocorrelation (fourier transform * of the intensity @see * https://en.wikipedia.org/wiki/Wiener%E2%80%93Khinchin_theorem */ #pragma omp parallel for for ( unsigned i = 0; i < nElements; ++i ) { curData[i][0] = rIntensity[i]; /* Re */ curData[i][1] = 0; } fftwf_execute( toRealSpace ); complexNormElementwise( isMasked, curData, nElements ); /* fftShift is not necessary, but I introduced this, because for the * example it shifted the result to a better looking position ... */ //fftShift( isMasked, Nx,Ny ); libs::gaussianBlur( isMasked, Nx, Ny, sigma ); #if DEBUG_SHRINKWRAPP_CPP == 1 std::ofstream file; std::string fname = std::string("shrinkWrap-init-mask-blurred"); file.open( ( fname + std::string(".dat") ).c_str() ); for ( unsigned ix = 0; ix < rSize[0]; ++ix ) { for ( unsigned iy = 0; iy < rSize[1]; ++iy ) file << std::setw(10) << isMasked[ iy*rSize[0] + ix ] << " "; file << "\n"; } file.close(); std::cout << "Written out " << fname << ".png\n"; #endif /* apply threshold to make binary mask */ { const auto absMax = vectorMax( isMasked, nElements ); const float threshold = rIntensityCutOffAutoCorel * absMax; #pragma omp parallel for for ( unsigned i = 0; i < nElements; ++i ) isMasked[i] = isMasked[i] < threshold ? 1 : 0; } #if DEBUG_SHRINKWRAPP_CPP == 1 fname = std::string("shrinkWrap-init-mask"); file.open( ( fname + std::string(".dat") ).c_str() ); for ( unsigned ix = 0; ix < rSize[0]; ++ix ) { for ( unsigned iy = 0; iy < rSize[1]; ++iy ) file << std::setw(10) << isMasked[ iy*rSize[0] + ix ] << " "; file << "\n"; } file.close(); std::cout << "Written out " << fname << ".png\n"; #endif /* copy original image into fftw_complex array and add random phase */ #pragma omp parallel for for ( unsigned i = 0; i < nElements; ++i ) { curData[i][0] = rIntensity[i]; /* Re */ curData[i][1] = 0; } /* in the first step the last value for g is to be approximated * by g'. The last value for g, called g_k is needed, because * g_{k+1} = g_k - hioBeta * g' ! This is inside the loop * because the fft is needed */ #pragma omp parallel for for ( unsigned i = 0; i < nElements; ++i ) { gPrevious[i][0] = curData[i][0]; gPrevious[i][1] = curData[i][1]; } /* repeatedly call HIO algorithm and change mask */ for ( unsigned iCycleShrinkWrap = 0; iCycleShrinkWrap < rnCycles; ++iCycleShrinkWrap ) { /************************** Update Mask ***************************/ std::cout << "Update Mask with sigma=" << sigma << "\n"; /* blur |g'| (normally g' should be real!, so |.| not necessary) */ complexNormElementwise( isMasked, curData, nElements ); libs::gaussianBlur( isMasked, Nx, Ny, sigma ); const auto absMax = vectorMax( isMasked, nElements ); /* apply threshold to make binary mask */ const float threshold = rIntensityCutOff * absMax; #pragma omp parallel for for ( unsigned i = 0; i < nElements; ++i ) isMasked[i] = isMasked[i] < threshold ? 1 : 0; /* update the blurring sigma */ sigma = fmax( 1.5, ( 1 - rSigmaChange ) * sigma ); for ( unsigned iHioCycle = 0; iHioCycle < rnHioCycles; ++iHioCycle ) { /* apply domain constraints to g' to get g */ #pragma omp parallel for for ( unsigned i = 0; i < nElements; ++i ) { if ( isMasked[i] == 1 or /* g' */ curData[i][0] < 0 ) { gPrevious[i][0] -= rHioBeta * curData[i][0]; gPrevious[i][1] -= rHioBeta * curData[i][1]; } else { gPrevious[i][0] = curData[i][0]; gPrevious[i][1] = curData[i][1]; } } /* Transform new guess g for f back into frequency space G' */ fftwf_execute( toFreqSpace ); /* Replace absolute of G' with measured absolute |F| */ applyComplexModulus( curData, curData, rIntensity, nElements ); fftwf_execute( toRealSpace ); } // HIO loop /* check if we are done */ const float currentError = imresh::libs::calculateHioError( curData /*g'*/, isMasked, nElements ); std::cout << "[Error " << currentError << "/" << rTargetError << "] " << "[Cycle " << iCycleShrinkWrap << "/" << rnCycles-1 << "]" << "\n"; if ( rTargetError > 0 && currentError < rTargetError ) break; if ( iCycleShrinkWrap >= rnCycles ) break; } // shrink wrap loop for ( unsigned i = 0; i < nElements; ++i ) rIntensity[i] = curData[i][0]; /* free buffers and plans */ fftwf_destroy_plan( toFreqSpace ); fftwf_destroy_plan( toRealSpace ); fftwf_free( curData ); fftwf_free( gPrevious); delete[] isMasked; return 0; }
void conv_tilde_init_fft_plans(t_conv_tilde* x) { post("Allocating FFT arrays.."); /* Allocate complex arrays for the fftw plans. */ x->input_complex = fftwf_alloc_complex(sizeof(fftwf_complex) * x->fft_size); x->ir_complex = fftwf_alloc_complex(sizeof(fftwf_complex) * x->fft_size); x->out_complex = fftwf_alloc_complex(sizeof(fftwf_complex) * x->fft_size); x->outTemp = (float*) fftwf_malloc(sizeof(float) * x->fft_size); post("Allocating plans. This might take a while..."); /* Create plans for in-place or out-of-place transform according to the INPLACE macro. */ #ifdef INPLACE x->fftplan_in = fftwf_plan_dft_1d(x->fft_size, x->input_complex, x->input_complex, FFTW_FORWARD, FFTW_MEASURE); x->fftplan_ir = fftwf_plan_dft_1d(x->fft_size, x->ir_complex, x->ir_complex, FFTW_FORWARD, FFTW_MEASURE); #else /* Need additional real arrays for out-of-place transform. */ x->input_to_fft = (float*) fftwf_malloc(sizeof(float) * x->fft_size); x->ir_to_fft = (float*) fftwf_malloc(sizeof(float) * x->fft_size); x->fftplan_in = fftwf_plan_dft_r2c_1d(x->fft_size, x->input_to_fft, x->input_complex, FFTW_MEASURE); x->fftplan_ir = fftwf_plan_dft_r2c_1d(x->fft_size, x->ir_to_fft, x->ir_complex, FFTW_MEASURE); #endif x->fftplan_inverse = fftwf_plan_dft_c2r_1d(x->fft_size, x->out_complex, x->outTemp, FFTW_MEASURE); /* With threads. */ #ifdef THREADS post("Allocating arrays for thread 2..."); x->input_complex_2 = fftwf_alloc_complex(sizeof(fftwf_complex) * x->fft_size); x->ir_complex_2 = fftwf_alloc_complex(sizeof(fftwf_complex) * x->fft_size); x->out_complex_2 = fftwf_alloc_complex(sizeof(fftwf_complex) * x->fft_size); x->outTemp_2 = (float*) fftwf_malloc(sizeof(float) * x->fft_size); post("Allocating plans for thread 2. This might take a while..."); #ifdef INPLACE x->fftplan_in_2 = fftwf_plan_dft_1d(x->fft_size, x->input_complex_2, x->input_complex_2, FFTW_FORWARD, FFTW_MEASURE); x->fftplan_ir_2 = fftwf_plan_dft_1d(x->fft_size, x->ir_complex_2, x->ir_complex_2, FFTW_FORWARD, FFTW_MEASURE); #else /* Need additional real arrays for out-of-place transform. */ x->input_to_fft_2 = (float*) fftwf_malloc(sizeof(float) * x->fft_size); x->ir_to_fft_2 = (float*) fftwf_malloc(sizeof(float) * x->fft_size); x->fftplan_in_2 = fftwf_plan_dft_r2c_1d(x->fft_size, x->input_to_fft_2, x->input_complex_2, FFTW_MEASURE); x->fftplan_ir_2 = fftwf_plan_dft_r2c_1d(x->fft_size, x->ir_to_fft_2, x->ir_complex_2, FFTW_MEASURE); #endif x->fftplan_inverse_2 = fftwf_plan_dft_c2r_1d(x->fft_size, x->out_complex_2, x->outTemp_2, FFTW_MEASURE); #endif post("Done!"); }
/* Constructor */ void *conv_tilde_new(t_floatarg channels) { int i, n; t_conv_tilde *x = (t_conv_tilde *)pd_new(conv_tilde_class); x->f = 0; x->framesize = DEFAULTFRAMESIZE; /* update this later if needed */ x->fft_size = 2 * x->framesize; x->out_gain = 1.0 / x->fft_size; /* Needs the decimal point! */ /* Clip the channel between 1 and default maximum channels */ x->channels = CLIP((int)channels, 1, DEFAULT_AUDIO_CHANNELS); /* Threads are not worth with only one channel. */ //if ( x->channels <= 1 ) // #undef THREADS x->all_channels = x->channels * 3; /* Assign an inlet pair (audio + IR) for each channel. One inlet is in place by default. */ for (i = 1; i < x->channels * 2; i++) inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_signal, &s_signal); /* Assign outlets for each output channel. */ for (i = 0; i < x->channels; i++) outlet_new(&x->x_obj, &s_signal); /* Allocate memory for the DSP vector */ x->x_myvec = (t_int **)t_getbytes(sizeof(t_int *) * (x->all_channels + 3)); if (!x->x_myvec) { error("conv~: out of memory"); return NULL; } /* Allocate memory for the parameters vector. */ //x->parameters = (t_float*) malloc(sizeof(t_float) * NUMBER_OF_PARAMETERS); /* Allocate memory for channel variables. 1 variable per channel. */ x->input_rw_ptr = (int*) malloc(sizeof(int) * x->channels); x->ir_end_ptr = (int*) malloc(sizeof(int) * x->channels); x->ir_frames = (int*) malloc(sizeof(int) * x->channels); x->frames_stored = (int*) malloc(sizeof(int) * x->channels); x->irlength = (int*) malloc(sizeof(t_float) * x->channels); x->ircount = (int*) malloc(sizeof(t_float) * x->channels); x->ircount_prev = (int*) malloc(sizeof(int) * x->channels); x->bypass = (int*) malloc(sizeof(int) * x->channels); /* Allocate multi-dimensional storage arrays and the overlap-save array. */ x->stored_input = (fftwf_complex**) malloc( sizeof(fftwf_complex*) * x->channels ); x->stored_ir = (fftwf_complex**) malloc( sizeof(fftwf_complex*) * x->channels ); x->overlap_save = (float**) malloc( sizeof(float*) * x->channels ); for ( i = 0; i < x->channels; i++) { x->stored_input[i] = fftwf_alloc_complex(sizeof(fftwf_complex) * 2 * STORAGELENGTH); x->stored_ir[i] = fftwf_alloc_complex(sizeof(fftwf_complex) * 2 * STORAGELENGTH); x->overlap_save[i] = (float*) fftwf_malloc( sizeof(float) * x->framesize ); } /* Init pointers and variables. */ for ( i = 0; i < x->channels; i++ ) { x->ir_end_ptr[i] = 0; x->input_rw_ptr[i] = 0; x->ircount[i] = 0; x->ircount_prev[i] = -1; x->irlength[i] = 0; x->ir_frames[i] = 0; x->frames_stored[i] = 0; x->bypass[i] = 0; } #ifdef THREADS /* round up the half way point. */ x->channels_halved = ( x->channels + 1 ) / 2; #endif /* Initialize FFTW arrays and plans. */ conv_tilde_init_fft_plans(x); return (void *)x; }