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); }
void fft_filt_c::prepare_filter() { fft_len = is_complex ? kiss_fft_next_fast_size(l + filter_inlen) : kiss_fftr_next_fast_size_real(l+filter_inlen); if (filter_is_ready) { make_unready(); } kiss_fft_cpx *filt_buf_in = new kiss_fft_cpx[fft_len]; filt_buf = new kiss_fft_cpx[fft_len]; float absmax =0; if (filter_is_complex) { for (uint32_t i=0;i<filter_inlen;i++) { filt_buf_in[i].i = fft_len * filter_inptr[2*i]; filt_buf_in[i].r = fft_len * filter_inptr[2*i+1]; } } else { for (uint32_t i=0;i<filter_inlen;i++) { filt_buf_in[i].r = fft_len * filter_inptr[i]; filt_buf_in[i].i = 0; } } for (uint32_t i=filter_inlen;i<fft_len;i++) { filt_buf_in[i].r = 0; filt_buf_in[i].i = 0; } kiss_fft_cfg filter_cfg = kiss_fft_alloc(fft_len,0,0,0); kiss_fft(filter_cfg,filt_buf_in,filt_buf); absmax = 0; for (uint32_t i=0;i<fft_len;i++) { if (filt_buf[i].i > absmax) { absmax = filt_buf[i].i; }; if (filt_buf[i].i < -absmax) { absmax = -filt_buf[i].i; }; if (filt_buf[i].r > absmax) { absmax = filt_buf[i].r; }; if (filt_buf[i].r < -absmax) { absmax = -filt_buf[i].r; }; } // for (uint32_t i=0;i<fft_len/2+1;i++) { d3c(i,filt_buf[i].i,filt_buf[i].r); }; float scale_factor = 32767.0 / absmax; for (uint32_t i=0;i<fft_len;i++) { filt_buf[i].r = (float)filt_buf[i].r * scale_factor; filt_buf[i].i = (float)filt_buf[i].i * scale_factor; } // for (uint32_t i=0;i<fft_len/2+1;i++) { d3c(i,filt_buf[i].i,filt_buf[i].r); }; filter_is_ready = true; delete filt_buf_in; };