SmartAudio/package/avs/libsensory/files/wrapper/include/snsr.h

2700 lines
90 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) Sensory, Inc. 2000-2017. All Rights Reserved.
* http://sensory.com/
*
* You may not use these files except in compliance with the license.
* A copy of the license is located the "LICENSE.txt" file accompanying
* this source. This file is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*---------------------------------------------------------------------------
* TrulyHandsfree SDK
*---------------------------------------------------------------------------
*/
/**
* @addtogroup c C API
* TrulyHandsfree C SDK.
*
* This library uses a [dataflow][] approach to evaluate speech
* recognition tasks.
* It relies on [inversion of control][ioc]:
* User-defined hooks are invoked to report results and control task flow.
* Task models define flow pipelines and behavior.
* The API contains two primary data types: @ref session and @ref stream.
* Sessions encapsulate the entire state of a task instance, and all
* session input and output data are are vectored through streams.
*
* [dataflow]: https://en.wikipedia.org/wiki/Flow-based_programming
* [ioc]: https://en.wikipedia.org/wiki/Inversion_of_control
*
* Session instance behavior is customized via settings, of which there
* are three cariants:
* - **Configuration** settings are serializable read-write values.
* These are used for parameter values and model objects.
* Task models contain reasonable default values - modify these only to
* tweak results.
* - **Runtime** settings are instance-specific and not serializable. These
* include callback handles, iterators, input streams and values
* such as the name of the phrase being enrolled.
* - **Result** settings are read-only values with very limited scope, such
* as the recognition results.
*
* Stream instances are created on various underlying data streams, such as
* @c FILE @c * handles, memory segments, and live audio sources. Only the
* constructors are type-specific, all other functions are independent of the
* underlying stream type. Operations that take stream handles as arguments
* operate on any of the types.
*
* Task evaluation typically follows this recipe:
* - Create a new session instance.
* - Load a task model into the instance.
* - Set the input source stream.
* - Register one or more event handlers.
* - Enter the main loop. The library will process the input streams and
* invoke event handlers at appropriate times. The main loop continues
* until a terminating condition is reached, such as an event returning
* an error code.
* - Release the sesion instance.
* @{
* @file snsr.h
* TrulyHandsfree SDK C API
*/
#ifndef SNSR_H
#define SNSR_H
#if defined(__cplusplus)
extern "C" {
#endif
#include <stdarg.h>
#ifndef _WIN32
# include <unistd.h>
#endif
/*---------------------------------------------------------------------------*/
/**
* @addtogroup libsettings Library Settings
* @{
* These settings return information about the library.
* Available in all contexts, even before a task model has been loaded.
*/
/**
* License expiration warning message. Use with snsrGetString().
* This value is `NULL` for library license keys that do not expire,
* or if the expiration date is more than 60 days into the future.
* For license keys expiring in 60 days or fewer, the returned string
* will be of the form `"License will expire in 37 days."`.
*/
#define SNSR_LICENSE_WARNING "license-exp-warn"
/**
* License expiration date.
* Example:
* @code
* double e;
* time_t expdate;
* snsrGetDouble(s, SNSR_LICENSE_EXPDATE, &e);
* expdate = (time_t)e;
* @endcode
* @see snsrGetDouble().
*/
#define SNSR_LICENSE_EXPDATE "license-exp-date"
/**
* License expiration message.
* The returned string is of the form `"License expires on <date>"`, or
* `NULL` for license keys that do not expire.
* Example:
* @code
* const char *expires;
* snsrGetString(s, SNSR_LICENSE_EXPIRES, &expires);
* if (expires) fprintf(stderr, "%s\n", expires);
* @endcode
* @see snsrGetString().
*/
#define SNSR_LICENSE_EXPIRES "license-exp-message"
/**
* SDK library information.
* Convenient summary of #SNSR_NAME, #SNSR_VERSION,
* #SNSR_VERSION_DSP, #SNSR_LICENSE_EXPIRES and #SNSR_LICENSE_WARNING.
* @note The session handle must be @c NULL.
*
* Example:
* @code
* const char *libInfo;
* snsrGetString(NULL, SNSR_LIBRARY_INFO, &libInfo);
* fprintf(stderr, "%s\n", libInfo);
* snsrRelease(libInfo);
* @endcode
*/
#define SNSR_LIBRARY_INFO "library-info"
/**
* Recognition pipeline behavior.
* This boolean value controls whether snsrRun() flushes the recognition
* pipeline when one (or more) of the input streams report an end-of-file
* condition.
*
* The default value is @c 1, which enables automatic flushing on #SNSR_RC_EOF.
* This is appropriate for most applications.
* Set #SNSR_AUTO_FLUSH to @c 0 when audio is presented to snsrRun() in small
* segments.
*
* @see snsrRun().
*/
#define SNSR_AUTO_FLUSH "auto-flush"
/** @} libsettings */
/*---------------------------------------------------------------------------
* Phrase spotter
*/
/* Task type */
/**
* @addtogroup task Task Settings
* These settings are task-specific, and valid only after a task has
* been loaded into as session.
* @{
*/
/**
* Task type key.
* @see snsrGetString(), snsrRequire().
*/
#define SNSR_TASK_TYPE "task-type"
/**
* Task name key.
* @see snsrGetString()
*/
#define SNSR_TASK_NAME "task-name"
/**
* Task version key.
* These strings follow [semantic versioning](http://semver.org/) rules.
* @see snsrGetString(), snsrRequire().
*/
#define SNSR_TASK_VERSION "task-version"
/**
* @addtogroup task-spot Phrase Spotter
* See @ref task-phrasespot.
* @{
*/
/**
* Phrase spotter task type.
* @see snsrRequire().
*/
#define SNSR_PHRASESPOT "phrasespot"
/**
* Phrase spot delay in ms.
* Delays the phrase spot result while searching for a better match.
* @see snsrSetInt().
*/
#define SNSR_SPOT_DELAY "delay"
/**
* Phrase spot listening window in seconds.
* Listening window the phrase spotter is tuned for.
* `0` for continuous/unbounded listening.
* @note Information only, does not affect SDK phrase spotter behaviour.
* Does, however, affect data generated for embedded use.
* @see snsrGetInt().
*/
#define SNSR_LISTEN_WINDOW "listen-window"
/**
* Embedded device target name.
* @see snsrSetString().
*/
#define SNSR_EMBEDDED_TARGET "dsp-target"
/**
* Embedded device search header.
* @see snsrGetStream().
*/
#define SNSR_EMBEDDED_HEADER_STREAM "dsp-header-stream"
/**
* Embedded device search model.
* @see snsrGetStream().
*/
#define SNSR_EMBEDDED_SEARCH_STREAM "dsp-search-stream"
/**
* Embedded device acoustic model.
* @see snsrGetStream().
*/
#define SNSR_EMBEDDED_ACMODEL_STREAM "dsp-acmodel-stream"
/**
* Spotter operating point.
* Selects the trade-off between false accept and false reject errors for
* fixed-phrase spotters. The operating point was known as the search index
* in earlier versions of the TrulyHandsfree SDK.
* - Range is @c 1 to @c 21 inclusive.
* - Lower-numbered points have a lower false accept rate at the expense
* of higher false reject fraction.
* - The false accept rate is expressed as the expected number of false accepts
* (where the recognizer mistakenly spots the trigger phrase) per time unit.
* - The false reject rate is the percentage of times the actual trigger phrase
* is spoken, but not recognized.
* - The default operating point is selected by Sensory during trigger
* development for a good balance between the these two error types.
* - Note that not all operating points are necessarily valid. Use
* #SNSR_OPERATING_POINT_LIST to iterate over the available points.
* @see snsrGetInt(), snsrSetInt(), #SNSR_OPERATING_POINT_LIST.
*/
#define SNSR_OPERATING_POINT "operating-point"
/**
* Iterate over available spotter operating points.
* @see snsrForEach(), #SNSR_RES_AVAILABLE_POINT.
*/
#define SNSR_OPERATING_POINT_LIST "operating-point-iterator"
/**
* Available operating point.
* This read-only value is valid during #SNSR_OPERATING_POINT_LIST
* iteration callbacks only.
* @see snsrGetInt(), #SNSR_OPERATING_POINT_LIST, #SNSR_OPERATING_POINT.
*/
#define SNSR_RES_AVAILABLE_POINT "available-point"
/**
* Sample rate in Hz.
* Read-only.
* @see snsrGetInt().
*/
#define SNSR_SAMPLE_RATE "samples-per-second"
/**
* Input audio buffer size.
* The number of audio samples kept in a circular audio history buffer,
* accessible through #SNSR_AUDIO_STREAM.
*
* This buffer can be used to retrieve segmented audio using alignments
* (#SNSR_RES_BEGIN_SAMPLE, #SNSR_RES_END_SAMPLE) obtained in the
* #SNSR_RESULT_EVENT callback.
*
* Set to `0` to disable audio buffering.
* @see snsrGetInt(), snsrSetInt().
*/
#define SNSR_AUDIO_STREAM_SIZE "audio-stream-size"
/**
* Audio buffer start sample index.
* The index of the first (oldest) audio sample contained in the
* #SNSR_AUDIO_STREAM.
* @see snsrGetDouble(), snsrSetDouble().
*/
#define SNSR_AUDIO_STREAM_FIRST "audio-stream-first"
/**
* Audio buffer end sample index.
* The index of the last (most recent) audio sample contained in the
* #SNSR_AUDIO_STREAM.
* @see snsrGetDouble(), snsrSetDouble().
*/
#define SNSR_AUDIO_STREAM_LAST "audio-stream-last"
/**
* Audio stream requested start index.
* Start the next #SNSR_AUDIO_STREAM at this sample index value.
* Defaults to #SNSR_AUDIO_STREAM_FIRST.
* @see snsrGetDouble(), snsrSetDouble().
*/
#define SNSR_AUDIO_STREAM_FROM "audio-stream-from"
/**
* Audio stream requested end index.
* End the next #SNSR_AUDIO_STREAM at this sample index value.
* Defaults to #SNSR_AUDIO_STREAM_LAST.
* @see snsrGetDouble(), snsrSetDouble().
*/
#define SNSR_AUDIO_STREAM_TO "audio-stream-to"
/**
* Source audio stream.
* This audio stream must be headerless, 16-bit PCM encoded and sampled
* at 16 kHz.
* @see snsrSetStream().
*/
#define SNSR_SOURCE_AUDIO_PCM "->audio-pcm"
/**
* Sequential task has started listening on second slot.
* Raised in a sequential task when audio focust has shifted from the
* first slot to the second. This typically happens when the spotter
* in the first slot has detected the phrase.
*
* This event is ignored for tasks that do not feature sequential behavior.
*
* @see snsrSetHandler(), #SNSR_LISTEN_END_EVENT
*/
#define SNSR_LISTEN_BEGIN_EVENT "^listen-begin"
/**
* Sequential task has stopped listening on second slot.
* Raised in a sequential task when audio focus has shifted from the second slot
* back to the first.
*
* This event is ignored for tasks that do not feature sequential behavior.
*
* @see snsrSetHandler(), #SNSR_LISTEN_BEGIN_EVENT, #SNSR_LISTEN_WINDOW
*/
#define SNSR_LISTEN_END_EVENT "^listen-end"
/**
* Result available event.
* Raised when a phrase has been spotted, and the speaker verification score
* is above threshold.
*/
#define SNSR_RESULT_EVENT "^result"
/**
* Samples available event.
* Raised whenever audio samples have been read from the input stream and
* are about to be processed.
* @see snsrSetHandler().
*/
#define SNSR_SAMPLES_EVENT "^sample-count"
/**
* Number of samples read from the input stream.
* The range of this value is limited to that of the native
* @c size_t type. On 32-bit architectures the sample count value will
* typically wrap to zero after 2**32 samples.
* @see snsrGetDouble(), #SNSR_SAMPLES_EVENT
*/
#define SNSR_RES_SAMPLES "sample-count"
/* Valid in an SNSR_RESULT_EVENT callback only */
/**
* Timestamp of the audio start point.
* The offset in ms from the beginning of the audio stream where:
* - the recognition unit started, or
* - the Voice Activity Detector first detected speech.
* @see snsrGetDouble().
*/
#define SNSR_RES_BEGIN_MS "begin-ms"
/**
* Sample index of the audio start point.
* The offset in samples from the beginning of the audio stream where:
* - the recognition unit started, or
* - the Voice Activity Detector first detected speech.
* @see snsrGetDouble().
*/
#define SNSR_RES_BEGIN_SAMPLE "begin-sample"
/**
* Timestamp of the audio endpoint.
* The offset in ms from the beginning of the audio stream:
* - where the recognition unit ended, or
* - the Voice Activity Detector last detected speech.
* @see snsrGetDouble().
*/
#define SNSR_RES_END_MS "end-ms"
/**
* Sample index of the audio endpoint.
* The offset in samples from the beginning of the audio stream:
* - where the recognition unit ended, or
* - the Voice Activity Detector last detected speech.
* @see snsrGetDouble().
*/
#define SNSR_RES_END_SAMPLE "end-sample"
/**
* Fixed-phrase confidence score.
* The confidence that the spotted phrase was actually spoken.
* This is a model-dependent optional feature not universally supported. It
* is not supported by enrolled models (use #SNSR_RES_SV_SCORE instead.)
*
* @note This value is defined at the #SNSR_PHRASE_LIST level only.
*
* The reported range is @c 0 to @c 1, or @c < @c 0
* if not supported by the spotter model.
* @see snsrGetDouble()
*/
#define SNSR_RES_CONF_SCORE "confidence-score"
/**
* Speaker verification score.
* The confidence that the spotted phrase was spoken by the enrolled speaker, in
* the range @c 0 to @c 1. For non-enrolled spotters the confidence
* is always @c 1.0.
* @see snsrGetDouble(), #SNSR_SV_THRESHOLD
*/
#define SNSR_RES_SV_SCORE "sv-score"
/**
* Speaker verification threshold.
* Phrase spot results with a #SNSR_RES_SV_SCORE less than this threshold are
* not reported (the #SNSR_RESULT_EVENT handler will not be invoked.)
* @see snsrGetDouble(), snsrSetDouble(), #SNSR_RES_SV_SCORE
*/
#define SNSR_SV_THRESHOLD "sv-threshold"
/**
* Signal energy.
* The energy (in dB relative to @c 1) in the spotted phrase.
*
* @see snsrGetDouble(), #SNSR_RES_NOISE_ENERGY, #SNSR_RES_SNR
*/
#define SNSR_RES_SIGNAL_ENERGY "signal-energy"
/**
* Noise energy.
* The energy (in dB relative to @c 1) in the background audio preceding
* the spotted phrase.
*
* @see snsrGetDouble(), #SNSR_RES_SIGNAL_ENERGY, #SNSR_RES_SNR
*/
#define SNSR_RES_NOISE_ENERGY "noise-energy"
/**
* Signal to noise ratio.
* The ratio of the signal energy to the noise energy, in dB.
*
* @see snsrGetDouble(), #SNSR_RES_NOISE_ENERGY, #SNSR_RES_SIGNAL_ENERGY
*/
#define SNSR_RES_SNR "snr"
/**
* **RESERVED**. Do not use.
* @see snsrSetDouble().
*/
#define SNSR_SCORE_OFFSET "score-offset"
/**
* Recognition text result.
* The phrase, word, or phoneme result of a phrase spot.
* @see snsrGetString()
*/
#define SNSR_RES_TEXT "text"
/**
* Iterate over phrase results.
* For phrase spotters there is a single result phrase.
* @see snsrForEach().
*/
#define SNSR_PHRASE_LIST "phrase-iterator"
/**
* Iterate over the words in a result.
* User-defined enrolled results are modeled as a single word.
* @see snsrForEach().
*/
#define SNSR_WORD_LIST "word-iterator"
/**
* Iterate over the phonemes in a result.
* @see snsrForEach().
*/
#define SNSR_PHONE_LIST "phone-iterator"
/**
* Iterate over the phoneme parts in a result.
* @see snsrForEach().
*/
#define SNSR_MODEL_LIST "model-iterator"
/** @} task-spot */
/*---------------------------------------------------------------------------
* Phrase spotter enrollment constants
*/
/* Task type */
/**
* @addtogroup task-enroll Enrollment
* See @ref task-enroll
* @{
*/
/**
* Phrase spotter enrollment task type.
* @see snsrRequire()
*/
#define SNSR_ENROLL "enroll"
/**
* Enrollment accuracy.
* Trades accuracy of the enrolled model for enrollment speed.
* The default accuracy is @c 1.0, for the best accuracy at the slowest
* enrollment speed. Valid range is @c 0.0 to @c 1.0.
* @see snsrSetDouble().
*/
#define SNSR_ACCURACY "accuracy"
/**
* Interactive enrollment mode.
* This changes the enrollment task behavior: When set to @c 0, enrollment
* for the current phrase will continue until the end of the stream.
* @see snsrSetInt().
*/
#define SNSR_INTERACTIVE_MODE "interactive"
/**
* Enrolling user tag.
* Sets the tag for the current enrollment. This should be a unique
* alphanumeric phrase, without spaces. It is the phrase returned
* as a recognition result.
* @see snsrGetString(), snsrSetString(), #SNSR_USER_LIST
*/
#define SNSR_USER "user"
/**
* Delete an enrolled user.
* Deletes the named enrollment.
* @see snsrSetString().
*/
#define SNSR_DELETE_USER "delete-user"
/**
* Force re-adaptation of all enrollments.
* If all users in an enrollment task have been adapted, the adaptation
* step is skipped. This is the case when one or more adapted enrollment
* contexts are loaded, and no new users are added.
*
* Setting #SNSR_RE_ADAPT to @c 1 changes this behavior to always do the
* adaptation step.
* @see snsrSetInt(), #SNSR_ADAPTED_EVENT
*/
#define SNSR_RE_ADAPT "re-adapt"
/**
* Enrollment progress.
* A value between @c 0 and @c 100 that is an estimate of the enrollment
* task completion progress.
* @see snsrGetDouble().
*/
#define SNSR_RES_PERCENT_DONE "percent-done"
/**
* Reason for enrollment failure.
* Provides a shorthand indication of why the enrollment was rejected.
* @see snsrGetString(), #SNSR_RES_GUIDANCE.
*/
#define SNSR_RES_REASON "reason"
/**
* End-user guidance to correct enrollment failure.
* Provides a human-readable string (in English) with a suggestion on
* how to correct an enrollment failure.
* @see snsrGetString()
*/
#define SNSR_RES_GUIDANCE "reason-guidance"
/**
* Enrollment success.
* @p 1 if the enrollment passed, @p 0 if it was rejected.
* @see snsrGetInt()
*/
#define SNSR_RES_REASON_PASS "reason-pass"
/**
* Enrollment check failure value.
* The value of a enrollment check parameter. This is compared
* to #SNSR_RES_REASON_THRESHOLD to determine #SNSR_RES_REASON_PASS.
* @see snsrGetDouble()
*/
#define SNSR_RES_REASON_VALUE "reason-value"
/**
* Enrollment check threshold value.
* @see snsrGetDouble(), #SNSR_RES_REASON_VALUE
*/
#define SNSR_RES_REASON_THRESHOLD "reason-threshold"
/**
* Enrollment count.
* The number of enrollments accumulated for the enrolled user.
* @see snsrGetInt(), #SNSR_USER_LIST, #SNSR_ENROLLMENT_TARGET
*/
#define SNSR_RES_ENROLLMENT_COUNT "enrollment-count"
/**
* Enrollment ID.
* A unique ID for the current user's current enrollment.
* @see snsrGetInt(), #SNSR_ENROLLMENT_LIST.
*/
#define SNSR_RES_ENROLLMENT_ID "enrollment-id"
/**
* Enrollment target.
* The recommended number of enrollments for each user. Using either more or
* fewer enrollments will reduce overall spotter performance.
* @see snsrGetInt(), #SNSR_USER_LIST, #SNSR_RES_ENROLLMENT_COUNT
*/
#define SNSR_ENROLLMENT_TARGET "req-enroll"
/**
* Number of enrollments with trailing context.
* The recommended number of enrollments where the phrase is followed by
* additional speech. For example: "Hey Sensory will it rain tomorrow?"
* @see snsrGetInt()
*/
#define SNSR_ENROLLMENT_CONTEXT "ctx-enroll"
/**
* The index of the sub-task to enroll.
* For enrollment tasks that contain multiple sub-tasks (for example,
* a user-defined trigger and an enrolled fixed trigger), this integer
* value selects which of the sub-tasks the enrollments should be applied to.
*
* See the documentation delivered with the task file for the sub-task mapping.
*
* @note For most enrollment tasks the only supported task index is @c 0.
*/
#define SNSR_ENROLLMENT_TASK_INDEX "enrollment-task-index"
/**
* Current enrollment includes trailing context.
* Set to `1` if the enrollment recording should include trailing context,
* for example: "Hey Sensory will it rain tomorrow?"
* @see snsrGetInt(), #SNSR_RESUME_EVENT
*/
#define SNSR_ADD_CONTEXT "add-context"
/**
* Include enrollment audio in enrollment context.
* Set to @c 1 to include the enrollment audio in enrollment contexts.
* @see snsrSetInt(), #SNSR_FM_RUNTIME
*/
#define SNSR_SAVE_ENROLLMENT_AUDIO "save-enroll-audio"
/**
* Enrolled model stream.
* The result after enrollment and adaptation. This is a model that will
* recognize the enrolled phrases. Save to permanent storage with
* snsrStreamCopy().
* @see snsrGetStream(), snsrStreamCopy()
*/
#define SNSR_MODEL_STREAM "model-stream"
/**
* Segmented input audio.
* - For enrollment tasks with #SNSR_SAVE_ENROLLMENT_AUDIO is set to @c 1 (on)
* this is the enrollment recording. If #SNSR_SAVE_ENROLLMENT_AUDIO
* is @c 0 (off), audio will only be available in the #SNSR_FAIL_EVENT.
* - For phrase spotter tasks, the samples from #SNSR_AUDIO_STREAM_FROM to
* #SNSR_AUDIO_STREAM_TO selected from the last
* #SNSR_AUDIO_STREAM_SIZE samples processed by the recognizer.
* The default #SNSR_AUDIO_STREAM_SIZE is @c 0, which disables audio
* buffering and will cause #SNSR_AUDIO_STREAM stream retrieval to fail.
* Be sure to set #SNSR_AUDIO_STREAM_SIZE to the expected number of
* samples before calling snsrRun().
*
* @see snsrGetStream().
*/
#define SNSR_AUDIO_STREAM "audio-stream"
/**
* Adaptation complete event.
* Handler called when adaptation has completed and
* the #SNSR_MODEL_STREAM model is available.
* This handler typically returns #SNSR_RC_STOP to end snsrRun() processing.
* @see snsrSetHandler()
*/
#define SNSR_DONE_EVENT "^done"
/**
* Enrollment complete event.
* Handler called when enrollment is complete, just before
* model adaptation starts. Use this handler for the earliest possible
* access to the enrollment context.
* @see snsrSetHandler()
*/
#define SNSR_ENROLLED_EVENT "^enrolled"
/**
* Adaptation complete event.
* Handler called when the adaptation of an enrollment is complete,
* Use this handler for access to the adapted enrollment context.
* @see snsrSetHandler()
*/
#define SNSR_ADAPTED_EVENT "^adapted"
/**
* Enrollment failed event.
* Handler called if an enrollment fails quailty checks.
* @see snsrSetHandler()
*/
#define SNSR_FAIL_EVENT "^fail"
/**
* Enrollment succeeded event.
* Handler called when an enrollment passes quality checks.
* @see snsrSetHandler()
*/
#define SNSR_PASS_EVENT "^pass"
/**
* Next user event.
* Handler called during interactive enrollment to prompt the end-user
* for a new enrollment phrase.
* This handler should set #SNSR_USER to the tag associated with the new
* user. Leave #SNSR_USER unchanged if there are no more users or phrases
* to enroll.
* @see snsrSetHandler()
*/
#define SNSR_NEXT_EVENT "^next"
/**
* Input stream pause event.
* Handler called when a time-consuming processing step is about to start.
* Use this handler to pause the input stream when doing interactive enrollment.
* @see snsrSetHandler()
*/
#define SNSR_PAUSE_EVENT "^pause"
/**
* Adaptation progress event.
* Handler called to report adaptation progress.
* @see snsrSetHandler(), #SNSR_RES_PERCENT_DONE
*/
#define SNSR_PROG_EVENT "^progress"
/**
* Input stream resume event.
* Handler called when a time-consuming processing step has completed.
* Use this handler to restart an input stream that was stopped during
* a #SNSR_PAUSE_EVENT handler.
* @see snsrSetHandler()
*/
#define SNSR_RESUME_EVENT "^resume"
/**
* Iterate over all enrollments for the current user.
* This can be used to retrieve enrollment audio, when
* #SNSR_SAVE_ENROLLMENT_AUDIO is enabled.
* @see snsrForEach(), #SNSR_USER, #SNSR_USER_LIST, #SNSR_SAVE_ENROLLMENT_AUDIO
*/
#define SNSR_ENROLLMENT_LIST "enrollment-iterator"
/**
* Iterate over all reasons for enrollment failure.
* @see snsrForEach()
*/
#define SNSR_REASON_LIST "reason-iterator"
/**
* Iterate over all enrolled users.
* Sets #SNSR_USER to each of the enrolled users before invoking the
* callback.
* @see snsrForEach(), #SNSR_USER
*/
#define SNSR_USER_LIST "user-iterator"
/** @} task-enroll */
/*---------------------------------------------------------------------------
* Voice Activity Detector constants
*/
/**
* @addtogroup task-vad Voice Activity Detection
* See @ref task-vad
* @{
*/
/**
* VAD task type.
* @see snsrRequire()
*/
#define SNSR_VAD "vad"
/**
* Output audio stream.
* Headerless audio output, 16-bit PCM encoded and sampled at 16 kHz.
* @see snsrSetStream().
*/
#define SNSR_SINK_AUDIO_PCM "<-audio-pcm"
/**
* Start point back-off in ms.
* Audio margin added before the start point found by a Voice Activity Detector.
*
* @see snsrSetInt(), #SNSR_RES_BEGIN_MS, #SNSR_RES_BEGIN_SAMPLE.
*/
#define SNSR_BACKOFF "backoff"
/**
* Endpoint hold-over.
* Audio margin added after the endpoint found by a Voice Activity Detector.
* This is the amount of trailing silence to include in the segmentation.
*
* @see snsrSetInt(), #SNSR_RES_END_MS, #SNSR_RES_END_SAMPLE.
*/
#define SNSR_HOLD_OVER "hold-over"
/**
* Include leading silence in VAD output.
* Set to @c 1 to include all audio up to the endpoint in the
* #SNSR_SINK_AUDIO_PCM output stream. Set to @c 0 to return to the
* default behavior, which discards leading silence.
*
* @see snsrSetInt(), #SNSR_SINK_AUDIO_PCM, #SNSR_PASS_THROUGH.
*/
#define SNSR_INCLUDE_LEADING_SILENCE "include-leading-silence"
/**
* VAD leading silence time-out, in ms.
* The Voice Activity Detector will invoke the #SNSR_SILENCE_EVENT handler
* if no speech is detected during the first #SNSR_LEADING_SILENCE ms of
* processed audio.
*
* @see snsrSetInt(), #SNSR_TRAILING_SILENCE, #SNSR_SILENCE_EVENT.
*/
#define SNSR_LEADING_SILENCE "leading-silence"
/**
* VAD maximum record duration, in ms.
* The Voice Activity Detector will invoke the #SNSR_LIMIT_EVENT handler
* if the detected speech segment exceeds this value.
*
* @see snsrSetInt(), #SNSR_LIMIT_EVENT.
*/
#define SNSR_MAX_RECORDING "max-recording"
/**
* VAD audio pass-through behaviour.
* If set to @c 0, no audio from #SNSR_SOURCE_AUDIO_PCM will be passed
* through to #SNSR_SINK_AUDIO_PCM. The begin- and endpoint handlers will
* still be invoked. The default value (@c 1) passes speech-detected samples
* to #SNSR_SINK_AUDIO_PCM.
*
* @see snsrSetInt(), #SNSR_INCLUDE_LEADING_SILENCE.
*/
#define SNSR_PASS_THROUGH "pass-through"
/**
* VAD trailing silence time-out, in ms.
* The Voice Activity Detector will invoke the #SNSR_DONE_EVENT handler
* once #SNSR_TRAILING_SILENCE of ms has followed the last bit of speech.
*
* @see snsrSetInt(), #SNSR_LEADING_SILENCE, #SNSR_END_EVENT, #SNSR_HOLD_OVER.
*/
#define SNSR_TRAILING_SILENCE "trailing-silence"
/**
* VAD initial ignore duration, in ms.
* Ignore the first #SNSR_SKIP_TO_MS ms of the #SNSR_SOURCE_AUDIO_PCM input
* stream. Use this runtime setting to skip over a trigger phrase included
* in the source audio. The default is to process all audio.
*
* @see snsrSetDouble(), #SNSR_SKIP_TO_SAMPLE.
*/
#define SNSR_SKIP_TO_MS "skip-to-ms"
/**
* VAD initial ignore duration, in samples.
* Ignore the first #SNSR_SKIP_TO_SAMPLE samples of the #SNSR_SOURCE_AUDIO_PCM
* input stream. Use this runtime setting to skip over a trigger phrase included
* in the source audio. The default is to process all audio.
*
* @see snsrSetDouble(), #SNSR_SKIP_TO_MS.
*/
#define SNSR_SKIP_TO_SAMPLE "skip-to-sample"
/**
* Begin point detected VAD event.
* Raised when speech has been detected. Use #SNSR_RES_BEGIN_MS or
* #SNSR_RES_BEGIN_SAMPLE to retrieve the start point relative to the beginning
* of #SNSR_SOURCE_AUDIO_PCM.
*
* @see snsrSetHandler(), #SNSR_BACKOFF.
*/
#define SNSR_BEGIN_EVENT "^begin"
/**
* Endpoint detected VAD event.
* Raised #SNSR_TRAILING_SILENCE ms after end-of-speech has been detected.
* Use #SNSR_RES_END_MS or #SNSR_RES_END_SAMPLE to retrieve the endpoint
* relative to the beginning of #SNSR_SOURCE_AUDIO_PCM.
*
* @see snsrSetHandler(), #SNSR_HOLD_OVER, #SNSR_TRAILING_SILENCE.
*/
#define SNSR_END_EVENT "^end"
/**
* Maxium recording reached VAD event.
* Raised when #SNSR_MAX_RECORDING ms of speech has been processed by the
* Voice Activity Detector before a trailing-silence endpoint is found.
* Use #SNSR_RES_END_MS or #SNSR_RES_END_SAMPLE to retrieve the endpoint
* relative to the beginning of #SNSR_SOURCE_AUDIO_PCM.
*
* @see snsrSetHandler(), #SNSR_HOLD_OVER, #SNSR_MAX_RECORDING.
*/
#define SNSR_LIMIT_EVENT "^limit"
/**
* No speech detected event.
* Raised if no speech is detected within #SNSR_LEADING_SILENCE ms from the
* start of #SNSR_SOURCE_AUDIO_PCM (adjusted by #SNSR_SKIP_TO_MS or
* #SNSR_SKIP_TO_SAMPLE).
*
* @see snsrSetHandler(), #SNSR_LEADING_SILENCE.
*/
#define SNSR_SILENCE_EVENT "^silence"
/** @} task-vad */
/*---------------------------------------------------------------------------
* Phrase Spotter Template
*/
/**
* @addtogroup task-template Phrase Spotter Template
* See @ref task-template
* @{
*/
/**
* Template slot 0.
* The first phrase spotter slot in a template task.
* @see snsrSetStream().
*/
#define SNSR_SLOT_0 "0."
/**
* Template slot 1.
* The second phrase spotter slot in a template task.
* @see snsrSetStream().
*/
#define SNSR_SLOT_1 "1."
/** @} task-template */
/*---------------------------------------------------------------------------
* Phrase Spotter with Voice Activity Detector constants
*/
/**
* @addtogroup task-phrasespot-vad Phrase Spotter with Voice Activity Detection
* See @ref task-phrasespot-vad
* @{
*/
/**
* Phrase Spotter VAD task type.
* @see snsrRequire()
*/
#define SNSR_PHRASESPOT_VAD "phrasespot-vad"
/** @} task-phrasespot-vad */
/** @} task */
/*---------------------------------------------------------------------------*/
#include <stddef.h>
/**
* @addtogroup build-info Version Macros
* Compile-time API version information.
* @{
*/
/** SDK variant name. */
#define SNSR_NAME "TrulyHandsfree"
/** API version. Follows [semantic versioning](http://semver.org/) rules. */
#define SNSR_VERSION "5.0.0-beta.14"
/** API major version number. Incremented for API changes that are
* **not** backwards-compatible. */
#define SNSR_VERSION_MAJOR 5
/** API minor version number. Incremented for changes and improvements that
* **are** backwards-compatible. */
#define SNSR_VERSION_MINOR 0
/** API patch version number. Incremented for bug fixes. */
#define SNSR_VERSION_PATCH 0
/** Pre-release version tag. This is empty for official releases. */
#define SNSR_VERSION_PRE "beta.14"
/** Build information. This is empty for official releases. */
#define SNSR_VERSION_BUILD ""
/** Unique release version counter. */
#define SNSR_VERSION_ID 27
/** DSP embedded library version. */
#define SNSR_VERSION_DSP "4.4.0"
/** Technology level. Referred to in marketing documentation. */
#define SNSR_TECH_LEVEL "5.0"
/** @} */
/* The largest supported setting key length. */
#define SNSR_SETTING_SZ 64
/**
* @addtogroup session Session
* Primary TrulyHandsfree SDK API.
* @{
*/
/**
* Opaque session handle. This is the primary handle for SDK operations.
* Session handles contain the entire state for a task.
*
* Functions operating on the same ::SnsrSession instance handle
* must be protected from re-entrant calls with application-level locks.
*
* Synchronization and locking is not needed if each ::SnsrSession instance
* is accessed from a single thread only.
*/
typedef struct SnsrSession_ *SnsrSession;
/**
* Session serialization format.
* @see snsrSave().
*/
typedef enum {
/** All configuration settings. */
SNSR_FM_CONFIG,
/** Runtime settings only, e.g. enrollments. */
SNSR_FM_RUNTIME
} SnsrDataFormat;
/** SDK return code. #SNSR_RC_OK indicates success, anything else is a failure.
*/
typedef enum {
/** Operation completed successfully. */
SNSR_RC_OK,
/** Cannot read or write past the end of the stream. */
SNSR_RC_EOF,
/** Operation failed. */
SNSR_RC_ERROR,
/** Stream is not open. */
SNSR_RC_NOT_OPEN,
/** Resource not found. */
SNSR_RC_NOT_FOUND,
/** Out of heap memory. */
SNSR_RC_NO_MEMORY,
/** Incorrect stream mode (read or write). */
SNSR_RC_WRONG_MODE,
/** Interrupted. */
SNSR_RC_INTERRUPTED,
/** Invalid argument. */
SNSR_RC_INVALID_ARG,
/** Invalid mode. */
SNSR_RC_INVALID_MODE,
/** Cannot re-open this stream. */
SNSR_RC_CANNOT_REOPEN,
/** The stream handle is invalid. */
SNSR_RC_INVALID_HANDLE,
/** Function is not implemented for this stream type. */
SNSR_RC_NOT_IMPLEMENTED,
/** Delimiter character not encountered. */
SNSR_RC_DELIM_NOT_FOUND,
/** Stream format is not supported. */
SNSR_RC_FORMAT_NOT_SUPPORTED,
/** Buffer overrun, stream not read from in time */
SNSR_RC_BUFFER_OVERRUN,
/** Buffer underrun, stream not written to in time. */
SNSR_RC_BUFFER_UNDERRUN,
/** _Invalid return code (SNSR_RC_RESERVED_A is not used)._ */
SNSR_RC_RESERVED_A,
/** Argument value is not in the valid range. */
SNSR_RC_ARG_OUT_OF_RANGE,
/** A channel with this name already exists in the bin. */
SNSR_RC_CHANNEL_EXISTS,
/** This channel is not backed by a circular buffer. */
SNSR_RC_CHANNEL_NOT_BUFFERED,
/** Channel not found. */
SNSR_RC_CHANNEL_NOT_FOUND,
/** Source and destination channel types are not compatible. */
SNSR_RC_CHANNELS_NOT_COMPATIBLE,
/** Element settings are inconsistent. */
SNSR_RC_CONFIGURATION_INCONSISTENT,
/** Element configuration is missing. */
SNSR_RC_CONFIGURATION_MISSING,
/** Connection not found. */
SNSR_RC_CONNECTION_NOT_FOUND,
/** Destination channel not found. */
SNSR_RC_DST_CHANNEL_NOT_FOUND,
/** Destination element is not in this bin. */
SNSR_RC_DST_ELEMENT_NOT_IN_BIN,
/** The destination port is already connected. */
SNSR_RC_DST_PORT_IN_USE,
/** Element ID is not known. */
SNSR_RC_ELEMENT_ID_NOT_KNOWN,
/** Element initialization failed. */
SNSR_RC_ELEMENT_INIT_FAILED,
/** Element initialization is incomplete. */
SNSR_RC_ELEMENT_INIT_INCOMPLETE,
/** Element is not a bin, function is not available. */
SNSR_RC_ELEMENT_IS_NOT_A_BIN,
/** Element is not in this bin. */
SNSR_RC_ELEMENT_NOT_IN_BIN,
/** Element is not the root bin, function is not available. */
SNSR_RC_ELEMENT_NOT_ROOT_BIN,
/** Element registration failed. */
SNSR_RC_ELEMENT_REGISTRATION_FAILED,
/** Setting is not of the correct type. */
SNSR_RC_INCORRECT_SETTING_TYPE,
/** License validation failed. */
SNSR_RC_LICENSE_NOT_VALID,
/** Push iteration limit exceeded. */
SNSR_RC_ITERATION_LIMIT,
/** Element API processing check failed. */
SNSR_RC_ELEMENT_API_VIOLATION,
/** Name is not unique for this bin. */
SNSR_RC_NAME_NOT_UNIQUE,
/** Buffer does not have enough free space. */
SNSR_RC_NOT_ENOUGH_SPACE,
/** Element has not been initialized. */
SNSR_RC_NOT_INITIALIZED,
/** Push failed. */
SNSR_RC_PUSH_FAILED,
/** Repeated by callback. */
SNSR_RC_REPEAT,
/** Setting could not be applied. */
SNSR_RC_SETTING_FAILED,
/** Setting is read-only. */
SNSR_RC_SETTING_IS_READ_ONLY,
/** Setting is not available in this context. */
SNSR_RC_SETTING_NOT_AVAILABLE,
/** Setting not found for this element. */
SNSR_RC_SETTING_NOT_FOUND,
/** Skipped by callback. */
SNSR_RC_SKIP,
/** Source channel not found. */
SNSR_RC_SRC_CHANNEL_NOT_FOUND,
/** Source element is not in this bin. */
SNSR_RC_SRC_ELEMENT_NOT_IN_BIN,
/** The source port is already connected. */
SNSR_RC_SRC_PORT_IN_USE,
/** Stopped by callback. */
SNSR_RC_STOP,
/** Stream operation failed. */
SNSR_RC_STREAM,
/** End-of-stream reached. */
SNSR_RC_STREAM_END,
/** Unknown configuration object type. */
SNSR_RC_UNKNOWN_OBJECT_TYPE,
/** Setting has no configured value. */
SNSR_RC_VALUE_NOT_SET,
/** _Invalid return code (SNSR_RC_RESERVED_B is not used)._ */
SNSR_RC_RESERVED_B,
/** No task model data found. */
SNSR_RC_NO_MODEL,
/** Task value does not match requirement. */
SNSR_RC_REQUIRE_MISMATCH,
/** Task version does not match the requirement. */
SNSR_RC_VERSION_MISMATCH,
/**
* The header file version does not match that of the library.
* SNSR_VERSION in snsr.h does not match the version the
* library archive was compiled with. Check include paths.
*/
SNSR_RC_LIBRARY_HEADER,
/**
* TrulyHandsfree library is too old.
* Loading of a new task failed as it requires features that are not
* available in this release of the library. Please contact Sensory for
* assistance.
* @see snsrLoad(), #SNSR_VERSION
*/
SNSR_RC_LIBRARY_TOO_OLD,
/** Operation timed out. */
SNSR_RC_TIMED_OUT,
} SnsrRC;
/**
* @addtogroup callback User Callbacks
* User-defined callback functions with associated data.
* A #SnsrCallback handle encapsulates a user-defined function with the
* #SnsrHandler signature, arbitrary user data as a `void *`, and a clean-up
* function used to release the user data when the SnsrCallback handle is
* released.
*
* #SnsrCallback handles are used for all events generated by #SnsrSession.
* @{
*/
/**
* Callback handle.
* @todo Add detail.
*/
typedef struct SnsrCallback_ *SnsrCallback;
/**
* Process event callbacks.
* Called when a ::SnsrCallback instance is invoked.
*
* @param[in] s the ::SnsrSession handle the callback was registered with.
* @param[in] key the name of the invoked ::SnsrSession callback setting.
* @param[in,out] data user pointer, the @p data parameter of snsrCallback().
* @return #SNSR_RC_OK if all is well. Errors are reported to the
* code that invoked the callback. #SNSR_RC_STOP is typically used to
* terminate snsrFlowRun() or snsrForEach().
*/
typedef SnsrRC (*SnsrHandler)(SnsrSession s, const char *key, void *data);
/**
* Release private user data.
* Called to release the private user data associated with a ::SnsrCallback
* when it is deleted.
*
* @param[in] data user pointer, the @p data parameter of snsrCallback().
*/
typedef void (*SnsrDataRelease)(const void *data);
/**
* Creates a new ::SnsrCallback instance. These are used to invoke
* library callbacks and iterators.
* - New handles have a reference count of `0`. Use snsrRetain()
* if keeping a reference and snsrRelease() to release such a reference.
* - ::SnsrHandler @p h will be called when this callback is invoked.
* - ::SnsrDataRelease @p r will be called when the callback reference count
* reaches `0` and is deleted. @p r must release the user @p data structure.
*
* @param[in] h the function to call when this callback is invoked.
* @param[in] r a function that releases @p data when the callback is destroyed.
* Use `NULL` if no clean-up is required.
* @param[in] data private user pointer.
* @return A new callback instance.
* `NULL` if `h` is `NULL` or heap allocation failed.
* @see snsrRun(), snsrForEach().
*/
SnsrCallback
snsrCallback(SnsrHandler h, SnsrDataRelease r, void *data);
/** @} callback */
/** @} session */
/**
* @addtogroup stream Stream
* Stream abstraction API.
* This section describes the stream abstraction through which all
* ::SnsrSession inputs and outputs are vectored.
*
* The stream API is small and has well-defined semantics. Streams
* can be created on different underlying data streams (file names, `FILE *`
* handles, memory segments, live audio sources and sinks, and so on).
* Only the @ref stream-provider are type-specific,
* all other functions are independent of the underlying stream type.
* @ref stream-ops that take ::SnsrStream handles as arguments operate on any of
* the types. The same recognition function, for example, could be used
* to recognize from file or live input.
*
* ::SnsrStream handles are reference-counted (snsrRetain(), snsrRelease()).
* Handles are disposed of when their reference counts reach zero.
* New handles are created with a reference count of `0`.
*
* No operations are done on the underlying data provider until
* snsrStreamOpen() is called, and no operations are done after
* snsrStreamClose() has been called.
*
* @note The current implementation does not do any thread-level locking.
* Threaded access to stream handles must be protected by explicit
* synchronization calls.
*
* @{
*/
/**
* @addtogroup stream-ops Operations
* Stream operations.
* Functions in this group are used for basic ::SnsrStream operations, such
* as opening, reading, writing and closing streams. Additional utility
* functions are provided to print formatted data to a stream, and to
* inspect stream state.
*
* The error state of a ::SnsrStream handle persists only until the next
* operation on the stream. This behaviour differs from ::SnsrSession errors,
* which must be cleared explicitly.
*
* These functions do not change ::SnsrStream handle reference counts.
* They are therefore safe to use on handles where reference count is zero.
* @{
*/
/**
* Opaque stream handle.
* All ::SnsrSession input and output is vectored through this type.
*/
typedef struct SnsrStream_ *SnsrStream;
/**
* Stream introspection key.
* @see snsrStreamGetMeta().
*/
typedef enum {
/** Number of bytes read from the stream. */
SNSR_ST_META_BYTES_READ,
/** Number of bytes written to the stream. */
SNSR_ST_META_BYTES_WRITTEN,
/** Boolean, 1 if the stream is open. */
SNSR_ST_META_IS_OPEN,
/** Boolean, 1 if the stream is readable. */
SNSR_ST_META_IS_READABLE,
/** Boolean, 1 if the stream is writable. */
SNSR_ST_META_IS_WRITABLE,
/** Number of times the stream has been opened. */
SNSR_ST_META_OPEN_COUNT,
} SnsrStreamMeta;
/**
* Reports stream end status.
* Returns `1` if the stream has reached its end.
* * Follows Unix semantics:
* - The end-of-stream indicator is only valid after a read attempt.
* - A read on a ::SnsrStream `b` could very well return `0`, even if
* `snsrStreamAtEnd(b)` returned `0` just before attempting the read.
* * Equivalent to `(snsrStreamRC(b) == SNSR_RC_EOF)`.
*
* @param[in] b ::SnsrStream handle.
* @return A boolean value, `1` if at end-of-stream, `0` if not.
* @see snsrStreamRC().
*/
int
snsrStreamAtEnd(SnsrStream b);
/**
* Closes an open stream.
* - Any remaining buffered output is flushed.
* - Any remaining buffered input is discarded.
* - Closing a stream that is not open is not an error.
* - This does not destroy the ::SnsrStream data structure,
* use snsrRelease() to do so.
* - Streams that are still open when the last reference is removed
* are closed before the handle is released.
*
* @param[in] b stream to close.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrStreamClose(SnsrStream b);
/**
* Copies from SnsrStream to SnsrStream.
* - Opens @p dst and @p src if these streams are not already open.
* - Copies @p sizeInBytes bytes from @p src to @p dst, then returns the
* number of bytes successfully written to @p dst.
* - If an error occurred (including an end-of-stream condition on either
* @p dst or @p src) the return value will be less than @p sizeInBytes.
* - Errors in @p src are copied to @p dst; use `snsrStreamRC(dst)` to
* retrieve these.
*
* @param[in] dst destination stream.
* @param[in] src source stream.
* @param[in] sizeInBytes number of bytes to copy from @p src to @p dst.
* @return The number of bytes successfully written to @p dst.
* @see snsrStreamRC().
*/
size_t
snsrStreamCopy(SnsrStream dst, SnsrStream src, size_t sizeInBytes);
/**
* Retrieves a detailed stream error message.
* - This human-readable error message containing the reason for failure.
* - Use for display or logging only, as the content of the message is
* unspecified and system-specific.
* - Do not parse this to determine program flow,
* use the ::SnsrRC return code instead.
*
* @param[in] b stream to examine.
* @return A detailed message describing the most recent reason for failure
* in ::SnsrStream @p b.
* The memory pointed to is owned by this library and must not be
* released. It is not reference-counted, calling snsrRetain() or
* snsrRelease() on this handle will panic the heap allocator.
* The handle remains valid only until the next API call on @p b.
*/
const char *
snsrStreamErrorDetail(SnsrStream b);
/**
* Reads one line from a stream.
* Reads a line from stream @p b, delimited by the character @p delim into
* @p buffer. This is similar to `getdelim()`, except that it operates on
* a ::SnsrStream and does not allocate memory for the destination buffer.
*
* - Opens the @p b stream if it is not already open.
* - Reads up to `bufferSize - 1` bytes from @p b into @p buffer, stops when
* @p delim has been read (@p buffer will include @p delim).
* Terminates the string in @p buffer with `\0` and
* returns the number of characters read (not including the terminating `\0`).
* - If the delimiter is not found after reading `bufferSize - 1` bytes, the
* error code in @p b is set to #SNSR_RC_DELIM_NOT_FOUND.
* - `buffer != NULL` and `bufferSize >= 2` is required.
* - `buffer` will contain all characters read and will be terminated with `\0`,
* even if an error occurs.
*
* @param[in] b input stream.
* @param[out] buffer destination buffer.
* @param[in] bufferSize size of @p buffer in bytes.
* @param[in] delim delimiter character to search for.
* @return The number of characters read and placed into @p buffer.
*/
size_t
snsrStreamGetDelim(SnsrStream b, void *buffer, size_t bufferSize, int delim);
/**
* Queries stream metadata.
* Returns ::SnsrStream metadata, selected by the ::SnsrStreamMeta @p key.
* If an error occurs this function returns `0` and sets the error state in
* stream @p b. Use snsrStreamRC() to check the error state.
*
* @param[in] b stream to query.
* @param[in] key query type.
* @return The integer value for @p key.
* @see snsrStreamRC().
*/
size_t
snsrStreamGetMeta(SnsrStream b, SnsrStreamMeta key);
/**
* Opens a stream.
* - Read and write operations are valid only on open streams.
* - Newly created streams are not open.
* - Streams are always opened in binary mode.
* - Some stream types can be closed and re-opened. This behaviour is
* documented in the `snsrStreamFrom*` section for each stream type. If
* re-opening is not supported snsrStreamOpen() will return
* #SNSR_RC_CANNOT_REOPEN when an attempt is made to open it a second time.
*
* @param[in] b stream to open.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrStreamOpen(SnsrStream b);
/**
* Prints a formatted string to a stream.
* This function is similar to `fprintf()`, but operates on a ::SnsrStream
* instead of a `FILE *`.
* Opens the @p b stream if it is not already open.
* If an error occurs this function returns `0` and sets the error state in
* stream @p b. Use snsrStreamRC() to check the error state.
*
* @param[in] b destination stream.
* @param[in] format `fprintf()` style format string.
* @param[in] ... arguments specified by the @p format string.
* @return The number of bytes written to @p b, or 0 if an error occurred.
* @see snsrStreamRC().
*/
size_t
snsrStreamPrint(SnsrStream b, const char *format, ...);
/**
* Retrieves the most recent return code for a stream.
*
* @param[in] b stream to examine.
* @return The ::SnsrRC code from stream @p b.
*/
SnsrRC
snsrStreamRC(SnsrStream b);
/**
* Reads from a stream into a memory location.
* - Opens the @p a stream if it is not already open.
* - Reads @p nitems items, each @p size bytes long, from the stream @p b
* into @p buffer and returns the number of items read.
* - If either @p size or @p nitems is zero this function returns `0` without
* reading anything.
* - A short read (number of items read less than @p nitems) will occur only
* if the end of the stream was reached before @p nitems were read, or if
* an error occurred. The stream return code will be set appropriately.
* Use snsrStreamAtEnd() or snsrStreamRC() to distinguish between these
* conditions.
* - If the end of the stream is encountered in the middle of an object, it
* returns the number of complete items read. The partial object is
* discarded and the stream remains in the end-of-stream condition.
* - Read operations block until all the requested data have been read, or
* an error or end-of-stream is encountered.
*
* @param[in] a stream to read from.
* @param[out] buffer memory to write to.
* @param[in] size the size of an item, in bytes.
* @param[in] nitems the number of items to read.
* @return The number of items read.
* @see snsrStreamAtEnd(), snsrStreamRC(), snsrStreamSkip().
*/
size_t
snsrStreamRead(SnsrStream a, void *buffer, size_t size, size_t nitems);
/**
* Reads from a stream and discards the results.
* This function is similar to snsrStreamRead(), but discards the read data
* instead of writing it to a memory buffer.
*
* @param[in] a stream to read from.
* @param[in] size the size of an item, in bytes.
* @param[in] nitems the number of items to read and discard.
* @return The number of items read.
* @see snsrStreamAtEnd(), snsrStreamRC(), snsrStreamRead().
*/
size_t
snsrStreamSkip(SnsrStream a, size_t size, size_t nitems);
/**
* Writes from a buffer to a stream.
* - Opens the @p a stream if it is not already open.
* - Writes @p nitems items, each @p size bytes long, to the stream @p b,
* obtaining them from @p buffer. Returns the number of items written.
* - Returns less than @p nitems only if an error occurred. Use
* snsrStreamRC() to obtain the error code.
* - Write operations block until the requested data have been transferred
* to the underlying implementation, but may return well before the
* data have reached their final destination (written to disk, played from
* a speaker, etc.)
*
* @param[in] a stream to write to.
* @param[in] buffer memory to read from.
* @param[in] size the size of an item, in bytes.
* @param[in] nitems the number of items to write.
* @return The number of items written.
* @see snsrStreamRC().
*/
size_t
snsrStreamWrite(SnsrStream a, const void *buffer, size_t size, size_t nitems);
/** @} stream-ops */
/**
* @addtogroup stream-provider Type Constructors
* This section describes the predefined stream type constructors.
*
* ::SnsrStream wrappers are provided for `<stdio.h>` files, memory segments,
* FIFO buffers and audio recording devices. Additional types provide
* support for ::SnsrStream transformations, such as concatenation and
* format conversion.
*
* Functions in this group that take ::SnsrStream arguments retain these
* handles and release them when they are no longer used. A ::SnsrStream
* handle with a zero reference count used as an argument will therefore
* be deallocated when it is no longer needed. Be sure to call
* snsrRetain() on handles that need to survive these function
* invocations.
*
* @todo Add SnsrStream Provider example, such as snsrStreamFromAsset()
* @{
*/
/**
* Process stream event callbacks.
* Functions of this type are called when a snsrStreamRaise() stream
* type is opened.
*
* @param[in] s the ::SnsrStream that was opened.
* @param[in] data user pointer, the @p data parameter of snsrStreamRaise()
* @return #SNSR_RC_OK if all is well. Errors are reported to the
* code that raised the callback, such as snsrStreamOpen().
*/
typedef SnsrRC (*SnsrStreamEvent)(SnsrStream s, void *data);
/**
* Stream audio format specifier.
* @see snsrStreamFromAudioDevice(), snsrStreamFromAudioStream().
*/
typedef enum {
/**
* Read-only default audio stream format.
*/
SNSR_ST_AF_DEFAULT,
/**
* Read-only default audio stream format, low latency.
* Low latency, at the expense of higher CPU overhead.
*/
SNSR_ST_AF_DEFAULT_LOW_LATENCY,
/**
* Read-only 16-bit little-endian LPCM at 16 kHz.
*/
SNSR_ST_AF_LPCM_S16_16K,
/**
* Read-only 16-bit little-endian LPCM at 16 kHz, low latency.
* Low latency, at the expense of higher CPU overhead.
*/
SNSR_ST_AF_LPCM_S16_16K_LOW_LATENCY,
/**
* Read-only 16-bit little-endian LPCM with a user-specified device.
* Expected args
* @code const char *device @endcode
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVICE, "default");
* @endcode
*/
SNSR_ST_AF_DEVICE,
/**
* Read-only 16-bit LE LPCM with a user-specified device, low latency.
* Low latency, at the expense of higher CPU overhead.
* Expected args
* @code const char *device @endcode
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVICE_LOW_LATENCY, "default");
* @endcode
*/
SNSR_ST_AF_DEVICE_LOW_LATENCY,
/**
* Read-only 16-bit LE LPCM, user-specified device, sample rate, and mode.
* Expected args:
* @code const char *device, unsigned int rate, SnsrStreamMode mode @endcode
*
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVICE_RATE_MODE,
* "default", 16000, SNSR_ST_MODE_READ);
* @endcode
*/
SNSR_ST_AF_DEVICE_RATE_MODE,
/**
* Read-only 16-bit LE LPCM, device, rate, and mode. Low latency.
* Low latency, at the expense of higher CPU overhead.
*
* Expected args:
* @code const char *device, unsigned int rate, SnsrStreamMode mode @endcode
*
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVICE_RATE_MODE_LOW_LATENCY,
* "default", 16000, SNSR_ST_MODE_READ);
* @endcode
*/
SNSR_ST_AF_DEVICE_RATE_MODE_LOW_LATENCY,
/**
* Read-only 16-bit little-endian LPCM with a user-specified device.
* Expected args
* @code int devid @endcode
*
* @note On Windows, @c devid is the device ID used with
* the Multimedia Extensions, such as [waveInGetDevCaps()][1].
*
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVID, 0);
* @endcode
*
* [1]: https://msdn.microsoft.com/en-us/library/dd743841(v=vs.85).aspx
*/
SNSR_ST_AF_DEVID,
/**
* Read-only 16-bit LE LPCM with a user-specified device, low latency.
* Low latency, at the expense of higher CPU overhead.
* Expected args
* @code int devid @endcode
*
* @note On Windows, @c devid is the device ID used with
* the Multimedia Extensions, such as [waveInGetDevCaps()][1].
*
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVID_LOW_LATENCY, 0);
* @endcode
*
* [1]: https://msdn.microsoft.com/en-us/library/dd743841(v=vs.85).aspx
*/
SNSR_ST_AF_DEVID_LOW_LATENCY,
/**
* Read-only 16-bit LE LPCM, user-specified device, sample rate, and mode.
* Expected args:
* @code int devid, unsigned int rate, SnsrStreamMode mode @endcode
*
* @note On Windows, @c devid is the device ID used with
* the Multimedia Extensions, such as [waveInGetDevCaps()][1].
*
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVID_RATE_MODE,
* 0, 16000, SNSR_ST_MODE_READ);
* @endcode
*
* [1]: https://msdn.microsoft.com/en-us/library/dd743841(v=vs.85).aspx
*/
SNSR_ST_AF_DEVID_RATE_MODE,
/**
* Read-only 16-bit LE LPCM, device, rate, and mode. Low latency.
* Low latency, at the expense of higher CPU overhead.
*
* Expected args:
* @code int devid, unsigned int rate, SnsrStreamMode mode @endcode
*
* @note On Windows, @c devid is the device ID used with
* the Multimedia Extensions, such as [waveInGetDevCaps()][1].
*
* Example:
* @code
* b = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVID_RATE_MODE_LOW_LATENCY,
* 0, 16000, SNSR_ST_MODE_READ);
* @endcode
*
* [1]: https://msdn.microsoft.com/en-us/library/dd743841(v=vs.85).aspx
*/
SNSR_ST_AF_DEVID_RATE_MODE_LOW_LATENCY,
} SnsrStreamAudioFormat;
/**
* Stream input or output mode.
* @see snsrStreamFromFILE(), snsrStreamFromMemory().
*/
typedef enum {
/** Read from this input stream. */
SNSR_ST_MODE_READ,
/** Write to this output stream. */
SNSR_ST_MODE_WRITE,
} SnsrStreamMode;
#if defined(__ANDROID__) || defined(DOXYGEN)
#include <android/asset_manager_jni.h>
/**
* Wraps a stream around an Android asset.
* Creates a new read-only ::SnsrStream on @p filename in the compressed assets
* section of an Android application.
* @p filename is relative to `assets/` and should not include this as part
* of the name.
* @note Available on Android SDKs only.
* @param[in] mgr Android [AAssetManager][1] object.
* @param[in] filename path to the asset, relative to the `assets/` directory.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
* [1]: https://developer.android.com/ndk/reference/group___asset.html
*/
SnsrStream
snsrStreamFromAsset(AAssetManager *mgr, const char *filename);
#endif
#include <stdio.h>
/**
* Wraps a stream around a FILE handle.
* Creates a new ::SnsrStream from on a @c &lt;stdio.h&gt;
* @c FILE @c * handle.
* Calls to snsrStreamClose() on this handle will not close the
* wrapped @c FILE @c *.
* This ::SnsrStream type does not support re-opening.
* Example:
* @code
* SnsrStream out = snsrStreamFromFILE(stderr, SNSR_ST_MODE_WRITE);
* snsrStreamOpen(out);
* snsrStreamPrint(out, "hello world\n");
* snsrRelease(out);
* @endcode
* @note Requires @c FILE support in the standard C library.
* @param[in] handle @c FILE @c *, typically @c stdout or @c stderr.
* @param[in] mode open for reading or writing, but not both.
* @return A new ::SnsrStream handle or @c NULL if memory allocation failed.
*/
SnsrStream
snsrStreamFromFILE(FILE *handle, SnsrStreamMode mode);
/**
* Wraps a stream around a stdio file.
* Creates a new ::SnsrStream using the @c &lt;stdio.h&gt; file functions.
*
* Only a subset of the @c fopen() modes are supported:
* - @c r for read-only access.
* - @c w for write-only access, truncating the file to zero on open.
* - @c a for write-only append access.
*
* This stream type supports re-opening. The behaviour follows that of
* @c fopen() with the given access mode.
*
* @note Requires @c FILE support in the standard C library.
* @param[in] filename the name of a file to open.
* @param[in] mode @c r, @c w, or @c a.
* @return A new ::SnsrStream handle or @c NULL if memory allocation failed.
*/
SnsrStream
snsrStreamFromFileName(const char *filename, const char *mode);
/**
* Streams live audio from an audio capture device.
* Creates a new ::SnsrStream attached to the specified audio device.
*
* @note Supports Linux audio capture with [ALSA][1], and Windows capture
* using the [Windows Multimedia Extentions][2] Wave API.
*
* #SNSR_ST_AF_DEFAULT uses the default capture device with the format
* (16-bit little-endian LPCM) and sample rate (16 kHz) required by most
* SDK recognizers. This is the recommended format specifier.
*
* Example:
* @code
* // Use a specific ALSA device, rather than the default.
* // The "plughw" device typically includes sample rate conversion,
* // use this if the hardware does not support sampling at 16 kHz.
* SnsrStream a = snsrStreamFromAudioDevice(SNSR_ST_AF_DEVICE, "plughw:1,0");
* @endcode
*
* @param[in] format Audio device selector and format specifier.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
* @see @ref alsa-stream.c, @ref wmme-stream.c
*
* [1]: http://www.alsa-project.org/main/index.php/ALSA_Library_API
* [2]: https://msdn.microsoft.com/en-us/library/dd743847(v=vs.85).aspx
*/
SnsrStream
snsrStreamFromAudioDevice(SnsrStreamAudioFormat format, ...);
/**
* Converts stream audio format.
* Creates a new ::SnsrStream on an existing stream, @p a. The new
* stream produces audio in @p format, converting as needed.
*
* The audio format header in @p a will be read when the stream is first opened.
* * If this is a known, but unsupported format, snsrStreamOpen() will report
* an error.
* * If the format is not known, the data in @p a will be treated as
* a headerless little-endian 16-bit LPCM stream.
*
* The initial implementation supports the 16-bit LPCM RIFF WAVE format,
* at 16 kHz sampling rate, for a single channel only.
*
* Example:
* @code
* SnsrStream a = snsrStreamFromFileName("hbg.wav", "r");
* a = snsrStreamFromAudioStream(a, SNSR_ST_AF_DEFAULT);
* snsrStreamOpen(a);
* // read 16-bit PCM data from a
* snsrRelease(a);
* @endcode
* @param[in] a source ::SnsrStream.
* @param[in] format output target audio format.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamFromAudioStream(SnsrStream a, SnsrStreamAudioFormat format, ...);
/**
* Wraps a stream around a circular buffer.
* Creates a new ::SnsrStream on a circular buffer with first-in-first-out
* semantics.
* The initial buffer will be large enough to hold @p initialSizeInBytes
* `char`s, and will dynamically grow up to @p maxSizeInBytes.
* If the ::SnsrStream the bufffer cannot be expanded, snsrStreamWrite() will
* set the ::SNSR_RC_EOF condition on the stream.
* This ::SnsrStream type does not support re-opening.
* @note snsrStreamRead() on streams of this type has non-blocking behavior,
* and will return #SNSR_RC_EOF if the buffer runs empty.
*
* @param[in] initialSizeInBytes the minimum size of the allocated ring buffer.
* @param[in] maxSizeInBytes the limit the buffer is allowed to expand to.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamFromBuffer(size_t initialSizeInBytes, size_t maxSizeInBytes);
/**
* Wraps a stream around a memory segment.
* Creates a new ::SnsrStream on a memory segment starting at @p buffer.
* ::SnsrStream operations will be limited to the first @p bufferSize bytes
* of this segment.
* This ::SnsrStream type does not support re-opening.
*
* Example:
* @code
* char *data = malloc(1000);
* SnsrStream b = snsrStreamFromMemory(data, 1000, SNSR_ST_MODE_WRITE);
* snsrStreamOpen(b);
* snsrStreamPrint(b, "hello world, data=%p\n", data);
* snsrRelease(b);
* printf("wrote: %s\n", data);
* free(data);
* @endcode
* @param[in] buffer pointer to a memory segment.
* @param[in] bufferSize size of the memory segment the stream has access to.
* @param[in] mode open for reading or writing, but not both.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamFromMemory(void *buffer, size_t bufferSize, SnsrStreamMode mode);
/**
* Wraps a stream around an open stream.
* Creates a new ::SnsrStream on an existing, open ::SnsrStream.
* The new stream mode (read or write) matches the @p source stream.
* Read and write operations are passed through to the @p source stream, but
* the number of bytes read or written is limited to @p sizeInBytes.
* In- and output operations will set the stream status to #SNSR_RC_EOF
* when this limit is reached.
*
* This function will retain @p source, and release it when the stream
* is closed. Be sure to snsrRetain() the @p source handle if it is to
* remain valid.
* Closing this ::SnsrStream will not close @p source.
*
* @param[in] source source stream.
* @param[in] sizeInBytes new stream read or write limit.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamFromOpenStream(SnsrStream source, size_t sizeInBytes);
/**
* Concatenates two streams.
* Creates a new ::SnsrStream that is a concatenation of @p a and @p b.
*
* Streams @p a and @p b will be each be opened exactly once. These should
* be unopened (snsrStreamGetMeta() for #SNSR_ST_META_OPEN_COUNT must be `0`)
* when snsrStreamFromStreams() is called.
* This limitation does not apply to streams returned by this function,
* these can be nested to arbitrary depth to concatenate more than two
* streams.
*
* The new stream will read from (or write to) @p a until end-of-stream
* is reached, then switch to stream @p b until that is exhausted,
* at which point #SNSR_RC_EOF is returned.
*
* Streams @p a and @p b must have identical modes. If one stream was opened
* for reading, and the other for writing, this function will set the
* error code to #SNSR_RC_WRONG_MODE.
*
* Closing this stream will close the current source stream. The next
* open call will open the next source stream. When no further source
* streams remain snsrStreamOpen() returns #SNSR_RC_CANNOT_REOPEN.
*
* Example:
* @code
* SnsrStream s;
* s = snsrStreamFromStreams(
* snsrStreamFromFileName("one.txt", "w"),
* snsrStreamFromStreams(snsrStreamFromFileName("two.txt", "w"),
* snsrStreamFromFILE(stdout, SNSR_ST_MODE_WRITE)));
* snsrStreamOpen(s);
* snsrStreamPrint(s, "This writes to \"one.txt\"\n");
* snsrStreamClose(s);
* snsrStreamOpen(s);
* snsrStreamPrint(s, "This writes to \"two.txt\"\n");
* snsrStreamClose(s);
* snsrStreamOpen(s);
* snsrStreamPrint(s, "This writes to stdout\n");
* snsrRelease(s);
* @endcode
*
* @param[in] a first source stream.
* @param[in] b second source stream.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamFromStreams(SnsrStream a, SnsrStream b);
/**
* Wraps a stream around a C string.
* Creates a new read-only ::SnsrStream from a zero-terminated C string.
*
* Equivalent to:
* @code
* snsrStreamFromMemory(string, strlen(string), SNSR_ST_MODE_READ);
* @endcode
* This stream type does not support re-opening.
*
* @param[in] string a `\0`-terminated C string.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamFromString(const char *string);
/**
* Inserts an event marker into a stream.
* Creates a new ::SnsrStream that is readable, but provides no data.
* Any read or skip operation will immediately return end-of-stream.
*
* Calls `e(b, data)` when ::SnsrStream `b` is opened, unless `e == NULL`.
*
* Calls `r(data)` when `b` is released, unless `r == NULL`.
* This function should release the `data` handle.
*
* Use this stream type with snsrStreamFromStreams() to embed
* events in a stream.
*
* @param[in] e the function to call when this stream is opened. Must not
* be `NULL`.
* @param[in] r a function that releases @p data when this stream is
* deallocated. Use `NULL` if no clean-up is required.
* @param[in,out] data user pointer, the @p data parameter of ::SnsrStreamEvent.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStreamRaise(SnsrStreamEvent e, SnsrDataRelease r, void *data);
/** @} stream-provider */
/** @addtogroup stream-spi Provider API
* This section describes the Service Provider Interface used
* to add new ::SnsrStream types.
*
* Each ::SnsrStream type exposes a single API function used to create a
* new instance of this type. This constructor function sets up the required
* data structures, copies function arguments into these structures and then
* calls snsrStream_alloc() to allocate a new ::SnsrStream, which it returns.
*
* The constructor function must **not** open the underlying data stream. The
* SnsrStream_Vmt::open() callback function will be used to do this instead.
* Delaying the open operation allows for function compositions, such as a
* ::SnsrStream that concatenates other ::SnsrStream s.
*
* @{
*/
/* SnsrStream plug-in SPI */
/** SnsrStream virtual method table.
* This method table defines stream behaviour when used as an argument to
* snsrStream_alloc(). This struct must remain valid for the entire life of
* all the streams of this type. Static allocation is recommended.
*
* When one of these functions return (open, close) or set (read, write)
* a ::SnsrRC error code other than #SNSR_RC_OK, and additional
* error detail is available, it should also set a detailed human-readable
* error message using snsrStream_setDetail().
*
* Error codes must be in the range
* from #SNSR_RC_OK to #SNSR_RC_FORMAT_NOT_SUPPORTED.
*/
typedef struct {
/** The name of the stream type, terminated with \\0.
* This field is required and must not be NULL.
*/
const char *name;
/** Opens the underlying data stream.
* - Called in response to a snsrStreamOpen() API call.
* - Will only be called on closed SnsrStream handles.
* - Must open the underlying stream in binary mode, unless documented
* otherwise.
* - Must return #SNSR_RC_OK if the operation succeeded, and an
* error code if the resource could not be opened.
*/
SnsrRC (*open)(SnsrStream b);
/** Closes the underlying data stream.
* - Called in response to a snsrStreamClose() API call.
* - Will only be called on open SnsrStream handles.
* - Buffered output must be flushed.
* - Buffered input must be discarded.
* - Must return #SNSR_RC_OK if the operation succeeded,
* and an error code if the underlying resource could not be closed.
*/
SnsrRC (*close)(SnsrStream b);
/** Releases private SnsrStream data.
* - Called just before the SnsrStream handle is de-allocated.
* - The handle will have been closed when this function is called -
* there is no need to check.
* - Must release resources allocated by the types creation function.
*/
void (*release)(SnsrStream b);
/** Reads data and makes it available as a SnsrStream.
* - Called in response to a snsrStreamRead() API call.
* - The handle will be open when this function is called and
* @p sizeInBytes @c > @c 0.
* - Must read @p sizeInBytes bytes into the buffer pointed to by data.
* - The read must block (i.e. not return) until all the requested data
* have been read, or an error is encountered.
* - Must return the number of actual bytes read.
* - This number of bytes read must be @p sizeInBytes, unless:
* * An error occurred, in which case snsrStream_setRC(b, <error>)
* with an appropriate error code must be called.
* * The end of the stream was reached, in which case
* snsrStream_setRC(b, SNSR_RC_EOF) must be called.
*/
size_t (*read)(SnsrStream b, void *data, size_t sizeInBytes);
/** Writes data to the underlying data stream.
* - Called in response to a snsrStreamWrite() API call.
* - The handle will be open when this function is called
* and @p sizeInBytes @c > @c 0.
* - Must write @p sizeInBytes bytes, reading them from the buffer
* pointed to by data.
* - The write must block (i.e. not return) until all of the
* requested data have been written to the underlying stream,
* or an error is encountered.
* - Must return the number of bytes actually written.
* - This number of bytes must be @p sizeInBytes, unless an error occurred,
* in which case snsrStream_setRC(b,) must be called with an
* appropriate error code.
*/
size_t (*write)(SnsrStream b, const void *data, size_t sizeInBytes);
} SnsrStream_Vmt;
/**
* Allocates a new ::SnsrStream.
* Called to allocate a new ::SnsrStream data structure, typically in
* the type-specific creation function.
*
* The behaviour of the new ::SnsrStream type is defined by the @p def
* virtual method table.
*
* @p data is an arbitrary pointer that can be retrieved from the
* ::SnsrStream handle with snsrStream_getData(). It is typically used
* to hold instance-specific data.
*
* @param[in] def virtual method table.
* @param[in] data user pointer.
* @param[in] readable `1` if the stream can be read from `0` if not.
* @param[in] writable `1` if the stream can be written to, `0` if not.
* @return A new ::SnsrStream handle or `NULL` if memory allocation failed.
*/
SnsrStream
snsrStream_alloc(SnsrStream_Vmt *def, void *data, int readable, int writable);
/**
* Gets the user data pointer from a stream.
* Returns the @p data parameter passed to snsrStream_alloc().
*
* @param[in] b ::SnsrStream handle.
* @return The @p data pointer for this stream instance.
*/
void *
snsrStream_getData(SnsrStream b);
/**
* Gets the virtual method table from a stream.
* Returns the ::SnsrStream_Vmt @p *def parameter passed to snsrStream_alloc().
*
* @param[in] b ::SnsrStream handle.
* @return The @p def ::SnsrStream_Vmt virtual method table pointer for this
* stream instance.
*/
SnsrStream_Vmt *
snsrStream_getVmt(SnsrStream b);
/**
* Sets stream return code.
* Sets the return code for ::SnsrStream @p h to @p code.
*
* Only a subset of the ::SnsrRC return codes are valid for streams,
* @p code must be in the range from
* #SNSR_RC_OK to #SNSR_RC_FORMAT_NOT_SUPPORTED.
*
* @param[in] h ::SnsrStream handle.
* @param[in] code Return code, #SNSR_RC_OK for success.
*/
void
snsrStream_setRC(SnsrStream h, SnsrRC code);
/**
* Sets a detailed stream error message.
* Sets the detailed human-readable error message in stream @p b to @p format,
* which a standard C library `fprintf()` format string.
*
* This detailed error message is made available through the
* snsrStreamErrorDetail() API call.
*
* @param[in] b ::SnsrStream handle.
* @param[in] format `fprintf()` stype format string.
* @param[in] ... arguments specified by the @p format string.
*/
void
snsrStream_setDetail(SnsrStream b, const char *format, ...);
/** @} stream-spi */
/** @} stream */
/** @addtogroup session Session
* @{
*/
/**
* Clears the ::SnsrSession error code.
* Once a ::SnsrSession error occurs (i.e. a return code other than
* #SNSR_RC_OK is reported), all library calls on the session handle will
* immediately return with the same error code.
*
* Call this function to clear the error detail and
* reset the code to #SNSR_RC_OK.
*
* @param[in] s session handle.
*/
void
snsrClearRC(SnsrSession s);
/**
* Sets the detailed session error message.
* Sets the detailed error message returned by snsrErrorDetail().
* Use this to propgate a human-readable error message generated
* by a callback function to the session handle.
* @param[in] s session handle.
* @param[in] format `fprintf()` style format string.
* @param[in] ... arguments specified by the @p format string.
*/
void
snsrDescribeError(SnsrSession s, const char *format, ...);
/**
* Duplicates a session handle.
* Creates a new ::SnsrSession handle that is a clone of a source handle.
* This function is roughly equivalent to:
* @code
* SnsrStream b = snsrStreamFromBuffer(1024, 1048576);
* snsrSave(s, SNSR_FM_CONFIG, b);
* snsrLoad(*dst, b);
* snsrRelease(b);
* @endcode
* The new ::SnsrSession @p dst contains all of the configuration from @p s,
* but none of the runtime settings. Immutable configuration settings
* (such as acoustic models) are shared between @p s and @p dst. Using snsrDup()
* to create two runtime instances of a task will therefore use less memory
* than loading the same task data into two ::SnsrSession handles.
*
* @param[in] s source session handle.
* @param[out] dst pointer to an allocated ::SnsrSession handle which will
* receive a clone of @p s.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrDup(SnsrSession s, SnsrSession *dst);
/**
* Retrieves a detailed session error message.
* This human-readable error message should be used
* for display or logging only. The content of the message is system-specific.
* Do not parse this to determine program flow, use the ::SnsrRC return
* code instead.
* @param[in] s session handle.
* @return A detailed message describing the most recent reason for failure.
* The memory pointed to is owned by this library and must not be
* released. It is not reference-counted, calling snsrRetain() or
* snsrRelease() on this handle will panic the heap allocator.
* The handle remains valid only until the next API call on @p s.
*/
const char *
snsrErrorDetail(SnsrSession s);
/**
* Calls a user function for each iteration over a list.
* Invokes @p c for each iteration over setting @p key.
* @p key must reference an iterator setting. These are task-specific -
* see the @ref task documentation for a list of available iterators.
*
* If @p c returns an error (i.e. not #SNSR_RC_OK) the iteration
* loop is terminated early, and snsrForEach() returns this result code.
*
* @param[in] s source session handle.
* @param[in] key iterator key, see task documentation.
* @param[in] c a ::SnsrCallback invoked for each iteration.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrForEach(SnsrSession s, const char *key, SnsrCallback c);
/**
* Retrieves a double value from a session setting.
* Returns the `double` value set for @p key in ::SnsrSession @p s.
* The @p key and @p value arguments must not be `NULL`.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[out] value `double` value associated with @p key.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrGetInt(), snsrSetDouble().
*/
SnsrRC
snsrGetDouble(SnsrSession s, const char *key, double *value);
/**
* Retrieves an int value from a session setting.
* Returns the `int` value set for @p key in ::SnsrSession @p s.
* The @p key and @p value arguments must not be `NULL`.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[out] value `int` value associated with @p key.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrGetDouble(), snsrSetInt().
*/
SnsrRC
snsrGetInt(SnsrSession s, const char *key, int *value);
/**
* Retrieves a stream handle from a runtime session setting.
* Returns the ::SnsrStream value set for @p key in ::SnsrSession @p s.
* The @p key and @p stream arguments must not be `NULL`.
*
* By default, the returned @p stream ::SnsrStream handle is valid only until
* the next library call on the @p s ::SnsrSession handle. This validity can
* be extended by retaining the handle with snsrRetain(). Be sure to
* (eventually) release retained handles or a memory leak will result.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
*
* @note This function retrieves runtime settings (such as recognition audio or
* enrolled phrase spot modules) only. It cannot be used to get the stream
* handles set with snsrStreamSet().
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[out] stream ::SnsrStream handle associated with @p key.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrGetStream(SnsrSession s, const char *key, SnsrStream *stream);
/**
* Retrieves a string value from a runtime session setting.
* Returns the string value for @p key in ::SnsrSession @p s.
* The @p key and @p value arguments must not be `NULL`.
*
* By default, the returned @p value string is valid only until
* the next library call on the @p s ::SnsrSession handle. This validity can
* be extended by retaining the handle with snsrRetain(). Be sure to
* (eventually) release retained handles or a memory leak will result.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[out] value C string value associated with @p key.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrGetString(SnsrSession s, const char *key, const char **value);
/**
* Loads a task model into a session.
* Loads a @ref task or configuration settings from a ::SnsrStream
* into ::SnsrSession @p s. The stream data must be in the format produced
* by snsrSave().
* This function retains a reference to @p inputStream on entry
* and releases it on exit. @p inputStream will be opened, but will not
* be closed explicitly. Streams are closed before deallocation, so
* @p inputStream would be closed if no other references to it are held.
*
* @param[in] s session handle.
* @param[in] inputStream readable ::SnsrStream that contains a task model.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrLoad(SnsrSession s, SnsrStream inputStream);
/**
* Creates a new ::SnsrSession handle.
* Session handles contain the entire state for a task.
*
* If a ::SnsrSession handle has to be shared across threads, all calls into
* this library that use the handle **must** be proctected by application-level
* thread synchronization calls. The ::SnsrSession API calls are not re-entrant.
*
* Best practice is to use a single thread per handle. Using multiple handles
* per thread is fully supported.
*
* snsrNew() is implemented as a macro, which validates the included
* snsr.h against the one that the archive library was built with.
* If these do not match, snsrNew() fails and returns #SNSR_RC_LIBRARY_HEADER.
*
* @param[out] s a pointer to an allocated ::SnsrSession handle.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* If @p s is not @c NULL a detailed error message can be retrieved with
* snsrErrorDetail().
* @see snsrDup().
*/
#define snsrNew(s) snsrNewValidateVersion((s), SNSR_VERSION)
SnsrRC
snsrNewValidateVersion(SnsrSession *s, const char *version);
/**
* Validates task requirements.
* Checks that the value for the @p key, for the task loaded into @p s,
* matches the required value @p value.
*
* If @p key is #SNSR_TASK_VERSION, this function uses [semantic version][1]
* precedence to determine whether the task version meets the @p value
* version requirement.
*
* @p value is a semantic version string, optionally prefixed with a comparison
* operation:
* <ul>
* <li> @c =, @c <, @c <=, @c >, @c >=: range comparisons.
* <li> @c ~: `taskVersion >= value && taskVersion < M` where M is
* the next major version number.
* <li> @c ^: `taskVersion >= value && taskVersion < M` where M is
* the next major version number,
* skipping over zeros from the left. For `taskVersion >= 1.0.0`
* this is equivalent to the @c ~ operator. `^0.minor.patch`
* allows only patch updates, e.g. `^0.1.1` will
* accept `0.1.2` but not `0.2.0`.
* <li> The default behavior when no operator is specified is @c ^.
* </ul>
*
* This function is used as a sanity check, to verify that the task model
* loaded is of the correct type, and that it has a compatible version.
*
* Example:
* @code
* snsrLoad(s, snsrStreamFromFileName("spotter.snsr", "r"));
* snsrRequire(s, SNSR_TASK_TYPE, SNSR_PHRASESPOT);
* snsrRequire(s, SNSR_TASK_VERSION, "1.0.0");
* @endcode
*
* @param[in] s session handle.
* @param[in] key the name of a setting to validate.
* @param[in] value string to match the @p key setting against.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* [1]: http://semver.org/
*/
SnsrRC
snsrRequire(SnsrSession s, const char *key, const char *value);
/**
* Processes stream data in a session.
* Enters the main ::SnsrSession processing loop. This function will
* process data read from input streams, invoke
* @ref callback registered in the session and (if defined) write to
* output streams.
*
* Processing will continue until:
* * one of the data streams reach #SNSR_RC_EOF, in which case snsrRun()
* returns #SNSR_RC_STREAM_END, or
* * one of the invoked callbacks returns an error code, which snsrRun()
* will return. #SNSR_RC_INTERRUPTED, #SNSR_RC_REPEAT, #SNSR_RC_SKIP,
* #SNSR_RC_STOP or #SNSR_RC_TIMED_OUT should be used to indicate
* that the operation was stopped on request.
*
* @ref callback are invoked on the thread that snsrRun() was
* called on. The processing loop is single-threaded, so it stalls while
* waiting for user functions to return.
*
* snsrRun() will flush the internal recognition pipeline an input stream
* reaches #SNSR_RC_EOF, unless #SNSR_AUTO_FLUSH is set to @c 0.
*
* @param[in] s session handle.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrSetHandler(), snsrSetStream(), #SNSR_AUTO_FLUSH.
*/
SnsrRC
snsrRun(SnsrSession s);
/**
* Retrieves the session return code.
* Returns the most recent ::SnsrRC return code from ::SnsrSession @p s.
*
* Use snsrClearRC() to reset the session error state to #SNSR_RC_OK.
*
* @param[in] s session handle.
* @return The current @p s ::SnsrRC return code.
* @see snsrClearRC(), snsrErrorDetail(), snsrRCMessage().
*/
SnsrRC
snsrRC(SnsrSession s);
/**
* Describes a return code.
* Provides a human-readable error message describing @p returnCode.
* This message should be used for display or logging only. The content
* of the message is unspecified and system-specific. Do not parse this
* to determine program flow, use the ::SnsrRC return code instead.
*
* If a ::SnsrSession handle is available, consider using snsrErrorDetail()
* instead, as this provides additional details.
*
* @param[in] returnCode ::SnsrRC returned by one of the API functions.
* @return A character string describing the @p returnCode.
* The memory pointed to is owned by this library and must not be
* released. It is not reference-counted, calling snsrRetain() or
* snsrRelease() on this handle will panic the heap allocator.
*/
const char *
snsrRCMessage(SnsrRC returnCode);
/**
* Retains a reference to an object.
* Increments the reference count on @p handle. The @p handle will remain
* valid until snsrRelease() is called on it.
*
* To avoid memory leaks, each call to snsrRetain() must be matched with
* a corresponding call to snsrRelease().
*
* @note @p handle must be a valid reference-counted object returned by
* this library, such as ::SnsrSession, ::SnsrStream, ::SnsrCallback
* or a `const char *` returned snsrGetString().
* Behaviour on any other pointer is undefined and will likely
* lead to the process calling `abort()`.
*
* @param[in] handle a reference-counted handle,
*/
void
snsrRetain(const void *handle);
/**
* Releases an object reference.
* Decrements the reference count on @p handle. If the reference count
* drops to zero, the @p handle will be deallocated.
*
* When this function returns @p handle will no longer be valid. Behaviour
* is undefined if it is used as an argument to any of the functions in this
* library.
*
* @note @p handle must be `NULL`, or a valid reference-counted object
* returned by this library, such as ::SnsrSession, ::SnsrStream,
* ::SnsrCallback or a `const char *` returned snsrGetString().
* Behaviour on any other pointer is undefined and will likely
* lead to the process calling `abort()`.
*
* @param[in] handle a reference-counted handle, or `NULL`.
*/
void
snsrRelease(const void *handle);
/**
* Serializes a session to a stream.
* Saves the configuration or runtime settings of ::SnsrSession @p s to
* writable ::SnsrStream @p outputStream.
*
* ::SnsrDataFormat specifies what is serialized:
* - #SNSR_FM_CONFIG serializes the task and all of its configuration
* settings.
* - #SNSR_FM_RUNTIME serializes runtime settings, such as
* phrase spotter enrollments in #SNSR_ENROLL tasks.
*
* @param[in] s session handle.
* @param[in] format ::SnsrDataFormat specifies the output format.
* @param[in] outputStream writable destination stream.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrSave(SnsrSession s, SnsrDataFormat format, SnsrStream outputStream);
/**
* Changes session configuration.
* This untility function parses the @p keyValue string and sets
* ::SnsrSession @p s configuration options. Use this to change task
* configuration from user-supplied configuration strings provided to
* a command-line application.
*
* @p keyValue should be of the form `"key=value ..."`, e.g. `"delay=30"` or
* `"accuracy=0.5 delete-user=hbg"`.
*
* Use snsrSetDouble(), snsrSetInt() and snsrSetString() when the key
* name is known at compile time, as these functions do not incur a
* string parsing overhead.
*
* @param[in] s session handle.
* @param[in] keyValue setting string, `key=value ...`.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrSetDouble(), snsrSetInt(), snsrSetString().
*/
SnsrRC
snsrSet(SnsrSession s, const char *keyValue);
/**
* Sets a session configuration to a `double` value.
* Sets the @p key in ::SnsrSession @p s to @p value.
* @p key must not be `NULL`.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[in] value `double` value for @p key.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrGetDouble(), snsrSetInt().
*/
SnsrRC
snsrSetDouble(SnsrSession s, const char *key, double value);
/**
* Sets a session callback handler.
* Registers callback @p c for @p key in ::SnsrSession @p s.
* This callback will be invoked as specified in the task documentation.
*
* See @ref task for details on task-specific callback keys.
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[in] c a ::SnsrCallback instance, a user function with private data.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrSetHandler(SnsrSession s, const char *key, SnsrCallback c);
/**
* Sets a session configuration to an `int` value.
* Sets the @p key in ::SnsrSession @p s to @p value.
* @p key must not be `NULL`.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[in] value `int` value for @p key.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrGetInt(), snsrSetDouble().
*/
SnsrRC
snsrSetInt(SnsrSession s, const char *key, int value);
/**
* Sets input and output streams for a session.
* Associates @p stream with the source or sink specified by @p key.
* Stream keys are task-specific and are described in @ref task.
*
* Example:
* @code
* snsrSetStream(s, SNSR_SOURCE_AUDIO_PCM,
* snsrStreamFromFileName("input.pcm", "r"));
* @endcode
*
* @param[in] s session handle.
* @param[in] key setting key.
* @param[in] stream a task-specific input or output stream.
* @return #SNSR_RC_OK for success, any other value indicates failure.
* @see snsrRun().
*/
SnsrRC
snsrSetStream(SnsrSession s, const char *key, SnsrStream stream);
/**
* Sets a session configuration to a string value.
* Sets the @p key in ::SnsrSession @p s to @p value.
* @p key must not be `NULL`.
*
* See @ref task for a list of keys and the contexts
* in which they are available.
* @param[in] s session handle.
* @param[in] key setting key.
* @param[in] value C string for @p key. This value is copied into the
* @p s session handle.
* @return #SNSR_RC_OK for success, any other value indicates failure.
*/
SnsrRC
snsrSetString(SnsrSession s, const char *key, const char *value);
/** @} session */
#ifdef _WIN32
/* Miscellaneous compatibility functions, for convenience only.
* These functions are not documented in the SDK API and are not
* supported in any way.
*/
int
getopt(int argc, char *const argv[], const char *optstr);
#endif
#if defined(__cplusplus)
}
#endif
#endif /* SNSR_H */
/** @} c */