C examples¶
The C sample programs are available in sample/c/ in the TrulyNatural installation directory.
See ~/Sensory/TrulyNaturalSDK/7.7.0/sample/c/
You can build the sample code with CMake or with GNU Make.
Examples¶
- live-spot.c
- Shows how to run a wake word recognizer on live audio captured from the default audio source.
- live-spot-stream.c
- Runs a wake word recognizer on live audio captured using a custom audio stream, defined in alsa-stream.c.
- live-segment.c
- Runs a wake word recognizer on live audio, segments the speech following the wake word with a VAD, and then saves this audio snippet to a file.
- push-audio.c
- Runs a recognizer where the application pushes data through the recognition pipeline. Shows VAD audio processing for use with third-party recognizers such as keyword-to-search applications.
- spot-data.c
- Runs a small keyword spotter from code space. It uses a custom memory allocator to avoid calls to the system heap allocator, and reads audio data from code space to avoid file system use.
- spot-data-stream.c
- This example runs a wake word from code space with a custom audio stream, using pull mode processing with run. It is a reasonable starting point for running on a small device with an RTOS.
- alsa-stream.c
- Source for the fromAudioDevice Stream implementation for ALSA, used for live audio capture on Linux.
- aqs-stream.c
- Source for the fromAudioDevice Stream implementation for Audio Queue Services, used for live audio capture on macOS and iOS.
- wmme-stream.c
- Source for the fromAudioDevice Stream implementation for Windows Multimedia Extensions, used for live audio capture on Windows.
- data-stream.c
- This is the source for the fromAudioDevice Stream implementation for memory data, similar to fromMemory. It's used in the spot-data-stream.c example.
- snsr-edit.c
- Source for the snsr-edit command-line tool.
- snsr-eval.c
- Source for the snsr-eval command-line tool, and the
snsr-eval-subsetsample. - spot-convert.c
- Source for the spot-convert command-line tool.
- spot-enroll.c
- Source for the spot-enroll command-line tool.
- live-enroll.c
- Source for the live-enroll command-line tool.
Build with CMake¶
We support building the code samples with CMake on Linux, macOS, and Windows. This requires CMake 3.10 or later and a compiler toolchain.
Open a terminal window and enter the commands below.
cd ~/Sensory/TrulyNaturalSDK/7.7.0/sample/c
cmake -S . -B build-sample
cmake --build build-sample --parallel --config Release
cmake --install build-sample
This installs the sample executables in the bin/ subdirectory.
CMakeLists.txt¶
These are the cmake configuration files used to build the sample code.
CMakeLists.txt
# Sensory Confidential
# Copyright (C)2024-2026 Sensory, Inc. https://sensory.com/
#
# TrulyNatural SDK sample code build configuration
#
# Configure, build, and install these samples with:
#
# cmake -S . -B build-sample
# cmake --build build-sample --parallel --config Release
# cmake --install build-sample
#
# Then find the sample executables in build-sample/bin/
cmake_minimum_required(VERSION 3.10.0)
if(POLICY CMP0177)
cmake_policy(SET CMP0177 NEW)
endif()
project(SnsrSamples)
list(APPEND CMAKE_MODULE_PATH "~/Sensory/TrulyNaturalSDK/7.7.0")
include(SnsrLibrary)
add_subdirectory(src)
src/CMakeLists.txt
# Sensory Confidential
# Copyright (C)2024-2026 Sensory, Inc. https://sensory.com/
#
# This is not a stand-alone configuration. See by ../CMakeLists.txt
set(SAMPLE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../bin)
set(MODEL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../model)
set(SRC_GEN ${PROJECT_BINARY_DIR}/src)
set(SPT_HBG spot-hbg-enUS-1.4.0-m)
set(TPL_VAD tpl-vad-lvcsr-3.17.0)
add_executable(live-enroll live-enroll.c)
target_link_libraries(live-enroll SnsrLibraryOmitOSS)
install(TARGETS live-enroll DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(live-segment live-segment.c)
target_link_libraries(live-segment SnsrLibraryOmitOSS)
install(TARGETS live-segment DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(live-spot live-spot.c)
target_link_libraries(live-spot SnsrLibrary)
install(TARGETS live-spot DESTINATION ${SAMPLE_BINARY_DIR})
if (APPLE)
add_executable(live-spot-stream live-spot-stream.c aqs-stream.c)
target_link_libraries(live-spot-stream SnsrLibrary)
install(TARGETS live-spot-stream DESTINATION ${SAMPLE_BINARY_DIR})
elseif (UNIX)
add_executable(live-spot-stream live-spot-stream.c alsa-stream.c)
target_link_libraries(live-spot-stream SnsrLibrary)
install(TARGETS live-spot-stream DESTINATION ${SAMPLE_BINARY_DIR})
elseif (WIN32)
add_executable(live-spot-stream live-spot-stream.c wmme-stream.c)
target_link_libraries(live-spot-stream SnsrLibrary)
install(TARGETS live-spot-stream DESTINATION ${SAMPLE_BINARY_DIR})
endif ()
add_executable(push-audio push-audio.c)
target_link_libraries(push-audio SnsrLibrary)
install(TARGETS push-audio DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(snsr-edit snsr-edit.c)
target_link_libraries(snsr-edit SnsrLibrary)
install(TARGETS snsr-edit DESTINATION ${SAMPLE_BINARY_DIR})
add_custom_command(
OUTPUT ${SRC_GEN}/${SPT_HBG}.c
COMMAND snsr-edit
-c spot_hbg_enUS
-t ${MODEL_DIR}/${SPT_HBG}.snsr
DEPENDS snsr-edit
)
add_custom_command(
OUTPUT ${SRC_GEN}/${TPL_VAD}.c
COMMAND snsr-edit
-c tpl_vad_lvcsr
-t ${MODEL_DIR}/${TPL_VAD}.snsr
DEPENDS snsr-edit
)
add_executable(snsr-eval snsr-eval.c
${SRC_GEN}/${TPL_VAD}.c)
target_link_libraries(snsr-eval SnsrLibrary)
install(TARGETS snsr-eval DESTINATION ${SAMPLE_BINARY_DIR})
add_custom_command(
OUTPUT ${SRC_GEN}/snsr-custom-init.c
COMMAND snsr-edit
-it ${MODEL_DIR}/${SPT_HBG}.snsr
DEPENDS snsr-edit
)
add_executable(snsr-eval-subset snsr-eval.c
${SRC_GEN}/${TPL_VAD}.c
${SRC_GEN}/snsr-custom-init.c)
target_link_libraries(snsr-eval-subset SnsrLibrary)
target_compile_options(snsr-eval-subset PRIVATE -DSNSR_USE_SUBSET)
install(TARGETS snsr-eval-subset DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(spot-convert spot-convert.c)
target_link_libraries(spot-convert SnsrLibraryOmitOSS)
install(TARGETS spot-convert DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(spot-data spot-data.c data.c
${SRC_GEN}/${SPT_HBG}.c)
target_link_libraries(spot-data SnsrLibrary)
install(TARGETS spot-data DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(spot-data-stream spot-data-stream.c data-stream.c data.c
${SRC_GEN}/${SPT_HBG}.c)
target_link_libraries(spot-data-stream SnsrLibrary)
install(TARGETS spot-data-stream DESTINATION ${SAMPLE_BINARY_DIR})
add_executable(spot-enroll spot-enroll.c)
target_link_libraries(spot-enroll SnsrLibraryOmitOSS)
install(TARGETS spot-enroll DESTINATION ${SAMPLE_BINARY_DIR})
Build with GNU Make¶
We support building the code samples with GNU Make on Linux and macOS only. This requires GNU Make 3.81 or later and a compiler toolchain.
Open a terminal window and enter the commands below.
This installs the sample executables in the bin/ subdirectory.
If you run make without arguments the Makefile lists all available targets:
% make
Make targets:
make all # build all executables in ./bin
make clean # remove build artifacts
make debug # build all with debugging enabled
make help # display this help message
make test # run enrollment and spotting tests
Building for macos from SDK root directory
../..
Run the sample tests:
% make -j -s test
Running test-enroll-0.
Running test-enroll-1.
Running test-enroll-2.
Running test-enroll-3.
Running test-convert-0.
Running test-data-0.
Running test-data-1.
Running test-subset-0.
./build/out/dsp-pc38-3.4.0-op10-prod-net.bin: OK
./build/out/dsp-pc38-3.4.0-op10-prod-search.bin: OK
./build/out/dsp-search-check.h: OK
Say the enrollment phrase (1/4) for "armadillo-1"
Recording: 1.88 s
Say the enrollment phrase (2/4) for "armadillo-1"
Recording: 1.71 s
Say the enrollment phrase (3/4) for "armadillo-1" with context,
for example: "<phrase> will it rain tomorrow?"
Recording: 4.02 s
Say the enrollment phrase (4/4) for "armadillo-1" with context,
for example: "<phrase> will it rain tomorrow?"
Recording: 2.91 s
Running test-push-0.
Running test-push-1.
SUCCESS: All tests passed.
Makefile¶
This is the make configuration file used to build and test the sample code.
Makefile
# Sensory Confidential
# Copyright (C)2015-2026 Sensory, Inc. https://sensory.com/
#
# TrulyNatural SDK GNU make build script
SNSR_ROOT := ../..
SNSR_EDIT = $(BIN_DIR)/snsr-edit
# This Makefile is meant to run on the target platform.
# Uncomment the following line if cross-compiling instead.
# SNSR_EDIT = $(TOOL_DIR)/snsr-edit
# OS-specific compiler defaults
OS_NAME := $(shell uname -s)
ifeq ($(OS_NAME),Linux)
# Linux
ARCH_NAME := $(shell $(CC) -dumpmachine)
OS_CFLAGS := -O3 -fPIC -DNDEBUG
OS_CFLAGS += -Wall -Werror
OS_CFLAGS += -fdata-sections -ffunction-sections
OS_LIBS := -lsnsr -lasound -lpthread -lm -ldl -lstdc++
OS_LDFLAGS+= -Wl,--gc-sections
STATSIZE := stat -c %s
else ifeq ($(OS_NAME),Darwin)
# macOS
ARCH_NAME := macos
ARCH := $(shell uname -m)
XCODE := /Applications/Xcode.app/Contents/Developer
SYSROOT := $(XCODE)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
CC := $(XCODE)/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
OS_ARCH := -arch $(ARCH)
OS_CFLAGS := -O3 -fPIC -DNDEBUG
OS_CFLAGS += $(OS_ARCH)
OS_CFLAGS += -Wall -Werror
OS_CFLAGS += -isysroot $(SYSROOT)
OS_CFLAGS += -fdata-sections -ffunction-sections
OS_LDFLAGS+= -isysroot $(SYSROOT)
OS_LDFLAGS+= -dead_strip
OS_LDFLAGS+= $(OS_ARCH)
OS_LIBS := -lsnsr -framework AudioToolbox -framework CoreFoundation
OS_LIBS += -framework Foundation -framework Accelerate
OS_LIBS += -lm -lstdc++
STATSIZE := stat -f %z
else
$(error This operating system ($(OS_NAME)) is not supported)
endif
OS_CFLAGS += -I$(SNSR_ROOT)/include
OS_LDFLAGS += -L$(SNSR_ROOT)/lib/$(ARCH_NAME)
TARGET_DIR := .
BIN_DIR = $(TARGET_DIR)/bin
SRC_DIR = $(TARGET_DIR)/src
OBJ_DIR = $(BUILD_DIR)/obj
OUT_DIR = $(BUILD_DIR)/out
BUILD_DIR = $(TARGET_DIR)/build
TEST_DIR = $(TARGET_DIR)/test
MODEL_DIR = $(SNSR_ROOT)/model
DATA_DIR = $(SNSR_ROOT)/data
TOOL_DIR = $(SNSR_ROOT)/bin
# $(call audio-files,filename-prefix,index-list)
# e.g. $(call audio-files,armadillo-6-,0 1 2)
# returns a list of absolute paths to SDK enrollment test data
audio-files = $(addsuffix .wav,$(addprefix $(DATA_DIR)/enrollments/$1,$2))
TEST_DATA := $(call audio-files,armadillo-1-,0 1 2 3 4 5)
TEST_DATA += $(call audio-files,armadillo-6-,0 1 2 3 4 5)
TEST_DATA += $(call audio-files,jackalope-1-,0 1 2 3 4 5)
TEST_DATA += $(call audio-files,jackalope-4-,0 1 2 3 4 5)
TEST_DATA += $(call audio-files,terminator-2-,0 1 2 3 4 5)
TEST_DATA += $(call audio-files,terminator-6-,0 1 2 3 4 5)
TEST_DATA += $(call audio-files,armadillo-1-,0-c 1-c 2-c 3-c 4-c 5-c)
TEST_DATA += $(call audio-files,jackalope-1-,0-c 1-c 2-c 3-c 4-c 5-c)
UDT_MODEL = $(MODEL_DIR)/udt-universal-3.67.1.0.snsr
UDT_MODEL_5 = $(MODEL_DIR)/udt-enUS-5.1.1.9.snsr
VTPL_MODEL = $(MODEL_DIR)/tpl-spot-vad-3.13.0.snsr
HBG_MODEL_V = spot-hbg-enUS-1.4.0-m
HBG_MODEL = $(MODEL_DIR)/$(HBG_MODEL_V).snsr
VG_MODEL = $(MODEL_DIR)/spot-voicegenie-enUS-6.5.1-m.snsr
BASE_MODEL = $(OUT_DIR)/enrolled-sv
VAD_MODEL_V = tpl-vad-lvcsr-3.17.0
VAD_MODEL = $(MODEL_DIR)/$(VAD_MODEL_V).snsr
.PHONY: all clean debug help test
.PHONY: test-enroll-0 test-enroll-1 test-enroll-2 test-enroll-3
.PHONY: test-convert-0
.PHONY: test-push-0 test-push-1
define help
Make targets:
make all # build all executables in $(BIN_DIR)
make clean # remove build artifacts
make debug # build all with debugging enabled
make help # display this help message
make test # run enrollment and spotting tests
Building for $(ARCH_NAME) from SDK root directory
$(SNSR_ROOT)
endef
# Adjust test program verbosity
# Resolves to -v, unless make is run with the -s (silent) flag.
v = $(if $(findstring s,$(MAKEFLAGS)),,-v)
# Default target
help:; $(info $(help))
clean:
rm -rf $(BIN_DIR) $(BUILD_DIR) $(OBJ_DIR) $(OUT_DIR) segmented-audio.wav
rm -f $(SRC_DIR)/snsr-custom-init.c
rm -f $(SRC_DIR)/$(HBG_MODEL_V).c $(SRC_DIR)/$(VAD_MODEL_V).c
debug: all
debug: CFLAGS=-O0 -g -UNDEBUG
test: test-enroll-0 test-enroll-1 test-enroll-2 test-enroll-3\
test-convert-0 test-push-0 test-push-1 test-data-0 test-data-1\
test-subset-0
$(info SUCCESS: All tests passed.)
# End-to-end UDT enrollment test
test-enroll-0: $(BIN_DIR)/spot-enroll $(BIN_DIR)/snsr-eval | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/spot-enroll $v $v -t $(UDT_MODEL)\
-o $(BASE_MODEL)-0.snsr\
+armadillo-6 $(call audio-files,armadillo-6-,0 1 2 3)\
+jackalope-4 $(call audio-files,jackalope-4-,0 1 2 3)\
+terminator-2 $(call audio-files,terminator-2-,0 1 2 3)\
+terminator-6 $(call audio-files,terminator-6-,0 1 2 3)\
+armadillo-1 $(call audio-files,armadillo-1-,0 1)\
-c $(call audio-files,armadillo-1-,0-c)\
-c $(call audio-files,armadillo-1-,1-c)\
+jackalope-1 $(call audio-files,jackalope-1-,0 1)\
-c $(call audio-files,jackalope-1-,0-c)\
-c $(call audio-files,jackalope-1-,1-c)
$(BIN_DIR)/snsr-eval -t $(BASE_MODEL)-0.snsr $(TEST_DATA)\
> $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 100)
# End-to-end UDT enrollment test, using adapted enrollment contexts
test-enroll-1: $(BIN_DIR)/spot-enroll $(BIN_DIR)/snsr-eval | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-a $(OUT_DIR)/armadillo-6.snsr\
-o $(OUT_DIR)/enrolled-armadillo-6.snsr\
+armadillo-6 $(call audio-files,armadillo-6-,0 1 2 3)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-a $(OUT_DIR)/jackalope-4.snsr\
-o $(OUT_DIR)/enrolled-jackalope-4.snsr\
+jackalope-4 $(call audio-files,jackalope-4-,0 1 2 3)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-a $(OUT_DIR)/terminator-2.snsr\
-o $(OUT_DIR)/enrolled-terminator-2.snsr\
+terminator-2 $(call audio-files,terminator-2-,0 1 2 3)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-a $(OUT_DIR)/terminator-6.snsr\
-o $(OUT_DIR)/enrolled-terminator-6.snsr\
+terminator-6 $(call audio-files,terminator-6-,0 1 2 3)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-a $(OUT_DIR)/armadillo-1.snsr\
-o $(OUT_DIR)/enrolled-armadillo.snsr\
+armadillo-1 $(call audio-files,armadillo-1-,0 1)\
-c $(call audio-files,armadillo-1-,0-c)\
-c $(call audio-files,armadillo-1-,1-c)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-a $(OUT_DIR)/jackalope-1.snsr\
-o $(OUT_DIR)/enrolled-jackalope-1.snsr\
+jackalope-1 $(call audio-files,jackalope-1-,0 1)\
-c $(call audio-files,jackalope-1-,0-c)\
-c $(call audio-files,jackalope-1-,1-c)
$(BIN_DIR)/spot-enroll $v -t $(UDT_MODEL)\
-t $(OUT_DIR)/armadillo-6.snsr\
-t $(OUT_DIR)/jackalope-4.snsr\
-t $(OUT_DIR)/terminator-2.snsr\
-t $(OUT_DIR)/terminator-6.snsr\
-t $(OUT_DIR)/armadillo-1.snsr\
-t $(OUT_DIR)/jackalope-1.snsr\
-o $(BASE_MODEL)-1.snsr
$(BIN_DIR)/snsr-eval -t $(BASE_MODEL)-1.snsr $(TEST_DATA)\
> $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt >/dev/null\
|| diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@-alt.txt >/dev/null\
|| (echo ERROR: $@ validation failed; exit 101)
# Live end-to-end UDT enrollment test.
test-enroll-2: $(BIN_DIR)/live-enroll $(BIN_DIR)/snsr-eval | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/live-enroll $v $v -t $(UDT_MODEL)\
-o $(BASE_MODEL)-2.snsr\
+armadillo-1 $(call audio-files,armadillo-1-,0 1 0-c 1-c)
$(BIN_DIR)/snsr-eval -t $(BASE_MODEL)-2.snsr $(TEST_DATA)\
> $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 102)
# Test old UDT model
test-enroll-3: $(BIN_DIR)/spot-enroll $(BIN_DIR)/snsr-eval | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/spot-enroll $v $v -t $(UDT_MODEL_5)\
-o $(BASE_MODEL)-3.snsr\
+armadillo-1 $(call audio-files,armadillo-1-,0 1 2 3)
$(BIN_DIR)/snsr-eval -t $(BASE_MODEL)-3.snsr $(TEST_DATA)\
> $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 103)
# Validate DSP conversion
test-convert-0: $(BIN_DIR)/spot-convert | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/spot-convert -t $(HBG_MODEL) -p $(OUT_DIR)/dsp pc38
tail -10 $(OUT_DIR)/dsp-pc38-3.4.0-op10-prod-search.h\
> $(OUT_DIR)/dsp-search-check.h
shasum -c $(TEST_DIR)/dsp-checksum.txt
# Push audio samples instead of the default pull
# Uses test-enroll-0 models
test-push-0: test-enroll-0 $(BIN_DIR)/push-audio | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/push-audio $(BASE_MODEL)-0.snsr\
$(call audio-files,jackalope-4-,0)\
> $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 104)
# Push audio samples instead of the default pull
# Uses test-enroll-0 models and the tpl-spot-vad-*.snsr template
test-push-1: test-enroll-0 $(BIN_DIR)/push-audio $(SNSR_EDIT) | $(OUT_DIR)
$(info Running $@.)
$(SNSR_EDIT) -t $(VTPL_MODEL)\
-f 0 $(BASE_MODEL)-0.snsr -o $(OUT_DIR)/spot-vad.snsr
$(BIN_DIR)/push-audio $(OUT_DIR)/spot-vad.snsr\
$(call audio-files,armadillo-1-,1-c)\
> $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 105)
test-data-0: $(BIN_DIR)/spot-data | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/spot-data > $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 104)
test-data-1: $(BIN_DIR)/spot-data-stream | $(OUT_DIR)
$(info Running $@.)
$(BIN_DIR)/spot-data-stream > $(OUT_DIR)/$@.txt
diff $(OUT_DIR)/$@.txt $(TEST_DIR)/$@.txt\
|| (echo ERROR: $@ validation failed; exit 104)
test-subset-0: $(BIN_DIR)/snsr-eval-subset $(BIN_DIR)/snsr-eval | $(OUT_DIR)
$(info Running $@.)
test $(shell $(STATSIZE) $(BIN_DIR)/snsr-eval-subset) -lt \
$(shell $(STATSIZE) $(BIN_DIR)/snsr-eval) ||\
(echo ERROR: $@ size validation failed; exit 105)
$(BIN_DIR)/snsr-eval-subset -t $(HBG_MODEL) /dev/null ||\
(echo ERROR: $@ validation failed; exit 106)
$(BIN_DIR)/snsr-eval-subset -t $(VG_MODEL) /dev/null 2>&1 |\
grep SNSR_USE_SUBSET >/dev/null ||\
(echo ERROR: $@ validation failed; exit 107)
# Create a rule for building name from source, in $(BIN_DIR)
# $(call add-target-rule,name,source1.c source2.c ...)
add-target-rule = $(eval $(call emit-target-rule,$1,$2))
define emit-target-rule
all: $$(BIN_DIR)/$(strip $1)
$$(BIN_DIR)/$(strip $1): $$(addprefix $$(OBJ_DIR)/,$(2:.c=.o)) | $$(BIN_DIR)
$$(CC) $$(OS_LDFLAGS) $$(LDFLAGS) -o $$@ $$^ $$(OS_LIBS) $$(LIBS)
endef
# Command-line application targets
$(call add-target-rule, spot-convert, spot-convert.c)
$(call add-target-rule, snsr-edit, snsr-edit.c)
$(call add-target-rule, spot-enroll, spot-enroll.c)
$(call add-target-rule, snsr-eval, snsr-eval.c tpl-vad-lvcsr-3.17.0.c)
$(call add-target-rule, snsr-eval-subset,\
snsr-eval-subset.c snsr-custom-init.c tpl-vad-lvcsr-3.17.0.c)
$(call add-target-rule, live-enroll, live-enroll.c)
$(call add-target-rule, live-segment, live-segment.c)
$(call add-target-rule, live-spot, live-spot.c)
$(call add-target-rule, push-audio, push-audio.c)
$(call add-target-rule, spot-data,\
spot-data.c spot-hbg-enUS-1.4.0-m.c data.c)
$(call add-target-rule, spot-data-stream,\
spot-data-stream.c data-stream.c spot-hbg-enUS-1.4.0-m.c data.c)
ifeq ($(OS_NAME),Linux)
# The custom stream sample uses ALSA on Linux.
$(call add-target-rule, live-spot-stream, live-spot-stream.c alsa-stream.c)
else ifeq ($(OS_NAME),Darwin)
# The custom stream sample uses AQS on macOS.
$(call add-target-rule, live-spot-stream, live-spot-stream.c aqs-stream.c)
endif
# Build object files from C sources
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c | $(OBJ_DIR)
$(CC) -c $(OS_CFLAGS) $(CFLAGS) -o $@ $<
# spot-enroll doesn't use OSS modules
$(OBJ_DIR)/spot-enroll.o : $(SRC_DIR)/spot-enroll.c | $(OBJ_DIR)
$(CC) -DSNSR_OMIT_OSS_COMPONENTS -c $(OS_CFLAGS) $(CFLAGS) -o $@ $<
# Create $(SRC_DIR)/snsr-custom-init.c using snsr-edit,
# limit support to those modules needed for $(HBG_MODEL)
$(SRC_DIR)/snsr-custom-init.c: $(SNSR_EDIT)
$(SNSR_EDIT) -o $@ -vit $(HBG_MODEL)
# Create $(SRC_DIR)/spot-hbg-enUS-*.c from the snsr model
$(SRC_DIR)/$(HBG_MODEL_V).c: $(SNSR_EDIT)
$(SNSR_EDIT) -o $@ -c spot_hbg_enUS -vt $(HBG_MODEL)
# Create $(SRC_DIR)/tpl-vad-lvcsr-*.c from the snsr model
$(SRC_DIR)/$(VAD_MODEL_V).c: $(SNSR_EDIT)
$(SNSR_EDIT) -o $@ -c tpl_vad_lvcsr -vt $(VAD_MODEL)
# Build snsr-eval-subset object files with -DSNSR_USE_SUBSET
$(OBJ_DIR)/snsr-eval-subset.o: $(SRC_DIR)/snsr-eval.c | $(OBJ_DIR)
$(CC) -c $(OS_CFLAGS) $(CFLAGS) -DSNSR_USE_SUBSET -o $@ $<
# Create output directories
$(BIN_DIR) $(BUILD_DIR) $(OBJ_DIR) $(OUT_DIR):
mkdir -p $@