File pn_core.h¶
FileList > inc > pn > pn_core.h
Go to the source code of this file
PN component API. More...
#include "clib_common.h"#include "dp_state.h"#include "jm_perf.h"
Classes¶
| Type | Name |
|---|---|
| struct | pn_state_t |
Public Types¶
| Type | Name |
|---|---|
| enum | pn__core_8h_1abc6126af1d45847bc59afa0aa3216b04 PN state. |
Public Functions¶
| Type | Name |
|---|---|
| pn_state_t * | pn_create (uint64_t poly, uint64_t seed, uint32_t length, int lfsr) Allocate and initialise a maximal-length-sequence LFSR. The register is seeded from seed and will produce a pseudo-random binary sequence with period 2^length - 1 for any primitivepoly . Both Galois and Fibonacci realizations share the same primitive polynomial and therefore the same period; they differ only in chip ordering/phase. |
| void | pn_destroy (pn_state_t * state) Destroy a pn instance and release all memory. Idempotent when state is NULL; safe to call at any point in the lifecycle. After return the pointer is dangling — do not dereference it. |
| size_t | pn_generate (pn_state_t * state, size_t n, uint8_t * out, size_t max_out) Generate n chips intoout and advance the LFSR byn positions. Each element ofout is 0 or 1. Requesting more than one MLS period is valid — the sequence simply wraps around. The Python binding returns a zero-copy NumPy uint8 view over a pre-allocated buffer; copy the result before calling generate again if you need a snapshot. |
| size_t | pn_generate_max_out (pn_state_t * state) |
| void | pn_get_state (const pn_state_t * state, void * blob) Serialize the LFSR register into blob . |
| JM_FORCEINLINE uint64_t | pn_mls_poly (uint32_t n) Maximal-length-sequence (MLS) primitive polynomial for a register of length n , in this module's right-shift Galois convention. |
| void | pn_reset (pn_state_t * state) Reset PN to its post-create state. Reloads the LFSR register from the original seed so the sequence restarts from chip 0. Useful for reproducible captures without re-allocating. |
| int | pn_set_state (pn_state_t * state, const void * blob) Restore the register; DP_OK, or DP_ERR_INVALID if rejected. |
| size_t | pn_state_bytes (const pn_state_t * state) Serialized-state byte size. |
| JM_FORCEINLINE uint8_t | pn_step (pn_state_t * state) Advance the LFSR one step and return the output chip (0 or 1). Both realizations output the register LSB and then shift right. Galois XORs the tap polynomial on a 1 output bit (internal feedback); Fibonacci computes the parity of all tapped positions and inserts it at the top (external feedback). Same primitive polynomial, same period. Inlined so per-sample modulators (e.g. synth's bpsk/qpsk data source) can pull chips in a tight hot loop without call overhead. |
Macros¶
| Type | Name |
|---|---|
| define | PN_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc)('P', 'N', '\_', '\_') |
| define | PN_STATE_VERSION 1u |
Detailed Description¶
Lifecycle: create -> [step / steps / reset]* -> destroy
Example:
Public Types Documentation¶
enum pn__core_8h_1abc6126af1d45847bc59afa0aa3216b04¶
PN state.
Allocate with pn_create(). LFSR realization: Galois (internal XOR) or Fibonacci (external XOR).
Public Functions Documentation¶
function pn_create¶
Allocate and initialise a maximal-length-sequence LFSR. The register is seeded from seed and will produce a pseudo-random binary sequence with period 2^length - 1 for any primitivepoly . Both Galois and Fibonacci realizations share the same primitive polynomial and therefore the same period; they differ only in chip ordering/phase.
Parameters:
polyGalois feedback tap polynomial (right-shift convention). The LSB is the tap at position 0 (always 1 for a primitive poly); bit k=1 means tap at position k. Default 96 (0x60) is primitive for length=7, giving period 127. The Fibonacci taps are derived automatically so you only supply one value.seedInitial LFSR register state; must be non-zero (the all-zero state is a fixed point). Default 1.lengthRegister width in bits, 1..64. The sequence period is 2^length - 1 for a primitive polynomial. Default 7.lfsrRealization: PN_GALOIS (0, default) or PN_FIBONACCI (1).
Returns:
Heap-allocated state, or NULL on allocation failure.
Note:
Caller must call pn_destroy() when done.
>>> from doppler.wfm import PN
>>> import numpy as np
>>> p = PN(poly=96, seed=1, length=7)
>>> chips = p.generate(127)
>>> chips.dtype
dtype('uint8')
>>> int(chips.sum()) # 64 ones per MLS period (2^(n-1))
64
function pn_destroy¶
Destroy a pn instance and release all memory. Idempotent when state is NULL; safe to call at any point in the lifecycle. After return the pointer is dangling — do not dereference it.
Parameters:
statePointer to heap-allocated state; may be NULL (no-op).
function pn_generate¶
Generate n chips intoout and advance the LFSR byn positions. Each element ofout is 0 or 1. Requesting more than one MLS period is valid — the sequence simply wraps around. The Python binding returns a zero-copy NumPy uint8 view over a pre-allocated buffer; copy the result before calling generate again if you need a snapshot.
Parameters:
stateInitialised PN state returned bypn_create.nNumber of chips to produce.outOutput buffer of at leastnuint8 elements; each element receives 0 or 1.max_outCapacity ofoutin elements. Emission stops there, so the return value is the number actually written.
Returns:
min(n, max_out) chips.
>>> from doppler.wfm import PN
>>> import numpy as np
>>> p = PN(poly=96, seed=1, length=7)
>>> chips = p.generate(127)
>>> chips[:8].tolist()
[1, 0, 0, 0, 0, 0, 1, 1]
>>> int(chips.sum()) # 64 ones per MLS period
64
function pn_generate_max_out¶
function pn_get_state¶
Serialize the LFSR register into blob .
function pn_mls_poly¶
Maximal-length-sequence (MLS) primitive polynomial for a register of length n , in this module's right-shift Galois convention.
The table lives here because the convention is pn's: poly is pn_create()'s tap mask, and "which mask makes it maximal-length" is a fact about this LFSR, not about any caller. It is header-only so no component grows a link-line dependency for a lookup.
A zero poly is not a polynomial. pn_create() takes the mask verbatim, so poly = 0 is a register with no feedback: it shifts out the seed and then emits zeros forever. Every caller that lets a user say "default" therefore resolves it as poly ? poly : pn_mls_poly (n) wfm_synth's create does, and wfm_frame's PN sequence kind does. A caller that forgets gets a constant field that still looks like a field.
Returns 0 for lengths outside 2..64 (caller errors). Generated from verified primitive polynomials (period 2^n-1); the n=2..16 values are unchanged.
function pn_reset¶
Reset PN to its post-create state. Reloads the LFSR register from the original seed so the sequence restarts from chip 0. Useful for reproducible captures without re-allocating.
Parameters:
stateMust be non-NULL.
function pn_set_state¶
Restore the register; DP_OK, or DP_ERR_INVALID if rejected.
function pn_state_bytes¶
Serialized-state byte size.
function pn_step¶
Advance the LFSR one step and return the output chip (0 or 1). Both realizations output the register LSB and then shift right. Galois XORs the tap polynomial on a 1 output bit (internal feedback); Fibonacci computes the parity of all tapped positions and inserts it at the top (external feedback). Same primitive polynomial, same period. Inlined so per-sample modulators (e.g. synth's bpsk/qpsk data source) can pull chips in a tight hot loop without call overhead.
Parameters:
stateMust be non-NULL.
Returns:
Output chip: 0 or 1 (register LSB before the shift).
Macro Definition Documentation¶
define PN_STATE_MAGIC¶
define PN_STATE_VERSION¶
The documentation for this class was generated from the following file native/inc/pn/pn_core.h