modusa 0.4.15__py3-none-any.whl → 0.4.16__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 +1 -1
- modusa/tools/audio_player.py +32 -60
- {modusa-0.4.15.dist-info → modusa-0.4.16.dist-info}/METADATA +1 -1
- {modusa-0.4.15.dist-info → modusa-0.4.16.dist-info}/RECORD +7 -7
- {modusa-0.4.15.dist-info → modusa-0.4.16.dist-info}/WHEEL +0 -0
- {modusa-0.4.15.dist-info → modusa-0.4.16.dist-info}/entry_points.txt +0 -0
- {modusa-0.4.15.dist-info → modusa-0.4.16.dist-info}/licenses/LICENSE.md +0 -0
modusa/__init__.py
CHANGED
modusa/tools/audio_player.py
CHANGED
|
@@ -1,88 +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,
|
|
6
|
+
def play(y: np.ndarray, sr: float, clip: tuple[float, float] | None = None, label: str | None = None) -> None:
|
|
7
7
|
"""
|
|
8
|
-
|
|
8
|
+
Simple audio player with optional clip selection and label,
|
|
9
|
+
displayed neatly in a small table.
|
|
9
10
|
|
|
10
11
|
Parameters
|
|
11
12
|
----------
|
|
12
13
|
y : np.ndarray
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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.
|
|
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
22
|
Returns
|
|
28
23
|
-------
|
|
29
24
|
None
|
|
30
25
|
"""
|
|
31
|
-
|
|
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")]
|
|
26
|
+
start_time, end_time = 0.0, len(y) / sr
|
|
39
27
|
|
|
40
|
-
if
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
|
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
|
|
60
35
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# Wrap rows in a table with border
|
|
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
|
+
|
|
66
40
|
table_html = f"""
|
|
67
41
|
<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:#
|
|
70
|
-
<th style="text-align:left;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
<tr style="background-color:#fcfcfc;">
|
|
74
|
-
<th style="text-align:left; padding:6px 12px;">Timing</th>
|
|
75
|
-
{''.join(timings)}
|
|
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;">Timing</th>
|
|
45
|
+
<th style="padding:6px 12px; text-align:left;">Label</th>
|
|
46
|
+
<th style="padding:6px 12px; text-align:left;">Audio</th>
|
|
76
47
|
</tr>
|
|
77
48
|
<tr>
|
|
78
|
-
<
|
|
79
|
-
{
|
|
49
|
+
<td style="padding:6px 12px; border-top:1px solid #ddd;">{start_time:.2f}s → {end_time:.2f}s</td>
|
|
50
|
+
<td style="padding:6px 12px; border-top:1px solid #ddd;">{label_html}</td>
|
|
51
|
+
<td style="padding:6px 12px; border-top:1px solid #ddd;">{audio_html}</td>
|
|
80
52
|
</tr>
|
|
81
53
|
</table>
|
|
82
54
|
</div>
|
|
83
55
|
"""
|
|
84
56
|
|
|
85
|
-
|
|
57
|
+
display(HTML(table_html))
|
|
86
58
|
|
|
87
59
|
|
|
88
60
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
modusa-0.4.
|
|
2
|
-
modusa-0.4.
|
|
3
|
-
modusa-0.4.
|
|
4
|
-
modusa-0.4.
|
|
5
|
-
modusa/__init__.py,sha256=
|
|
1
|
+
modusa-0.4.16.dist-info/METADATA,sha256=pLWuRj0GcmfeniEEcjwUbsShuSxYnPqFIGVLXqdX3KQ,1467
|
|
2
|
+
modusa-0.4.16.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
|
3
|
+
modusa-0.4.16.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
|
|
4
|
+
modusa-0.4.16.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
|
|
5
|
+
modusa/__init__.py,sha256=YzOOf42ipGf7nXgrkH0VFvL9WGLAuqIFIft8VuCKgXo,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=
|
|
47
|
+
modusa/tools/audio_player.py,sha256=NQv7sAGhJerju5_JKkvtVW9IcbjDv_mj7cDdxwK-blw,1911
|
|
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.
|
|
60
|
+
modusa-0.4.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|