modusa 0.3.68__py3-none-any.whl → 0.3.70__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.
@@ -8,14 +8,18 @@
8
8
 
9
9
  from pathlib import Path
10
10
 
11
- def load_ann(path):
11
+ def load_ann(path, clip=None):
12
12
  """
13
13
  Load annotation from audatity label text file.
14
14
 
15
15
  Parameters
16
16
  ----------
17
17
  path: str
18
- label text file path.
18
+ - label text file path.
19
+ clip: tuple[number, number] | number | None
20
+ - Incase you clipped the audio signal, this parameter will help clip the annotation.
21
+ - If you clip the audio, say from (10, 20), set the clip to (10, 20).
22
+ - Default: None
19
23
 
20
24
  Returns
21
25
  -------
@@ -27,12 +31,35 @@ def load_ann(path):
27
31
  if not isinstance(path, (str, Path)):
28
32
  raise ValueError(f"`path` must be one of (str, Path), got {type(path)}")
29
33
 
34
+ if clip is not None:
35
+ # Map clip input to the right format
36
+ if isinstance(clip, int or float):
37
+ clip = (0, clip)
38
+ elif isinstance(clip, tuple) and len(clip) > 1:
39
+ clip = (clip[0], clip[1])
40
+ else:
41
+ raise ValueError(f"Invalid clip type or length: {type(clip)}, len={len(clip)}")
42
+
30
43
  ann = []
44
+
31
45
  with open(str(path), "r") as f:
32
46
  lines = [line.rstrip("\n") for line in f]
33
47
  for line in lines:
34
48
  start, end, tag = line.split("\t")
35
49
  start, end = float(start), float(end)
36
- ann.append((start, end, tag))
37
50
 
51
+ # Incase user has clipped the audio signal, we adjust the annotation
52
+ # to match the clipped audio
53
+ if clip is not None:
54
+ offset = clip[0]
55
+ # Clamp annotation to clip boundaries
56
+ new_start = max(start, clip[0]) - offset
57
+ new_end = min(end, clip[1]) - offset
58
+
59
+ # only keep if there's still overlap
60
+ if new_start < new_end:
61
+ ann.append((new_start, new_end, tag))
62
+ else:
63
+ ann.append((start, end, tag))
64
+
38
65
  return ann
@@ -10,7 +10,7 @@ from .youtube_downloader import download
10
10
  from .audio_converter import convert
11
11
 
12
12
 
13
- def load(path, sr=None):
13
+ def load(path, sr=None, clip=None):
14
14
  """
15
15
  Loads audio file from various sources.
16
16
 
@@ -19,15 +19,19 @@ def load(path, sr=None):
19
19
  import modusa as ms
20
20
  audio_fp = ms.load(
21
21
  "https://www.youtube.com/watch?v=lIpw9-Y_N0g",
22
- sr = None)
22
+ sr = None, clip=(5, 10))
23
23
 
24
24
  Parameters
25
25
  ----------
26
26
  path: str
27
27
  - Path to the audio
28
28
  - Youtube URL
29
- sr: int
29
+ sr: int | None
30
30
  - Sampling rate to load the audio in.
31
+ clip: number | tuple[number, number] | None
32
+ - Which segment of the audio you want.
33
+ - Eg., 10 => First 10 sec, (5, 10) => 5 to 10 second
34
+ - Default: None => Entire audio.
31
35
 
32
36
  Return
33
37
  ------
@@ -86,5 +90,17 @@ def load(path, sr=None):
86
90
  n_samples = int(len(audio_data) * sr / audio_sr)
87
91
  audio_data = resample(audio_data, n_samples)
88
92
  audio_sr = sr
93
+
94
+ # Clip the audio signal as per needed
95
+ if clip is not None:
96
+ # Map clip input to the right format
97
+ if isinstance(clip, int or float):
98
+ clip = (0, clip)
99
+ elif isinstance(clip, tuple) and len(clip) > 1:
100
+ clip = (clip[0], clip[1])
101
+ else:
102
+ raise ValueError(f"Invalid clip type or length: {type(clip)}, len={len(clip)}")
103
+
104
+ audio_data = audio_data[int(clip[0]*sr):int(clip[1]*sr)]
89
105
 
90
106
  return audio_data, audio_sr, title
modusa/tools/plotter.py CHANGED
@@ -60,9 +60,12 @@ class Fig:
60
60
  dark_mode: bool
61
61
  - Do you want dark mode?
62
62
  - Default: True
63
+ grid: bool
64
+ - Do you want the grid?
65
+ - Default: True
63
66
  """
64
67
 
65
- def __init__(self, arrangement="asm", xlim=None, width=16, dark_mode=True):
68
+ def __init__(self, arrangement="asm", xlim=None, width=16, dark_mode=True, grid=True):
66
69
 
67
70
  if dark_mode:
68
71
  plt.style.use("dark_background")
@@ -80,6 +83,7 @@ class Fig:
80
83
  self._xlim = xlim
81
84
  self._curr_row_idx = 1 # Starting from 1 because row 0 is reserved for reference subplot
82
85
  self._curr_color_idx = 0 # So that we have different color across all the subplots to avoid legend confusion
86
+ self._grid = grid
83
87
 
84
88
  # Subplot setup
85
89
  self._fig, self._axs = self._generate_subplots(arrangement, width) # This will fill in the all the above variables
@@ -134,6 +138,7 @@ class Fig:
134
138
  """
135
139
 
136
140
  xlim = self._xlim
141
+ grid: bool = self._grid
137
142
  fig_width = width
138
143
 
139
144
  n_aux_sp = arrangement.count("a")
@@ -167,14 +172,17 @@ class Fig:
167
172
  axs[i, 1].axis("off")
168
173
  elif char == "a": # Remove ticks and labels from all the aux subplots
169
174
  axs[i, 0].tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
170
- axs[i, 0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
175
+ if grid:
176
+ axs[i, 0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
171
177
  axs[i, 1].axis("off")
172
178
  elif char == "s":
173
179
  axs[i, 0].tick_params(bottom=False, labelbottom=False)
174
- axs[i, 0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
180
+ if grid:
181
+ axs[i, 0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
175
182
  axs[i, 1].axis("off")
176
183
  elif char == "m":
177
- axs[i, 0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
184
+ if grid:
185
+ axs[i, 0].grid(True, linestyle='--', linewidth=0.7, color="lightgray" ,alpha=0.6)
178
186
  axs[i, 0].tick_params(bottom=False, labelbottom=False)
179
187
 
180
188
  axs[i, 0].sharex(axs[0, 0])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modusa
3
- Version: 0.3.68
3
+ Version: 0.3.70
4
4
  Summary: A modular signal analysis python library.
5
5
  Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
- modusa-0.3.68.dist-info/METADATA,sha256=kOUJdmGTDXd5CHrTUbg_b7pBR0jZgTcuAx3lK_Ttkls,1436
2
- modusa-0.3.68.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- modusa-0.3.68.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
4
- modusa-0.3.68.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
1
+ modusa-0.3.70.dist-info/METADATA,sha256=CRoFdZMzJT8bW68fBL5GpMsirp_zJDXFRqFdSnHyPfs,1436
2
+ modusa-0.3.70.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ modusa-0.3.70.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
4
+ modusa-0.3.70.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
5
5
  modusa/.DS_Store,sha256=_gm6qJREwfMi8dE7n5S89_RG46u5t3xHyD-smNhtNoM,6148
6
6
  modusa/__init__.py,sha256=RMIKAZZ27w1oh2UFMJvZQtQ-SluIQsac_3mSK_LaM30,277
7
7
  modusa/config.py,sha256=bTqK4t00FZqERVITrxW_q284aDDJAa9aMSfFknfR-oU,280
@@ -43,14 +43,14 @@ modusa/plugins/__init__.py,sha256=r1Bf5mnrVKRIwxboutY1iGzDy4EPQhqpk1kSW7iJj_Q,54
43
43
  modusa/plugins/base.py,sha256=Bh_1Bja7fOymFsCgwhXDbV6ys3D8muNrPwrfDrG_G_A,2382
44
44
  modusa/tools/__init__.py,sha256=TfIlnbSRVEk8C9YY6H5y0qiaKttFV_X3m6nI2qPYUH0,295
45
45
  modusa/tools/_plotter_old.py,sha256=KGow7mihA2H1WNq7s5bpivhCgGo2qVIeDaO6iabpsrg,19294
46
- modusa/tools/ann_loader.py,sha256=RePlwD4qG6gGrD4mOJ3RDR9q_gUscCY90_R9lgFU9lM,780
46
+ modusa/tools/ann_loader.py,sha256=GWiX7v4CxyAECthmtBAaSMMqsjo1YaVfRA9u-CtTTFM,1718
47
47
  modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
48
- modusa/tools/audio_loader.py,sha256=DrCzq0pdiQrUDIG-deLJGcu8EaylO5yRtwT4lr8WSf8,2166
48
+ modusa/tools/audio_loader.py,sha256=LEknkmc09SoUGN80-Uy59sVyeC6_55tD3a6ICbvaqWQ,2768
49
49
  modusa/tools/audio_player.py,sha256=GP04TWW4jBwQBjANkfR_cJtEy7cIhvbu8RTwnf9hD6E,2817
50
50
  modusa/tools/audio_recorder.py,sha256=d2fVt0Sd2tlBdb2WlUs60K4N23zuxM3KUpQqX0ifPi8,2769
51
51
  modusa/tools/base.py,sha256=C0ESJ0mIfjjRlAkRbSetNtMoOfS6IrHBjexRp3l_Mh4,1293
52
52
  modusa/tools/math_ops.py,sha256=ZZ7U4DgqT7cOeE7_Lzi_Qq-48WYfwR9_osbZwTmE9eg,8690
53
- modusa/tools/plotter.py,sha256=2BotJit9on5R5pfDMMxE8w-cREAHUW6_QpVzoqtx8-s,21051
53
+ modusa/tools/plotter.py,sha256=aWHjZ0nbPj7pQPrBV8urw9HUIlFoLwzIsE4cGm-BMKI,21206
54
54
  modusa/tools/youtube_downloader.py,sha256=hB_X8-7nOHXOlxg6vv3wyhBLoAsWyomrULP6_uCQL7s,1698
55
55
  modusa/utils/.DS_Store,sha256=nLXMwF7QJNuglLI_Gk74F7vl5Dyus2Wd74Mgowijmdo,6148
56
56
  modusa/utils/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
@@ -59,4 +59,4 @@ modusa/utils/excp.py,sha256=L9vhaGjKpv9viJYdmC9n5ndmk2GVbUBuFyZyhAQZmWY,906
59
59
  modusa/utils/logger.py,sha256=K0rsnObeNKCxlNeSnVnJeRhgfmob6riB2uyU7h3dDmA,571
60
60
  modusa/utils/np_func_cat.py,sha256=TyIFgRc6bARRMDnZxlVURO5Z0I-GWhxRONYyIv-Vwxs,1007
61
61
  modusa/utils/plot.py,sha256=s_vNdxvKfwxEngvJPgrF1PcmxZNnNaaXPViHWjyjJ-c,5335
62
- modusa-0.3.68.dist-info/RECORD,,
62
+ modusa-0.3.70.dist-info/RECORD,,