class sdr.NCO

Implements a numerically-controlled oscillator (NCO).

Notes

Numerically-Controlled Oscillator Block Diagram
               constant          constant
              increment           offset   p[n]
                  |                 |        |
         +----+   v                 v        v  +--------+
 f[n] -->| K0 |-->@--------------+--@--------@--| e^(j.) |--> y[n]
         +----+   ^              |              +--------+
                  |   +------+   |
                  +---| z^-1 |---+
                      +------+

 f[n] = Input frequency signal (radians/sample)
 p[n] = Input phase signal (radians)
 y[n] = Output complex signal
 K0 = NCO gain
 increment = Constant phase accumulation (radians/sample)
 offset = Absolute phase offset (radians)
 z^-1 = Unit delay
 @ = Adder

Examples

Create an NCO with a constant phase increment of \(2 \pi / 20\) radians/sample and a constant phase offset of \(\pi\) radians.

In [1]: nco = sdr.NCO(increment=2 * np.pi / 20, offset=np.pi); \
   ...: y = nco.step(100)
   ...: 

In [2]: plt.figure(figsize=(8, 4)); \
   ...: sdr.plot.time_domain(y, marker="."); \
   ...: plt.title("Constant frequency NCO"); \
   ...: plt.tight_layout();
   ...: 
../../_images/sdr_NCO_1.png

Create an NCO with a constant phase increment of 0 radians/sample and a constant phase offset of 0 radians. Then step the NCO with a FSK frequency signal.

In [3]: nco = sdr.NCO(); \
   ...: freq = np.array([1, 2, -3, 0, 2, -1]) * 2 * np.pi / 60; \
   ...: freq = np.repeat(freq, 20); \
   ...: y = nco(freq=freq)
   ...: 

In [4]: plt.figure(figsize=(8, 4)); \
   ...: sdr.plot.time_domain(y, marker="."); \
   ...: plt.title("NCO implementing CP-FSK modulation"); \
   ...: plt.tight_layout();
   ...: 
../../_images/sdr_NCO_2.png

Create an NCO with a constant phase increment of \(2 \pi / 57\) radians/sample and a constant phase offset of 0 radians. Then step the NCO with a BPSK phase signal.

In [5]: nco = sdr.NCO(increment=2 * np.pi / 57); \
   ...: phase = np.array([0, 1, 0, 1, 0, 1]) * np.pi; \
   ...: phase = np.repeat(phase, 20); \
   ...: y = nco(phase=phase)
   ...: 

In [6]: plt.figure(figsize=(8, 4)); \
   ...: sdr.plot.time_domain(y, marker="."); \
   ...: plt.title("NCO implementing BPSK modulation"); \
   ...: plt.tight_layout();
   ...: 
../../_images/sdr_NCO_3.png

See the Phase-locked loops example.

Constructors

NCO(K0: float = 1.0, increment: float = 0.0, offset: float = 0.0)

Creates a numerically-controlled oscillator (NCO).

Special methods

__call__(...) NDArray[complex_]

Steps the NCO with variable frequency and/or phase signals.

Methods

reset()

Resets the NCO.

step(N: int) NDArray[complex_]

Steps the NCO forward by \(N\) samples.

Properties

property K0 : float

(Settable) The NCO gain \(K_0\).

property increment : float

(Settable) The constant phase accumulation \(\omega\) of the NCO in radians/sample.

property offset : float

(Settable) The absolute phase offset \(\theta\) of the NCO in radians.