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 <vector> 00027 // #include <gr_sincos.h> 00028 #include <cmath> 00029 00030 using std::vector; 00031 00037 //FIXME Eventually generalize this to fixed point 00038 00039 template<class o_type, class i_type> 00040 class gr_nco { 00041 public: 00042 gr_nco () : phase (0), phase_inc(0) {} 00043 00044 virtual ~gr_nco () {} 00045 00046 // radians 00047 void set_phase (float angle) { 00048 phase = angle; 00049 } 00050 00051 void adjust_phase (float delta_phase) { 00052 phase += delta_phase; 00053 } 00054 00055 00056 // angle_rate is in radians / step 00057 void set_freq (float angle_rate){ 00058 phase_inc = angle_rate; 00059 } 00060 00061 // angle_rate is a delta in radians / step 00062 void adjust_freq (float delta_angle_rate) 00063 { 00064 phase_inc += delta_angle_rate; 00065 } 00066 00067 // increment current phase angle 00068 00069 void step () 00070 { 00071 phase += phase_inc; 00072 if (fabs (phase) > M_PI){ 00073 00074 while (phase > M_PI) 00075 phase -= 2*M_PI; 00076 00077 while (phase < -M_PI) 00078 phase += 2*M_PI; 00079 } 00080 } 00081 00082 void step (int n) { phase += phase_inc * n; } 00083 00084 // units are radians / step 00085 float get_phase () const { return phase; } 00086 float get_freq () const { return phase_inc; } 00087 00088 // compute cos and sin for current phase angle 00089 void cossin (float &i, float &q) const; 00090 00091 // compute cos or sin for current phase angle 00092 float cos () const { return std::cos (phase); } 00093 float sin () const { return std::sin (phase); } 00094 00095 protected: 00096 float phase; 00097 float phase_inc; 00098 }; 00099 00100 /* 00101 * FIXME: since this is a template, we can't include <config.h>. 00102 * This appears to preclude conditionalizing the availability of 00103 * __sincosf. If you know better, please fix this code. 00104 * Actually, I guess we could create out own function and have 00105 * it do the include (later...) 00106 */ 00107 00108 template<class o_type, class i_type> 00109 void 00110 gr_nco<o_type,i_type>::cossin (float &i, float &q) const 00111 { 00112 #if 0 00113 __sincosf (phase, &q, &i); 00114 #else 00115 i = std::cos (phase); 00116 q = std::sin (phase); 00117 #endif 00118 } 00119 00120 #endif /* _NCO_H_ */