Skip to content

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

  1. Build the sample code. In the same terminal window type the command after the %, then say "hello blue genie":

    % ./bin/live-spot-stream ../../model/spot-hbg-enUS-1.4.0-m.snsr
    Spotted "hello blue genie" at 5.34 seconds.
    
  2. 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-stream example again and say one of these phrases:

    % ./bin/live-spot-stream spot-vg-or-hbg.snsr
    Spotted "voicegenie" at 6.75 seconds.
    
    % ./bin/live-spot-stream spot-vg-or-hbg.snsr
    Spotted "hello blue genie" at 8.28 seconds.
    
  3. 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;
}