live-spot-stream.c¶
This example shows how to run a recognizer on live audio captured using a custom audio stream.
alsa-stream.c, aqs-stream.c, wmme-stream.c, fromProvider
Instructions¶
-
Build the sample code. In the same terminal window type the command after the
%, then say "hello blue genie": -
This example works with any phrasespot recognizer type, so let's create a concurrent combination of two wake words:
% ./bin/snsr-edit -vt ../../model/tpl-spot-concurrent-1.5.0.snsr \ -f 0 ../../model/spot-voicegenie-enUS-6.5.1-m.snsr \ -f 1 ../../model/spot-hbg-enUS-1.4.0-m.snsr \ -o spot-vg-or-hbg.snsr Output written to "spot-vg-or-hbg.snsr".spot-vg-or-hbg.snsr listens for both "voice genie" and "hello blue genie". Run the
live-spot-streamexample again and say one of these phrases: -
tnl A VAD combined with either an LVCSR or STT model also works:
% ./bin/snsr-edit -vt ../../model/tpl-vad-lvcsr-3.17.0.snsr \ -f 0 ../../model/lvcsr-build-enUS-2.7.3.snsr \ -g phrases-stream "hello world; this is a test sentence; stop everything" \ -o vad-lvcsr.snsr Output written to "vad-lvcsr.snsr". % ./bin/live-spot-stream vad-lvcsr.snsr Spotted "this is a test sentence" at 4.46 seconds. % ./bin/live-spot-stream vad-lvcsr.snsr Spotted "<no-match/>" at 2.15 seconds. % ./bin/live-spot-stream vad-lvcsr.snsr Spotted "stop everything" at 1.88 seconds.
Code¶
Available in this TrulyNatural SDK installation at ~/Sensory/TrulyNaturalSDK/7.6.1/sample/c/src/live-spot-stream.c
live-spot-stream.c
/* Sensory Confidential
* Copyright (C)2016-2025 Sensory, Inc. https://sensory.com/
*
* Keyword spotting minimal example using a custom audio stream.
*------------------------------------------------------------------------------
*/
#include <snsr.h>
#include <stdlib.h>
/* Use the custom audio stream for this operating system */
#ifdef __linux__
# include "alsa-stream.h"
# define streamFromCustom(r, m, l) streamFromALSA("default", r, m, l)
#elif defined(__APPLE__)
# include "aqs-stream.h"
# define streamFromCustom(r, m, l) streamFromAQS(r, m, l)
#elif defined(_WIN32)
# include "wmme-stream.h"
# define streamFromCustom(r, m, l) streamFromWMME(-1, r, m, l)
#else
# error Not supported on this platform.
#endif
/* Result callback function, see snsrSetHandler() in main() below.
* Print the result text and the start time of the first spotted phrase.
*/
static SnsrRC
resultEvent(SnsrSession s, const char *key, void *privateData)
{
SnsrRC r;
const char *phrase;
double begin;
/* Retrieve the phrase text and start time from the session handle. */
snsrGetDouble(s, SNSR_RES_BEGIN_MS, &begin);
r = snsrGetString(s, SNSR_RES_TEXT, &phrase);
/* Quit early if an error occurred. */
if (r != SNSR_RC_OK) return r;
printf("Spotted \"%s\" at %.2f seconds.\n", phrase, begin/1000.0);
/* Returning a code other than SNSR_RC_OK instructs snsrRun() to return it. */
return SNSR_RC_STOP;
}
int
main(int argc, char *argv[])
{
SnsrRC r;
SnsrSession s;
if (argc != 2) {
fprintf(stderr, "usage: %s spotter-model\n", argv[0]);
exit(1);
}
/* Create a new session handle. */
snsrNew(&s);
/* Load and validate the spotter model task file. */
snsrLoad(s, snsrStreamFromFileName(argv[1], "r"));
snsrRequire(s, SNSR_TASK_TYPE, SNSR_PHRASESPOT);
/* Create a live audio stream instance using a custom stream type,
* then attach it to the session.
*/
snsrSetStream(s, SNSR_SOURCE_AUDIO_PCM,
streamFromCustom(16000, SNSR_ST_MODE_READ, STREAM_LATENCY_LOW));
/* Register a result callback. Private data handle is not used */
snsrSetHandler(s, SNSR_RESULT_EVENT, snsrCallback(resultEvent, NULL, NULL));
/* Main recognition loop. The result handler will cause snsrRun() to
* return SNSR_RC_STOP. Other return codes indicate an unexpected error.
* Session errors remain until explicitly cleared: Any errors that occured
* earlier will also be reported here.
*/
r = snsrRun(s);
if (r != SNSR_RC_STOP)
fprintf(stderr, "ERROR: %s\n", snsrErrorDetail(s));
/* Release the session. This will also release the model and audio streams,
* and the callback handler. No other references to these handles are held,
* so their memory will be reclaimed.
*/
snsrRelease(s);
return r;
}