00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2002 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 * Boston, MA 02111-1307, USA. 00021 */ 00022 #ifndef _GR_NCO_H_ 00023 #define _GR_NCO_H_ 00024 00025 00026 #include <VrComplex.h> 00027 #include <vector> 00028 // #include <gr_sincos.h> 00029 #include <cmath> 00030 00031 using std::vector; 00032 00038 //FIXME Eventually generalize this to fixed point 00039 00040 template<class o_type, class i_type> 00041 class gr_nco { 00042 public: 00043 gr_nco () : phase (0), phase_inc(0) {} 00044 00045 virtual ~gr_nco () {} 00046 00047 // radians 00048 void set_phase (float angle) { 00049 phase = angle; 00050 } 00051 00052 void adjust_phase (float delta_phase) { 00053 phase += delta_phase; 00054 } 00055 00056 00057 // angle_rate is in radians / step 00058 void set_freq (float angle_rate){ 00059 phase_inc = angle_rate; 00060 } 00061 00062 // angle_rate is a delta in radians / step 00063 void adjust_freq (float delta_angle_rate) 00064 { 00065 phase_inc += delta_angle_rate; 00066 } 00067 00068 // increment current phase angle 00069 00070 void step () 00071 { 00072 phase += phase_inc; 00073 if (fabs (phase) > M_PI){ 00074 00075 while (phase > M_PI) 00076 phase -= 2*M_PI; 00077 00078 while (phase < -M_PI) 00079 phase += 2*M_PI; 00080 } 00081 } 00082 00083 void step (int n) { phase += phase_inc * n; } 00084 00085 // units are radians / step 00086 float get_phase () const { return phase; } 00087 float get_freq () const { return phase_inc; } 00088 00089 // compute cos and sin for current phase angle 00090 void cossin (float &i, float &q) const; 00091 00092 // compute cos or sin for current phase angle 00093 float cos () const { return std::cos (phase); } 00094 float sin () const { return std::sin (phase); } 00095 00096 protected: 00097 float phase; 00098 float phase_inc; 00099 }; 00100 00101 /* 00102 * FIXME: since this is a template, we can't include <config.h>. 00103 * This appears to preclude conditionalizing the availability of 00104 * __sincosf. If you know better, please fix this code. 00105 * Actually, I guess we could create out own function and have 00106 * it do the include (later...) 00107 */ 00108 00109 template<class o_type, class i_type> 00110 void 00111 gr_nco<o_type,i_type>::cossin (float &i, float &q) const 00112 { 00113 #if 0 00114 __sincosf (phase, &q, &i); 00115 #else 00116 i = std::cos (phase); 00117 q = std::sin (phase); 00118 #endif 00119 } 00120 00121 #endif /* _NCO_H_ */