Files
wdsp/Makefile
Uladzimir Karpenka 65cb3c386e wfm: add a wideband FM modulator and demodulator
Model the pair on fmd.c / fmmod.c, but with the parts that a 75 kHz
deviation forces:

  - the demodulator discriminates with arg(x[n] * conj(x[n-1])) rather
    than a PLL; an omegaN in the tens of kHz cannot track 75 kHz.
  - emphasis is a one-pole RC (tau 75 us) on both ends, not fmd's 1/f
    fc_impulse FIR.  A 1/f FIR from f_low = 20 Hz would sit ~+57 dB at
    20 Hz, where broadcast FM specifies flat below the corner.
  - TXA_WFM leaves the shared preemph block off; wfmmod carries its own.
  - wfmmod clamps bp_fc = deviation + f_high to 0.45 * samplerate, since
    +/-90 kHz exceeds Nyquist at the rates the narrowband modes use.

Scope is mono: no 19 kHz pilot, no 38 kHz stereo subcarrier, no RDS.

Both mode enums are appended to so the ABI stays stable for clients.
The JNI bindings are deliberately left alone.

Verified against a wfmmod -> wfmd loopback: the discriminator is exact,
the dc-removal one-pole tracks |H_lp(f)| * ain * sdelta to ratio 1.000,
and a 700 + 1900 Hz two-tone comes back with THD+N ~ 3e-5 % at +/-37.5
kHz deviation.  Note the demodulator aliases unless samplerate exceeds
2 * deviation * |aud|max, so 192 kHz is the practical floor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 07:43:07 +03:00

231 lines
5.2 KiB
Makefile

#
# Makefile for WDSP library
# Builds static, shared and (optionally) Java JNI libraries.
#
UNAME_S := $(shell uname -s)
PREFIX ?= /usr/local
LIBDIR ?= $(PREFIX)/lib
INCLUDEDIR ?= $(PREFIX)/include
CC ?= gcc
AR ?= ar
RANLIB ?= ranlib
CFLAGS ?= -pthread -O3 -D_GNU_SOURCE -Wno-parentheses
CPPFLAGS ?=
LDFLAGS ?=
JNI_CFLAGS ?= -std=gnu89 -Wno-implicit-function-declaration -Wno-int-conversion -Wno-incompatible-pointer-types -Wno-incompatible-pointer-types-discards-qualifiers
FFTWINCLUDE := $(shell pkg-config --cflags fftw3 2>/dev/null)
FFTWLIBS := $(shell pkg-config --libs fftw3 2>/dev/null)
FFTWLIBS_F := $(shell pkg-config --libs fftw3f 2>/dev/null)
ifeq ($(strip $(FFTWLIBS)),)
FFTWLIBS := -lfftw3
endif
ifeq ($(strip $(FFTWLIBS_F)),)
FFTWLIBS_F := -lfftw3f
endif
ifeq ($(UNAME_S),Darwin)
SHARED_EXT := dylib
SHARED_LDFLAGS := -dynamiclib
PIC_CFLAGS :=
NOEXECSTACK :=
JAVA_OS_INCLUDE := darwin
else
SHARED_EXT := so
SHARED_LDFLAGS := -shared
PIC_CFLAGS := -fPIC
NOEXECSTACK := -Wl,-z,noexecstack
JAVA_OS_INCLUDE := linux
endif
OBJDIR := obj
OUTDIR := lib
STATIC_LIB_FILE := libwdsp.a
SHARED_LIB_FILE := libwdsp.$(SHARED_EXT)
JAVA_LIB_FILE := libwdspj.$(SHARED_EXT)
STATIC_LIB := $(OUTDIR)/$(STATIC_LIB_FILE)
SHARED_LIB := $(OUTDIR)/$(SHARED_LIB_FILE)
JAVA_LIB := $(OUTDIR)/$(JAVA_LIB_FILE)
ifeq ($(UNAME_S),Darwin)
SHARED_LDFLAGS += -install_name $(LIBDIR)/$(SHARED_LIB_FILE)
JAVA_SHARED_LDFLAGS := -dynamiclib -install_name $(LIBDIR)/$(JAVA_LIB_FILE)
else
JAVA_SHARED_LDFLAGS := $(SHARED_LDFLAGS)
endif
JAVA_HOME ?= $(shell /usr/libexec/java_home 2>/dev/null || sh -c 'J=$$(command -v javac 2>/dev/null); if [ -n "$$J" ]; then dirname "$$(dirname "$$(readlink -f "$$J")")"; fi')
JAVA_INCLUDE := -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(JAVA_OS_INCLUDE)
ifneq ($(NR34LIB),ON)
CPPFLAGS += -I third_party/rnnoise/include -I third_party/libspecbleach/include
NR34_DEPS := third_party/rnnoise/librnnoise.a third_party/libspecbleach/libspecbleach.a
NR34_LIBS := $(NR34_DEPS) $(FFTWLIBS_F)
else
NR34_DEPS :=
NR34_LIBS :=
endif
COMMON_LIBS := $(FFTWLIBS) -lpthread -lm
COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) $(PIC_CFLAGS) $(FFTWINCLUDE)
SOURCES = amd.c \
ammod.c \
amsq.c \
analyzer.c \
anf.c \
anr.c \
apfshadow.c \
bandpass.c \
calcc.c \
calculus.c \
cblock.c \
cfcomp.c \
cfir.c \
channel.c \
cmath.c \
compress.c \
delay.c \
dexp.c \
div.c \
doublepole.c \
eer.c \
emnr.c \
emph.c \
eq.c \
fcurve.c \
FDnoiseIQ.c \
fir.c \
firmin.c \
fmd.c \
fmmod.c \
fmsq.c \
gain.c \
gaussian.c \
gen.c \
icfir.c \
iir.c \
impulse_cache.c \
iobuffs.c \
iqc.c \
linux_port.c \
lmath.c \
main.c \
matchedCW.c \
meter.c \
meterlog10.c \
nbp.c \
nob.c \
nobII.c \
osctrl.c \
patchpanel.c \
resample.c \
rmatch.c \
rnnr.c \
RXA.c \
sbnr.c \
sender.c \
shift.c \
siphon.c \
slew.c \
snb.c \
ssql.c \
syncbuffs.c \
TXA.c \
utilities.c \
varsamp.c \
version.c \
wcpAGC.c \
wfmd.c \
wfmmod.c \
wisdom.c \
zetaHat.c
OBJS = $(addprefix $(OBJDIR)/, $(SOURCES:.c=.o))
JAVA_SOURCES = org_openhpsdr_dsp_Wdsp.c
JAVA_OBJS = $(addprefix $(OBJDIR)/, $(JAVA_SOURCES:.c=.o))
JAVA_CLASS = java/org/openhpsdr/dsp/Wdsp.java
JAVA_BUILD_DIR = java/build
.PHONY: all static shared java java-classes android install install_java install-dirs clean release
all: static shared java
static: $(STATIC_LIB)
shared: $(SHARED_LIB)
java:
ifeq ($(strip $(JAVA_HOME)),)
@echo "Skipping Java build: JAVA_HOME is not set and javac was not found in PATH"
else
@$(MAKE) $(JAVA_LIB) java-classes
endif
android:
$(MAKE) -f Makefile.android all
$(OUTDIR) $(OBJDIR):
mkdir -p $@
$(STATIC_LIB): $(OBJS) | $(OUTDIR)
$(AR) rv $@ $(OBJS)
$(RANLIB) $@
$(SHARED_LIB): $(OBJS) $(NR34_DEPS) | $(OUTDIR)
$(CC) $(SHARED_LDFLAGS) $(NOEXECSTACK) $(LDFLAGS) -o $@ $(OBJS) $(NR34_LIBS) $(COMMON_LIBS)
$(JAVA_LIB): $(JAVA_OBJS) $(SHARED_LIB) | $(OUTDIR)
$(CC) $(JAVA_SHARED_LDFLAGS) $(NOEXECSTACK) $(LDFLAGS) -o $@ $(JAVA_OBJS) -L$(OUTDIR) -lwdsp
java-classes: $(JAVA_CLASS)
@mkdir -p $(JAVA_BUILD_DIR)
javac -d $(JAVA_BUILD_DIR) $(JAVA_CLASS)
third_party/rnnoise/librnnoise.a:
$(MAKE) -C third_party/rnnoise CFLAGS="$(CFLAGS) $(PIC_CFLAGS) -Iinclude -Isrc"
third_party/libspecbleach/libspecbleach.a:
$(MAKE) -C third_party/libspecbleach CFLAGS="$(CFLAGS) $(PIC_CFLAGS) $(shell pkg-config --cflags fftw3f 2>/dev/null)"
$(OBJDIR)/%.o: %.c | $(OBJDIR)
$(COMPILE) -c -o $@ $<
$(OBJDIR)/org_openhpsdr_dsp_Wdsp.o: org_openhpsdr_dsp_Wdsp.c org_openhpsdr_dsp_Wdsp.h | $(OBJDIR)
@test -n "$(JAVA_HOME)" || (echo "JAVA_HOME is required to build JNI object org_openhpsdr_dsp_Wdsp.o"; exit 2)
$(CC) $(CPPFLAGS) $(CFLAGS) $(JNI_CFLAGS) $(PIC_CFLAGS) $(FFTWINCLUDE) $(JAVA_INCLUDE) -c -o $@ $<
install-dirs:
mkdir -p $(LIBDIR) $(INCLUDEDIR)
install: $(STATIC_LIB) $(SHARED_LIB) install-dirs
cp wdsp.h $(INCLUDEDIR)
cp $(STATIC_LIB) $(LIBDIR)
cp $(SHARED_LIB) $(LIBDIR)
ifeq ($(UNAME_S),Darwin)
/usr/bin/install_name_tool -id $(LIBDIR)/$(SHARED_LIB_FILE) $(LIBDIR)/$(SHARED_LIB_FILE)
else
ldconfig || :
endif
install_java: $(JAVA_LIB) install-dirs
cp $(JAVA_LIB) $(LIBDIR)
release: $(SHARED_LIB)
cp $(SHARED_LIB) ../pihpsdr/release/pihpsdr
clean:
-rm -rf $(OBJDIR) $(OUTDIR)
-rm -rf $(JAVA_BUILD_DIR)
-$(MAKE) -C third_party/rnnoise clean
-$(MAKE) -C third_party/libspecbleach clean