---
source_path: "models/types/enroll.md"
canonical_url: "https://doc.sensory.com/tnl/7.8/models/types/enroll/"
---

# Wake word enrollment

These models provide user enrollment for EFT and UDT. They produce [wake-word models](https://doc.sensory.com/tnl/7.8/models/index.md#wake-word-models).

Enrollment models have [task-type](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#task-type)` == `[enroll](https://doc.sensory.com/tnl/7.8/api/setting-keys/values.md#enroll)
and filenames that by convention match `eft-*.snsr` or `udt-*.snsr`

**Also see these related items:** [wake word enrollment models](https://doc.sensory.com/tnl/7.8/models/index.md#enroll-models) included in this distribution.

## Operation

Wake word enrollment has two modes: [interactive](https://doc.sensory.com/tnl/7.8/models/types/enroll.md#enroll-interactive)
for live recordings, and [offline](https://doc.sensory.com/tnl/7.8/models/types/enroll.md#enroll-offline) for pre-recorded
enrollment audio.

### Interactive

With [interactive](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#interactive) `= 1` enrollment tasks expect live audio and re-record enrollments
that cannot be used.

```mermaid
flowchart TD
    start((start))
    fetch[/samples from ->audio-pcm/]
    audio(^sample-count)
    segment[segment audio]
    check[check audio quality]
    validate[check enrollment consistency]
    resume(^resume)
    next(^next)
    pause(^pause)
    pass(^pass)
    fail0(^fail)
    fail1(^fail)
    enrolled(^enrolled)
    progress(^progress)
    adapted(^adapted)
    done(^done)

    zeroCount[count&larr;0]
    incrCount[count++]

    start --> next
    next --> zeroCount
    zeroCount --> resume
    resume --> fetch
    fetch --> audio
    audio --> segment
    segment --> fetch
    segment -->|endpoint| pause
    pause --> check
    check -->|good| pass
    pass ---> incrCount
    incrCount --> resume
    pass -->|count == required| validate
    validate -->|good| next
    validate -->|bad| fail1
    check -->|bad| fail0
    fail0 --> resume
    fail1 --> zeroCount

    next -->|user == NULL| enrolled
    enrolled --> enroll
    enroll --> progress
    progress --> enroll
    enroll --->|complete| adapted
    adapted --> done

    done ~~~ validate
```

Interactive enrollment flow.

1. Invoke [^next](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#next).
      * If the callback set [user](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#user) to `NULL`, start model adaptation at step 8.
2. Reset the enrollment `count` to `0`. This tracks the number of usable enrollments
   for the current user or phrase.
3. Invoke [^resume](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#resume). Application should use this to restart audio recording.
4. Make an audio recording and segment it with a VAD (UDT) or a wake word (EFT).
      * Read audio data from [->audio-pcm](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#-audio-pcm).
      * Invoke [^sample-count](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#sample-count-event).
      * Process and repeat until a speech segment is found.
5. Invoke [^pause](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#pause). Application should pause audio recording.
6. Check enrollment audio quality.
      * If good, invoke [^pass](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#pass).
        If [req-enroll](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#req-enroll) enrollments remain, start validation at step 7,
        else start the next recording at step 3.
      * If bad, invoke [^fail](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#fail) and redo the current recording at step 3.
7. Validate all the enrollment recordings, checking for consistency.
      * If good, start enrolling the next user or phrase at step 1.
      * If bad, invoke [^fail](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#fail) and restart at step 2.
8. When all users / phrases are available, invoke [^enrolled](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#enrolled).
9. Train a new recognizer with the enrollments
      * Call [^progress](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#progress) repeatedly until done.
10. Invoke [^adapted](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#adapted).
11. Invoke [^done](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#done).

**Also see these related items:** [live-enroll.c](https://doc.sensory.com/tnl/7.8/api/sample/c/live-enroll.md#live-enroll-code), [enrollUDT.java](https://doc.sensory.com/tnl/7.8/api/sample/java/enrollUDT.md#enrolludt-code), [Enroll.java](https://doc.sensory.com/tnl/7.8/api/sample/android/enroll-trigger.md#et-enroll)

### Offline

With [interactive](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#interactive) `= 0` enrollment tasks expect pre-recorded audio and fails
if any of the enrollments cannot be used.

```mermaid
flowchart TD
    start((start))
    fetch[/samples from ->audio-pcm/]
    audio(^sample-count)
    segment[segment audio]
    check[check audio quality]
    validate[check enrollment consistency]
    next(^next)
    pass(^pass)
    fail0(^fail)
    fail1(^fail)
    enrolled(^enrolled)
    progress(^progress)
    adapted(^adapted)
    done(^done)

    skip[discard enrollment]
    skipBad[discard bad enrollment]
    zeroCount[count&larr;0]
    incrCount[count++]

    user0{user == NULL?}
    user1{user == NULL?}

    start --> user0
    user0 -->|yes| next
    user0 -->|no| user1
    next --> user1

    user1 -->|no| zeroCount
    zeroCount --> fetch
    fetch --> audio
    audio --> segment
    segment --> fetch
    segment -->|endpoint| check
    check --->|good| pass
    pass --> incrCount
    incrCount --> fetch
    validate --->|bad| fail1
    fail1 --> skipBad
    skipBad --> validate
    validate --> user1
    check -->|bad| fail0
    fail0 --> skip
    skip --> fetch
    fetch -->|STREAM_END| validate

    user1 ---->|yes| enrolled
    enrolled --> enroll
    enroll --> progress
    progress --> enroll
    enroll --->|complete| adapted
    adapted --> done
```

Offline enrollment flow.

1. If [user](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#user) `== NULL`, invoke [^next](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#next). The application should set [user](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#user) before
   starting enrollment, or do so in the [^next](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#next) callback.
2. If [user](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#user) `== NULL`, start model adaptation at step 7.
3. Reset the enrollment `count` to `0`. This tracks the number of usable enrollments
   for the current user or phrase.
4. Segment audio with a VAD (UDT) or a wake word (EFT).
      * Read audio data from [->audio-pcm](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#-audio-pcm).
      * Invoke [^sample-count](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#sample-count-event).
      * Process and repeat until a speech segment is found or [STREAM_END](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_stream_end).
      * If [STREAM_END](https://doc.sensory.com/tnl/7.8/api/inference.md#rc_stream_end), validate at step 6.
5. Check enrollment audio quality.
      * If good, invoke [^pass](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#pass) and keep the recording.
      * If bad, invoke [^fail](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#fail) and discard the recording.
      * Start the next recording at step 4.
6. Validate all the enrollment recordings, checking for consistency.
      * If no bad recordings remain, start enrolling the next user or phrase at step 2.
      * If bad, invoke [^fail](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#fail), remove the recording and revalidate.
7. When all users / phrases are available, invoke [^enrolled](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#enrolled).
8. Train a new recognizer with the enrollments
      * Call [^progress](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#progress) repeatedly until done.
9. Invoke [^adapted](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#adapted).
10. Invoke [^done](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#done).

**Also see these related items:** [spot-enroll.c](https://doc.sensory.com/tnl/7.8/api/sample/c/spot-enroll.md#spot-enroll-code)

## Settings

**Available events:** [^adapted](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#adapted), [^done](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#done), [^enrolled](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#enrolled), [^fail](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#fail), [^next](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#next), [^pass](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#pass), [^pause](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#pause), [^progress](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#progress), [^resume](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#resume), [^sample-count](https://doc.sensory.com/tnl/7.8/api/setting-keys/events.md#sample-count-event)

**Available iterators:** [enrollment-iterator](https://doc.sensory.com/tnl/7.8/api/setting-keys/iterators.md#enrollment-iterator), [user-iterator](https://doc.sensory.com/tnl/7.8/api/setting-keys/iterators.md#user-iterator), [vocab-iterator](https://doc.sensory.com/tnl/7.8/api/setting-keys/iterators.md#vocab-iterator)

**Available results:** _none_

**Available runtime settings:** [->audio-pcm](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#-audio-pcm), [add-context](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#add-context), [audio-stream-from](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#audio-stream-from), [audio-stream-to](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#audio-stream-to), [delete-user](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#delete-user), [re-adapt](https://doc.sensory.com/tnl/7.8/api/setting-keys/runtime.md#re-adapt), [user](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#user)

**Available configuration settings:** [accuracy](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#accuracy), [enrollment-task-index](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#enrollment-task-index), [interactive](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#interactive), [req-enroll](https://doc.sensory.com/tnl/7.8/api/setting-keys/configuration.md#req-enroll)

**Available values:** [enroll](https://doc.sensory.com/tnl/7.8/api/setting-keys/values.md#enroll)

**Also see these related items:** [live-spot.c](https://doc.sensory.com/tnl/7.8/api/sample/c/live-spot.md#live-spot-code), [snsr-eval.c](https://doc.sensory.com/tnl/7.8/api/sample/c/snsr-eval.md#snsr-eval-code)

<!-- Abbreviation definitions from includes/abbreviations.md -->
*[API]: Application Programming Interface
*[EFT]: Enrolled Fixed Trigger: fixed wake words adapted to a speaker to improve accuracy
*[TNL]: TrulyNatural, Sensory's large-vocabulary speech recognition technology
*[UDT]: User-Defined Trigger: enrolled wake words and command sets
*[VAD]: Voice Activity Detector
