File size: 1,800 Bytes
f6aec75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Keyword-filler Viterbi spotter over streaming logits - C port of
// phoneme_engine/decoder.py (KeywordSpotter). Same states, gates and
// scoring; consumes raw logits (only within-frame differences matter).
#pragma once
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#define PWW_DEC_MAX_PHONES 24
#define PWW_DEC_MAX_STATES (3 * PWW_DEC_MAX_PHONES + 1)
#define PWW_DEC_MAX_ALLOWED 3

typedef struct {
    int n_phones;
    int n_states;
    uint8_t labels[PWW_DEC_MAX_STATES];        // class id per state
    uint8_t n_allowed[PWW_DEC_MAX_STATES];
    uint8_t allowed[PWW_DEC_MAX_STATES][PWW_DEC_MAX_ALLOWED];
    int8_t preds[PWW_DEC_MAX_STATES][2];       // predecessor ids, -1 unused
    uint8_t entry[PWW_DEC_MAX_STATES];
    int min_dur, max_dur;
    float threshold;
    float strong_margin;                        // 1.5
    float strong_ratio;                         // 0.5
    int refractory;                             // frames

    // runtime state
    float rel[PWW_DEC_MAX_STATES];
    int32_t start[PWW_DEC_MAX_STATES];
    int32_t pframes[PWW_DEC_MAX_STATES];
    int32_t strong[PWW_DEC_MAX_STATES];
    int cooldown;
    int32_t t;
    float best_seen;   // best gate-passing score since last clear (diag)
} pww_spotter_t;

// phone_ids: sequence of class ids (1..39, from PWW_PHONES order +1).
// Returns 0 on success, -1 if too long/short.
int pww_spotter_init(pww_spotter_t *sp, const uint8_t *phone_ids,
                     int n_phones, float threshold);
void pww_spotter_reset(pww_spotter_t *sp);

// One frame of logits (PWW_NUM_CLASSES floats). Returns 1 and fills
// score/dur when the keyword fires, else 0.
int pww_spotter_step(pww_spotter_t *sp, const float *logits,
                     float *score_out, int *dur_out);

#ifdef __cplusplus
}
#endif