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
54
55
56
57
58
59
60
61
62
63
64
65
66
use super::{comp::WakewordComparator, WakewordDetector, WakewordFile};
use crate::{
    mfcc::MfccComparator,
    wakewords::{WakewordLoad, WakewordSave},
    ScoreMode, WakewordRefBuildFromBuffers, WakewordRefBuildFromFiles,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// Wakeword representation.
#[derive(Serialize, Deserialize)]
pub struct WakewordRef {
    pub name: String,
    pub avg_features: Option<Vec<Vec<f32>>>,
    pub samples_features: HashMap<String, Vec<Vec<f32>>>,
    pub threshold: Option<f32>,
    pub avg_threshold: Option<f32>,
    pub rms_level: f32,
    pub mfcc_size: u16,
}
impl WakewordLoad for WakewordRef {}
impl WakewordSave for WakewordRef {}
impl WakewordRefBuildFromBuffers for WakewordRef {}
impl WakewordRefBuildFromFiles for WakewordRef {}
impl WakewordFile for WakewordRef {
    fn get_detector(
        &self,
        score_ref: f32,
        band_size: u16,
        score_mode: ScoreMode,
    ) -> Box<dyn WakewordDetector> {
        Box::new(WakewordComparator::new(
            self,
            MfccComparator::new(score_ref, band_size),
            score_mode,
        ))
    }

    fn get_mfcc_size(&self) -> u16 {
        self.mfcc_size
    }
}
impl WakewordRef {
    pub(crate) fn new(
        name: String,
        threshold: Option<f32>,
        avg_threshold: Option<f32>,
        avg_features: Option<Vec<Vec<f32>>>,
        rms_level: f32,
        samples_features: HashMap<String, Vec<Vec<f32>>>,
    ) -> Result<WakewordRef, String> {
        if samples_features.is_empty() {
            return Err("Can not create an empty wakeword".to_string());
        }
        let mfcc_size = samples_features.values().next().unwrap()[0].len() as u16;
        Ok(WakewordRef {
            name,
            threshold,
            avg_threshold,
            avg_features,
            samples_features,
            rms_level,
            mfcc_size,
        })
    }
}