Skip to content

File delay_core.h

FileList > delay > delay_core.h

Go to the source code of this file

Delay component API. More...

  • #include "clib_common.h"
  • #include "jm_perf.h"
  • #include "dp_state.h"

Classes

Type Name
struct delay_state_t
Delay state.

Public Functions

Type Name
delay_state_t * delay_create (size_t num_taps)
Create a dual-buffer circular delay line of length num_taps. The internal capacity is rounded up to the next power of two so that modular indexing reduces to a single bitwise AND. Any window of num_taps consecutive samples is always contiguous in the backing store; no wrap-around copy is ever needed.
void delay_destroy (delay_state_t * state)
Destroy a delay instance and release all memory. Frees the internal dual buffer and the state struct itself. Safe to call with a NULL pointer (no-op). After this call the pointer must not be used; the Python binding raises RuntimeError on any subsequent method call.
void delay_get_state (const delay_state_t * state, void * blob)
size_t delay_ptr (delay_state_t * state, size_t n, double complex * out)
Return a zero-copy view of the n most recent samples. Copies at most min(n, num_taps) samples starting from buf[head] into out. Because the dual-buffer layout guarantees contiguity, this is a single memcpy of up to num_taps elements; no wrap-around logic is needed. The Python binding returns a NumPy array backed directly by the pre-allocated output buffer (base object is the DelayCf64 itself).
size_t delay_ptr_max_out (delay_state_t * state)
Return the maximum output capacity for delay_ptr() . Returns num_taps; the Python binding uses this to pre-allocate the output buffer before callingdelay_ptr() .
void delay_push (delay_state_t * state, double complex x)
Advance the write pointer and insert a new sample. The head pointer decrements (mod capacity) before the write so that buf[head] always holds the most recent sample. The same value is simultaneously written atbuf[head + capacity] to keep the mirror half in sync; this ensures any num_taps-length window starting at head is contiguous without an extra copy.
size_t delay_push_ptr (delay_state_t * state, double complex x, double complex * out)
Atomically push a sample and snapshot the current window. Equivalent to calling delay_push() then delay_ptr(num_taps), but avoids the overhead of a second function call. Always writes exactly num_taps samples to out. The Python binding returns a NumPy array backed by the pre-allocated push_ptr output buffer.
size_t delay_push_ptr_max_out (delay_state_t * state)
Return the maximum output capacity for delay_push_ptr() . Returns num_taps; the Python binding uses this to pre-allocate the output buffer before callingdelay_push_ptr() .
void delay_reset (delay_state_t * state)
Reset the delay line to its post-create state. Zeroes the entire dual buffer and resets the write pointer to 0, discarding all previously pushed samples. The num_taps and capacity are preserved; only the sample history is cleared.
int delay_set_state (delay_state_t * state, const void * blob)
size_t delay_state_bytes (const delay_state_t * state)
void delay_write (delay_state_t * state, double complex x)
Alias for delay_push() ; insert a sample without reading back. Provided for API symmetry with write-then-read patterns where the caller wants to decouple sample ingestion from window inspection. Internally delegates todelay_push() with no additional overhead.

Macros

Type Name
define DELAY_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('D','L','A','Y')
define DELAY_STATE_VERSION 1u

Detailed Description

Lifecycle: create -> (step / steps / reset)* -> destroy

Example:

delay_state_t *obj = delay_create();
float complex y = delay_step(obj, 0.0f + 0.0f * I);
delay_destroy(obj);

Public Functions Documentation

function delay_create

Create a dual-buffer circular delay line of length num_taps. The internal capacity is rounded up to the next power of two so that modular indexing reduces to a single bitwise AND. Any window of num_taps consecutive samples is always contiguous in the backing store; no wrap-around copy is ever needed.

delay_state_t * delay_create (
    size_t num_taps
) 

Parameters:

  • num_taps Number of delay taps (window length, >= 1). Internally rounded up to the next power of two.

Returns:

Heap-allocated state, or NULL on allocation failure.

>>> from doppler.delay import DelayCf64
>>> d = DelayCf64(num_taps=3)
>>> d.num_taps
3
>>> d.capacity   # next power-of-two >= 3
4


function delay_destroy

Destroy a delay instance and release all memory. Frees the internal dual buffer and the state struct itself. Safe to call with a NULL pointer (no-op). After this call the pointer must not be used; the Python binding raises RuntimeError on any subsequent method call.

void delay_destroy (
    delay_state_t * state
) 

Parameters:

  • state Heap-allocated delay state, or NULL.
    >>> from doppler.delay import DelayCf64
    >>> d = DelayCf64(num_taps=2)
    >>> d.push(1+0j)
    >>> d.destroy()
    >>> try:
    ...     d.push(2+0j)
    ... except RuntimeError as e:
    ...     print(e)
    destroyed
    

function delay_get_state

void delay_get_state (
    const delay_state_t * state,
    void * blob
) 

function delay_ptr

Return a zero-copy view of the n most recent samples. Copies at most min(n, num_taps) samples starting from buf[head] into out. Because the dual-buffer layout guarantees contiguity, this is a single memcpy of up to num_taps elements; no wrap-around logic is needed. The Python binding returns a NumPy array backed directly by the pre-allocated output buffer (base object is the DelayCf64 itself).

size_t delay_ptr (
    delay_state_t * state,
    size_t n,
    double complex * out
) 

Parameters:

  • state Must be non-NULL.
  • n Number of samples to copy; clamped to num_taps.
  • out Output buffer; must hold at least min(n, num_taps) elements.

Returns:

Number of samples written.

>>> from doppler.delay import DelayCf64
>>> d = DelayCf64(num_taps=3)
>>> d.push(1+0j)
>>> d.push(2+0j)
>>> y = d.ptr()
>>> y.tolist()
[(2+0j), (1+0j), 0j]
>>> y.dtype
dtype('complex128')
>>> y.shape
(3,)


function delay_ptr_max_out

Return the maximum output capacity for delay_ptr() . Returns num_taps; the Python binding uses this to pre-allocate the output buffer before callingdelay_ptr() .

size_t delay_ptr_max_out (
    delay_state_t * state
) 

Parameters:

  • state Must be non-NULL.

Returns:

num_taps (maximum samples delay_ptr() can write).


function delay_push

Advance the write pointer and insert a new sample. The head pointer decrements (mod capacity) before the write so that buf[head] always holds the most recent sample. The same value is simultaneously written atbuf[head + capacity] to keep the mirror half in sync; this ensures any num_taps-length window starting at head is contiguous without an extra copy.

void delay_push (
    delay_state_t * state,
    double complex x
) 

Parameters:

  • state Must be non-NULL.
  • x New complex sample to insert.
    >>> from doppler.delay import DelayCf64
    >>> d = DelayCf64(num_taps=3)
    >>> d.push(1+2j)
    >>> d.push(3+4j)
    >>> d.ptr().tolist()
    [(3+4j), (1+2j), 0j]
    

function delay_push_ptr

Atomically push a sample and snapshot the current window. Equivalent to calling delay_push() then delay_ptr(num_taps), but avoids the overhead of a second function call. Always writes exactly num_taps samples to out. The Python binding returns a NumPy array backed by the pre-allocated push_ptr output buffer.

size_t delay_push_ptr (
    delay_state_t * state,
    double complex x,
    double complex * out
) 

Parameters:

  • state Must be non-NULL.
  • x New complex sample to insert.
  • out Output buffer; must hold at least num_taps elements.

Returns:

num_taps (always equal to the window length).

>>> from doppler.delay import DelayCf64
>>> d = DelayCf64(num_taps=3)
>>> d.push_ptr(1+0j).tolist()
[(1+0j), 0j, 0j]
>>> d.push_ptr(2+0j).tolist()
[(2+0j), (1+0j), 0j]


function delay_push_ptr_max_out

Return the maximum output capacity for delay_push_ptr() . Returns num_taps; the Python binding uses this to pre-allocate the output buffer before callingdelay_push_ptr() .

size_t delay_push_ptr_max_out (
    delay_state_t * state
) 

Parameters:

  • state Must be non-NULL.

Returns:

num_taps (number of samples delay_push_ptr() will write).


function delay_reset

Reset the delay line to its post-create state. Zeroes the entire dual buffer and resets the write pointer to 0, discarding all previously pushed samples. The num_taps and capacity are preserved; only the sample history is cleared.

void delay_reset (
    delay_state_t * state
) 

Parameters:

  • state Must be non-NULL.
    >>> from doppler.delay import DelayCf64
    >>> d = DelayCf64(num_taps=3)
    >>> d.push(1+2j)
    >>> d.push(3+4j)
    >>> d.ptr().tolist()
    [(3+4j), (1+2j), 0j]
    >>> d.reset()
    >>> d.ptr().tolist()
    [0j, 0j, 0j]
    

function delay_set_state

int delay_set_state (
    delay_state_t * state,
    const void * blob
) 

function delay_state_bytes

size_t delay_state_bytes (
    const delay_state_t * state
) 

function delay_write

Alias for delay_push() ; insert a sample without reading back. Provided for API symmetry with write-then-read patterns where the caller wants to decouple sample ingestion from window inspection. Internally delegates todelay_push() with no additional overhead.

void delay_write (
    delay_state_t * state,
    double complex x
) 

Parameters:

  • state Must be non-NULL.
  • x New complex sample to insert.
    >>> from doppler.delay import DelayCf64
    >>> d = DelayCf64(num_taps=2)
    >>> d.write(5+6j)
    >>> d.ptr().tolist()
    [(5+6j), 0j]
    

Macro Definition Documentation

define DELAY_STATE_MAGIC

#define DELAY_STATE_MAGIC `DP_FOURCC ('D','L','A','Y')`

define DELAY_STATE_VERSION

#define DELAY_STATE_VERSION `1u`


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