modusa 0.4.10__py3-none-any.whl → 0.4.12__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.
modusa/.DS_Store CHANGED
Binary file
modusa/__init__.py CHANGED
@@ -8,4 +8,4 @@ from modusa.tools import play, convert, record, save
8
8
  from modusa.tools import download
9
9
  from modusa.tools import load, load_ann
10
10
 
11
- __version__ = "0.4.10"
11
+ __version__ = "0.4.12"
@@ -6,16 +6,15 @@
6
6
  # Email: ankit0.anand0@gmail.com
7
7
  #---------------------------------
8
8
 
9
- from pathlib import Path
10
-
11
9
  def load_ann(path, clip=None):
12
10
  """
13
- Load annotation from audatity label text file.
11
+ Load annotation from audatity label
12
+ text file and also ctm file.
14
13
 
15
14
  Parameters
16
15
  ----------
17
16
  path: str
18
- - label text file path.
17
+ - label text/ctm file path.
19
18
  clip: tuple[number, number] | number | None
20
19
  - Incase you clipped the audio signal, this parameter will help clip the annotation.
21
20
  - If you clip the audio, say from (10, 20), set the clip to (10, 20).
@@ -25,12 +24,23 @@ def load_ann(path, clip=None):
25
24
  -------
26
25
  list[tuple, ...]
27
26
  - annotation data structure
28
- - [(start, end, tag), ...]
27
+ - [(start, end, label), ...]
29
28
  """
29
+ from pathlib import Path
30
30
 
31
31
  if not isinstance(path, (str, Path)):
32
32
  raise ValueError(f"`path` must be one of (str, Path), got {type(path)}")
33
33
 
34
+ # Convert to Path object
35
+ path = Path(path)
36
+
37
+ # Check if the path exists
38
+ if not path.exists():
39
+ raise FileExistsError(f"{path} does not exist")
40
+
41
+ ann = [] # This will store the annotation
42
+
43
+ # Clipping the annotation to match with the clipped audio
34
44
  if clip is not None:
35
45
  # Map clip input to the right format
36
46
  if isinstance(clip, int or float):
@@ -40,26 +50,56 @@ def load_ann(path, clip=None):
40
50
  else:
41
51
  raise ValueError(f"Invalid clip type or length: {type(clip)}, len={len(clip)}")
42
52
 
43
- ann = []
44
-
45
- with open(str(path), "r") as f:
46
- lines = [line.rstrip("\n") for line in f]
47
- for line in lines:
48
- start, end, tag = line.split("\t")
49
- start, end = float(start), float(end)
53
+ if path.suffix == ".txt":
54
+ with open(str(path), "r") as f:
55
+ lines = [line.rstrip("\n") for line in f]
56
+ for line in lines:
57
+ start, end, label = line.split("\t")
58
+ start, end = float(start), float(end)
59
+
60
+ # Incase user has clipped the audio signal, we adjust the annotation
61
+ # to match the clipped audio
62
+ if clip is not None:
63
+ offset = clip[0]
64
+ # Clamp annotation to clip boundaries
65
+ new_start = max(start, clip[0]) - offset
66
+ new_end = min(end, clip[1]) - offset
67
+
68
+ # only keep if there's still overlap
69
+ if new_start < new_end:
70
+ ann.append((new_start, new_end, label))
71
+ else:
72
+ ann.append((start, end, label))
73
+
74
+ elif path.suffix == ".ctm":
75
+ with open(str(path), "r") as f:
76
+ content = f.read().split("\n")
50
77
 
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
78
+ for c in content:
79
+ c = c.strip()
80
+ if c == "": # Handle empty line usually at the end of the ctm file
81
+ continue
82
+ elif len(c.split(" ")) != 5:
83
+ warnings.warn(f" '{c}' is not a standard ctm line.")
84
+ if len(c.split(" ")) == 5:
85
+ _, _, start, dur, label = c.split(" ")
86
+ start, dur = float(start), float(dur)
87
+ end = start + dur
58
88
 
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))
89
+ # Incase user has clipped the audio signal, we adjust the annotation
90
+ # to match the clipped audio
91
+ if clip is not None:
92
+ offset = clip[0]
93
+ # Clamp annotation to clip boundaries
94
+ new_start = max(start, clip[0]) - offset
95
+ new_end = min(end, clip[1]) - offset
96
+
97
+ # only keep if there's still overlap
98
+ if new_start < new_end:
99
+ ann.append((new_start, new_end, label))
100
+ else:
101
+ ann.append((start, end, label))
64
102
 
103
+ else:
104
+ raise Exception(f"Unsupported file type {path.suffix}")
65
105
  return ann
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modusa
3
- Version: 0.4.10
3
+ Version: 0.4.12
4
4
  Summary: A modular signal analysis python library.
5
5
  Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
6
6
  License: MIT
@@ -1,9 +1,9 @@
1
- modusa-0.4.10.dist-info/METADATA,sha256=TmKus5RBUh4HkCZ-1eK7GLmsMM2S00MMyJc5KMurV-o,1436
2
- modusa-0.4.10.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- modusa-0.4.10.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
4
- modusa-0.4.10.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
5
- modusa/.DS_Store,sha256=_gm6qJREwfMi8dE7n5S89_RG46u5t3xHyD-smNhtNoM,6148
6
- modusa/__init__.py,sha256=PGHCD9XdADguJN6KWAqLZRORiKMNdIGkU18hCMlY57Q,318
1
+ modusa-0.4.12.dist-info/METADATA,sha256=VrYqleweSm6-s9GwBfaR5k8Q6K4vdSDKKdMJT0WxfLc,1436
2
+ modusa-0.4.12.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ modusa-0.4.12.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
4
+ modusa-0.4.12.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
5
+ modusa/.DS_Store,sha256=b3Lw2RBGnDArqCyxps1EmN2oazEM0wnzg3BgurdE0_M,8196
6
+ modusa/__init__.py,sha256=9qlTZXo5slwSmrlrdbAcvoc09imlI4fETfalfMCBpIM,318
7
7
  modusa/config.py,sha256=bTqK4t00FZqERVITrxW_q284aDDJAa9aMSfFknfR-oU,280
8
8
  modusa/decorators.py,sha256=8zeNX_wE37O6Vp0ysR4-WCZaEL8mq8dyCF_I5DHOzks,5905
9
9
  modusa/devtools/generate_docs_source.py,sha256=UDflHsk-Yh9-3YJTVBzKL32y8hcxiRgAlFEBTMiDqwM,3301
@@ -43,7 +43,7 @@ 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=q4d7J4xGraVLVLsk4h1OcWvi19FXd7DbJrGdUAOn5Es,336
45
45
  modusa/tools/_plotter_old.py,sha256=KGow7mihA2H1WNq7s5bpivhCgGo2qVIeDaO6iabpsrg,19294
46
- modusa/tools/ann_loader.py,sha256=GWiX7v4CxyAECthmtBAaSMMqsjo1YaVfRA9u-CtTTFM,1718
46
+ modusa/tools/ann_loader.py,sha256=EMV6lTm1IeTjvWjvagDgwosux9IV6MZkVdUMzVft9Pc,3017
47
47
  modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
48
48
  modusa/tools/audio_loader.py,sha256=n9Q9t_GmlE8AtioVwRcXX3rnd6PkbGTx-hAoNgUnNOQ,2780
49
49
  modusa/tools/audio_player.py,sha256=pXKaNsDbqhCVbrMx5QRv7aC2IPMJFY5POAG60f-1LmU,2901
@@ -60,4 +60,4 @@ modusa/utils/excp.py,sha256=L9vhaGjKpv9viJYdmC9n5ndmk2GVbUBuFyZyhAQZmWY,906
60
60
  modusa/utils/logger.py,sha256=K0rsnObeNKCxlNeSnVnJeRhgfmob6riB2uyU7h3dDmA,571
61
61
  modusa/utils/np_func_cat.py,sha256=TyIFgRc6bARRMDnZxlVURO5Z0I-GWhxRONYyIv-Vwxs,1007
62
62
  modusa/utils/plot.py,sha256=s_vNdxvKfwxEngvJPgrF1PcmxZNnNaaXPViHWjyjJ-c,5335
63
- modusa-0.4.10.dist-info/RECORD,,
63
+ modusa-0.4.12.dist-info/RECORD,,