modusa 0.4.15__py3-none-any.whl → 0.4.17__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/__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.15"
11
+ __version__ = "0.4.17"
@@ -1,89 +1,60 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
+ from IPython.display import Audio, HTML, display
3
4
  import numpy as np
4
- from IPython.display import display, HTML, Audio
5
5
 
6
- def play(y: np.ndarray, sr: float, title = None, t0: float = 0.0, regions = None) -> None:
7
- """
8
- Plays audio clips for given regions in Jupyter Notebooks.
6
+ def play(y: np.ndarray, sr: float, clip: tuple[float, float] | None = None, label: str | None = None) -> None:
7
+ """
8
+ Simple audio player with optional clip selection and label,
9
+ displayed neatly in a small table.
9
10
 
10
- Parameters
11
- ----------
12
- y : np.ndarray
13
- - Audio data.
14
- - Mono (1D) numpy array.
15
- sr: float
16
- - Sampling rate of the audio.
17
- title : str | None
18
- - Title to display above audio players.
19
- t0: float
20
- - Starting timestamp, incase the audio is cropped
21
- - Default: 0.0 → Starts from 0.0 sec
22
- regions : list[tuple[float, float, str]] | tuple[float, float, str] | None
23
- - Regions to extract and play (in sec), e.g. [(0, 10.2, "tag")]
24
- - If there is only one region, a tuple should also work. e.g. (0, 10.2, "tag")
25
- - Default: None → The entire song is selected.
11
+ Parameters
12
+ ----------
13
+ y : np.ndarray
14
+ Mono audio data (1D numpy array).
15
+ sr : float
16
+ Sampling rate.
17
+ clip : tuple[float, float] | None
18
+ (start_time, end_time) in seconds. Plays whole audio if None.
19
+ label : str | None
20
+ Optional label to describe the clip (e.g. "Chorus", "Intro").
26
21
 
27
- Returns
28
- -------
29
- None
30
- """
31
- if title:
32
- display(HTML(f"<p style='font-size:15px; font-weight:600; text-decoration: underline; margin-left:10px'>{title}</p>"))
33
-
34
- clip_tags = []
35
- timings = []
36
- players = []
37
-
38
- if isinstance(regions, tuple): regions = [regions] # (10, 20, "Region 1") -> [(10, 20, "Region 1")]
39
-
40
- if regions is not None:
41
- for region in regions:
42
- assert len(region) == 3
43
-
44
- start_sec = region[0] - t0
45
- end_sec = region[1] - t0
46
- tag = region[2]
47
-
48
- start_sample, end_sample = int(start_sec * sr), int(end_sec * sr)
49
- clip = y[start_sample: end_sample]
50
- audio_player = Audio(data=clip, rate=sr)._repr_html_()
51
-
52
- clip_tags.append(f"<td style='text-align:center; border-right:1px solid #ccc; padding:6px;'>{tag}</td>")
53
- timings.append(f"<td style='text-align:center; border-right:1px solid #ccc; padding:6px;'>{start_sec:.2f}s → {end_sec:.2f}s</td>")
54
- players.append(f"<td style='padding:6px;'>{audio_player}</td>")
55
- else:
56
- audio_player = Audio(data=y, rate=sr)._repr_html_()
57
-
58
- start_sec = t0
59
- end_sec = t0 + y.shape[0] / sr
60
-
61
- clip_tags.append(f"<td style='text-align:center; border-right:1px solid #ccc; padding:6px;'>1</td>")
62
- timings.append(f"<td style='text-align:center; border-right:1px solid #ccc; padding:6px;'>{start_sec:.2f}s → {end_sec:.2f}s</td>")
63
- players.append(f"<td style='padding:6px;'>{audio_player}</td>")
64
-
65
- # Wrap rows in a table with border
66
- table_html = f"""
67
- <div style="display:inline-block; border:1px solid #ccc; border-radius:6px; overflow:hidden;">
68
- <table style="border-collapse:collapse;">
69
- <tr style="background-color:#f2f2f2;">
70
- <th style="text-align:left; padding:6px 12px;">Clip</th>
71
- {''.join(clip_tags)}
72
- </tr>
73
- <tr style="background-color:#fcfcfc;">
74
- <th style="text-align:left; padding:6px 12px;">Timing</th>
75
- {''.join(timings)}
76
- </tr>
77
- <tr>
78
- <th style="text-align:left; padding:6px 12px;">Player</th>
79
- {''.join(players)}
80
- </tr>
81
- </table>
82
- </div>
83
- """
84
-
85
- return HTML(table_html)
22
+ Returns
23
+ -------
24
+ None
25
+ """
26
+ start_time, end_time = 0.0, len(y) / sr
86
27
 
28
+ if clip is not None:
29
+ if not isinstance(clip, tuple) or len(clip) != 2:
30
+ raise ValueError("`clip` must be a tuple of (start_time, end_time)")
31
+ start_sample = int(clip[0] * sr)
32
+ end_sample = int(clip[1] * sr)
33
+ y = y[start_sample:end_sample]
34
+ start_time, end_time = clip
87
35
 
88
-
89
-
36
+ # Build the HTML table
37
+ audio_html = Audio(data=y, rate=sr)._repr_html_()
38
+ label_html = label if label is not None else "-"
39
+
40
+ table_html = f"""
41
+ <div style="display:inline-block; border:1px solid #ccc; border-radius:6px; overflow:hidden;">
42
+ <table style="border-collapse:collapse; font-family:sans-serif; font-size:14px;">
43
+ <tr style="background-color:#f8f8f8;">
44
+ <th style="padding:6px 12px; text-align:left; min-width:120px;">Timing</th>
45
+ <th style="padding:6px 12px; text-align:left;">Label</th>
46
+ <th style="padding:6px 12px; text-align:left;">Player</th>
47
+ </tr>
48
+ <tr>
49
+ <td style="padding:6px 12px; border-top:1px; solid #ddd; text-align:left">
50
+ {start_time:.2f}s → {end_time:.2f}s
51
+ </td>
52
+ <td style="padding:6px 12px; border-top:1px solid #ddd; text-align:left;">{label_html}</td>
53
+ <td style="padding:6px 12px; border-top:1px solid #ddd;">{audio_html}</td>
54
+ </tr>
55
+ </table>
56
+ </div>
57
+ """
58
+
59
+ display(HTML(table_html))
60
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modusa
3
- Version: 0.4.15
3
+ Version: 0.4.17
4
4
  Summary: A modular signal analysis python library.
5
5
  Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
6
6
  License: MIT
@@ -1,8 +1,8 @@
1
- modusa-0.4.15.dist-info/METADATA,sha256=qelNJCY5rCt2iZqupkgxj9UNbmU7KsCo4eqLsWF_2ro,1467
2
- modusa-0.4.15.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- modusa-0.4.15.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
4
- modusa-0.4.15.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
5
- modusa/__init__.py,sha256=gsKRNB93HfNyg4zhrGRdJew7uSPFAlxp5knuHuj-4s0,324
1
+ modusa-0.4.17.dist-info/METADATA,sha256=gTD43GxNvoHVMboXO65-hAPBAk_-VoCAueUb0gK39hg,1467
2
+ modusa-0.4.17.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ modusa-0.4.17.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
4
+ modusa-0.4.17.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
5
+ modusa/__init__.py,sha256=04m67mOQo3NdpAa-54JOtStE7fuj4SSY4LokeTz43EQ,324
6
6
  modusa/config.py,sha256=bTqK4t00FZqERVITrxW_q284aDDJAa9aMSfFknfR-oU,280
7
7
  modusa/decorators.py,sha256=8zeNX_wE37O6Vp0ysR4-WCZaEL8mq8dyCF_I5DHOzks,5905
8
8
  modusa/devtools/generate_docs_source.py,sha256=UDflHsk-Yh9-3YJTVBzKL32y8hcxiRgAlFEBTMiDqwM,3301
@@ -44,7 +44,7 @@ modusa/tools/_plotter_old.py,sha256=KGow7mihA2H1WNq7s5bpivhCgGo2qVIeDaO6iabpsrg,
44
44
  modusa/tools/ann_loader.py,sha256=BEdwAh_lccx_SnAO3bNMeY3O5zGiJlH2o4snWmXj8eQ,3034
45
45
  modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
46
46
  modusa/tools/audio_loader.py,sha256=n9Q9t_GmlE8AtioVwRcXX3rnd6PkbGTx-hAoNgUnNOQ,2780
47
- modusa/tools/audio_player.py,sha256=pXKaNsDbqhCVbrMx5QRv7aC2IPMJFY5POAG60f-1LmU,2901
47
+ modusa/tools/audio_player.py,sha256=wz5iwBMVb6vE6vFiM2lD9qbyh2F5XauVamC58aQoosM,1910
48
48
  modusa/tools/audio_recorder.py,sha256=K_LGqsPdjTdf3figEZTSQLmgMzYWgz18HTO8C1j5fE4,2788
49
49
  modusa/tools/audio_saver.py,sha256=ldzfr_AydsHTnKbxmBLJblN-hLzTmOlppOm306xI4Ug,510
50
50
  modusa/tools/base.py,sha256=C0ESJ0mIfjjRlAkRbSetNtMoOfS6IrHBjexRp3l_Mh4,1293
@@ -57,4 +57,4 @@ modusa/utils/excp.py,sha256=L9vhaGjKpv9viJYdmC9n5ndmk2GVbUBuFyZyhAQZmWY,906
57
57
  modusa/utils/logger.py,sha256=K0rsnObeNKCxlNeSnVnJeRhgfmob6riB2uyU7h3dDmA,571
58
58
  modusa/utils/np_func_cat.py,sha256=TyIFgRc6bARRMDnZxlVURO5Z0I-GWhxRONYyIv-Vwxs,1007
59
59
  modusa/utils/plot.py,sha256=s_vNdxvKfwxEngvJPgrF1PcmxZNnNaaXPViHWjyjJ-c,5335
60
- modusa-0.4.15.dist-info/RECORD,,
60
+ modusa-0.4.17.dist-info/RECORD,,