diff options
Diffstat (limited to 'gr-fft/lib/fft_vcc_fftw.cc')
-rw-r--r-- | gr-fft/lib/fft_vcc_fftw.cc | 208 |
1 files changed, 101 insertions, 107 deletions
diff --git a/gr-fft/lib/fft_vcc_fftw.cc b/gr-fft/lib/fft_vcc_fftw.cc index 3b23058df5..9c546a92d7 100644 --- a/gr-fft/lib/fft_vcc_fftw.cc +++ b/gr-fft/lib/fft_vcc_fftw.cc @@ -30,117 +30,111 @@ #include <volk/volk.h> namespace gr { - namespace fft { - - fft_vcc::sptr fft_vcc::make(int fft_size, bool forward, - const std::vector<float> &window, - bool shift, int nthreads) - { - return gnuradio::get_initial_sptr(new fft_vcc_fftw - (fft_size, forward, window, - shift, nthreads)); - } - - fft_vcc_fftw::fft_vcc_fftw(int fft_size, bool forward, - const std::vector<float> &window, - bool shift, int nthreads) - : sync_block("fft_vcc_fftw", - io_signature::make(1, 1, fft_size * sizeof(gr_complex)), - io_signature::make(1, 1, fft_size * sizeof(gr_complex))), - d_fft_size(fft_size), d_forward(forward), d_shift(shift) - { - d_fft = new fft_complex(d_fft_size, forward, nthreads); - if(!set_window(window)) +namespace fft { + +fft_vcc::sptr fft_vcc::make(int fft_size, + bool forward, + const std::vector<float>& window, + bool shift, + int nthreads) +{ + return gnuradio::get_initial_sptr( + new fft_vcc_fftw(fft_size, forward, window, shift, nthreads)); +} + +fft_vcc_fftw::fft_vcc_fftw(int fft_size, + bool forward, + const std::vector<float>& window, + bool shift, + int nthreads) + : sync_block("fft_vcc_fftw", + io_signature::make(1, 1, fft_size * sizeof(gr_complex)), + io_signature::make(1, 1, fft_size * sizeof(gr_complex))), + d_fft_size(fft_size), + d_forward(forward), + d_shift(shift) +{ + d_fft = new fft_complex(d_fft_size, forward, nthreads); + if (!set_window(window)) throw std::runtime_error("fft_vcc: window not the same length as fft_size\n"); - } - - fft_vcc_fftw::~fft_vcc_fftw() - { - delete d_fft; - } - - void - fft_vcc_fftw::set_nthreads(int n) - { - d_fft->set_nthreads(n); - } +} + +fft_vcc_fftw::~fft_vcc_fftw() { delete d_fft; } + +void fft_vcc_fftw::set_nthreads(int n) { d_fft->set_nthreads(n); } + +int fft_vcc_fftw::nthreads() const { return d_fft->nthreads(); } + +bool fft_vcc_fftw::set_window(const std::vector<float>& window) +{ + if (window.size() == 0 || window.size() == d_fft_size) { + d_window = window; + return true; + } else + return false; +} + +int fft_vcc_fftw::work(int noutput_items, + gr_vector_const_void_star& input_items, + gr_vector_void_star& output_items) +{ + const gr_complex* in = (const gr_complex*)input_items[0]; + gr_complex* out = (gr_complex*)output_items[0]; + + unsigned int input_data_size = input_signature()->sizeof_stream_item(0); + unsigned int output_data_size = output_signature()->sizeof_stream_item(0); + + int count = 0; + + while (count++ < noutput_items) { + + // copy input into optimally aligned buffer + if (d_window.size()) { + gr_complex* dst = d_fft->get_inbuf(); + if (!d_forward && d_shift) { + unsigned int offset = (!d_forward && d_shift) ? (d_fft_size / 2) : 0; + int fft_m_offset = d_fft_size - offset; + volk_32fc_32f_multiply_32fc( + &dst[fft_m_offset], &in[0], &d_window[0], offset); + volk_32fc_32f_multiply_32fc( + &dst[0], &in[offset], &d_window[offset], d_fft_size - offset); + } else { + volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); + } + } else { + if (!d_forward && d_shift) { // apply an ifft shift on the data + gr_complex* dst = d_fft->get_inbuf(); + unsigned int len = (unsigned int)(floor( + d_fft_size / 2.0)); // half length of complex array + memcpy(&dst[0], &in[len], sizeof(gr_complex) * (d_fft_size - len)); + memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex) * len); + } else { + memcpy(d_fft->get_inbuf(), in, input_data_size); + } + } - int - fft_vcc_fftw::nthreads() const - { - return d_fft->nthreads(); - } + // compute the fft + d_fft->execute(); + + // copy result to our output + if (d_forward && d_shift) { // apply a fft shift on the data + unsigned int len = (unsigned int)(ceil(d_fft_size / 2.0)); + memcpy(&out[0], + &d_fft->get_outbuf()[len], + sizeof(gr_complex) * (d_fft_size - len)); + memcpy(&out[d_fft_size - len], + &d_fft->get_outbuf()[0], + sizeof(gr_complex) * len); + } else { + memcpy(out, d_fft->get_outbuf(), output_data_size); + } - bool - fft_vcc_fftw::set_window(const std::vector<float> &window) - { - if(window.size()==0 || window.size()==d_fft_size) { - d_window=window; - return true; - } - else - return false; + in += d_fft_size; + out += d_fft_size; } - int - fft_vcc_fftw::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) - { - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - unsigned int input_data_size = input_signature()->sizeof_stream_item (0); - unsigned int output_data_size = output_signature()->sizeof_stream_item (0); - - int count = 0; - - while(count++ < noutput_items) { - - // copy input into optimally aligned buffer - if(d_window.size()) { - gr_complex *dst = d_fft->get_inbuf(); - if(!d_forward && d_shift) { - unsigned int offset = (!d_forward && d_shift)?(d_fft_size/2):0; - int fft_m_offset = d_fft_size - offset; - volk_32fc_32f_multiply_32fc(&dst[fft_m_offset], &in[0], &d_window[0], offset); - volk_32fc_32f_multiply_32fc(&dst[0], &in[offset], &d_window[offset], d_fft_size-offset); - } - else { - volk_32fc_32f_multiply_32fc(&dst[0], in, &d_window[0], d_fft_size); - } - } - else { - if(!d_forward && d_shift) { // apply an ifft shift on the data - gr_complex *dst = d_fft->get_inbuf(); - unsigned int len = (unsigned int)(floor(d_fft_size/2.0)); // half length of complex array - memcpy(&dst[0], &in[len], sizeof(gr_complex)*(d_fft_size - len)); - memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex)*len); - } - else { - memcpy(d_fft->get_inbuf(), in, input_data_size); - } - } - - // compute the fft - d_fft->execute(); - - // copy result to our output - if(d_forward && d_shift) { // apply a fft shift on the data - unsigned int len = (unsigned int)(ceil(d_fft_size/2.0)); - memcpy(&out[0], &d_fft->get_outbuf()[len], sizeof(gr_complex)*(d_fft_size - len)); - memcpy(&out[d_fft_size - len], &d_fft->get_outbuf()[0], sizeof(gr_complex)*len); - } - else { - memcpy (out, d_fft->get_outbuf (), output_data_size); - } - - in += d_fft_size; - out += d_fft_size; - } - - return noutput_items; - } + return noutput_items; +} - } /* namespace fft */ +} /* namespace fft */ } /* namespace gr */ |