Skip to content

C examples

The C sample programs are available in sample/c/ in the TrulyNatural installation directory.

See ~/Sensory/TrulyNaturalSDK/7.6.1/sample/c/

You can build the sample code with CMake or with GNU Make.

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.6.1/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)2025 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.6.1")
include(SnsrLibrary)

add_subdirectory(src)
src/CMakeLists.txt
# Sensory Confidential
# Copyright (C)2025 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.

cd ~/Sensory/TrulyNaturalSDK/7.6.1/sample/c
make -j all

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-2025 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.10.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 $@

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-subset sample.
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.