File wfm_sink.h¶
File List > inc > wfm > wfm_sink.h
Go to the documentation of this file
#ifndef WFM_SINK_H
#define WFM_SINK_H
#include "clib_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* The real ZMQ sink lives in the optional `libdoppler_stream` component (it
* pulls in the vendored C++ libzmq). The pure-C core embeds wfmgen, which
* references these symbols on the `--output zmq://` path. So that the core
* stays self-contained and links *everywhere* with no special linker flags
* (ELF allows undefined symbols in a .so; Mach-O's ld64 does not, neither in a
* dylib nor in a downstream's executable that statically links libdoppler.a),
* the core ships **weak no-op definitions** of every wfm_zmq_sink_* symbol (see
* wfm_sink_stub.c). Linking `libdoppler_stream` supplies the STRONG real
* definitions, which override the weak stubs. wfmgen gates the path with
* `wfm_zmq_sink_available()` (0 from the stub, 1 from the real component).
*
* NB: when linking the *static* stream archive, pull it whole
* (`-Wl,--whole-archive` / `-Wl,-force_load`) or prefer the shared
* libdoppler_stream — otherwise the linker keeps the core's weak stubs. */
typedef struct wfm_zmq_sink wfm_zmq_sink_t;
int wfm_zmq_sink_available(void);
wfm_zmq_sink_t *wfm_zmq_sink_open(const char *endpoint, int sample_type);
int wfm_zmq_sink_send(wfm_zmq_sink_t *sink, const float _Complex *iq, size_t n,
double fs, double fc);
void wfm_zmq_sink_close(wfm_zmq_sink_t *sink);
/* Clip detection, mirroring wfm_writer (peak always tracked on the integer
* paths, where saturation can occur; the per-component fraction is opt-in). The
* cf32 path is left untouched — it never clips and is the streaming hot path. */
void wfm_zmq_sink_track_clipping(wfm_zmq_sink_t *sink, int on);
void wfm_zmq_sink_set_gain(wfm_zmq_sink_t *sink, double gain);
double wfm_zmq_sink_peak(const wfm_zmq_sink_t *sink);
double wfm_zmq_sink_clip_fraction(const wfm_zmq_sink_t *sink);
#ifdef __cplusplus
}
#endif
#endif /* WFM_SINK_H */