Skip to content

Commit

Permalink
nco: improvement of NCO object with VCO precision
Browse files Browse the repository at this point in the history
Restoring promised precision of object created with type==LIQUID_VCO.
API and performance characteristics changed.
Introducing two VCO implementations (selected by object type at runtime):
- LIQUID_VCO_INTERP, which is fully compatible with LIQUID_NCO type API and
aliased to LIQUID_VCO type for backward compatibility;
- LIQUID_VCO_DIRECT, which frequency (phase) can be setup with nco_set_vcodirect_frequency() only,
and methods nco_<set/adjust/get>_<frequency/phase>(), nco_pll_step() are unavailable for it.
Additional improvements and refactoring:
- get rid of 'float' type/literals specifics (where appropriate);
- sine/cosine lookup table calculation optimized to use T type operations only (where appropriate);
- hard-coded NCO sine table size numbers macrofied and used with both LIQUID_NCO and LIQUID_VCO_INTERP types;
- cosmetic tweaks of comments and documentation.

Fixes #179
  • Loading branch information
ArtemPisarenko authored and jgaeddert committed May 21, 2024
1 parent 2496c79 commit 8f4ca0b
Show file tree
Hide file tree
Showing 3 changed files with 433 additions and 58 deletions.
32 changes: 28 additions & 4 deletions include/liquid.h
Original file line number Diff line number Diff line change
Expand Up @@ -9073,11 +9073,19 @@ int ofdmframesync_debug_print(ofdmframesync _q, const char * _filename);
//

// oscillator type
// LIQUID_NCO : numerically-controlled oscillator (fast)
// LIQUID_VCO : "voltage"-controlled oscillator (precise)
typedef enum {
// numerically-controlled oscillator (fastest in all aspects)
LIQUID_NCO=0,
LIQUID_VCO

// "voltage"-controlled oscillator (precise)
LIQUID_VCO,
LIQUID_VCO_INTERP=LIQUID_VCO,

// fast at computing output but having separate limited API,
// and each time frequency being set it does dynamic (re-)allocating and
// calculating of lookup table with resulting memory size and speed slowdown
// proportional to divider coefficient value)
LIQUID_VCO_DIRECT
} liquid_ncotype;

#define LIQUID_NCO_MANGLE_FLOAT(name) LIQUID_CONCAT(nco_crcf, name)
Expand All @@ -9092,7 +9100,7 @@ typedef enum {
typedef struct NCO(_s) * NCO(); \
\
/* Create nco object with either fixed-point or floating-point phase */ \
/* _type : oscillator type, _type in {LIQUID_NCO, LIQUID_VCO} */ \
/* _type : oscillator type */ \
NCO() NCO(_create)(liquid_ncotype _type); \
\
/* Copy object including all internal objects and state */ \
Expand Down Expand Up @@ -9138,6 +9146,22 @@ int NCO(_set_phase)(NCO() _q, \
int NCO(_adjust_phase)(NCO() _q, \
T _dphi); \
\
/* Get frequency of nco object as fraction of sample rate (n/m) */ \
/* _q : nco object */ \
/* _n : pointer to output multiplier coefficient (normalized) */ \
/* _m : pointer to output divider coefficient (normalized) */ \
void NCO(_get_vcodirect_frequency)(NCO() _q, \
int* _n, \
unsigned int* _m); \
\
/* Set frequency of nco object as fraction of sample rate (n/m) */ \
/* _q : nco object */ \
/* _n : input multiplier coefficient */ \
/* _m : input divider coefficient */ \
void NCO(_set_vcodirect_frequency)(NCO() _q, \
int _n, \
unsigned int _m); \
\
/* Increment phase by internal phase step (frequency) */ \
int NCO(_step)(NCO() _q); \
\
Expand Down
Loading

0 comments on commit 8f4ca0b

Please sign in to comment.