File size: 4,082 Bytes
5838d6a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"""Configuration, phrase banks and default catalogs for the dataset creator."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import List


# --------------------------------------------------------------------------- #
# Default phrase banks (target phrase: "Hey Android")
# --------------------------------------------------------------------------- #

DEFAULT_WAKE_PHRASES: List[str] = [
    "Hey Android",
    "Hey, Android",
    "Hello Android",
    "Okay Android",
    "OK Android",
    "Android",
]

DEFAULT_UNKNOWN_PHRASES: List[str] = [
    "Hey Andrew",
    "Hey Adrian",
    "Hey Andrea",
    "Hello phone",
    "Open settings",
    "Start recording",
    "Stop recording",
    "Good morning",
    "Where is my phone",
    "Androids are useful",
    "This is a test",
    "Turn on the light",
    "Turn off the light",
    "Increase volume",
    "Decrease volume",
    "Play music",
    "Pause music",
]

# The three primary keyword-spotting classes.
WAKE_LABEL = "hey_android"
UNKNOWN_LABEL = "unknown"
NOISE_LABEL = "background_noise"

NOISE_TYPES: List[str] = ["white", "pink", "brown", "hum", "fan", "cafe", "street"]


# --------------------------------------------------------------------------- #
# Piper voice catalog (free, downloaded from rhasspy/piper-voices on the Hub)
# --------------------------------------------------------------------------- #

@dataclass(frozen=True)
class PiperVoice:
    """A downloadable Piper voice model on the Hugging Face Hub."""

    voice_id: str
    repo_path: str  # path inside rhasspy/piper-voices (without extension)
    locale: str
    description: str


PIPER_VOICES: List[PiperVoice] = [
    PiperVoice(
        "en_US-lessac-medium",
        "en/en_US/lessac/medium/en_US-lessac-medium",
        "en-US",
        "English US",
    ),
    PiperVoice(
        "en_GB-alba-medium",
        "en/en_GB/alba/medium/en_GB-alba-medium",
        "en-GB",
        "English GB",
    ),
    PiperVoice(
        "en_GB-northern_english_male-medium",
        "en/en_GB/northern_english_male/medium/en_GB-northern_english_male-medium",
        "en-GB",
        "English GB Northern male",
    ),
    PiperVoice(
        "nl_NL-mls-medium",
        "nl/nl_NL/mls/medium/nl_NL-mls-medium",
        "nl-NL",
        "Dutch NL",
    ),
    PiperVoice(
        "de_DE-thorsten-medium",
        "de/de_DE/thorsten/medium/de_DE-thorsten-medium",
        "de-DE",
        "German",
    ),
    PiperVoice(
        "fr_FR-siwis-medium",
        "fr/fr_FR/siwis/medium/fr_FR-siwis-medium",
        "fr-FR",
        "French",
    ),
    PiperVoice(
        "es_ES-sharvard-medium",
        "es/es_ES/sharvard/medium/es_ES-sharvard-medium",
        "es-ES",
        "Spanish",
    ),
]


# --------------------------------------------------------------------------- #
# Dataset generation config
# --------------------------------------------------------------------------- #

@dataclass
class DatasetConfig:
    """All knobs controlling a single dataset build."""

    # Output
    out_dir: str = "output"
    dataset_name: str = "hey_android"

    # Audio
    sample_rate_hz: int = 16000
    duration_seconds: float = 2.0

    # Classes / phrases
    wake_label: str = WAKE_LABEL
    unknown_label: str = UNKNOWN_LABEL
    noise_label: str = NOISE_LABEL
    wake_phrases: List[str] = field(default_factory=lambda: list(DEFAULT_WAKE_PHRASES))
    unknown_phrases: List[str] = field(default_factory=lambda: list(DEFAULT_UNKNOWN_PHRASES))

    # Size controls
    base_repeats_per_phrase_per_voice: int = 1
    augmentations_per_speech_clip: int = 8
    background_noise_samples: int = 200
    max_piper_voices: int = 7
    max_gcp_voices_per_locale: int = 3

    # GCP voice selection
    gcp_language_prefixes: List[str] = field(
        default_factory=lambda: ["en", "nl", "de", "fr", "es"]
    )

    # Split
    test_ratio: float = 0.2

    # Reproducibility
    seed: int = 1337

    @property
    def target_samples(self) -> int:
        return int(self.sample_rate_hz * self.duration_seconds)