sonusai 1.0.16__cp311-abi3-macosx_10_12_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sonusai/__init__.py +170 -0
- sonusai/aawscd_probwrite.py +148 -0
- sonusai/audiofe.py +481 -0
- sonusai/calc_metric_spenh.py +1136 -0
- sonusai/config/__init__.py +0 -0
- sonusai/config/asr.py +21 -0
- sonusai/config/config.py +65 -0
- sonusai/config/config.yml +49 -0
- sonusai/config/constants.py +53 -0
- sonusai/config/ir.py +124 -0
- sonusai/config/ir_delay.py +62 -0
- sonusai/config/source.py +275 -0
- sonusai/config/spectral_masks.py +15 -0
- sonusai/config/truth.py +64 -0
- sonusai/constants.py +14 -0
- sonusai/data/__init__.py +0 -0
- sonusai/data/silero_vad_v5.1.jit +0 -0
- sonusai/data/silero_vad_v5.1.onnx +0 -0
- sonusai/data/speech_ma01_01.wav +0 -0
- sonusai/data/whitenoise.wav +0 -0
- sonusai/datatypes.py +383 -0
- sonusai/deprecated/gentcst.py +632 -0
- sonusai/deprecated/plot.py +519 -0
- sonusai/deprecated/tplot.py +365 -0
- sonusai/doc.py +52 -0
- sonusai/doc_strings/__init__.py +1 -0
- sonusai/doc_strings/doc_strings.py +531 -0
- sonusai/genft.py +196 -0
- sonusai/genmetrics.py +183 -0
- sonusai/genmix.py +199 -0
- sonusai/genmixdb.py +235 -0
- sonusai/ir_metric.py +551 -0
- sonusai/lsdb.py +141 -0
- sonusai/main.py +134 -0
- sonusai/metrics/__init__.py +43 -0
- sonusai/metrics/calc_audio_stats.py +42 -0
- sonusai/metrics/calc_class_weights.py +90 -0
- sonusai/metrics/calc_optimal_thresholds.py +73 -0
- sonusai/metrics/calc_pcm.py +45 -0
- sonusai/metrics/calc_pesq.py +36 -0
- sonusai/metrics/calc_phase_distance.py +43 -0
- sonusai/metrics/calc_sa_sdr.py +64 -0
- sonusai/metrics/calc_sample_weights.py +25 -0
- sonusai/metrics/calc_segsnr_f.py +82 -0
- sonusai/metrics/calc_speech.py +382 -0
- sonusai/metrics/calc_wer.py +71 -0
- sonusai/metrics/calc_wsdr.py +57 -0
- sonusai/metrics/calculate_metrics.py +395 -0
- sonusai/metrics/class_summary.py +74 -0
- sonusai/metrics/confusion_matrix_summary.py +75 -0
- sonusai/metrics/one_hot.py +283 -0
- sonusai/metrics/snr_summary.py +128 -0
- sonusai/metrics_summary.py +314 -0
- sonusai/mixture/__init__.py +15 -0
- sonusai/mixture/audio.py +187 -0
- sonusai/mixture/class_balancing.py +103 -0
- sonusai/mixture/constants.py +3 -0
- sonusai/mixture/data_io.py +173 -0
- sonusai/mixture/db.py +169 -0
- sonusai/mixture/db_datatypes.py +92 -0
- sonusai/mixture/effects.py +344 -0
- sonusai/mixture/feature.py +78 -0
- sonusai/mixture/generation.py +1116 -0
- sonusai/mixture/helpers.py +351 -0
- sonusai/mixture/ir_effects.py +77 -0
- sonusai/mixture/log_duration_and_sizes.py +23 -0
- sonusai/mixture/mixdb.py +1857 -0
- sonusai/mixture/pad_audio.py +35 -0
- sonusai/mixture/resample.py +7 -0
- sonusai/mixture/sox_effects.py +195 -0
- sonusai/mixture/sox_help.py +650 -0
- sonusai/mixture/spectral_mask.py +51 -0
- sonusai/mixture/truth.py +61 -0
- sonusai/mixture/truth_functions/__init__.py +45 -0
- sonusai/mixture/truth_functions/crm.py +105 -0
- sonusai/mixture/truth_functions/energy.py +222 -0
- sonusai/mixture/truth_functions/file.py +48 -0
- sonusai/mixture/truth_functions/metadata.py +24 -0
- sonusai/mixture/truth_functions/metrics.py +28 -0
- sonusai/mixture/truth_functions/phoneme.py +18 -0
- sonusai/mixture/truth_functions/sed.py +98 -0
- sonusai/mixture/truth_functions/target.py +142 -0
- sonusai/mkwav.py +135 -0
- sonusai/onnx_predict.py +363 -0
- sonusai/parse/__init__.py +0 -0
- sonusai/parse/expand.py +156 -0
- sonusai/parse/parse_source_directive.py +129 -0
- sonusai/parse/rand.py +214 -0
- sonusai/py.typed +0 -0
- sonusai/queries/__init__.py +0 -0
- sonusai/queries/queries.py +239 -0
- sonusai/rs.abi3.so +0 -0
- sonusai/rs.pyi +1 -0
- sonusai/rust/__init__.py +0 -0
- sonusai/speech/__init__.py +0 -0
- sonusai/speech/l2arctic.py +121 -0
- sonusai/speech/librispeech.py +102 -0
- sonusai/speech/mcgill.py +71 -0
- sonusai/speech/textgrid.py +89 -0
- sonusai/speech/timit.py +138 -0
- sonusai/speech/types.py +12 -0
- sonusai/speech/vctk.py +53 -0
- sonusai/speech/voxceleb.py +108 -0
- sonusai/utils/__init__.py +3 -0
- sonusai/utils/asl_p56.py +130 -0
- sonusai/utils/asr.py +91 -0
- sonusai/utils/asr_functions/__init__.py +3 -0
- sonusai/utils/asr_functions/aaware_whisper.py +69 -0
- sonusai/utils/audio_devices.py +50 -0
- sonusai/utils/braced_glob.py +50 -0
- sonusai/utils/calculate_input_shape.py +26 -0
- sonusai/utils/choice.py +51 -0
- sonusai/utils/compress.py +25 -0
- sonusai/utils/convert_string_to_number.py +6 -0
- sonusai/utils/create_timestamp.py +5 -0
- sonusai/utils/create_ts_name.py +14 -0
- sonusai/utils/dataclass_from_dict.py +27 -0
- sonusai/utils/db.py +16 -0
- sonusai/utils/docstring.py +53 -0
- sonusai/utils/energy_f.py +44 -0
- sonusai/utils/engineering_number.py +166 -0
- sonusai/utils/evaluate_random_rule.py +15 -0
- sonusai/utils/get_frames_per_batch.py +2 -0
- sonusai/utils/get_label_names.py +20 -0
- sonusai/utils/grouper.py +6 -0
- sonusai/utils/human_readable_size.py +7 -0
- sonusai/utils/keyboard_interrupt.py +12 -0
- sonusai/utils/load_object.py +21 -0
- sonusai/utils/max_text_width.py +9 -0
- sonusai/utils/model_utils.py +28 -0
- sonusai/utils/numeric_conversion.py +11 -0
- sonusai/utils/onnx_utils.py +155 -0
- sonusai/utils/parallel.py +162 -0
- sonusai/utils/path_info.py +7 -0
- sonusai/utils/print_mixture_details.py +60 -0
- sonusai/utils/rand.py +13 -0
- sonusai/utils/ranges.py +43 -0
- sonusai/utils/read_predict_data.py +32 -0
- sonusai/utils/reshape.py +154 -0
- sonusai/utils/seconds_to_hms.py +7 -0
- sonusai/utils/stacked_complex.py +82 -0
- sonusai/utils/stratified_shuffle_split.py +170 -0
- sonusai/utils/tokenized_shell_vars.py +143 -0
- sonusai/utils/write_audio.py +26 -0
- sonusai/utils/yes_or_no.py +8 -0
- sonusai/vars.py +47 -0
- sonusai-1.0.16.dist-info/METADATA +56 -0
- sonusai-1.0.16.dist-info/RECORD +150 -0
- sonusai-1.0.16.dist-info/WHEEL +4 -0
- sonusai-1.0.16.dist-info/entry_points.txt +3 -0
sonusai/genft.py
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
"""sonusai genft
|
2
|
+
|
3
|
+
usage: genft [-hvsn] [-i MIXID] LOC
|
4
|
+
|
5
|
+
options:
|
6
|
+
-h, --help
|
7
|
+
-v, --verbose Be verbose.
|
8
|
+
-i MIXID, --mixid MIXID Mixture ID(s) to generate. [default: *].
|
9
|
+
-s, --segsnr Save segsnr. [default: False].
|
10
|
+
-n, --nopar Do not run in parallel. [default: False].
|
11
|
+
|
12
|
+
Generate SonusAI feature/truth data from a SonusAI mixture database.
|
13
|
+
|
14
|
+
Inputs:
|
15
|
+
LOC A SonusAI mixture database directory.
|
16
|
+
MIXID A glob of mixture ID(s) to generate.
|
17
|
+
|
18
|
+
Outputs the following to the mixture database directory:
|
19
|
+
<id>
|
20
|
+
feature.pkl
|
21
|
+
truth_f.pkl
|
22
|
+
segsnr.pkl (optional)
|
23
|
+
metadata.txt
|
24
|
+
genft.log
|
25
|
+
|
26
|
+
"""
|
27
|
+
|
28
|
+
from sonusai.datatypes import GeneralizedIDs
|
29
|
+
from sonusai.datatypes import GenFTData
|
30
|
+
|
31
|
+
|
32
|
+
def genft(
|
33
|
+
location: str,
|
34
|
+
mixids: GeneralizedIDs = "*",
|
35
|
+
compute_truth: bool = True,
|
36
|
+
compute_segsnr: bool = False,
|
37
|
+
cache: bool = False,
|
38
|
+
show_progress: bool = False,
|
39
|
+
force: bool = True,
|
40
|
+
no_par: bool = False,
|
41
|
+
) -> list[GenFTData]:
|
42
|
+
from functools import partial
|
43
|
+
|
44
|
+
from sonusai.mixture import MixtureDatabase
|
45
|
+
from sonusai.utils.parallel import par_track
|
46
|
+
from sonusai.utils.parallel import track
|
47
|
+
|
48
|
+
mixdb = MixtureDatabase(location)
|
49
|
+
mixids = mixdb.mixids_to_list(mixids)
|
50
|
+
|
51
|
+
progress = track(total=len(mixids), disable=not show_progress)
|
52
|
+
results = par_track(
|
53
|
+
partial(
|
54
|
+
_genft_kernel,
|
55
|
+
location=location,
|
56
|
+
compute_truth=compute_truth,
|
57
|
+
compute_segsnr=compute_segsnr,
|
58
|
+
cache=cache,
|
59
|
+
force=force,
|
60
|
+
),
|
61
|
+
mixids,
|
62
|
+
progress=progress,
|
63
|
+
no_par=no_par,
|
64
|
+
)
|
65
|
+
progress.close()
|
66
|
+
|
67
|
+
return results
|
68
|
+
|
69
|
+
|
70
|
+
def _genft_kernel(
|
71
|
+
m_id: int,
|
72
|
+
location: str,
|
73
|
+
compute_truth: bool,
|
74
|
+
compute_segsnr: bool,
|
75
|
+
cache: bool,
|
76
|
+
force: bool,
|
77
|
+
) -> GenFTData:
|
78
|
+
from functools import partial
|
79
|
+
from typing import Any
|
80
|
+
|
81
|
+
from sonusai.mixture import MixtureDatabase
|
82
|
+
from sonusai.mixture.data_io import write_cached_data
|
83
|
+
from sonusai.mixture.helpers import write_mixture_metadata
|
84
|
+
|
85
|
+
mixdb = MixtureDatabase(location)
|
86
|
+
|
87
|
+
write_func = partial(write_cached_data, location=mixdb.location, name="mixture", index=mixdb.mixture(m_id).name)
|
88
|
+
|
89
|
+
result = GenFTData()
|
90
|
+
|
91
|
+
mixture = mixdb.mixture_mixture(m_id)
|
92
|
+
|
93
|
+
feature, truth_f = mixdb.mixture_ft(m_id=m_id, mixture=mixture, force=force)
|
94
|
+
result.feature = feature
|
95
|
+
items: dict[str, Any] = {"feature": feature}
|
96
|
+
|
97
|
+
if compute_truth:
|
98
|
+
result.truth_f = truth_f
|
99
|
+
items["truth_f"] = truth_f
|
100
|
+
|
101
|
+
if compute_segsnr:
|
102
|
+
segsnr_t = mixdb.mixture_segsnr_t(m_id)
|
103
|
+
result.segsnr = mixdb.mixture_segsnr(m_id=m_id, segsnr_t=segsnr_t, force=force, cache=cache)
|
104
|
+
|
105
|
+
if cache:
|
106
|
+
write_func(items=items)
|
107
|
+
write_mixture_metadata(mixdb, m_id=m_id)
|
108
|
+
|
109
|
+
return result
|
110
|
+
|
111
|
+
|
112
|
+
def main() -> None:
|
113
|
+
from docopt import docopt
|
114
|
+
|
115
|
+
from sonusai import __version__ as sai_version
|
116
|
+
from sonusai.utils.docstring import trim_docstring
|
117
|
+
|
118
|
+
args = docopt(trim_docstring(__doc__), version=sai_version, options_first=True)
|
119
|
+
|
120
|
+
import time
|
121
|
+
from os.path import join
|
122
|
+
|
123
|
+
from sonusai import create_file_handler
|
124
|
+
from sonusai import initial_log_messages
|
125
|
+
from sonusai import logger
|
126
|
+
from sonusai import update_console_handler
|
127
|
+
from sonusai.constants import SAMPLE_RATE
|
128
|
+
from sonusai.mixture import MixtureDatabase
|
129
|
+
from sonusai.mixture.helpers import check_audio_files_exist
|
130
|
+
from sonusai.utils.human_readable_size import human_readable_size
|
131
|
+
from sonusai.utils.seconds_to_hms import seconds_to_hms
|
132
|
+
|
133
|
+
verbose = args["--verbose"]
|
134
|
+
mixids = args["--mixid"]
|
135
|
+
compute_segsnr = args["--segsnr"]
|
136
|
+
no_par = args["--nopar"]
|
137
|
+
location = args["LOC"]
|
138
|
+
|
139
|
+
start_time = time.monotonic()
|
140
|
+
|
141
|
+
create_file_handler(join(location, "genft.log"), verbose)
|
142
|
+
update_console_handler(verbose)
|
143
|
+
initial_log_messages("genft")
|
144
|
+
|
145
|
+
logger.info(f"Load mixture database from {location}")
|
146
|
+
mixdb = MixtureDatabase(location)
|
147
|
+
mixids = mixdb.mixids_to_list(mixids)
|
148
|
+
|
149
|
+
total_samples = mixdb.total_samples(mixids)
|
150
|
+
duration = total_samples / SAMPLE_RATE
|
151
|
+
total_transform_frames = total_samples // mixdb.ft_config.overlap
|
152
|
+
total_feature_frames = total_samples // mixdb.feature_step_samples
|
153
|
+
|
154
|
+
logger.info("")
|
155
|
+
logger.info(f"Found {len(mixids):,} mixtures to process")
|
156
|
+
logger.info(
|
157
|
+
f"{total_samples:,} samples, "
|
158
|
+
f"{total_transform_frames:,} transform frames, "
|
159
|
+
f"{total_feature_frames:,} feature frames"
|
160
|
+
)
|
161
|
+
|
162
|
+
check_audio_files_exist(mixdb)
|
163
|
+
|
164
|
+
genft(
|
165
|
+
location=location,
|
166
|
+
mixids=mixids,
|
167
|
+
compute_segsnr=compute_segsnr,
|
168
|
+
cache=True,
|
169
|
+
show_progress=True,
|
170
|
+
no_par=no_par,
|
171
|
+
)
|
172
|
+
|
173
|
+
logger.info(f"Wrote {len(mixids)} mixtures to {location}")
|
174
|
+
logger.info("")
|
175
|
+
logger.info(f"Duration: {seconds_to_hms(seconds=duration)}")
|
176
|
+
logger.info(
|
177
|
+
f"feature: {human_readable_size(total_feature_frames * mixdb.fg_stride * mixdb.feature_parameters * 4, 1)}"
|
178
|
+
)
|
179
|
+
logger.info(f"truth_f: {human_readable_size(total_feature_frames * mixdb.num_classes * 4, 1)}")
|
180
|
+
if compute_segsnr:
|
181
|
+
logger.info(f"segsnr: {human_readable_size(total_transform_frames * 4, 1)}")
|
182
|
+
|
183
|
+
end_time = time.monotonic()
|
184
|
+
logger.info(f"Completed in {seconds_to_hms(seconds=end_time - start_time)}")
|
185
|
+
logger.info("")
|
186
|
+
|
187
|
+
|
188
|
+
if __name__ == "__main__":
|
189
|
+
from sonusai import exception_handler
|
190
|
+
from sonusai.utils.keyboard_interrupt import register_keyboard_interrupt
|
191
|
+
|
192
|
+
register_keyboard_interrupt()
|
193
|
+
try:
|
194
|
+
main()
|
195
|
+
except Exception as e:
|
196
|
+
exception_handler(e)
|
sonusai/genmetrics.py
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
"""sonusai genmetrics
|
2
|
+
|
3
|
+
usage: genmetrics [-hvusd] [-i MIXID] [-n INCLUDE] [-x EXCLUDE] [-p NUMPROC] LOC
|
4
|
+
|
5
|
+
options:
|
6
|
+
-h, --help
|
7
|
+
-v, --verbose Be verbose.
|
8
|
+
-i MIXID, --mixid MIXID Mixture ID(s) to generate. [default: *].
|
9
|
+
-n INCLUDE, --include INCLUDE Metrics to include. [default: all]
|
10
|
+
-x EXCLUDE, --exclude EXCLUDE Metrics to exclude. [default: none]
|
11
|
+
-p NUMPROC, --nproc NUMPROC Number of parallel processes to use. Default single thread.
|
12
|
+
-u, --update Update metrics (do not regenerate existing metrics).
|
13
|
+
-s, --supported Show list of supported metrics.
|
14
|
+
-d, --dryrun Show list of metrics that will be generated and exit.
|
15
|
+
|
16
|
+
Calculate speech enhancement metrics of SonusAI mixture data in LOC.
|
17
|
+
|
18
|
+
Inputs:
|
19
|
+
LOC A SonusAI mixture database directory.
|
20
|
+
MIXID A glob of mixture ID(s) to generate.
|
21
|
+
INCLUDE Comma separated list of metrics to include. Can be "all" or
|
22
|
+
any of the supported metrics or glob(s).
|
23
|
+
EXCLUDE Comma separated list of metrics to exclude. Can be "none" or
|
24
|
+
any of the supported metrics or glob(s)
|
25
|
+
|
26
|
+
Note: The default include of "all" excludes the generation of ASR metrics,
|
27
|
+
i.e., "*asr*,*wer*". However, if include is manually specified to something other than "all",
|
28
|
+
then this behavior is overridden.
|
29
|
+
|
30
|
+
Similarly, the default exclude of "none" excludes the generation of ASR metrics,
|
31
|
+
i.e., "*asr*,*wer*". However, if exclude is manually specified to something other than "none",
|
32
|
+
then this behavior is also overridden.
|
33
|
+
|
34
|
+
Examples:
|
35
|
+
|
36
|
+
Generate all available mxwer metrics (as determined by mixdb asr_configs parameter):
|
37
|
+
> sonusai genmetrics -n"mxwer*" mixdb_loc
|
38
|
+
|
39
|
+
Generate only mxwer.faster metrics:
|
40
|
+
> sonusai genmetrics -n"mxwer.faster" mixdb_loc
|
41
|
+
|
42
|
+
Generate only faster metrics:
|
43
|
+
> sonusai genmetrics -n"*faster" mixdb_loc
|
44
|
+
|
45
|
+
Generate all available metrics except for mxcovl
|
46
|
+
> sonusai genmetrics -x"mxcovl" mixdb_loc
|
47
|
+
|
48
|
+
"""
|
49
|
+
|
50
|
+
|
51
|
+
def _process_mixture(mixid: int, location: str, metrics: list[str], update: bool = False) -> set[str]:
|
52
|
+
from sonusai.mixture import MixtureDatabase
|
53
|
+
from sonusai.mixture.data_io import write_cached_data
|
54
|
+
from sonusai.mixture.helpers import write_mixture_metadata
|
55
|
+
|
56
|
+
mixdb = MixtureDatabase(location)
|
57
|
+
results = mixdb.mixture_metrics(m_id=mixid, metrics=metrics, force=not update)
|
58
|
+
write_cached_data(mixdb.location, "mixture", mixdb.mixture(mixid).name, results)
|
59
|
+
write_mixture_metadata(mixdb, mixture=mixdb.mixture(mixid))
|
60
|
+
|
61
|
+
return set(results.keys())
|
62
|
+
|
63
|
+
|
64
|
+
def main() -> None:
|
65
|
+
from docopt import docopt
|
66
|
+
|
67
|
+
from sonusai import __version__ as sai_version
|
68
|
+
from sonusai.mixture import MixtureDatabase
|
69
|
+
from sonusai.utils.docstring import trim_docstring
|
70
|
+
|
71
|
+
args = docopt(trim_docstring(__doc__), version=sai_version, options_first=True)
|
72
|
+
|
73
|
+
verbose = args["--verbose"]
|
74
|
+
mixids = args["--mixid"]
|
75
|
+
includes = {x.strip() for x in args["--include"].replace(" ", ",").lower().split(",") if x != ""}
|
76
|
+
excludes = {x.strip() for x in args["--exclude"].replace(" ", ",").lower().split(",") if x != ""}
|
77
|
+
update = args["--update"]
|
78
|
+
show_supported = args["--supported"]
|
79
|
+
dryrun = args["--dryrun"]
|
80
|
+
num_proc = args["--nproc"]
|
81
|
+
location = args["LOC"]
|
82
|
+
|
83
|
+
import fnmatch
|
84
|
+
import sys
|
85
|
+
import time
|
86
|
+
from functools import partial
|
87
|
+
from os.path import join
|
88
|
+
|
89
|
+
from sonusai import create_file_handler
|
90
|
+
from sonusai import initial_log_messages
|
91
|
+
from sonusai import logger
|
92
|
+
from sonusai import update_console_handler
|
93
|
+
from sonusai.utils.parallel import par_track
|
94
|
+
from sonusai.utils.parallel import track
|
95
|
+
from sonusai.utils.seconds_to_hms import seconds_to_hms
|
96
|
+
|
97
|
+
start_time = time.monotonic()
|
98
|
+
|
99
|
+
# Setup logging file
|
100
|
+
create_file_handler(join(location, "genmetrics.log"), verbose)
|
101
|
+
update_console_handler(verbose)
|
102
|
+
initial_log_messages("genmetrics")
|
103
|
+
|
104
|
+
logger.info(f"Load mixture database from {location}")
|
105
|
+
|
106
|
+
mixdb = MixtureDatabase(location)
|
107
|
+
supported = mixdb.supported_metrics
|
108
|
+
if show_supported:
|
109
|
+
logger.info(f"\nSupported metrics:\n\n{supported.pretty}")
|
110
|
+
sys.exit(0)
|
111
|
+
|
112
|
+
# Handle default excludes
|
113
|
+
if "none" in excludes:
|
114
|
+
if "all" in includes:
|
115
|
+
excludes = {"*asr*", "*wer*"}
|
116
|
+
else:
|
117
|
+
excludes = set()
|
118
|
+
|
119
|
+
# Handle default includes
|
120
|
+
if "all" in includes:
|
121
|
+
includes = {"*"}
|
122
|
+
|
123
|
+
included_metrics: set[str] = set()
|
124
|
+
for include in includes:
|
125
|
+
for m in fnmatch.filter(supported.names, include):
|
126
|
+
included_metrics.add(m)
|
127
|
+
|
128
|
+
excluded_metrics: set[str] = set()
|
129
|
+
for exclude in excludes:
|
130
|
+
for m in fnmatch.filter(supported.names, exclude):
|
131
|
+
excluded_metrics.add(m)
|
132
|
+
|
133
|
+
requested = included_metrics - excluded_metrics
|
134
|
+
|
135
|
+
metrics = sorted(requested)
|
136
|
+
|
137
|
+
if len(metrics) == 0:
|
138
|
+
logger.warning("No metrics were requested")
|
139
|
+
sys.exit(1)
|
140
|
+
|
141
|
+
logger.info("Generating metrics:")
|
142
|
+
logger.info(f"{', '.join(metrics)}")
|
143
|
+
if dryrun:
|
144
|
+
sys.exit(0)
|
145
|
+
|
146
|
+
mixids = mixdb.mixids_to_list(mixids)
|
147
|
+
logger.info("")
|
148
|
+
logger.info(f"Found {len(mixids):,} mixtures to process")
|
149
|
+
|
150
|
+
no_par = num_proc == 1 or len(mixids) == 1
|
151
|
+
|
152
|
+
if num_proc is not None:
|
153
|
+
num_proc = int(num_proc)
|
154
|
+
|
155
|
+
progress = track(total=len(mixids), desc="genmetrics")
|
156
|
+
results = par_track(
|
157
|
+
partial(_process_mixture, location=location, metrics=metrics, update=update),
|
158
|
+
mixids,
|
159
|
+
progress=progress,
|
160
|
+
num_cpus=num_proc,
|
161
|
+
no_par=no_par,
|
162
|
+
)
|
163
|
+
progress.close()
|
164
|
+
|
165
|
+
written_metrics = sorted(set().union(*results))
|
166
|
+
logger.info(f"Wrote metrics for {len(mixids)} mixtures to {location}:")
|
167
|
+
logger.info(f"{', '.join(written_metrics)}")
|
168
|
+
logger.info("")
|
169
|
+
|
170
|
+
end_time = time.monotonic()
|
171
|
+
logger.info(f"Completed in {seconds_to_hms(seconds=end_time - start_time)}")
|
172
|
+
logger.info("")
|
173
|
+
|
174
|
+
|
175
|
+
if __name__ == "__main__":
|
176
|
+
from sonusai import exception_handler
|
177
|
+
from sonusai.utils.keyboard_interrupt import register_keyboard_interrupt
|
178
|
+
|
179
|
+
register_keyboard_interrupt()
|
180
|
+
try:
|
181
|
+
main()
|
182
|
+
except Exception as e:
|
183
|
+
exception_handler(e)
|
sonusai/genmix.py
ADDED
@@ -0,0 +1,199 @@
|
|
1
|
+
"""sonusai genmix
|
2
|
+
|
3
|
+
usage: genmix [-hvtsn] [-i MIXID] LOC
|
4
|
+
|
5
|
+
options:
|
6
|
+
-h, --help
|
7
|
+
-v, --verbose Be verbose.
|
8
|
+
-i MIXID, --mixid MIXID Mixture ID(s) to generate. [default: *].
|
9
|
+
-t, --truth Save truth_t. [default: False].
|
10
|
+
-s, --segsnr Save segsnr_t. [default: False].
|
11
|
+
-n, --nopar Do not run in parallel. [default: False].
|
12
|
+
|
13
|
+
Create mixture data from a SonusAI mixture database.
|
14
|
+
|
15
|
+
Inputs:
|
16
|
+
LOC A SonusAI mixture database directory.
|
17
|
+
MIXID A glob of mixture ID(s) to generate.
|
18
|
+
|
19
|
+
Outputs the following to the mixture database directory:
|
20
|
+
<id>
|
21
|
+
metadata.txt
|
22
|
+
sources.pkl
|
23
|
+
source.pkl
|
24
|
+
noise.pkl
|
25
|
+
mixture.pkl
|
26
|
+
truth_t.pkl (optional)
|
27
|
+
segsnr_t.pkl (optional)
|
28
|
+
genmix.log
|
29
|
+
"""
|
30
|
+
|
31
|
+
from sonusai.datatypes import GeneralizedIDs
|
32
|
+
from sonusai.datatypes import GenMixData
|
33
|
+
|
34
|
+
|
35
|
+
def genmix(
|
36
|
+
location: str,
|
37
|
+
mixids: GeneralizedIDs = "*",
|
38
|
+
compute_truth: bool = False,
|
39
|
+
compute_segsnr: bool = False,
|
40
|
+
cache: bool = False,
|
41
|
+
show_progress: bool = False,
|
42
|
+
force: bool = True,
|
43
|
+
no_par: bool = False,
|
44
|
+
) -> list[GenMixData]:
|
45
|
+
from functools import partial
|
46
|
+
|
47
|
+
from sonusai.mixture import MixtureDatabase
|
48
|
+
from sonusai.utils.parallel import par_track
|
49
|
+
from sonusai.utils.parallel import track
|
50
|
+
|
51
|
+
mixdb = MixtureDatabase(location)
|
52
|
+
mixids = mixdb.mixids_to_list(mixids)
|
53
|
+
progress = track(total=len(mixids), disable=not show_progress)
|
54
|
+
results = par_track(
|
55
|
+
partial(
|
56
|
+
_genmix_kernel,
|
57
|
+
location=location,
|
58
|
+
compute_truth=compute_truth,
|
59
|
+
compute_segsnr=compute_segsnr,
|
60
|
+
cache=cache,
|
61
|
+
force=force,
|
62
|
+
),
|
63
|
+
mixids,
|
64
|
+
progress=progress,
|
65
|
+
no_par=no_par,
|
66
|
+
)
|
67
|
+
progress.close()
|
68
|
+
|
69
|
+
return results
|
70
|
+
|
71
|
+
|
72
|
+
def _genmix_kernel(
|
73
|
+
m_id: int,
|
74
|
+
location: str,
|
75
|
+
compute_truth: bool,
|
76
|
+
compute_segsnr: bool,
|
77
|
+
cache: bool,
|
78
|
+
force: bool,
|
79
|
+
) -> GenMixData:
|
80
|
+
from sonusai.mixture import MixtureDatabase
|
81
|
+
from sonusai.mixture.helpers import write_mixture_metadata
|
82
|
+
|
83
|
+
mixdb = MixtureDatabase(location)
|
84
|
+
|
85
|
+
result = GenMixData()
|
86
|
+
result.sources = mixdb.mixture_sources(m_id=m_id, force=force, cache=cache)
|
87
|
+
result.source = mixdb.mixture_source(m_id=m_id, sources=result.sources, force=force, cache=cache)
|
88
|
+
result.noise = mixdb.mixture_noise(m_id=m_id, sources=result.sources, force=force, cache=cache)
|
89
|
+
result.mixture = mixdb.mixture_mixture(
|
90
|
+
m_id=m_id,
|
91
|
+
sources=result.sources,
|
92
|
+
source=result.source,
|
93
|
+
noise=result.noise,
|
94
|
+
force=force,
|
95
|
+
cache=cache,
|
96
|
+
)
|
97
|
+
|
98
|
+
if compute_truth:
|
99
|
+
result.truth_t = mixdb.mixture_truth_t(m_id=m_id, force=force, cache=cache)
|
100
|
+
|
101
|
+
if compute_segsnr:
|
102
|
+
result.segsnr_t = mixdb.mixture_segsnr_t(
|
103
|
+
m_id=m_id,
|
104
|
+
sources=result.sources,
|
105
|
+
source=result.source,
|
106
|
+
noise=result.noise,
|
107
|
+
force=force,
|
108
|
+
cache=cache,
|
109
|
+
)
|
110
|
+
|
111
|
+
if cache:
|
112
|
+
write_mixture_metadata(mixdb, m_id=m_id)
|
113
|
+
|
114
|
+
return result
|
115
|
+
|
116
|
+
|
117
|
+
def main() -> None:
|
118
|
+
from docopt import docopt
|
119
|
+
|
120
|
+
from sonusai import __version__ as sai_version
|
121
|
+
from sonusai.utils.docstring import trim_docstring
|
122
|
+
|
123
|
+
args = docopt(trim_docstring(__doc__), version=sai_version, options_first=True)
|
124
|
+
|
125
|
+
import time
|
126
|
+
from os.path import join
|
127
|
+
|
128
|
+
from sonusai import create_file_handler
|
129
|
+
from sonusai import initial_log_messages
|
130
|
+
from sonusai import logger
|
131
|
+
from sonusai import update_console_handler
|
132
|
+
from sonusai.constants import SAMPLE_RATE
|
133
|
+
from sonusai.mixture import MixtureDatabase
|
134
|
+
from sonusai.mixture.helpers import check_audio_files_exist
|
135
|
+
from sonusai.utils.human_readable_size import human_readable_size
|
136
|
+
from sonusai.utils.seconds_to_hms import seconds_to_hms
|
137
|
+
|
138
|
+
verbose = args["--verbose"]
|
139
|
+
location = args["LOC"]
|
140
|
+
mixids = args["--mixid"]
|
141
|
+
compute_truth = args["--truth"]
|
142
|
+
compute_segsnr = args["--segsnr"]
|
143
|
+
no_par = args["--nopar"]
|
144
|
+
|
145
|
+
start_time = time.monotonic()
|
146
|
+
|
147
|
+
create_file_handler(join(location, "genmix.log"), verbose)
|
148
|
+
update_console_handler(verbose)
|
149
|
+
initial_log_messages("genmix")
|
150
|
+
|
151
|
+
logger.info(f"Load mixture database from {location}")
|
152
|
+
mixdb = MixtureDatabase(location)
|
153
|
+
mixids = mixdb.mixids_to_list(mixids)
|
154
|
+
|
155
|
+
total_samples = mixdb.total_samples(mixids)
|
156
|
+
duration = total_samples / SAMPLE_RATE
|
157
|
+
|
158
|
+
logger.info("")
|
159
|
+
logger.info(f"Found {len(mixids):,} mixtures to process")
|
160
|
+
logger.info(f"{total_samples:,} samples")
|
161
|
+
|
162
|
+
check_audio_files_exist(mixdb)
|
163
|
+
|
164
|
+
genmix(
|
165
|
+
location=location,
|
166
|
+
mixids=mixids,
|
167
|
+
compute_truth=compute_truth,
|
168
|
+
compute_segsnr=compute_segsnr,
|
169
|
+
cache=True,
|
170
|
+
show_progress=True,
|
171
|
+
force=True,
|
172
|
+
no_par=no_par,
|
173
|
+
)
|
174
|
+
|
175
|
+
logger.info(f"Wrote {len(mixids)} mixtures to {location}")
|
176
|
+
logger.info("")
|
177
|
+
logger.info(f"Duration: {seconds_to_hms(seconds=duration)}")
|
178
|
+
logger.info(f"mixture: {human_readable_size(total_samples * 2, 1)}")
|
179
|
+
if compute_truth:
|
180
|
+
logger.info(f"truth_t: {human_readable_size(total_samples * mixdb.num_classes * 4, 1)}")
|
181
|
+
logger.info(f"target: {human_readable_size(total_samples * 2, 1)}")
|
182
|
+
logger.info(f"noise: {human_readable_size(total_samples * 2, 1)}")
|
183
|
+
if compute_segsnr:
|
184
|
+
logger.info(f"segsnr: {human_readable_size(total_samples * 4, 1)}")
|
185
|
+
|
186
|
+
end_time = time.monotonic()
|
187
|
+
logger.info(f"Completed in {seconds_to_hms(seconds=end_time - start_time)}")
|
188
|
+
logger.info("")
|
189
|
+
|
190
|
+
|
191
|
+
if __name__ == "__main__":
|
192
|
+
from sonusai import exception_handler
|
193
|
+
from sonusai.utils.keyboard_interrupt import register_keyboard_interrupt
|
194
|
+
|
195
|
+
register_keyboard_interrupt()
|
196
|
+
try:
|
197
|
+
main()
|
198
|
+
except Exception as e:
|
199
|
+
exception_handler(e)
|