GNU Radio C++ API Reference  gcd20ee2
The Free & Open Software Radio Ecosystem
nco.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002,2013,2018 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * SPDX-License-Identifier: GPL-3.0-or-later
8  *
9  */
10 
11 #ifndef _GR_NCO_H_
12 #define _GR_NCO_H_
13 
14 #include <gnuradio/gr_complex.h>
15 #include <gnuradio/math.h>
16 #include <gnuradio/sincos.h>
17 
18 #include <cmath>
19 
20 namespace gr {
21 
22 /*!
23  * \brief base class template for Numerically Controlled Oscillator (NCO)
24  * \ingroup misc
25  */
26 template <class o_type, class i_type>
27 class nco
28 {
29 public:
30  nco() : phase(0), phase_inc(0) {}
31 
32  virtual ~nco() {}
33 
34  // radians
35  void set_phase(double angle) { phase = angle; }
36 
37  void adjust_phase(double delta_phase) { phase += delta_phase; }
38 
39  // angle_rate is in radians / step
40  void set_freq(double angle_rate) { phase_inc = angle_rate; }
41 
42  // angle_rate is a delta in radians / step
43  void adjust_freq(double delta_angle_rate) { phase_inc += delta_angle_rate; }
44 
45  // increment current phase angle
46  void step(int n = 1)
47  {
48  phase += phase_inc * n;
49  if (fabs(phase) > GR_M_PI) {
50  while (phase > GR_M_PI)
51  phase -= 2 * GR_M_PI;
52 
53  while (phase < -GR_M_PI)
54  phase += 2 * GR_M_PI;
55  }
56  }
57 
58  // units are radians / step
59  double get_phase() const { return phase; }
60  double get_freq() const { return phase_inc; }
61 
62  // compute sin and cos for current phase angle
63  void sincos(float* sinx, float* cosx) const { gr::sincosf(phase, sinx, cosx); }
64 
65  // compute cos or sin for current phase angle
66  float cos() const { return std::cos(phase); }
67  float sin() const { return std::sin(phase); }
68 
69  // compute a block at a time
70  void sin(float* output, int noutput_items, double ampl = 1.0);
71  void cos(float* output, int noutput_items, double ampl = 1.0);
72  void sincos(gr_complex* output, int noutput_items, double ampl = 1.0);
73  void sin(short* output, int noutput_items, double ampl = 1.0);
74  void cos(short* output, int noutput_items, double ampl = 1.0);
75  void sin(int* output, int noutput_items, double ampl = 1.0);
76  void cos(int* output, int noutput_items, double ampl = 1.0);
77 
78 protected:
79  double phase;
80  double phase_inc;
81 };
82 
83 template <class o_type, class i_type>
84 void nco<o_type, i_type>::sin(float* output, int noutput_items, double ampl)
85 {
86  for (int i = 0; i < noutput_items; i++) {
87  output[i] = (float)(sin() * ampl);
88  step();
89  }
90 }
91 
92 template <class o_type, class i_type>
93 void nco<o_type, i_type>::cos(float* output, int noutput_items, double ampl)
94 {
95  for (int i = 0; i < noutput_items; i++) {
96  output[i] = (float)(cos() * ampl);
97  step();
98  }
99 }
100 
101 template <class o_type, class i_type>
102 void nco<o_type, i_type>::sin(short* output, int noutput_items, double ampl)
103 {
104  for (int i = 0; i < noutput_items; i++) {
105  output[i] = (short)(sin() * ampl);
106  step();
107  }
108 }
109 
110 template <class o_type, class i_type>
111 void nco<o_type, i_type>::cos(short* output, int noutput_items, double ampl)
112 {
113  for (int i = 0; i < noutput_items; i++) {
114  output[i] = (short)(cos() * ampl);
115  step();
116  }
117 }
118 
119 template <class o_type, class i_type>
120 void nco<o_type, i_type>::sin(int* output, int noutput_items, double ampl)
121 {
122  for (int i = 0; i < noutput_items; i++) {
123  output[i] = (int)(sin() * ampl);
124  step();
125  }
126 }
127 
128 template <class o_type, class i_type>
129 void nco<o_type, i_type>::cos(int* output, int noutput_items, double ampl)
130 {
131  for (int i = 0; i < noutput_items; i++) {
132  output[i] = (int)(cos() * ampl);
133  step();
134  }
135 }
136 
137 template <class o_type, class i_type>
138 void nco<o_type, i_type>::sincos(gr_complex* output, int noutput_items, double ampl)
139 {
140  for (int i = 0; i < noutput_items; i++) {
141  float cosx, sinx;
142  nco::sincos(&sinx, &cosx);
143  output[i] = gr_complex(cosx * ampl, sinx * ampl);
144  step();
145  }
146 }
147 
148 } /* namespace gr */
149 
150 #endif /* _NCO_H_ */
base class template for Numerically Controlled Oscillator (NCO)
Definition: nco.h:28
double phase_inc
Definition: nco.h:80
void sincos(float *sinx, float *cosx) const
Definition: nco.h:63
float sin() const
Definition: nco.h:67
void set_freq(double angle_rate)
Definition: nco.h:40
void adjust_phase(double delta_phase)
Definition: nco.h:37
virtual ~nco()
Definition: nco.h:32
double phase
Definition: nco.h:79
void adjust_freq(double delta_angle_rate)
Definition: nco.h:43
void step(int n=1)
Definition: nco.h:46
void set_phase(double angle)
Definition: nco.h:35
float cos() const
Definition: nco.h:66
double get_phase() const
Definition: nco.h:59
double get_freq() const
Definition: nco.h:60
nco()
Definition: nco.h:30
std::complex< float > gr_complex
Definition: gr_complex.h:15
#define GR_M_PI
Definition: math.h:32
GNU Radio logging wrapper.
Definition: basic_block.h:29
void sincosf(float x, float *sinx, float *cosx)
Definition: sincos.h:49