23#include <bsd/string.h>
30#define VERSION() { fprintf(stderr,"KA9Q Multichannel SDR %s last modified %s\n",__FILE__,__TIMESTAMP__); \
31 fprintf(stderr,"Copyright 2026, Phil Karn, KA9Q. May be used under the terms of the GNU Public License\n"); \
32 fprintf(stderr," Repo: %s\n",GIT_REMOTE_URL); \
33 fprintf(stderr," Commit: %s\n",GIT_HASH); \
34 fprintf(stderr," Date: %s\n",GIT_TIME); \
35 fprintf(stderr," Branch:%s\n",GIT_BRANCH); \
36 fprintf(stderr,"Version: %s\n",GIT_VERSION); \
37 fprintf(stderr,"Summary: %s\n",GIT_SUMMARY); \
40#define VERSION() { fprintf(stderr,"KA9Q Multichannel SDR %s last modified %s\n",__FILE__,__TIMESTAMP__); \
41 fprintf(stderr,"Copyright 2026, Phil Karn, KA9Q. May be used under the terms of the GNU Public License\n"); \
42 fprintf(stderr," Repo: %s\n",GIT_REMOTE_URL); \
43 fprintf(stderr," Commit: %s\n",GIT_HASH); \
46#define ASSERT_ZEROED(ptr, size) assert(memcmp(ptr, &(typeof(*(ptr))){0}, size) == 0)
50 int rc = pthread_mutex_trylock(mutex);
52 pthread_mutex_unlock(mutex);
59 #if defined(__ARM_FP16_FORMAT_IEEE)
60 typedef __fp16 float16_t;
62 typedef float float16_t;
64 #define HAS_FLOAT16 = 1
66 #if defined(__FLT16_MAX__)
67 typedef _Float16 float16_t;
68 #define HAS_FLOAT16 = 1
72#define DEGPRA (180./M_PI)
73#define RAPDEG (M_PI/180.)
74#define TAI_GPS_OFFSET (19)
75#define GPS_UTC_OFFSET (18)
76#define TAI_UTC_OFFSET (TAI_GPS_OFFSET+GPS_UTC_OFFSET)
77#define UNIX_EPOCH ((time_t)315964800)
79#define BOLTZMANN (1.380649e-23)
81static float const SCALE16 = 1.f/INT16_MAX;
83static float const SCALE8 = 1.f/INT8_MAX;
86#define FULL_SAMPRATE (48000)
102typedef int pthread_barrierattr_t;
105 pthread_mutex_t mutex;
110int pthread_barrier_init(pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr,
unsigned int count);
111int pthread_barrier_destroy(pthread_barrier_t *barrier);
112int pthread_barrier_wait(pthread_barrier_t *barrier);
118#define pthread_setname(x) pthread_setname_np(x)
119#include <malloc/malloc.h>
120#define malloc_usable_size(x) malloc_size(x)
121#define sincos(x,s,c) __sincos((x),(s),(c))
122#define sincosf(x,s,c) __sincosf((x),(s),(c))
128#define pthread_setname(x) pthread_setname_np(pthread_self(),(x))
134 pthread_mutexattr_t attr;
135 pthread_mutexattr_init(&attr);
136 pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
137 return pthread_mutex_init(m,&attr);
143 typeof(x) _x = (x); \
144 typeof(y) _y = (y); \
145 (void) (&_x == &_y); \
146 _x < _y ? _x : _y; })
149 typeof(x) _x = (x); \
150 typeof(y) _y = (y); \
151 (void) (&_x == &_y); \
152 _x > _y ? _x : _y; })
158 return pow(10.0,x/10.0);
163 return 10.0 * log10(x);
166 return pow(10.0,x/20.0);
171 return 20.0 * log10(x);
185#define cisf(x) csincosf(x)
186#define cispif(x) csincospif(x)
187#define cis(x) csincos(x)
188#define cispi(x) csincospi(x)
191static inline double sinc(
double x){
194 return sin(M_PI * x) / (M_PI * x);
200extern char const *
Months[12];
203int dist_path(
char *path,
int path_len,
const char *fname);
208char *
ftime(
char *result,
int size,int64_t t);
210double parse_frequency(
char const *,
bool);
215uint32_t
ElfHash(uint8_t
const *s,
size_t length);
220double i0(
double const z);
221double i1(
double const z);
223double xi(
double thetasq);
228 return (x >= 1.0) ? INT16_MAX : (x <= -1.0) ? -INT16_MAX : (int16_t)(INT16_MAX * x);
230static inline float complex
csincosf(
float const x){
242static inline double complex
csincos(
double const x){
254static inline float cnrmf(
float complex
const x){
255 return crealf(x)*crealf(x) + cimagf(x) * cimagf(x);
257static inline double cnrm(
double complex
const x){
258 return creal(x)*creal(x) + cimag(x) * cimag(x);
263 static double const Alpha = 0.947543636291;
264 static double const Beta = 0.392485425092;
266 double absr = fabs(__real__ x);
267 double absi = fabs(__imag__ x);
269 return Alpha *
max(absr,absi) + Beta *
min(absr,absi);
273static inline void time_sub(
struct timespec *result,
struct timespec
const *a,
struct timespec
const *b){
274 result->tv_sec = a->tv_sec - b->tv_sec;
275 result->tv_nsec = a->tv_nsec - b->tv_nsec;
279static inline void time_add(
struct timespec *result,
struct timespec
const *a,
struct timespec
const *b){
280 result->tv_sec = a->tv_sec + b->tv_sec;
281 result->tv_nsec = a->tv_nsec + b->tv_nsec;
289static inline int time_cmp(
struct timespec
const *a,
struct timespec
const *b){
291 return (a->tv_sec > b->tv_sec) ? 1
292 : (a->tv_sec < b->tv_sec) ? -1
293 : (a->tv_nsec > b->tv_nsec) ? +1
294 : (a->tv_nsec < b->tv_nsec) ? -1
303static inline int64_t
ts2ns(
struct timespec
const *ts){
304 return ts->tv_sec *
BILLION + ts->tv_nsec;
307static inline void ns2ts(
struct timespec *ts,int64_t ns){
316 clock_gettime(CLOCK_REALTIME,&now);
317 return (time_t)now.tv_sec;
327 clock_gettime(CLOCK_REALTIME,&now);
337#define FREE(p) (free(p), p = NULL)
347static inline void mirror_wrap(
void const **p,
void const *
const base,
size_t const size){
349 assert(*p < base + 2 * size);
351 if((uint8_t *)*p >= (uint8_t *)base + size)
352 *p = (uint8_t *)*p - size;
static void mirror_wrap(void const **p, void const *const base, size_t const size)
Definition misc.h:347
#define UNIX_EPOCH
Definition misc.h:77
static int const MILLION
Definition misc.h:298
static void ASSERT_UNLOCKED(pthread_mutex_t *mutex)
Definition misc.h:48
static int16_t scaleclip(float const x)
Definition misc.h:227
uint32_t nextfastfft(uint32_t n)
char * format_gpstime(char *result, int len, int64_t t)
static void time_add(struct timespec *result, struct timespec const *a, struct timespec const *b)
Definition misc.h:279
char * format_gpstime_iso8601(char *result, int len, int64_t t)
static float cnrmf(float complex const x)
Definition misc.h:254
uint32_t round2(uint32_t v)
static double dB2voltage(double x)
Definition misc.h:165
uint32_t ElfHash(uint8_t const *s, size_t length)
uint32_t fnv1hash(const uint8_t *s, size_t length)
char * format_utctime_iso8601(char *result, int len, int64_t t)
void * lmalloc(size_t size)
static int64_t const BILLION
Definition misc.h:297
static double dB2power(double x)
Definition misc.h:157
static double cnrm(double complex const x)
Definition misc.h:257
void sincospif(float x, float *s, float *c)
static double voltage2dB(double x)
Definition misc.h:168
static double complex csincospi(double const x)
Definition misc.h:248
static double sinc(double x)
Definition misc.h:191
static int time_cmp(struct timespec const *a, struct timespec const *b)
Definition misc.h:289
static float const SCALE8
Definition misc.h:83
char * ensure_suffix(char const *str, char const *suffix)
int64_t gps_time_ns(void)
void * mirror_alloc(size_t size)
static float complex csincosf(float const x)
Definition misc.h:230
static void ns2ts(struct timespec *ts, int64_t ns)
Definition misc.h:307
void sincospi(double x, double *s, double *c)
char * format_utctime(char *result, int len, int64_t t)
static double complex csincos(double const x)
Definition misc.h:242
double xi(double thetasq)
static int64_t ts2ns(struct timespec const *ts)
Definition misc.h:303
static int64_t utc_time_ns(void)
Definition misc.h:325
ssize_t pipefill(int, void *, size_t)
char * ftime(char *result, int size, int64_t t)
static time_t utc_time_sec(void)
Definition misc.h:314
uint32_t ElfHashString(char const *s)
static double complex complex_gauss(void)
Definition misc.h:372
static double approx_magf(double complex x)
Definition misc.h:262
static int init_recursive_mutex(pthread_mutex_t *m)
Definition misc.h:133
void xoshiro256ss_jump(xoshiro256ss_state *st)
static void time_sub(struct timespec *result, struct timespec const *a, struct timespec const *b)
Definition misc.h:273
double i1(double const z)
#define min(x, y)
Definition misc.h:142
static float const SCALE12
Definition misc.h:82
int dist_path(char *path, int path_len, const char *fname)
static time_t gps_time_sec(void)
Definition misc.h:320
static float const SCALE16
Definition misc.h:81
#define max(x, y)
Definition misc.h:148
void normalize_time(struct timespec *x)
void mirror_free(void **p, size_t size)
static int const THOUSAND
Definition misc.h:299
static float complex csincospif(float const x)
Definition misc.h:236
uint64_t xoshiro256ss_next(xoshiro256ss_state *st)
#define GPS_UTC_OFFSET
Definition misc.h:75
double i0(double const z)
void drop_cache(void *mem, size_t bytes)
static double power2dB(double x)
Definition misc.h:160
void xoshiro256ss_seed(xoshiro256ss_state *st, uint64_t seed)
size_t round_to_page(size_t size)
uint64_t s[4]
Definition misc.h:364