GNU Radio Manual and C++ API Reference 3.8.5.0
The Free & Open Software Radio Ecosystem
 
Loading...
Searching...
No Matches
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 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
11 *
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#ifndef _GR_NCO_H_
24#define _GR_NCO_H_
25
26#include <gnuradio/gr_complex.h>
27#include <gnuradio/math.h>
28#include <gnuradio/sincos.h>
29
30#include <cmath>
31#include <vector>
32
33namespace gr {
34
35/*!
36 * \brief base class template for Numerically Controlled Oscillator (NCO)
37 * \ingroup misc
38 */
39template <class o_type, class i_type>
40class nco
41{
42public:
43 nco() : phase(0), phase_inc(0) {}
44
45 virtual ~nco() {}
46
47 // radians
48 void set_phase(double angle) { phase = angle; }
49
50 void adjust_phase(double delta_phase) { phase += delta_phase; }
51
52 // angle_rate is in radians / step
53 void set_freq(double angle_rate) { phase_inc = angle_rate; }
54
55 // angle_rate is a delta in radians / step
56 void adjust_freq(double delta_angle_rate) { phase_inc += delta_angle_rate; }
57
58 // increment current phase angle
59 void step()
60 {
62 if (fabs(phase) > GR_M_PI) {
63 while (phase > GR_M_PI)
64 phase -= 2 * GR_M_PI;
65
66 while (phase < -GR_M_PI)
67 phase += 2 * GR_M_PI;
68 }
69 }
70
71 void step(int n)
72 {
73 phase += phase_inc * n;
74 if (fabs(phase) > GR_M_PI) {
75 while (phase > GR_M_PI)
76 phase -= 2 * GR_M_PI;
77
78 while (phase < -GR_M_PI)
79 phase += 2 * GR_M_PI;
80 }
81 }
82
83 // units are radians / step
84 double get_phase() const { return phase; }
85 double get_freq() const { return phase_inc; }
86
87 // compute sin and cos for current phase angle
88 void sincos(float* sinx, float* cosx) const;
89
90 // compute cos or sin for current phase angle
91 float cos() const { return std::cos(phase); }
92 float sin() const { return std::sin(phase); }
93
94 // compute a block at a time
95 void sin(float* output, int noutput_items, double ampl = 1.0);
96 void cos(float* output, int noutput_items, double ampl = 1.0);
97 void sincos(gr_complex* output, int noutput_items, double ampl = 1.0);
98 void sin(short* output, int noutput_items, double ampl = 1.0);
99 void cos(short* output, int noutput_items, double ampl = 1.0);
100 void sin(int* output, int noutput_items, double ampl = 1.0);
101 void cos(int* output, int noutput_items, double ampl = 1.0);
102
103protected:
104 double phase;
105 double phase_inc;
106};
107
108template <class o_type, class i_type>
109void nco<o_type, i_type>::sincos(float* sinx, float* cosx) const
110{
111 gr::sincosf(phase, sinx, cosx);
112}
113
114template <class o_type, class i_type>
115void nco<o_type, i_type>::sin(float* output, int noutput_items, double ampl)
116{
117 for (int i = 0; i < noutput_items; i++) {
118 output[i] = (float)(sin() * ampl);
119 step();
120 }
121}
122
123template <class o_type, class i_type>
124void nco<o_type, i_type>::cos(float* output, int noutput_items, double ampl)
125{
126 for (int i = 0; i < noutput_items; i++) {
127 output[i] = (float)(cos() * ampl);
128 step();
129 }
130}
131
132template <class o_type, class i_type>
133void nco<o_type, i_type>::sin(short* output, int noutput_items, double ampl)
134{
135 for (int i = 0; i < noutput_items; i++) {
136 output[i] = (short)(sin() * ampl);
137 step();
138 }
139}
140
141template <class o_type, class i_type>
142void nco<o_type, i_type>::cos(short* output, int noutput_items, double ampl)
143{
144 for (int i = 0; i < noutput_items; i++) {
145 output[i] = (short)(cos() * ampl);
146 step();
147 }
148}
149
150template <class o_type, class i_type>
151void nco<o_type, i_type>::sin(int* output, int noutput_items, double ampl)
152{
153 for (int i = 0; i < noutput_items; i++) {
154 output[i] = (int)(sin() * ampl);
155 step();
156 }
157}
158
159template <class o_type, class i_type>
160void nco<o_type, i_type>::cos(int* output, int noutput_items, double ampl)
161{
162 for (int i = 0; i < noutput_items; i++) {
163 output[i] = (int)(cos() * ampl);
164 step();
165 }
166}
167
168template <class o_type, class i_type>
169void nco<o_type, i_type>::sincos(gr_complex* output, int noutput_items, double ampl)
170{
171 for (int i = 0; i < noutput_items; i++) {
172 float cosx, sinx;
173 nco::sincos(&sinx, &cosx);
174 output[i] = gr_complex(cosx * ampl, sinx * ampl);
175 step();
176 }
177}
178
179} /* namespace gr */
180
181#endif /* _NCO_H_ */
base class template for Numerically Controlled Oscillator (NCO)
Definition nco.h:41
double phase_inc
Definition nco.h:105
void sincos(float *sinx, float *cosx) const
Definition nco.h:109
float sin() const
Definition nco.h:92
void set_freq(double angle_rate)
Definition nco.h:53
void adjust_phase(double delta_phase)
Definition nco.h:50
virtual ~nco()
Definition nco.h:45
double phase
Definition nco.h:104
void adjust_freq(double delta_angle_rate)
Definition nco.h:56
void set_phase(double angle)
Definition nco.h:48
float cos() const
Definition nco.h:91
double get_phase() const
Definition nco.h:84
void step()
Definition nco.h:59
double get_freq() const
Definition nco.h:85
nco()
Definition nco.h:43
void step(int n)
Definition nco.h:71
std::complex< float > gr_complex
Definition gr_complex.h:27
#define GR_M_PI
Definition math.h:44
GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
Definition basic_block.h:46
GR_RUNTIME_API void sincosf(float x, float *sin, float *cos)