void FftConvolver::setResponse(int length, float* newResponse) { int neededLength= kiss_fftr_next_fast_size_real (block_size+length); int newTailSize=neededLength-block_size; if(neededLength !=fft_size || tail_size !=newTailSize) { if(workspace) freeArray(workspace); workspace=allocArray<float>(neededLength); if(tail) freeArray(tail); tail=allocArray<float>(newTailSize); fft_size=neededLength/2+1; workspace_size=neededLength; tail_size=newTailSize; if(fft) kiss_fftr_free(fft); fft = kiss_fftr_alloc(workspace_size, 0, nullptr, nullptr); if(ifft) kiss_fftr_free(ifft); ifft=kiss_fftr_alloc(workspace_size, 1, nullptr, nullptr); if(response_fft) freeArray(response_fft); response_fft=allocArray<kiss_fft_cpx>(fft_size); if(block_fft) freeArray(block_fft); block_fft=allocArray<kiss_fft_cpx>(fft_size); } memset(workspace, 0, sizeof(float)*workspace_size); memset(tail, 0, sizeof(float)*tail_size); //Store the fft of the response. std::copy(newResponse, newResponse+length, workspace); kiss_fftr(fft, workspace, response_fft); }
// ---------------------------------------------------------------------------- ofOpenALSoundPlayer::~ofOpenALSoundPlayer(){ unloadSound(); close(); if(fftCfg!=0) kiss_fftr_free(fftCfg); //kiss_fftr_free(fftCfg); //players.erase(this); }
HrtfData::~HrtfData() { if(temporary_buffer1) freeArray(temporary_buffer1); if(temporary_buffer2) freeArray(temporary_buffer2); if(hrirs == nullptr) return; //we never loaded one. for(int i = 0; i < elev_count; i++) { //The staticResamplerKernel allocates with new[], not allocArray. for(int j = 0; j < azimuth_counts[i]; j++) delete[] hrirs[i][j]; delete[] hrirs[i]; } delete[] hrirs; delete[] azimuth_counts; freeArray(fft_time_data); freeArray(fft_data); kiss_fftr_free(fft); kiss_fftr_free(ifft); }
// ---------------------------------------------------------------------------- void ofOpenALSoundPlayer::initSystemFFT(int bands){ if(int(systemBins.size())==bands) return; int signalSize = (bands-1)*2; if(systemFftCfg!=0) kiss_fftr_free(systemFftCfg); systemFftCfg = kiss_fftr_alloc(signalSize, 0, NULL, NULL); systemCx_out.resize(bands); systemBins.resize(bands); createWindow(signalSize); }
// ---------------------------------------------------------------------------- void ofOpenALSoundPlayer_TimelineAdditions::initFFT(int bands){ if(int(bins.size())==bands) return; int signalSize = (bands-1)*2; if(fftCfg!=0) kiss_fftr_free(fftCfg); fftCfg = kiss_fftr_alloc(signalSize, 0, NULL, NULL); cx_out.resize(bands); bins.resize(bands); createWindow(signalSize); }
int main(int argc, char *argv[]) { const char *filename_wav, *filename_png; kiss_fftr_cfg fft; int err = 0; for (;;) { const int c = getopt(argc, argv, "h"); if (0 > c) break; switch (c) { case '?': err = EINVAL; /*@fallthrough@*/ case 'h': usage(); return err; } } if (argc < 3 || argc != (optind + 2)) { usage(); return -EINVAL; } filename_wav = argv[optind++]; filename_png = argv[optind++]; fft = kiss_fftr_alloc(NUM_FFT, 0, 0, 0); if (!fft) { err = ENOMEM; goto out; } err = read_wav(fft, filename_wav); if (err) goto out; err = plot_spectrum(filename_png); if (err) goto out; out: if (fft) kiss_fftr_free(fft); tmr_debug(); mem_debug(); return err; }
// ---------------------------------------------------------------------------- ofOpenALSoundPlayer::~ofOpenALSoundPlayer(){ unloadSound(); kiss_fftr_free(fftCfg); players.erase(this); }
FFTLib::~FFTLib() { kiss_fftr_free(m_cfg); KISS_FFT_FREE(m_output); KISS_FFT_FREE(m_input); KISS_FFT_FREE(m_window); }
// ---------------------------------------------------------------------------- ofOpenALSoundPlayer_TimelineAdditions::~ofOpenALSoundPlayer_TimelineAdditions(){ unloadSound(); kiss_fftr_free(fftCfg); players.erase(this); }
SjOscSpectrum::~SjOscSpectrum() { kiss_fftr_free(m_kiss_fft_setup); }
FftConvolver::~FftConvolver() { if(workspace) freeArray(workspace); if(tail) freeArray(tail); if(fft) kiss_fftr_free(fft); if(ifft) kiss_fftr_free(ifft); }
void FFTCorrelation::convolve(const float *left, const int leftSize, const float *right, const int rightSize, float *out_convolved) { QTime time; time.start(); // To avoid issues with repetition (we are dealing with cosine waves // in the fourier domain) we need to pad the vectors to at least twice their size, // otherwise convolution would convolve with the repeated pattern as well int largestSize = leftSize; if (rightSize > largestSize) { largestSize = rightSize; } // The vectors must have the same size (same frequency resolution!) and should // be a power of 2 (for FFT). int size = 64; while (size/2 < largestSize) { size = size << 1; } kiss_fftr_cfg fftConfig = kiss_fftr_alloc(size, false, NULL,NULL); kiss_fftr_cfg ifftConfig = kiss_fftr_alloc(size, true, NULL,NULL); kiss_fft_cpx leftFFT[size/2]; kiss_fft_cpx rightFFT[size/2]; kiss_fft_cpx correlatedFFT[size/2]; // Fill in the data into our new vectors with padding float leftData[size]; float rightData[size]; float convolved[size]; std::fill(leftData, leftData+size, 0); std::fill(rightData, rightData+size, 0); std::copy(left, left+leftSize, leftData); std::copy(right, right+rightSize, rightData); // Fourier transformation of the vectors kiss_fftr(fftConfig, leftData, leftFFT); kiss_fftr(fftConfig, rightData, rightFFT); // Convolution in spacial domain is a multiplication in fourier domain. O(n). for (int i = 0; i < size/2; i++) { correlatedFFT[i].r = leftFFT[i].r*rightFFT[i].r - leftFFT[i].i*rightFFT[i].i; correlatedFFT[i].i = leftFFT[i].r*rightFFT[i].i + leftFFT[i].i*rightFFT[i].r; } // Inverse fourier tranformation to get the convolved data. // Insert one element at the beginning to obtain the same result // that we also get with the nested for loop correlation. *out_convolved = 0; int out_size = leftSize+rightSize+1; kiss_fftri(ifftConfig, correlatedFFT, convolved); std::copy(convolved, convolved+out_size-1, out_convolved+1); // Finally some cleanup. kiss_fftr_free(fftConfig); kiss_fftr_free(ifftConfig); std::cout << "FFT convolution computed. Time taken: " << time.elapsed() << " ms" << std::endl; }