sonusai 0.15.9__py3-none-any.whl → 0.16.1__py3-none-any.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.
Files changed (49) hide show
  1. sonusai/__init__.py +36 -4
  2. sonusai/audiofe.py +111 -106
  3. sonusai/calc_metric_spenh.py +38 -22
  4. sonusai/genft.py +15 -6
  5. sonusai/genmix.py +14 -6
  6. sonusai/genmixdb.py +15 -7
  7. sonusai/gentcst.py +13 -6
  8. sonusai/lsdb.py +15 -5
  9. sonusai/main.py +58 -61
  10. sonusai/mixture/__init__.py +1 -0
  11. sonusai/mixture/config.py +1 -2
  12. sonusai/mkmanifest.py +43 -8
  13. sonusai/mkwav.py +15 -6
  14. sonusai/onnx_predict.py +16 -6
  15. sonusai/plot.py +16 -6
  16. sonusai/post_spenh_targetf.py +13 -6
  17. sonusai/summarize_metric_spenh.py +71 -0
  18. sonusai/tplot.py +14 -6
  19. sonusai/utils/__init__.py +4 -7
  20. sonusai/utils/asl_p56.py +3 -3
  21. sonusai/utils/asr.py +35 -8
  22. sonusai/utils/asr_functions/__init__.py +0 -5
  23. sonusai/utils/asr_functions/aaware_whisper.py +2 -2
  24. sonusai/utils/asr_manifest_functions/__init__.py +1 -0
  25. sonusai/utils/asr_manifest_functions/mcgill_speech.py +29 -0
  26. sonusai/utils/{trim_docstring.py → docstring.py} +20 -0
  27. sonusai/utils/model_utils.py +30 -0
  28. sonusai/utils/onnx_utils.py +19 -45
  29. {sonusai-0.15.9.dist-info → sonusai-0.16.1.dist-info}/METADATA +7 -25
  30. {sonusai-0.15.9.dist-info → sonusai-0.16.1.dist-info}/RECORD +32 -46
  31. sonusai/data_generator/__init__.py +0 -5
  32. sonusai/data_generator/dataset_from_mixdb.py +0 -143
  33. sonusai/data_generator/keras_from_mixdb.py +0 -169
  34. sonusai/data_generator/torch_from_mixdb.py +0 -122
  35. sonusai/keras_onnx.py +0 -86
  36. sonusai/keras_predict.py +0 -231
  37. sonusai/keras_train.py +0 -334
  38. sonusai/torchl_onnx.py +0 -216
  39. sonusai/torchl_predict.py +0 -542
  40. sonusai/torchl_train.py +0 -223
  41. sonusai/utils/asr_functions/aixplain_whisper.py +0 -59
  42. sonusai/utils/asr_functions/data.py +0 -16
  43. sonusai/utils/asr_functions/deepgram.py +0 -97
  44. sonusai/utils/asr_functions/fastwhisper.py +0 -90
  45. sonusai/utils/asr_functions/google.py +0 -95
  46. sonusai/utils/asr_functions/whisper.py +0 -49
  47. sonusai/utils/keras_utils.py +0 -226
  48. {sonusai-0.15.9.dist-info → sonusai-0.16.1.dist-info}/WHEEL +0 -0
  49. {sonusai-0.15.9.dist-info → sonusai-0.16.1.dist-info}/entry_points.txt +0 -0
sonusai/lsdb.py CHANGED
@@ -15,11 +15,25 @@ Inputs:
15
15
  LOC A SonusAI mixture database directory.
16
16
 
17
17
  """
18
+ import signal
19
+
18
20
  from sonusai import logger
19
21
  from sonusai.mixture import GeneralizedIDs
20
22
  from sonusai.mixture import MixtureDatabase
21
23
 
22
24
 
25
+ def signal_handler(_sig, _frame):
26
+ import sys
27
+
28
+ from sonusai import logger
29
+
30
+ logger.info('Canceled due to keyboard interrupt')
31
+ sys.exit(1)
32
+
33
+
34
+ signal.signal(signal.SIGINT, signal_handler)
35
+
36
+
23
37
  def lsdb(mixdb: MixtureDatabase,
24
38
  mixids: GeneralizedIDs = None,
25
39
  truth_index: int = None,
@@ -142,8 +156,4 @@ def main() -> None:
142
156
 
143
157
 
144
158
  if __name__ == '__main__':
145
- try:
146
- main()
147
- except KeyboardInterrupt:
148
- logger.info('Canceled due to keyboard interrupt')
149
- raise SystemExit(0)
159
+ main()
sonusai/main.py CHANGED
@@ -3,91 +3,88 @@
3
3
  usage: sonusai [--version] [--help] <command> [<args>...]
4
4
 
5
5
  The sonusai commands are:
6
- audiofe Audio front end
7
- calc_metric_spenh Run speech enhancement and analysis
8
- doc Documentation
9
- genft Generate feature and truth data
10
- genmix Generate mixture and truth data
11
- genmixdb Generate a mixture database
12
- gentcst Generate target configuration from a subdirectory tree
13
- keras_onnx Convert a trained Keras model to ONNX
14
- keras_predict Run Keras predict on a trained model
15
- keras_train Train a model using Keras
16
- lsdb List information about a mixture database
17
- mkmanifest Make ASR manifest JSON file
18
- mkwav Make WAV files from a mixture database
19
- onnx_predict Run ONNX predict on a trained model
20
- plot Plot mixture data
21
- post_spenh_targetf Run post-processing for speech enhancement targetf data
22
- torchl_onnx Convert a trained Pytorch Lightning model to ONNX
23
- torchl_predict Run Lightning predict on a trained model
24
- torchl_train Train a model using Lightning
25
- tplot Plot truth data
26
- vars List custom SonusAI variables
6
+ <This information is automatically generated.>
27
7
 
28
8
  Aaware Sound and Voice Machine Learning Framework. See 'sonusai help <command>'
29
9
  for more information on a specific command.
30
10
 
31
11
  """
32
- from sonusai import logger
12
+ import signal
13
+
14
+
15
+ def signal_handler(_sig, _frame):
16
+ import sys
17
+
18
+ from sonusai import logger
19
+
20
+ logger.info('Canceled due to keyboard interrupt')
21
+ sys.exit(1)
22
+
23
+
24
+ signal.signal(signal.SIGINT, signal_handler)
33
25
 
34
26
 
35
27
  def main() -> None:
28
+ from importlib import import_module
29
+ from pkgutil import iter_modules
30
+
31
+ from sonusai import commands_list
32
+
33
+ plugins = {}
34
+ plugin_docstrings = []
35
+ for _, name, _ in iter_modules():
36
+ if name.startswith('sonusai_') and not name.startswith('sonusai_asr_'):
37
+ module = import_module(name)
38
+ plugins[name] = {
39
+ 'commands': commands_list(module.commands_doc),
40
+ 'basedir': module.BASEDIR,
41
+ }
42
+ plugin_docstrings.append(module.commands_doc)
43
+
36
44
  from docopt import docopt
37
45
 
38
- import sonusai
46
+ from sonusai import __version__
47
+ from sonusai.utils import add_commands_to_docstring
39
48
  from sonusai.utils import trim_docstring
40
49
 
41
- commands = (
42
- 'audiofe',
43
- 'calc_metric_spenh',
44
- 'doc',
45
- 'genft',
46
- 'genmix',
47
- 'genmixdb',
48
- 'gentcst',
49
- 'keras_onnx',
50
- 'keras_predict',
51
- 'keras_train',
52
- 'lsdb',
53
- 'mkmanifest',
54
- 'mkwav',
55
- 'onnx_predict',
56
- 'plot',
57
- 'post_spenh_targetf',
58
- 'torchl_onnx',
59
- 'torchl_predict',
60
- 'torchl_train',
61
- 'tplot',
62
- 'vars',
63
- )
64
-
65
- args = docopt(trim_docstring(__doc__), version=sonusai.__version__, options_first=True)
50
+ args = docopt(trim_docstring(add_commands_to_docstring(__doc__, plugin_docstrings)),
51
+ version=__version__,
52
+ options_first=True)
66
53
 
67
54
  command = args['<command>']
68
55
  argv = args['<args>']
69
56
 
57
+ import sys
58
+ from os.path import join
70
59
  from subprocess import call
71
60
 
72
61
  import sonusai
73
- from sonusai import SonusAIError
62
+ from sonusai import logger
74
63
 
64
+ base_commands = sonusai.commands_list()
75
65
  if command == 'help':
76
66
  if not argv:
77
67
  exit(call(['sonusai', '-h']))
78
- elif argv[0] in commands:
79
- exit(call(['python', f'{sonusai.BASEDIR}/{argv[0]}.py', '-h']))
80
- else:
81
- raise SonusAIError(f"{argv[0]} is not a SonusAI command. See 'sonusai help'.")
82
- elif command in commands:
83
- exit(call(['python', f'{sonusai.BASEDIR}/{command}.py'] + argv))
68
+ elif argv[0] in base_commands:
69
+ exit(call(['python', f'{join(sonusai.BASEDIR, argv[0])}.py', '-h']))
70
+
71
+ for plugin, data in plugins.items():
72
+ if argv[0] in data['commands']:
73
+ exit(call(['python', f'{join(data["basedir"], argv[0])}.py', '-h']))
74
+
75
+ logger.error(f"{argv[0]} is not a SonusAI command. See 'sonusai help'.")
76
+ sys.exit(1)
77
+
78
+ if command in base_commands:
79
+ exit(call(['python', f'{join(sonusai.BASEDIR, command)}.py'] + argv))
80
+
81
+ for plugin, data in plugins.items():
82
+ if command in data['commands']:
83
+ exit(call(['python', f'{join(data["basedir"], command)}.py'] + argv))
84
84
 
85
- raise SonusAIError(f"{command} is not a SonusAI command. See 'sonusai help'.")
85
+ logger.error(f"{command} is not a SonusAI command. See 'sonusai help'.")
86
+ sys.exit(1)
86
87
 
87
88
 
88
89
  if __name__ == '__main__':
89
- try:
90
- main()
91
- except KeyboardInterrupt:
92
- logger.info('Canceled due to keyboard interrupt')
93
- raise SystemExit(0)
90
+ main()
@@ -108,6 +108,7 @@ from .helpers import get_transform_from_audio
108
108
  from .helpers import get_truth_t
109
109
  from .helpers import inverse_transform
110
110
  from .helpers import mixture_metadata
111
+ from .helpers import read_mixture_data
111
112
  from .helpers import write_mixture_data
112
113
  from .helpers import write_mixture_metadata
113
114
  from .log_duration_and_sizes import log_duration_and_sizes
sonusai/mixture/config.py CHANGED
@@ -480,11 +480,10 @@ def append_noise_files(entry: dict | str, tokens: dict = None) -> list[dict]:
480
480
  return noise_files
481
481
 
482
482
 
483
- def get_impulse_response_files(config: dict, show_progress: bool = False) -> ImpulseResponseFiles:
483
+ def get_impulse_response_files(config: dict) -> ImpulseResponseFiles:
484
484
  """Get the list of impulse response files from a config
485
485
 
486
486
  :param config: Config dictionary
487
- :param show_progress: Show progress bar
488
487
  :return: List of impulse response files
489
488
  """
490
489
  from itertools import chain
sonusai/mkmanifest.py CHANGED
@@ -30,6 +30,8 @@ Inputs:
30
30
  - 'librispeech'
31
31
  - 'vctk_noisy_speech' expects subdirs named like <name>_wav/ and <name>_txt/ with files in
32
32
  each using same basename, but with .wav and .txt respectively.
33
+ - 'mcgill-speech' expects audio data in basename/speakerid/speakerid-promptid.wav and
34
+ transcript data in Scripts/HarvardLists.dat
33
35
  ADAT Audio data environment variable. All found files will be expanded to their full, absolute path and
34
36
  then parts of the path that match the specified environment variable value will be replaced with
35
37
  the variable. This accommodates portability across platforms where the sound datasets may in
@@ -42,11 +44,23 @@ Outputs the following to the current directory:
42
44
 
43
45
  Example usage for LibriSpeech:
44
46
  sonusai mkmanifest -mlibrispeech -eADAT -oasr_manifest.json --include='*.flac' train-clean-100
45
-
47
+ sonusai mkmanifest -m mcgill-speech -e ADAT -o asr_manifest_16k.json 16k-LP7/
46
48
  """
47
- from sonusai import logger
49
+ import signal
50
+
51
+
52
+ def signal_handler(_sig, _frame):
53
+ import sys
54
+
55
+ from sonusai import logger
56
+
57
+ logger.info('Canceled due to keyboard interrupt')
58
+ sys.exit(1)
59
+
60
+
61
+ signal.signal(signal.SIGINT, signal_handler)
48
62
 
49
- VALID_METHOD = ['librispeech', 'vctk_noisy_speech']
63
+ VALID_METHOD = ['librispeech', 'vctk_noisy_speech', 'mcgill-speech']
50
64
 
51
65
 
52
66
  def main() -> None:
@@ -88,6 +102,7 @@ def main() -> None:
88
102
  from sonusai.utils.asr_manifest_functions import collect_vctk_noisy_speech_transcripts
89
103
  from sonusai.utils.asr_manifest_functions import get_librispeech_manifest_entry
90
104
  from sonusai.utils.asr_manifest_functions import get_vctk_noisy_speech_manifest_entry
105
+ from sonusai.utils.asr_manifest_functions import get_mcgill_speech_manifest_entry
91
106
 
92
107
  start_time = time.monotonic()
93
108
 
@@ -160,6 +175,30 @@ def main() -> None:
160
175
  for result in results:
161
176
  f.write(json.dumps(result) + '\n')
162
177
 
178
+ if method == 'mcgill-speech':
179
+ logger.info(f'Found {len(entries)} Mcgill Speech files, opening prompt file ...')
180
+ # Note expecting only one path pointing to data subdir
181
+ if len(paths) != 1:
182
+ raise SonusAIError(f'mcgill-speech only support a single path')
183
+ prompt_fpath = join(join(realpath(abspath(paths[0]))), '../Scripts/HarvardList.dat')
184
+ with open(prompt_fpath, encoding='utf-8') as f:
185
+ lines = f.readlines()
186
+
187
+ logger.info(f'Found {len(lines) - 4} entries in prompt file.')
188
+ # First 4 lines are header stuff, can use remaining directly with simple lookup
189
+ # example line: '01_02:Glue the sheet ...\n' (paragraph 1, sentence 2)
190
+ # 11 entries per group, so getting line is 11*(p1-1)+(s2-1)
191
+ lines = lines[4:]
192
+
193
+ processing_func = partial(get_mcgill_speech_manifest_entry, transcript_data=lines)
194
+ progress = tqdm(total=len(entries), desc='Creating Mcgill Speech manifest data')
195
+ results = pp_tqdm_imap(processing_func, entries, progress=progress)
196
+ progress.close()
197
+
198
+ with open(output, 'w') as f:
199
+ for result in results:
200
+ f.write(json.dumps(result) + '\n')
201
+
163
202
  end_time = time.monotonic()
164
203
  logger.info('')
165
204
  logger.info(f'Completed in {seconds_to_hms(seconds=end_time - start_time)}')
@@ -167,8 +206,4 @@ def main() -> None:
167
206
 
168
207
 
169
208
  if __name__ == '__main__':
170
- try:
171
- main()
172
- except KeyboardInterrupt:
173
- logger.info('Canceled due to keyboard interrupt')
174
- raise SystemExit(0)
209
+ main()
sonusai/mkwav.py CHANGED
@@ -23,13 +23,25 @@ Outputs the following to the mixture database directory:
23
23
  mkwav.log
24
24
 
25
25
  """
26
+ import signal
26
27
  from dataclasses import dataclass
27
28
 
28
- from sonusai import logger
29
29
  from sonusai.mixture import AudioT
30
30
  from sonusai.mixture import MixtureDatabase
31
31
 
32
32
 
33
+ def signal_handler(_sig, _frame):
34
+ import sys
35
+
36
+ from sonusai import logger
37
+
38
+ logger.info('Canceled due to keyboard interrupt')
39
+ sys.exit(1)
40
+
41
+
42
+ signal.signal(signal.SIGINT, signal_handler)
43
+
44
+
33
45
  @dataclass
34
46
  class MPGlobal:
35
47
  mixdb: MixtureDatabase = None
@@ -120,6 +132,7 @@ def main() -> None:
120
132
  import sonusai
121
133
  from sonusai import create_file_handler
122
134
  from sonusai import initial_log_messages
135
+ from sonusai import logger
123
136
  from sonusai import update_console_handler
124
137
  from sonusai.mixture import check_audio_files_exist
125
138
  from sonusai.utils import pp_tqdm_imap
@@ -164,8 +177,4 @@ def main() -> None:
164
177
 
165
178
 
166
179
  if __name__ == '__main__':
167
- try:
168
- main()
169
- except KeyboardInterrupt:
170
- logger.info('Canceled due to keyboard interrupt')
171
- raise SystemExit(0)
180
+ main()
sonusai/onnx_predict.py CHANGED
@@ -29,12 +29,25 @@ Outputs the following to opredict-<TIMESTAMP> directory:
29
29
 
30
30
  """
31
31
 
32
- from sonusai import logger
32
+ import signal
33
+
33
34
  from sonusai.mixture import Feature
34
35
  from sonusai.mixture import Predict
35
36
  from sonusai.utils import SonusAIMetaData
36
37
 
37
38
 
39
+ def signal_handler(_sig, _frame):
40
+ import sys
41
+
42
+ from sonusai import logger
43
+
44
+ logger.info('Canceled due to keyboard interrupt')
45
+ sys.exit(1)
46
+
47
+
48
+ signal.signal(signal.SIGINT, signal_handler)
49
+
50
+
38
51
  def main() -> None:
39
52
  from docopt import docopt
40
53
 
@@ -60,6 +73,7 @@ def main() -> None:
60
73
 
61
74
  from sonusai import create_file_handler
62
75
  from sonusai import initial_log_messages
76
+ from sonusai import logger
63
77
  from sonusai import update_console_handler
64
78
  from sonusai.mixture import MixtureDatabase
65
79
  from sonusai.mixture import get_feature_from_audio
@@ -233,8 +247,4 @@ def pad_and_predict(feature: Feature,
233
247
 
234
248
 
235
249
  if __name__ == '__main__':
236
- try:
237
- main()
238
- except KeyboardInterrupt:
239
- logger.info('Canceled due to keyboard interrupt')
240
- raise SystemExit(0)
250
+ main()
sonusai/plot.py CHANGED
@@ -41,16 +41,29 @@ Outputs:
41
41
 
42
42
  """
43
43
 
44
+ import signal
45
+
44
46
  import numpy as np
45
47
  from matplotlib import pyplot as plt
46
48
 
47
- from sonusai import logger
48
49
  from sonusai.mixture import AudioT
49
50
  from sonusai.mixture import Feature
50
51
  from sonusai.mixture import Predict
51
52
  from sonusai.mixture import Truth
52
53
 
53
54
 
55
+ def signal_handler(_sig, _frame):
56
+ import sys
57
+
58
+ from sonusai import logger
59
+
60
+ logger.info('Canceled due to keyboard interrupt')
61
+ sys.exit(1)
62
+
63
+
64
+ signal.signal(signal.SIGINT, signal_handler)
65
+
66
+
54
67
  def spec_plot(mixture: AudioT,
55
68
  feature: Feature,
56
69
  predict: Predict = None,
@@ -264,6 +277,7 @@ def main() -> None:
264
277
  from sonusai import SonusAIError
265
278
  from sonusai import create_file_handler
266
279
  from sonusai import initial_log_messages
280
+ from sonusai import logger
267
281
  from sonusai import update_console_handler
268
282
  from sonusai.mixture import MixtureDatabase
269
283
  from sonusai.mixture import FeatureGeneratorConfig
@@ -457,8 +471,4 @@ def main() -> None:
457
471
 
458
472
 
459
473
  if __name__ == '__main__':
460
- try:
461
- main()
462
- except KeyboardInterrupt:
463
- logger.info('Canceled due to keyboard interrupt')
464
- raise SystemExit(0)
474
+ main()
@@ -20,9 +20,20 @@ Outputs the following to post_spenh_targetf-<TIMESTAMP> directory:
20
20
  post_spenh_targetf.log
21
21
 
22
22
  """
23
+ import signal
23
24
  from dataclasses import dataclass
24
25
 
25
- from sonusai import logger
26
+
27
+ def signal_handler(_sig, _frame):
28
+ import sys
29
+
30
+ from sonusai import logger
31
+
32
+ logger.info('Canceled due to keyboard interrupt')
33
+ sys.exit(1)
34
+
35
+
36
+ signal.signal(signal.SIGINT, signal_handler)
26
37
 
27
38
 
28
39
  @dataclass
@@ -146,8 +157,4 @@ def _process(file: str) -> None:
146
157
 
147
158
 
148
159
  if __name__ == '__main__':
149
- try:
150
- main()
151
- except KeyboardInterrupt:
152
- logger.info('Canceled due to keyboard interrupt')
153
- exit()
160
+ main()
@@ -0,0 +1,71 @@
1
+ """sonusai summarize_metric_spenh
2
+
3
+ usage: summarize_metric_spenh [-hr] [-s SORT] LOC
4
+
5
+ options:
6
+ -h, --help
7
+ -s SORT, --sort SORT Sort by SORT column. [default: MIXID]
8
+ -r, --reverse Reverse sort order.
9
+
10
+ Summarize speech enhancement metrics results using data generated by SonusAI calc_metric_spenh.
11
+
12
+ Inputs:
13
+ LOC A SonusAI calc_metric_spenh results directory.
14
+
15
+ """
16
+ import signal
17
+
18
+
19
+ def signal_handler(_sig, _frame):
20
+ import sys
21
+
22
+ from sonusai import logger
23
+
24
+ logger.info('Canceled due to keyboard interrupt')
25
+ sys.exit(1)
26
+
27
+
28
+ signal.signal(signal.SIGINT, signal_handler)
29
+
30
+
31
+ def summarize_metric_spenh(location: str, by: str = 'MIXID', reverse: bool = False) -> str:
32
+ import glob
33
+
34
+ import pandas as pd
35
+
36
+ files = sorted(glob.glob(location + '/*_metric_spenh.txt'))
37
+ need_header = True
38
+ header = ['MIXID']
39
+ data = []
40
+ for file in files:
41
+ with open(file, 'r') as f:
42
+ for i, line in enumerate(f):
43
+ if i == 1 and need_header:
44
+ need_header = False
45
+ header.extend(line.strip().split())
46
+ elif i == 2:
47
+ data.append(line.strip().split())
48
+ break
49
+
50
+ df = pd.DataFrame(data, columns=header)
51
+ df[header[0:-2]] = df[header[0:-2]].apply(pd.to_numeric, errors='coerce')
52
+ return df.sort_values(by=by, ascending=not reverse).to_string(index=False)
53
+
54
+
55
+ def main():
56
+ from docopt import docopt
57
+
58
+ import sonusai
59
+ from sonusai.utils import trim_docstring
60
+
61
+ args = docopt(trim_docstring(__doc__), version=sonusai.__version__, options_first=True)
62
+
63
+ by = args['--sort']
64
+ reverse = args['--reverse']
65
+ location = args['LOC']
66
+
67
+ print(summarize_metric_spenh(location, by, reverse))
68
+
69
+
70
+ if __name__ == '__main__':
71
+ main()
sonusai/tplot.py CHANGED
@@ -41,7 +41,19 @@ options:
41
41
  A multi-page plot TARGET-tplot.pdf or CONFIG-tplot.pdf is generated.
42
42
 
43
43
  """
44
- from sonusai import logger
44
+ import signal
45
+
46
+
47
+ def signal_handler(_sig, _frame):
48
+ import sys
49
+
50
+ from sonusai import logger
51
+
52
+ logger.info('Canceled due to keyboard interrupt')
53
+ sys.exit(1)
54
+
55
+
56
+ signal.signal(signal.SIGINT, signal_handler)
45
57
 
46
58
 
47
59
  # TODO: re-work for modern mixdb API
@@ -328,8 +340,4 @@ def main() -> None:
328
340
 
329
341
 
330
342
  if __name__ == '__main__':
331
- try:
332
- main()
333
- except KeyboardInterrupt:
334
- logger.info('Canceled due to keyboard interrupt')
335
- raise SystemExit(0)
343
+ main()
sonusai/utils/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  # SonusAI general utilities
2
2
  from .asl_p56 import asl_p56
3
+ from .asr import ASRData
3
4
  from .asr import ASRResult
4
5
  from .asr import calc_asr
5
6
  from .audio_devices import get_default_input_device
@@ -14,24 +15,21 @@ from .create_ts_name import create_ts_name
14
15
  from .dataclass_from_dict import dataclass_from_dict
15
16
  from .db import db_to_linear
16
17
  from .db import linear_to_db
18
+ from .docstring import add_commands_to_docstring
19
+ from .docstring import trim_docstring
17
20
  from .energy_f import compute_energy_f
18
21
  from .engineering_number import EngineeringNumber
19
22
  from .get_frames_per_batch import get_frames_per_batch
20
23
  from .get_label_names import get_label_names
21
24
  from .grouper import grouper
22
25
  from .human_readable_size import human_readable_size
23
- from .keras_utils import check_keras_overrides
24
- from .keras_utils import create_onnx_from_keras
25
- from .keras_utils import import_and_check_keras_model
26
- from .keras_utils import import_keras_model
27
- from .keras_utils import keras_onnx
28
26
  from .max_text_width import max_text_width
27
+ from .model_utils import import_module
29
28
  from .numeric_conversion import float_to_int16
30
29
  from .numeric_conversion import int16_to_float
31
30
  from .onnx_utils import SonusAIMetaData
32
31
  from .onnx_utils import add_sonusai_metadata
33
32
  from .onnx_utils import get_sonusai_metadata
34
- from .onnx_utils import replace_stateful_grus
35
33
  from .parallel import pp_imap
36
34
  from .parallel import pp_tqdm_imap
37
35
  from .print_mixture_details import print_class_count
@@ -50,6 +48,5 @@ from .stacked_complex import stacked_complex_imag
50
48
  from .stacked_complex import stacked_complex_real
51
49
  from .stacked_complex import unstack_complex
52
50
  from .stratified_shuffle_split import stratified_shuffle_split_mixid
53
- from .trim_docstring import trim_docstring
54
51
  from .wave import write_wav
55
52
  from .yes_or_no import yes_or_no
sonusai/utils/asl_p56.py CHANGED
@@ -22,7 +22,7 @@ def asl_p56(audio: AudioT) -> float:
22
22
  # Hangover time in seconds
23
23
  H = 0.2
24
24
  # Rounded up to next integer
25
- I = np.ceil(H * SAMPLE_RATE)
25
+ H_samples = np.ceil(H * SAMPLE_RATE)
26
26
 
27
27
  # Margin in dB, difference between threshold and active speech level
28
28
  M = 15.9
@@ -40,7 +40,7 @@ def asl_p56(audio: AudioT) -> float:
40
40
  a = np.full(thresh_num, -1)
41
41
 
42
42
  # Hangover counter for each threshold
43
- h = np.full(thresh_num, I)
43
+ h = np.full(thresh_num, H_samples)
44
44
 
45
45
  # Long-term level square energy of audio
46
46
  sq = sum(np.square(audio))
@@ -55,7 +55,7 @@ def asl_p56(audio: AudioT) -> float:
55
55
  if q[k] >= c[j]:
56
56
  a[j] = a[j] + 1
57
57
  h[j] = 0
58
- elif h[j] < I:
58
+ elif h[j] < H_samples:
59
59
  a[j] = a[j] + 1
60
60
  h[j] = h[j] + 1
61
61
  else: