sonusai 1.0.9__py3-none-any.whl → 1.0.11__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.
@@ -28,4 +28,4 @@ from .helpers import inverse_transform
28
28
  from .helpers import write_mixture_metadata
29
29
  from .log_duration_and_sizes import log_duration_and_sizes
30
30
  from .mixdb import MixtureDatabase
31
- from .db_file import db_file
31
+ from .db import db_file
sonusai/mixture/db.py CHANGED
@@ -2,12 +2,21 @@ import contextlib
2
2
  import sqlite3
3
3
  from os import remove
4
4
  from os.path import exists
5
+ from os.path import join
6
+ from os.path import normpath
5
7
  from sqlite3 import Connection
6
8
  from sqlite3 import Cursor
7
9
  from typing import Any
8
10
 
9
- from .. import logger_db
10
- from .db_file import db_file
11
+ from sonusai import logger_db
12
+
13
+
14
+ def db_file(location: str, test: bool = False) -> str:
15
+ from .constants import MIXDB_NAME
16
+ from .constants import TEST_MIXDB_NAME
17
+
18
+ name = TEST_MIXDB_NAME if test else MIXDB_NAME
19
+ return normpath(join(location, name))
11
20
 
12
21
 
13
22
  class SQLiteDatabase:
@@ -15,9 +24,6 @@ class SQLiteDatabase:
15
24
 
16
25
  # Constants for database configuration
17
26
  READONLY_MODE = "?mode=ro"
18
- WRITE_OPTIMIZED_PRAGMAS = (
19
- "?_journal_mode=OFF&_synchronous=OFF&_cache_size=10000&_temp_store=MEMORY&_locking_mode=EXCLUSIVE"
20
- )
21
27
  CONNECTION_TIMEOUT = 20
22
28
 
23
29
  def __init__(
@@ -39,7 +45,7 @@ class SQLiteDatabase:
39
45
  """
40
46
  self.location = location
41
47
  self.create = create
42
- self.readonly = readonly
48
+ self.readonly = readonly and not create
43
49
  self.test = test
44
50
  self.verbose = verbose
45
51
  self.con: Connection | None = None
@@ -61,6 +67,7 @@ class SQLiteDatabase:
61
67
  raise
62
68
 
63
69
  if self.cur:
70
+ self.cur.execute("BEGIN TRANSACTION")
64
71
  return self.cur
65
72
  raise sqlite3.Error("Failed to connect to database")
66
73
 
@@ -78,9 +85,13 @@ class SQLiteDatabase:
78
85
  exc_tb: The exception traceback, if any.
79
86
  """
80
87
  if self.con:
81
- if exc_type is None and not self.readonly:
82
- # Commit only on successful exit if not readonly
83
- self.con.commit()
88
+ if not self.readonly:
89
+ if exc_type is None:
90
+ # Commit only on successful exit
91
+ self.con.commit()
92
+ else:
93
+ # Rollback on exception
94
+ self.con.rollback()
84
95
  self._close_resources()
85
96
 
86
97
  def _close_resources(self) -> None:
@@ -107,9 +118,21 @@ class SQLiteDatabase:
107
118
  uri = self._build_connection_uri(db_path)
108
119
 
109
120
  try:
110
- self.con = sqlite3.connect(f"file:{uri}", uri=True, timeout=self.CONNECTION_TIMEOUT)
121
+ self.con = sqlite3.connect(
122
+ f"file:{uri}",
123
+ uri=True,
124
+ timeout=self.CONNECTION_TIMEOUT,
125
+ isolation_level=None,
126
+ )
111
127
  if self.verbose and self.con:
112
128
  self.con.set_trace_callback(logger_db.debug)
129
+ if self.create or not self.readonly:
130
+ self.con.execute("PRAGMA journal_mode=wal")
131
+ self.con.execute("PRAGMA synchronous=0") # off
132
+ self.con.execute("PRAGMA cache_size=10000")
133
+ self.con.execute("PRAGMA temp_store=2") # memory
134
+ self.con.execute("PRAGMA locking_mode=exclusive")
135
+ self.con.commit()
113
136
  except sqlite3.Error as e:
114
137
  raise sqlite3.Error(f"Failed to connect to database: {e}") from e
115
138
 
@@ -153,11 +176,4 @@ class SQLiteDatabase:
153
176
  if not self.create and self.readonly:
154
177
  uri += self.READONLY_MODE
155
178
 
156
- # Add optimized pragmas for write mode
157
- if not self.readonly:
158
- if "?" in uri:
159
- uri = uri.replace("?", f"{self.WRITE_OPTIMIZED_PRAGMAS}&")
160
- else:
161
- uri += self.WRITE_OPTIMIZED_PRAGMAS
162
-
163
179
  return uri
sonusai/mixture/mixdb.py CHANGED
@@ -30,7 +30,7 @@ from ..datatypes import TruthsConfigs
30
30
  from ..datatypes import TruthsDict
31
31
  from ..datatypes import UniversalSNR
32
32
  from .db import SQLiteDatabase
33
- from .db_file import db_file
33
+ from .db import db_file
34
34
 
35
35
 
36
36
  class MixtureDatabase:
@@ -0,0 +1,145 @@
1
+ """
2
+ Parse config rules
3
+
4
+ sai_expand(0, 5)
5
+ sai_expand(.0, 5)
6
+ sai_expand(0., 5)
7
+ sai_expand(0.0, 5)
8
+ sai_expand(0, .5)
9
+ sai_expand(.0, .5)
10
+ sai_expand(0., .5)
11
+ sai_expand(0.0, .5)
12
+ sai_expand(0, 5.)
13
+ sai_expand(.0, 5.)
14
+ sai_expand(0., 5.)
15
+ sai_expand(0.0, 5.)
16
+ sai_expand(0, 5.0)
17
+ sai_expand(.0, 5.0)
18
+ sai_expand(0., 5.0)
19
+ sai_expand(0.0, 5.0)
20
+
21
+ sai_rand(-1, 1)
22
+ sai_choose(repeat=False)
23
+ sai_choose(repeat=False, tag=tag)
24
+ sai_sequence()
25
+ sai_sequence(tag=tag)
26
+
27
+ sai_expand(0, sai_rand(-1, 1))
28
+ sai_expand(sai_rand(0, 4), 0)
29
+ sai_expand(sai_rand(0, 4), sai_rand(-1, 1))
30
+
31
+ sai_choose(num=1, unique=speaker_id, repeat=False)
32
+ sai_choose(num=1, repeat=False)
33
+ sai_choose(num=1, unique=speaker_id, repeat=True)
34
+ sai_choose(num=1, repeat=True)
35
+ sai_sequence(num=0)
36
+ sai_sequence(num=0, unique=speaker_id)
37
+
38
+ """
39
+
40
+ from dataclasses import dataclass
41
+
42
+
43
+ @dataclass
44
+ class Match:
45
+ group: str
46
+ span: tuple[int, int]
47
+
48
+ def start(self) -> int:
49
+ return self.span[0]
50
+
51
+ def end(self) -> int:
52
+ return self.span[1]
53
+
54
+
55
+ def find_sai_expand(text: str) -> list[Match]:
56
+ import re
57
+
58
+ results = []
59
+ matches = re.finditer(r"sai_expand\(", text)
60
+ if matches:
61
+ for match in matches:
62
+ s = match.start()
63
+ e = match.end()
64
+ num_lparen = 1
65
+ while num_lparen != 0 and e < len(text):
66
+ if text[e] == "(":
67
+ num_lparen += 1
68
+ elif text[e] == ")":
69
+ num_lparen -= 1
70
+ e += 1
71
+ if num_lparen != 0:
72
+ raise ValueError(f"Unbalanced parenthesis in '{text}'")
73
+
74
+ results.append(Match(group=text[s:e], span=(s, e)))
75
+
76
+ return results
77
+
78
+
79
+ def parse_sai_expand(text: str) -> list[str]:
80
+ """
81
+ expand_syntax ::= expand_keyword lparen expand_item next_expand_item+ rparen
82
+ expand_keyword ::= sai_expand
83
+ lparen ::= (
84
+ expand_item ::= expand_syntax | rand_syntax | number
85
+ rand_syntax ::= rand_keyword lparen rand_item comma rand_item rparen
86
+ rand_item ::= real number
87
+ comma ::= ,
88
+ number ::= real number or signed integer
89
+ next_item ::= comma item
90
+ rparen ::= )
91
+ """
92
+ import pyparsing as pp
93
+
94
+ lparen = pp.Literal("(")
95
+ rparen = pp.Literal(")")
96
+ comma = pp.Literal(",")
97
+
98
+ real_number = pp.pyparsing_common.real
99
+ signed_integer = pp.pyparsing_common.signed_integer
100
+ number = real_number | signed_integer
101
+
102
+ identifier = pp.Word(pp.alphanums + "_.-")
103
+
104
+ rand_literal = pp.Literal("sai_rand")
105
+ rand_expression = (rand_literal + lparen + number + comma + number + rparen).set_parse_action(
106
+ lambda tokens: "".join(map(str, tokens))
107
+ )
108
+
109
+ expand_literal = pp.Literal("sai_expand")
110
+ expand_args = pp.DelimitedList(rand_expression | identifier, min=1)
111
+ expand_expression = expand_literal + lparen + expand_args("args") + rparen
112
+
113
+ try:
114
+ result = expand_expression.parse_string(text)
115
+ except pp.ParseException as e:
116
+ raise ValueError(f"Could not parse '{text}'") from e
117
+
118
+ return list(result.args)
119
+
120
+
121
+ def sai_expand(text: str) -> list[str]:
122
+ # initialize with input
123
+ expanded = [text]
124
+
125
+ # look for pattern
126
+ matches = find_sai_expand(text)
127
+
128
+ # if not found, early exit
129
+ if not matches:
130
+ return expanded
131
+
132
+ # remove entry we are expanding
133
+ expanded.pop()
134
+
135
+ # start with the innermost match
136
+ match = matches[-1]
137
+ prelude = text[: match.start()]
138
+ postlude = text[match.end() :]
139
+
140
+ # loop over parsed expand values
141
+ for value in parse_sai_expand(match.group):
142
+ # extend result with expand of replacement (for handling multiple expands in a single rule)
143
+ expanded.extend(sai_expand(prelude + value + postlude))
144
+
145
+ return expanded
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sonusai
3
- Version: 1.0.9
3
+ Version: 1.0.11
4
4
  Summary: Framework for building deep neural network models for sound, speech, and voice AI
5
5
  Home-page: https://aaware.com
6
6
  License: GPL-3.0-only
@@ -45,15 +45,14 @@ sonusai/metrics/confusion_matrix_summary.py,sha256=lhd8TyHVMC03khX85h_D75XElmawx
45
45
  sonusai/metrics/one_hot.py,sha256=aKc-xYd4zWIjbmoQikIcQ6BJB1k-68XKTg8eJCacHTU,13906
46
46
  sonusai/metrics/snr_summary.py,sha256=qKHctpmvGeu2cmjTG7iQPX1lvVUEtEnCIKwUGu6VrEQ,5773
47
47
  sonusai/metrics_summary.py,sha256=jtSwHomw23qwTYfzjFo_JmqzrkZcts1CMFFzTmJCmWk,12189
48
- sonusai/mixture/__init__.py,sha256=l4CgJN0gH4Z19jcQvXJbR8KSZ5f_ysnoAGi93LQaTjM,1260
48
+ sonusai/mixture/__init__.py,sha256=GGx8WG0pZwKmlXiWVBrtQXVY0dKW4yqDxSBgv7BI2Xc,1255
49
49
  sonusai/mixture/audio.py,sha256=JyrVtVPLH3aTXFgyl446f5uVHxlFRa4aBaSPYaMdg80,5814
50
50
  sonusai/mixture/class_balancing.py,sha256=lubicVCzxs4TMh2dZSsuIffkLkk1gmwjmwtrtQ27BVQ,3638
51
51
  sonusai/mixture/config.py,sha256=2_hEndyRXxyBpGzyBFaDT9REYGoK9Q7HQy8vDqPozus,23320
52
52
  sonusai/mixture/constants.py,sha256=Kklzhf5DL30yb3TpqRbvRUhcFrEXJ4s2S3D_nw4ARxM,1498
53
53
  sonusai/mixture/data_io.py,sha256=DV48sFcP2Qp3NBzvcnlptQOXU3aUEcAeLuh3XOtC5jI,5341
54
- sonusai/mixture/db.py,sha256=yd0bCiihuUAw3IgRlLqcshXB2QHep837O3TwjPyo-LM,5132
54
+ sonusai/mixture/db.py,sha256=zZnMFdW30leMCT1nX1Ml57ByLkqYEcm4VlekELvCFyc,5678
55
55
  sonusai/mixture/db_datatypes.py,sha256=VvNtbOgt5WSeSnBoVcNGC5gs_7hX_38pDUPjy5KRbG4,1471
56
- sonusai/mixture/db_file.py,sha256=P48TWYNyqchycENIqBu1QqhfsRDP6WK2VanPgxN1Imk,278
57
56
  sonusai/mixture/effects.py,sha256=zIb6ir0WSdKQJo7uJ3QQnV52RA6lJaqgQqvQh-s0dhc,11038
58
57
  sonusai/mixture/feature.py,sha256=7GJvFhfqeqerfjy9Vq9aKt-cecgYblK0IypNNo5hgwY,2285
59
58
  sonusai/mixture/generation.py,sha256=_vGTyqo0ocyOK84rTj_1QXciq1Tmxxl5XhwaXPWIEL0,33105
@@ -61,8 +60,9 @@ sonusai/mixture/helpers.py,sha256=dmyHwf1C5dZjYOd11kVV16KI33CaM-dU_fyaxOrrKt8,11
61
60
  sonusai/mixture/ir_delay.py,sha256=aiC23HMWQ08-v5wORgMx1_DOJSdh4kunULqiQ-SGuMo,2026
62
61
  sonusai/mixture/ir_effects.py,sha256=PqiqD4PS42-7kD6ESnsZi2a3tnKCFa4E0xqUujRBvGg,2152
63
62
  sonusai/mixture/log_duration_and_sizes.py,sha256=3ekS27IMKlnxIkQAmprzmBnzHOpRjZh3d7maL2VqWQU,927
64
- sonusai/mixture/mixdb.py,sha256=5YI0zKisFw_B-jKpB-Y1EYlJ8pHQDvOQLs9LEe0gT1w,84905
63
+ sonusai/mixture/mixdb.py,sha256=h8ZBARqKyFvMhAlXhXGSIwQ_zMAVtHok4wOfM4USVdQ,84900
65
64
  sonusai/mixture/pad_audio.py,sha256=KNxVQAejA0hblLOnMJgLS6lFaeE0n3tWQ5rclaHBnIY,1015
65
+ sonusai/mixture/parse.py,sha256=nqhjuR-J7_3wlGhVitYFvQwLJ1sclU8WZrVF0SyW2Cw,3700
66
66
  sonusai/mixture/resample.py,sha256=jXqH6FrZ0mlhQ07XqPx88TT9elu3HHVLw7Q0a7Lh5M4,221
67
67
  sonusai/mixture/sox_effects.py,sha256=tndS9qrh3eJOTUPrufyWHCt3UqjbPuh81I4Lo4MNmDg,5328
68
68
  sonusai/mixture/sox_help.py,sha256=DOTMBZfYQs3bXrqra25iH92lJFhqcGe9M1am4OrKkBY,29855
@@ -133,7 +133,7 @@ sonusai/utils/tokenized_shell_vars.py,sha256=EDrrAgz5lJ0RBAjLcTJt1MeyjhbNZiqXkym
133
133
  sonusai/utils/write_audio.py,sha256=IHzrJoFtFcea_J6wo6QSiojRkgnNOzAEcg-z0rFV7nU,810
134
134
  sonusai/utils/yes_or_no.py,sha256=0h1okjXmDNbJp7rZJFR2V-HFU1GJDm3YFTUVmYExkOU,263
135
135
  sonusai/vars.py,sha256=m8pdgfR4A6A9TCGf_rok6jPAT5BgrEsYXTSISIh1nrI,1163
136
- sonusai-1.0.9.dist-info/METADATA,sha256=PnNdFaS3cIoP8dZEDP6bKK-QoR5W_rV-z5OwEhxhlQs,2694
137
- sonusai-1.0.9.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
138
- sonusai-1.0.9.dist-info/entry_points.txt,sha256=zMNjEphEPO6B3cD1GNpit7z-yA9tUU5-j3W2v-UWstU,92
139
- sonusai-1.0.9.dist-info/RECORD,,
136
+ sonusai-1.0.11.dist-info/METADATA,sha256=mW6s4W6kXhofeFWjfMaQZAAisbdCYoc0bWPlD53JvFA,2695
137
+ sonusai-1.0.11.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
138
+ sonusai-1.0.11.dist-info/entry_points.txt,sha256=zMNjEphEPO6B3cD1GNpit7z-yA9tUU5-j3W2v-UWstU,92
139
+ sonusai-1.0.11.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- from os.path import join
2
- from os.path import normpath
3
-
4
- from .constants import MIXDB_NAME
5
- from .constants import TEST_MIXDB_NAME
6
-
7
-
8
- def db_file(location: str, test: bool = False) -> str:
9
- name = TEST_MIXDB_NAME if test else MIXDB_NAME
10
- return normpath(join(location, name))