Skip to content

File RateConverter_core.h

FileList > inc > RateConverter > RateConverter_core.h

Go to the source code of this file

Optimal-speed rate conversion cascade. More...

  • #include "clib_common.h"
  • #include "dp_state.h"
  • #include <complex.h>
  • #include <stddef.h>
  • #include "resamp/resamp_core.h"
  • #include "fir/fir_core.h"

Classes

Type Name
struct RateConverter_state_t
Cascade state owns all sub-stage C objects.

Public Types

Type Name
enum rc_stage_t

Public Functions

Type Name
size_t RateConverter_convert (double rate, int compensate, const float _Complex * in, size_t n_in, float _Complex * out, size_t max_out)
One-shot rate conversion — no persistent state required.
RateConverter_state_t * RateConverter_create (double rate, int compensate)
Create a rate converter for the given output/input rate ratio. Selects the cheapest cascade of CIC, HalfbandDecimator, and/or polyphase Resampler stages at construction time (see file header for the selection table). Setting compensate=1 appends a closed-form Molnar-Vucic CIC droop-compensating FIR after any CIC stage, which improves passband flatness at the cost of one extra FIR stage.
void RateConverter_destroy (RateConverter_state_t * s)
Free all resources. NULL is a no-op.
size_t RateConverter_execute (RateConverter_state_t * s, const float _Complex * in, size_t n_in, float _Complex * out, size_t max_out)
Convert a block of CF32 samples through the cascade. Passes input through each stage in order, ping-ponging between two intermediate buffers. State persists between calls, so contiguous calls on sequential blocks give the same result as one large call. Output length is approximately n_in * rate.
size_t RateConverter_execute_max_out (RateConverter_state_t * s)
Upper bound on execute output for a standard 65536-sample block.
double RateConverter_get_rate (const RateConverter_state_t * s)
Get / set the output-to-input sample rate ratio. The setter rebuilds the entire cascade (new stage selection, new sub-objects) and resets all filter memories — equivalent to destroying and recreating with the new rate. Setting rate <= 0 is silently ignored.
void RateConverter_get_state (const RateConverter_state_t * s, void * blob)
Serialize s's active-stage state intoblob .
void RateConverter_reset (RateConverter_state_t * s)
Zero all sub-stage filter memories. Rate, stage count, and stage types are preserved. Processing from a reset state produces the same output as a freshly created converter fed the same input. Use between signal bursts to suppress transient artefacts from prior filter memory.
void RateConverter_set_rate (RateConverter_state_t * s, double rate)
Change the rate; rebuilds the cascade and resets all filter state. Silently ignores rate <= 0.
int RateConverter_set_state (RateConverter_state_t * s, const void * blob)
Restore active-stage state from blob (same rate).
int RateConverter_stage_label (RateConverter_state_t * s, int i, char * buf, size_t len)
Write a human-readable label for stage i into buf.
size_t RateConverter_state_bytes (const RateConverter_state_t * s)
Bytes RateConverter_get_state() writes fors (envelope + stages).

Macros

Type Name
define RC_MAX_STAGES 3
define RC_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('R', 'C', 'V', 'T')
define RC_STATE_VERSION 1u

Detailed Description

Selects the cheapest cascade of CIC, HalfbandDecimator, and/or polyphase Resampler stages for a given output/input sample rate ratio at creation time. All sub-stage C objects are owned by the state struct.

Stage selection (D = 1/rate):

rate >= 1.0 or D < 2 [Resampler(rate)] D ~= 2^1 [HalfbandDecimator] D ~= 2^2 [HalfbandDecimator, HalfbandDecimator] D ~= 2^n, n>=3, D<=4096 [CIC(D)] D >= 8, non-power-of-2 [CIC(R*), Resampler correction] R* = nearest power-of-2 to D otherwise (2 <= D < 8, non-int) [Resampler(rate)]

Lifecycle:

RateConverter_state_t *rc = RateConverter_create(0.1, 0);
// rc->n_stages == 2: CIC(8) then Resampler(0.8)
float _Complex out[512];
size_t n = RateConverter_execute(rc, in, 4096, out, 512);
RateConverter_destroy(rc);

Public Types Documentation

enum rc_stage_t

enum rc_stage_t {
    RC_STAGE_HB = 0,
    RC_STAGE_CIC = 1,
    RC_STAGE_RESAMP = 2
};

Stage type tags.


Public Functions Documentation

function RateConverter_convert

One-shot rate conversion — no persistent state required.

size_t RateConverter_convert (
    double rate,
    int compensate,
    const float _Complex * in,
    size_t n_in,
    float _Complex * out,
    size_t max_out
) 

Creates a temporary converter, converts n_in samples, destroys it. Equivalent to:

RateConverter_state_t *rc = RateConverter_create(rate, compensate);
size_t n = RateConverter_execute(rc, in, n_in, out, max_out);
RateConverter_destroy(rc);

Use RateConverter_create() directly when processing multiple blocks at the same rate — the one-shot form resets filter memory on every call.

Parameters:

  • rate Output-to-input sample rate ratio.
  • compensate Non-zero to enable CIC droop compensation.
  • in CF32 input samples.
  • n_in Number of input samples.
  • out Output buffer.
  • max_out Output buffer capacity in samples.

Returns:

Number of output samples written; 0 only if OOM or n_in == 0.


function RateConverter_create

Create a rate converter for the given output/input rate ratio. Selects the cheapest cascade of CIC, HalfbandDecimator, and/or polyphase Resampler stages at construction time (see file header for the selection table). Setting compensate=1 appends a closed-form Molnar-Vucic CIC droop-compensating FIR after any CIC stage, which improves passband flatness at the cost of one extra FIR stage.

RateConverter_state_t * RateConverter_create (
    double rate,
    int compensate
) 

Parameters:

  • rate Output-to-input sample rate ratio. Any positive float.
  • compensate Non-zero to append a CIC passband-droop compensating FIR after any CIC stage.

Returns:

Non-NULL on success; NULL if rate <= 0 or OOM.

>>> from doppler.resample import RateConverter
>>> rc = RateConverter(rate=0.5, compensate=0)
>>> rc.rate
0.5

function RateConverter_destroy

Free all resources. NULL is a no-op.

void RateConverter_destroy (
    RateConverter_state_t * s
) 


function RateConverter_execute

Convert a block of CF32 samples through the cascade. Passes input through each stage in order, ping-ponging between two intermediate buffers. State persists between calls, so contiguous calls on sequential blocks give the same result as one large call. Output length is approximately n_in * rate.

size_t RateConverter_execute (
    RateConverter_state_t * s,
    const float _Complex * in,
    size_t n_in,
    float _Complex * out,
    size_t max_out
) 

Parameters:

  • s Pointer to a valid RateConverter_state_t.
  • in CF32 input block.
  • n_in Number of input samples.
  • out Output buffer; must hold at least max_out samples.
  • max_out Capacity of out in samples.

Returns:

CF32 output array; length is approximately n_in * rate.

>>> from doppler.resample import RateConverter
>>> import numpy as np
>>> rc = RateConverter(rate=0.5, compensate=0)
>>> y = rc.execute(np.zeros(1024, dtype=np.complex64))
>>> y.shape, y.dtype
((512,), dtype('complex64'))

function RateConverter_execute_max_out

Upper bound on execute output for a standard 65536-sample block.

size_t RateConverter_execute_max_out (
    RateConverter_state_t * s
) 

Returns (size_t)(65536 * max(rate, 1.0)) + 2. The Python extension uses this to pre-allocate the output buffer on the first execute call.


function RateConverter_get_rate

Get / set the output-to-input sample rate ratio. The setter rebuilds the entire cascade (new stage selection, new sub-objects) and resets all filter memories — equivalent to destroying and recreating with the new rate. Setting rate <= 0 is silently ignored.

double RateConverter_get_rate (
    const RateConverter_state_t * s
) 

>>> from doppler.resample import RateConverter
>>> rc = RateConverter(rate=0.5, compensate=0)
>>> rc.rate
0.5
>>> rc.rate = 2.0
>>> rc.rate
2.0

function RateConverter_get_state

Serialize s's active-stage state intoblob .

void RateConverter_get_state (
    const RateConverter_state_t * s,
    void * blob
) 


function RateConverter_reset

Zero all sub-stage filter memories. Rate, stage count, and stage types are preserved. Processing from a reset state produces the same output as a freshly created converter fed the same input. Use between signal bursts to suppress transient artefacts from prior filter memory.

void RateConverter_reset (
    RateConverter_state_t * s
) 

>>> from doppler.resample import RateConverter
>>> rc = RateConverter(rate=0.5, compensate=0)
>>> rc.reset()
>>> rc.rate
0.5

function RateConverter_set_rate

Change the rate; rebuilds the cascade and resets all filter state. Silently ignores rate <= 0.

void RateConverter_set_rate (
    RateConverter_state_t * s,
    double rate
) 

Parameters:


function RateConverter_set_state

Restore active-stage state from blob (same rate).

int RateConverter_set_state (
    RateConverter_state_t * s,
    const void * blob
) 

Returns:

DP_OK, or DP_ERR_INVALID if the blob's envelope rejects.


function RateConverter_stage_label

Write a human-readable label for stage i into buf.

int RateConverter_stage_label (
    RateConverter_state_t * s,
    int i,
    char * buf,
    size_t len
) 

Examples: "HalfbandDecimator", "CIC(8)", "CIC(8)+FIR", "Resampler(0.8)".

Parameters:

  • s Must be non-NULL.
  • i Stage index in [0, s->n_stages).
  • buf Output buffer.
  • len Capacity of buf in bytes.

Returns:

1 on success, 0 if i is out of range.


function RateConverter_state_bytes

Bytes RateConverter_get_state() writes fors (envelope + stages).

size_t RateConverter_state_bytes (
    const RateConverter_state_t * s
) 


Macro Definition Documentation

define RC_MAX_STAGES

#define RC_MAX_STAGES `3`

Maximum number of visible cascade stages.


define RC_STATE_MAGIC

#define RC_STATE_MAGIC `DP_FOURCC ('R', 'C', 'V', 'T')`

define RC_STATE_VERSION

#define RC_STATE_VERSION `1u`


The documentation for this class was generated from the following file native/inc/RateConverter/RateConverter_core.h