Changeset 8244

Show
Ignore:
Timestamp:
04/22/08 16:24:16
Author:
eb
Message:

Merged eb/gcell -r8215:8243 into trunk. This adds gr-gcell, the GNU
Radio interface to the Cell Broadband Engine.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gnuradio/trunk/config/Makefile.am

    r8086 r8244  
    4343        grc_gr_audio_windows.m4 \ 
    4444        grc_gr_comedi.m4 \ 
     45        grc_gr_gcell.m4 \ 
    4546        grc_gr_gpio.m4 \ 
    4647        grc_gr_gsm_fr_vocoder.m4 \ 
  • gnuradio/trunk/config/grc_gcell.m4

    r8209 r8244  
    6666        AC_SUBST(gcell_spu_INCLUDES) 
    6767        AC_SUBST(gcell_spu_LA) 
     68 
     69        dnl kludge up initial swig dependency files 
     70        AC_CONFIG_COMMANDS([swig_gcell_deps], [ 
     71            touch gr-gcell/src/gcell.d 
     72        ]) 
    6873    fi 
    6974 
  • gnuradio/trunk/configure.ac

    r8086 r8244  
    246246GRC_USRP 
    247247GRC_GR_USRP                     dnl this must come after GRC_USRP 
     248GRC_GR_GCELL                    dnl this must come after GRC_GCELL and GRC_GNURADIO_CORE 
    248249GRC_GR_MSDD6000 
    249250GRC_GR_AUDIO_ALSA 
  • gnuradio/trunk/gcell/src/lib/runtime/Makefile.am

    r8209 r8244  
    3333 
    3434libruntime_la_SOURCES = \ 
     35        gc_aligned_alloc.cc \ 
    3536        gc_job_manager.cc \ 
    3637        gc_job_manager_impl.cc \ 
     
    4748 
    4849gcellinclude_HEADERS = \ 
     50        gc_aligned_alloc.h \ 
    4951        gc_job_manager.h 
    5052 
  • gnuradio/trunk/gcell/src/lib/runtime/gc_job_manager.cc

    r8209 r8244  
    3030 
    3131static boost::weak_ptr<gc_job_manager> s_singleton; 
     32 
     33 
     34// custom deleter of gc_job_desc allocated via alloc_job_desc_sptr 
     35class job_desc_deleter { 
     36  gc_job_manager_sptr   d_mgr; 
     37public: 
     38  job_desc_deleter(gc_job_manager_sptr mgr) : d_mgr(mgr) {} 
     39 
     40  void operator()(gc_job_desc *jd) { 
     41    d_mgr->free_job_desc(jd); 
     42  } 
     43}; 
     44 
    3245 
    3346 
     
    7184  return gc_job_manager_sptr(s_singleton); 
    7285} 
     86 
     87gc_job_desc_sptr  
     88gc_job_manager::make_jd_sptr(gc_job_manager_sptr mgr, gc_job_desc *jd) 
     89{ 
     90  return gc_job_desc_sptr(jd, job_desc_deleter(mgr)); 
     91} 
     92 
     93gc_job_desc_sptr  
     94gc_job_manager::alloc_job_desc(gc_job_manager_sptr mgr) 
     95{ 
     96  return make_jd_sptr(mgr, mgr->alloc_job_desc()); 
     97} 
     98 
    7399 
    74100// ------------------------------------------------------------------------ 
  • gnuradio/trunk/gcell/src/lib/runtime/gc_job_manager.h

    r8209 r8244  
    3434typedef boost::shared_ptr<gc_job_manager> gc_job_manager_sptr; 
    3535typedef boost::shared_ptr<spe_program_handle_t> spe_program_handle_sptr; 
     36typedef boost::shared_ptr<gc_job_desc> gc_job_desc_sptr; 
    3637 
    3738/*! 
     
    8788  gc_jm_options() : 
    8889    max_jobs(0), max_client_threads(0), nspes(0), 
    89     gang_schedule(true), use_affinity(false), 
     90    gang_schedule(false), use_affinity(false), 
    9091    enable_logging(false), log2_nlog_entries(12) 
     92  { 
     93  } 
     94 
     95  gc_jm_options(spe_program_handle_sptr program_handle_, 
     96                unsigned int nspes_ = 0) : 
     97    max_jobs(0), max_client_threads(0), nspes(nspes_), 
     98    gang_schedule(false), use_affinity(false), 
     99    enable_logging(false), log2_nlog_entries(12), 
     100    program_handle(program_handle_) 
    91101  { 
    92102  } 
     
    237247  virtual std::vector<std::string> proc_names() = 0; 
    238248 
     249  virtual void set_debug(int debug); 
     250  virtual int debug(); 
     251 
     252  /* ----- static methods ----- */ 
     253 
    239254  /*! 
    240255   * \brief Set the singleton gc_job_manager instance. 
     
    257272  static gc_job_manager_sptr singleton(); 
    258273 
    259  
    260   virtual void set_debug(int debug); 
    261   virtual int debug(); 
     274  /*! 
     275   * \brief return a boost::shared_ptr to a job descriptor. 
     276   */ 
     277  static gc_job_desc_sptr make_jd_sptr(gc_job_manager_sptr mgr, gc_job_desc *jd); 
     278 
     279  /*! 
     280   * \brief allocate a job descriptor and return a boost::shared_ptr to it. 
     281   */ 
     282  static gc_job_desc_sptr alloc_job_desc(gc_job_manager_sptr mgr); 
    262283}; 
    263284 
  • gnuradio/trunk/gcell/src/lib/runtime/gc_job_manager_impl.cc

    r8209 r8244  
    2626#include <gc_mbox.h> 
    2727#include <gc_proc_def_utils.h> 
    28  
     28#include <gc_aligned_alloc.h> 
    2929#include <stdio.h> 
    3030#include <stdexcept> 
     
    8484{ 
    8585  ((gc_client_thread_info *) p)->d_free = 1; 
    86 } 
    87  
    88 /* 
    89  * Return pointer to cache-aligned chunk of storage of size size bytes. 
    90  * Throw if can't allocate memory.  The storage should be freed 
    91  * with "free" when done.  The memory is initialized to zero. 
    92  */ 
    93 static void * 
    94 aligned_alloc(size_t size, size_t alignment = CACHE_LINE_SIZE) 
    95 { 
    96   void *p = 0; 
    97   if (posix_memalign(&p, alignment, size) != 0){ 
    98     perror("posix_memalign"); 
    99     throw std::runtime_error("memory"); 
    100   } 
    101   memset(p, 0, size);           // zero the memory 
    102   return p; 
    10386} 
    10487 
     
    197180  // initalize the job queue 
    198181   
    199   d_queue = (gc_jd_queue_t *) aligned_alloc(sizeof(gc_jd_queue_t)); 
     182  d_queue = (gc_jd_queue_t *) gc_aligned_alloc(sizeof(gc_jd_queue_t), CACHE_LINE_SIZE); 
    200183  _d_queue_boost = 
    201184    boost::shared_ptr<void>((void *) d_queue, free_deleter()); 
     
    209192  assert(sizeof(gc_spu_args_t) % 16 == 0); 
    210193  d_spu_args = 
    211     (gc_spu_args_t *) aligned_alloc(MAX_SPES * sizeof(gc_spu_args_t), 16); 
     194    (gc_spu_args_t *) gc_aligned_alloc(MAX_SPES * sizeof(gc_spu_args_t), 16); 
    212195  _d_spu_args_boost = 
    213196    boost::shared_ptr<void>((void *) d_spu_args, free_deleter()); 
     
    216199  assert(sizeof(gc_comp_info_t) % CACHE_LINE_SIZE == 0); 
    217200  d_comp_info = 
    218     (gc_comp_info_t *) aligned_alloc(2 * MAX_SPES * sizeof(gc_comp_info_t), 
    219                                      CACHE_LINE_SIZE); 
     201    (gc_comp_info_t *) gc_aligned_alloc(2 * MAX_SPES * sizeof(gc_comp_info_t), 
     202                                       CACHE_LINE_SIZE); 
    220203  _d_comp_info_boost = 
    221204    boost::shared_ptr<void>((void *) d_comp_info, free_deleter()); 
     
    270253  // initalize the free list of job descriptors 
    271254   
    272   d_free_list = (gc_jd_stack_t *) aligned_alloc(sizeof(gc_jd_stack_t)); 
     255  d_free_list = (gc_jd_stack_t *) gc_aligned_alloc(sizeof(gc_jd_stack_t), CACHE_LINE_SIZE); 
    273256  // This ensures that the memory associated with d_free_list is 
    274257  // automatically freed in the destructor or if an exception occurs 
     
    284267 
    285268  // Initialize the array of job descriptors. 
    286   d_jd = (gc_job_desc_t *) aligned_alloc(sizeof(d_jd[0]) * d_options.max_jobs); 
     269  d_jd = (gc_job_desc_t *) gc_aligned_alloc(sizeof(d_jd[0]) * d_options.max_jobs, CACHE_LINE_SIZE); 
    287270  _d_jd_boost = boost::shared_ptr<void>((void *) d_jd, free_deleter()); 
    288271 
     
    318301  // allocate all bitvectors in a single cache-aligned chunk 
    319302  size_t nlongs = d_bvlen * d_options.max_client_threads; 
    320   void *p = aligned_alloc(nlongs * sizeof(unsigned long)); 
     303  void *p = gc_aligned_alloc(nlongs * sizeof(unsigned long), CACHE_LINE_SIZE); 
    321304  _d_all_bitvectors = boost::shared_ptr<void>(p, free_deleter()); 
    322305 
  • gnuradio/trunk/gcell/src/lib/wrapper/gcp_fft_1d_r2.cc

    r8211 r8244  
    3131        gc_proc_id_t proc_id, 
    3232        unsigned log2_fft_length, 
    33         bool forward
     33        bool shift
    3434        std::complex<float> *out, 
    3535        const std::complex<float> *in, 
    36         const std::complex<float> *W) 
     36        const std::complex<float> *twiddle, 
     37        const float *window) 
    3738{ 
    3839  jd->proc_id = proc_id; 
    3940  jd->input.nargs = 2; 
    4041  jd->output.nargs = 0; 
    41   jd->eaa.nargs = 3
     42  jd->eaa.nargs = 4
    4243 
    4344  jd->input.arg[0].u32 = log2_fft_length; 
    44   jd->input.arg[1].u32 = forward
     45  jd->input.arg[1].u32 = shift
    4546  unsigned int fft_length = 1 << log2_fft_length; 
    4647 
     
    5354  jd->eaa.arg[1].get_size = sizeof(std::complex<float>) * fft_length; 
    5455 
    55   jd->eaa.arg[2].ea_addr = ptr_to_ea(const_cast<std::complex<float>*>(W)); 
     56  jd->eaa.arg[2].ea_addr = ptr_to_ea(const_cast<std::complex<float>*>(twiddle)); 
    5657  jd->eaa.arg[2].direction = GCJD_DMA_GET; 
    5758  jd->eaa.arg[2].get_size = sizeof(std::complex<float>) * fft_length / 4; 
     59 
     60  jd->eaa.arg[3].ea_addr = ptr_to_ea(const_cast<float*>(window)); 
     61  jd->eaa.arg[3].direction = GCJD_DMA_GET; 
     62  if (window == 0) 
     63    jd->eaa.arg[3].get_size = 0; 
     64  else 
     65    jd->eaa.arg[3].get_size = sizeof(float) * fft_length; 
    5866} 
    5967 
    60  
    61 gc_job_desc * 
     68   
     69gc_job_desc_sptr 
    6270gcp_fft_1d_r2_submit(gc_job_manager_sptr mgr, 
    6371                     unsigned int log2_fft_length, 
    6472                     bool forward, 
     73                     bool shift, 
    6574                     std::complex<float> *out, 
    6675                     const std::complex<float> *in, 
    67                      const std::complex<float> *W) 
     76                     const std::complex<float> *twiddle, 
     77                     const float *window) 
    6878{ 
    6979  unsigned int fft_length = 1 << log2_fft_length; 
     
    7585  if ((intptr_t)in & 0xf) 
    7686    throw gc_bad_align("in"); 
    77   if ((intptr_t)W & 0xf) 
    78     throw gc_bad_align("W"); 
     87  if ((intptr_t)twiddle & 0xf) 
     88    throw gc_bad_align("twiddle"); 
     89  if ((intptr_t)window & 0xf) 
     90    throw gc_bad_align("window"); 
    7991 
    80   gc_proc_id_t fft_id = mgr->lookup_proc("fft_1d_r2"); 
    81   gc_job_desc *jd = mgr->alloc_job_desc(); 
    82   init_jd(jd, fft_id, log2_fft_length, forward, out, in, W); 
    83   if (!mgr->submit_job(jd)){ 
     92  std::string proc_name; 
     93  if (forward) 
     94    proc_name = "fwd_fft_1d_r2"; 
     95  else 
     96    proc_name = "inv_fft_1d_r2"; 
     97 
     98  gc_proc_id_t fft_id = mgr->lookup_proc(proc_name); 
     99  gc_job_desc_sptr jd = gc_job_manager::alloc_job_desc(mgr); 
     100  init_jd(jd.get(), fft_id, log2_fft_length, shift, out, in, twiddle, window); 
     101  if (!mgr->submit_job(jd.get())){ 
    84102    gc_job_status_t s = jd->status; 
    85     mgr->free_job_desc(jd); 
    86     throw gc_bad_submit("fft_1d_r2", s); 
     103    throw gc_bad_submit(proc_name, s); 
    87104  } 
    88105  return jd; 
     
    90107 
    91108void 
    92 gcp_fft_1d_r2_twiddle(unsigned int log2_fft_length, std::complex<float> *W
     109gcp_fft_1d_r2_twiddle(unsigned int log2_fft_length, std::complex<float> *twiddle
    93110{ 
    94111  unsigned int n = 1 << log2_fft_length; 
    95112 
    96   W[0].real() = 1.0; 
    97   W[0].imag() = 0.0; 
     113  twiddle[0].real() = 1.0; 
     114  twiddle[0].imag() = 0.0; 
    98115  for (unsigned i=1; i < n/4; i++){ 
    99     W[i].real() =  cos(i * 2*M_PI/n); 
    100     W[n/4 - i].imag() = -W[i].real(); 
     116    twiddle[i].real() =  cos(i * 2*M_PI/n); 
     117    twiddle[n/4 - i].imag() = -twiddle[i].real(); 
    101118  } 
    102119} 
  • gnuradio/trunk/gcell/src/lib/wrapper/gcp_fft_1d_r2.h

    r8211 r8244  
    2626 
    2727/*! 
    28  * \brief Submit a job that computes the forward or reverse FFT. 
     28 * \brief Submit a job that computes the forward or inverse FFT. 
    2929 * 
    3030 * \param mgr is the job manager instance 
    3131 * \param log2_fft_length is the log2 of the fft_length (4 <= x <= 12). 
    32  * \param forward is true to compute the forward xform 
     32 * \param forward is true to compute the forward transform, else the inverse. 
     33 * \param shift indicates if an "fftshift" should be applied to the output data 
    3334 * \param out is the fft_length output from FFT (must be 16-byte aligned). 
    3435 * \param in is the fft_length input to FFT (must be 16-byte aligned). 
    35  * \param W is fft_length/4 twiddle factor input to FFT (must be 16-byte aligned). 
     36 * \param twiddle is fft_length/4 twiddle factor input to FFT (must be 16-byte aligned). 
     37 * \param window is the window to be applied to the input data. 
     38 *    The window length must be either 0 or fft_length (must be 16-byte aligned). 
    3639 * 
    37  * Returns a job descriptor which should be passed to wait_job*. 
     40 * Returns a shared_ptr to a job descriptor which should be passed to wait_job*. 
    3841 * Throws an exception in the event of a problem. 
     42 * This uses the FFTW conventions for scaling.  That is, neither the forward nor inverse 
     43 * are scaled by 1/fft_length. 
    3944 */ 
    40 gc_job_desc * 
     45gc_job_desc_sptr 
    4146gcp_fft_1d_r2_submit(gc_job_manager_sptr mgr, 
    4247                     unsigned int log2_fft_length, 
    4348                     bool forward, 
     49                     bool shift, 
    4450                     std::complex<float> *out, 
    4551                     const std::complex<float> *in, 
    46                      const std::complex<float> *W); 
     52                     const std::complex<float> *twiddle, 
     53                     const float *window); 
    4754 
    4855/*! 
  • gnuradio/trunk/gcell/src/lib/wrapper/qa_gcp_fft_1d_r2.cc

    r8211 r8244  
    8181} 
    8282 
    83 // test reverse FFT 
     83// test inverse FFT 
    8484void 
    8585qa_gcp_fft_1d_r2::t2() 
     
    102102qa_gcp_fft_1d_r2::t3() 
    103103{ 
     104  // FIXME Test fwd and inv with windowing option 
    104105} 
    105106 
     
    107108qa_gcp_fft_1d_r2::t4() 
    108109{ 
     110  // FIXME Test fwd and inv with shift option 
    109111} 
    110112 
     
    179181  // ------------------------------------------------------------------------ 
    180182  // compute the answer on the cell 
    181   gc_job_desc *jd = gcp_fft_1d_r2_submit(mgr, log2_fft_size, forward
    182                                          cell_out, cell_in, cell_twiddle); 
    183   if (!mgr->wait_job(jd)){ 
     183  gc_job_desc_sptr jd = gcp_fft_1d_r2_submit(mgr, log2_fft_size, forward, false
     184                                             cell_out, cell_in, cell_twiddle, 0); 
     185  if (!mgr->wait_job(jd.get())){ 
    184186    fprintf(stderr, "wait_job failed: %s\n", gc_job_status_string(jd->status).c_str()); 
    185     mgr->free_job_desc(jd); 
    186187    CPPUNIT_ASSERT(0); 
    187188  } 
    188   mgr->free_job_desc(jd); 
    189189 
    190190  // ------------------------------------------------------------------------ 
  • gnuradio/trunk/gcell/src/lib/wrapper/spu/gcs_fft_1d_r2.c

    r8211 r8244  
    2222#include <gc_declare_proc.h> 
    2323#include <libfft.h> 
     24#include <assert.h> 
    2425 
    2526/* 
     
    3637 
    3738static void 
    38 gcs_fft_1d_r2(const gc_job_direct_args_t *input, 
    39               gc_job_direct_args_t *output __attribute__((unused)), 
    40               const gc_job_ea_args_t *eaa) 
     39gcs_fwd_fft_1d_r2(const gc_job_direct_args_t *input, 
     40                 gc_job_direct_args_t *output __attribute__((unused)), 
     41                 const gc_job_ea_args_t *eaa) 
    4142{ 
    42   vector float *out = (vector float *) eaa->arg[0].ls_addr; 
    43   vector float *in = (vector float *) eaa->arg[1].ls_addr; 
    44   vector float *W = (vector float *) eaa->arg[2].ls_addr; 
     43  vector float *out = (vector float *) eaa->arg[0].ls_addr;     // complex 
     44  vector float *in = (vector float *) eaa->arg[1].ls_addr;      // complex 
     45  vector float *twiddle = (vector float *) eaa->arg[2].ls_addr; // complex 
     46  vector float *window = (vector float *) eaa->arg[3].ls_addr;  // float 
     47 
    4548  int log2_fft_length = input->arg[0].u32; 
    46   int forward = input->arg[1].u32;     // non-zero if forward xform 
     49  int shift = input->arg[1].u32;       // non-zero if we should apply fftshift 
    4750 
    48   if (forward){ 
    49     fft_1d_r2(out, in, W, log2_fft_length); 
     51  if (eaa->arg[3].get_size){    // apply window 
     52    // FIXME pointwise multiply in *= window 
     53    assert(0); 
    5054  } 
    51   else { 
    52     conjugate_vector(in, 1 << (log2_fft_length - 1)); 
    53     fft_1d_r2(out, in, W, log2_fft_length); 
    54     conjugate_vector(out, 1 << (log2_fft_length - 1)); 
     55 
     56  fft_1d_r2(out, in, twiddle, log2_fft_length); 
     57 
     58  if (shift){ 
     59    // FIXME apply "fftshift" to output data in-place 
     60    assert(0); 
    5561  } 
    5662} 
    5763 
    58 GC_DECLARE_PROC(gcs_fft_1d_r2, "fft_1d_r2"); 
     64GC_DECLARE_PROC(gcs_fwd_fft_1d_r2, "fwd_fft_1d_r2"); 
     65 
     66static void 
     67gcs_inv_fft_1d_r2(const gc_job_direct_args_t *input, 
     68                  gc_job_direct_args_t *output __attribute__((unused)), 
     69                  const gc_job_ea_args_t *eaa) 
     70
     71  vector float *out = (vector float *) eaa->arg[0].ls_addr;     // complex 
     72  vector float *in = (vector float *) eaa->arg[1].ls_addr;      // complex 
     73  vector float *twiddle = (vector float *) eaa->arg[2].ls_addr; // complex 
     74  vector float *window = (vector float *) eaa->arg[3].ls_addr;  // float 
     75 
     76  int log2_fft_length = input->arg[0].u32; 
     77  int shift = input->arg[1].u32;        // non-zero if we should apply fftshift 
     78 
     79  if (eaa->arg[3].get_size){    // apply window 
     80    // FIXME pointwise multiply in *= window 
     81    assert(0); 
     82  } 
     83 
     84  if (shift){ 
     85    // FIXME apply "fftshift" to input data in-place 
     86    assert(0); 
     87  } 
     88 
     89  conjugate_vector(in, 1 << (log2_fft_length - 1)); 
     90  fft_1d_r2(out, in, twiddle, log2_fft_length); 
     91  conjugate_vector(out, 1 << (log2_fft_length - 1)); 
     92
     93 
     94GC_DECLARE_PROC(gcs_inv_fft_1d_r2, "inv_fft_1d_r2"); 
  • gnuradio/trunk/gnuradio-core/src/lib/general/Makefile.am

    r8206 r8244  
    7373        gr_feval.cc                     \ 
    7474        gr_fft_vcc.cc                   \ 
     75        gr_fft_vcc_fftw.cc              \ 
    7576        gr_fft_vfc.cc                   \ 
    7677        gr_firdes.cc                    \ 
     
    216217        gr_feval.h                      \ 
    217218        gr_fft_vcc.h                    \ 
     219        gr_fft_vcc_fftw.h               \ 
    218220        gr_fft_vfc.h                    \ 
    219221        gr_firdes.h                     \ 
  • gnuradio/trunk/gnuradio-core/src/lib/general/gr_fft_vcc.cc

    r6044 r8244  
    11/* -*- c++ -*- */ 
    22/* 
    3  * Copyright 2004,2007 Free Software Foundation, Inc. 
     3 * Copyright 2004,2007,2008 Free Software Foundation, Inc. 
    44 *  
    55 * This file is part of GNU Radio 
     
    2525#endif 
    2626 
    27 #include <gr_fft_vcc.h> 
     27#include <gr_fft_vcc.h>         // abstract class 
     28#include <gr_fft_vcc_fftw.h>    // concrete class 
    2829#include <gr_io_signature.h> 
    2930#include <gri_fft.h> 
     
    3132 
    3233gr_fft_vcc_sptr 
    33 gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> window, bool shift) 
     34gr_make_fft_vcc (int fft_size, bool forward,const std::vector<float> &window, bool shift) 
    3435{ 
    35   return gr_fft_vcc_sptr (new gr_fft_vcc (fft_size, forward, window, shift)); 
     36  return gr_make_fft_vcc_fftw(fft_size, forward, window, shift); 
    3637} 
    3738 
    38 gr_fft_vcc::gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window, bool shift) 
    39   : gr_sync_block ("fft_vcc", 
     39gr_fft_vcc::gr_fft_vcc (const std::string &name, 
     40                        int fft_size, bool forward, const std::vector<float> &window, 
     41                        bool shift) 
     42  : gr_sync_block (name, 
    4043                   gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex)), 
    4144                   gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))), 
    4245    d_fft_size(fft_size), d_forward(forward), d_shift(shift) 
    4346{ 
    44   d_fft = new gri_fft_complex (d_fft_size, forward); 
    45  
    4647  set_window(window); 
    47  
    4848} 
    4949 
    5050gr_fft_vcc::~gr_fft_vcc () 
    5151{ 
    52   delete d_fft; 
    53 } 
    54  
    55 int 
    56 gr_fft_vcc::work (int noutput_items, 
    57                   gr_vector_const_void_star &input_items, 
    58                   gr_vector_void_star &output_items) 
    59 { 
    60   const gr_complex *in = (const gr_complex *) input_items[0]; 
    61   gr_complex *out = (gr_complex *) output_items[0]; 
    62  
    63   unsigned int input_data_size = input_signature()->sizeof_stream_item (0); 
    64   unsigned int output_data_size = output_signature()->sizeof_stream_item (0); 
    65  
    66   int count = 0; 
    67  
    68   while (count++ < noutput_items){ 
    69      
    70     // copy input into optimally aligned buffer 
    71      
    72     if (d_window.size()){ 
    73       gr_complex *dst = d_fft->get_inbuf(); 
    74       for (unsigned int i = 0; i < d_fft_size; i++)             // apply window 
    75         dst[i] = in[i] * d_window[i]; 
    76     } 
    77     else { 
    78       if(!d_forward && d_shift) {  // apply an ifft shift on the data 
    79         gr_complex *dst = d_fft->get_inbuf(); 
    80         unsigned int len = (unsigned int)(floor(d_fft_size/2.0)); // half length of complex array 
    81         memcpy(&dst[0], &in[len], sizeof(gr_complex)*(d_fft_size - len)); 
    82         memcpy(&dst[d_fft_size - len], &in[0], sizeof(gr_complex)*len); 
    83       } 
    84       else { 
    85         memcpy (d_fft->get_inbuf(), in, input_data_size); 
    86       } 
    87     } 
    88      
    89     // compute the fft 
    90     d_fft->execute (); 
    91      
    92     // copy result to our output 
    93     if(d_forward && d_shift) {  // apply a fft shift on the data 
    94       unsigned int len = (unsigned int)(ceil(d_fft_size/2.0)); 
    95       memcpy(&out[0], &d_fft->get_outbuf()[len], sizeof(gr_complex)*(d_fft_size - len)); 
    96       memcpy(&out[d_fft_size - len], &d_fft->get_outbuf()[0], sizeof(gr_complex)*len); 
    97     } 
    98     else { 
    99       memcpy (out, d_fft->get_outbuf (), output_data_size); 
    100     } 
    101      
    102     in  += d_fft_size; 
    103     out += d_fft_size; 
    104   } 
    105    
    106   return noutput_items; 
    10752} 
    10853 
    10954bool  
    110 gr_fft_vcc::set_window(const std::vector<float> window) 
     55gr_fft_vcc::set_window(const std::vector<float> &window) 
    11156{ 
    11257  if(window.size()==0 || window.size()==d_fft_size) { 
     
    11762    return false; 
    11863} 
    119  
    120 /* 
    121 fftshift 
    122  
    123   for(i=0; i < ceil(d_occupied_carriers/2.0); i++) { 
    124     unsigned int k=ceil(d_occupied_carriers/2.0); 
    125     out[i] = gr_complex(-1+2*in[i+k],0); 
    126   } 
    127   for(; i < d_vlen - ceil(d_occupied_carriers/2.0); i++) { 
    128     out[i]=gr_complex(0,0); 
    129   } 
    130   for(unsigned int j=0;i<d_vlen;i++,j++) { 
    131     out[i]= gr_complex((-1+2*in[j]),0); 
    132   } 
    133 */ 
  • gnuradio/trunk/gnuradio-core/src/lib/general/gr_fft_vcc.h

    r7504 r8244  
    11/* -*- c++ -*- */ 
    22/* 
    3  * Copyright 2004,2007 Free Software Foundation, Inc. 
     3 * Copyright 2004,2007,2008 Free Software Foundation, Inc. 
    44 *  
    55 * This file is part of GNU Radio 
     
    2626#include <gr_sync_block.h> 
    2727 
    28 class gri_fft_complex; 
    29  
    3028class gr_fft_vcc; 
    3129typedef boost::shared_ptr<gr_fft_vcc> gr_fft_vcc_sptr; 
    3230 
    3331gr_fft_vcc_sptr 
    34 gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window, bool shift=false); 
     32gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); 
    3533 
    3634/*! 
    3735 * \brief Compute forward or reverse FFT.  complex vector in / complex vector out. 
    3836 * \ingroup dft 
     37 * 
     38 * Abstract base class 
    3939 */ 
    40  
    4140class gr_fft_vcc : public gr_sync_block 
    4241{ 
     42protected: 
    4343  friend gr_fft_vcc_sptr 
    44   gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window, bool shift); 
     44  gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift); 
    4545 
    46   unsigned int     d_fft_size; 
     46  unsigned int         d_fft_size; 
    4747  std::vector<float>   d_window; 
    48   gri_fft_complex *d_fft; 
    4948  bool d_forward; 
    5049  bool d_shift; 
    5150 
    52   gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window, bool shift); 
     51  gr_fft_vcc (const std::string &name, int fft_size, bool forward, 
     52              const std::vector<float> &window, bool shift); 
    5353 
    5454 public: 
    5555  ~gr_fft_vcc (); 
    5656 
    57   int work (int noutput_items, 
    58             gr_vector_const_void_star &input_items, 
    59             gr_vector_void_star &output_items); 
    60   bool set_window(const std::vector<float> window); 
     57  bool set_window(const std::vector<float> &window); 
    6158}; 
    6259 
    63  
    6460#endif /* INCLUDED_GR_FFT_VCC_H */ 
  • gnuradio/trunk/gnuradio-core/src/lib/general/gr_fft_vcc.i

    r6044 r8244  
    11/* -*- c++ -*- */ 
    22/* 
    3  * Copyright 2004,2007 Free Software Foundation, Inc. 
     3 * Copyright 2004,2007,2008 Free Software Foundation, Inc. 
    44 *  
    55 * This file is part of GNU Radio 
     
    2929{ 
    3030 protected: 
    31   gr_fft_vcc (int fft_size, bool forward, const std::vector<float> window, bool shift); 
     31  gr_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift); 
    3232 
    3333 public: 
    34   bool set_window(const std::vector<float> window); 
     34  bool set_window(const std::vector<float> &window); 
    3535}; 
  • gnuradio/trunk/gnuradio-core/src/lib/general/gr_math.h

    r7504 r8244  
    2929 
    3030#include <gr_complex.h> 
     31 
     32static inline bool 
     33gr_is_power_of_2(long x) 
     34{ 
     35  return x != 0 && (x & (x-1)) == 0; 
     36} 
    3137 
    3238long gr_gcd (long m, long n); 
  • gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am

    r8207 r8244  
    5959        qa_ecc_ccsds_27.py              \ 
    6060        qa_feval.py                     \ 
     61        qa_fft.py                       \ 
    6162        qa_fft_filter.py                \ 
    6263        qa_filter_delay_fc.py           \