modusa 0.2.23__py3-none-any.whl → 0.3.1__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 +0 -0
- modusa/__init__.py +8 -1
- modusa/devtools/{generate_doc_source.py → generate_docs_source.py} +5 -5
- modusa/devtools/generate_template.py +5 -5
- modusa/devtools/main.py +3 -3
- modusa/devtools/templates/generator.py +1 -1
- modusa/devtools/templates/io.py +1 -1
- modusa/devtools/templates/{signal.py → model.py} +18 -11
- modusa/devtools/templates/plugin.py +1 -1
- modusa/generators/__init__.py +11 -1
- modusa/generators/audio.py +188 -0
- modusa/generators/audio_waveforms.py +1 -1
- modusa/generators/base.py +1 -1
- modusa/generators/ftds.py +298 -0
- modusa/generators/s1d.py +270 -0
- modusa/generators/s2d.py +300 -0
- modusa/generators/s_ax.py +102 -0
- modusa/generators/t_ax.py +64 -0
- modusa/generators/tds.py +267 -0
- modusa/models/__init__.py +14 -0
- modusa/models/__pycache__/signal1D.cpython-312.pyc.4443461152 +0 -0
- modusa/models/audio.py +90 -0
- modusa/models/base.py +70 -0
- modusa/models/data.py +457 -0
- modusa/models/ftds.py +584 -0
- modusa/models/s1d.py +578 -0
- modusa/models/s2d.py +619 -0
- modusa/models/s_ax.py +448 -0
- modusa/models/t_ax.py +335 -0
- modusa/models/tds.py +465 -0
- modusa/plugins/__init__.py +3 -1
- modusa/tmp.py +98 -0
- modusa/tools/__init__.py +5 -0
- modusa/tools/audio_converter.py +56 -67
- modusa/tools/audio_loader.py +90 -0
- modusa/tools/audio_player.py +42 -67
- modusa/tools/math_ops.py +104 -1
- modusa/tools/plotter.py +305 -497
- modusa/tools/youtube_downloader.py +31 -98
- modusa/utils/excp.py +6 -0
- modusa/utils/np_func_cat.py +44 -0
- modusa/utils/plot.py +142 -0
- {modusa-0.2.23.dist-info → modusa-0.3.1.dist-info}/METADATA +24 -19
- modusa-0.3.1.dist-info/RECORD +60 -0
- modusa/devtools/docs/source/generators/audio_waveforms.rst +0 -8
- modusa/devtools/docs/source/generators/base.rst +0 -8
- modusa/devtools/docs/source/generators/index.rst +0 -8
- modusa/devtools/docs/source/io/audio_loader.rst +0 -8
- modusa/devtools/docs/source/io/base.rst +0 -8
- modusa/devtools/docs/source/io/index.rst +0 -8
- modusa/devtools/docs/source/plugins/base.rst +0 -8
- modusa/devtools/docs/source/plugins/index.rst +0 -7
- modusa/devtools/docs/source/signals/audio_signal.rst +0 -8
- modusa/devtools/docs/source/signals/base.rst +0 -8
- modusa/devtools/docs/source/signals/frequency_domain_signal.rst +0 -8
- modusa/devtools/docs/source/signals/index.rst +0 -11
- modusa/devtools/docs/source/signals/spectrogram.rst +0 -8
- modusa/devtools/docs/source/signals/time_domain_signal.rst +0 -8
- modusa/devtools/docs/source/tools/audio_converter.rst +0 -8
- modusa/devtools/docs/source/tools/audio_player.rst +0 -8
- modusa/devtools/docs/source/tools/base.rst +0 -8
- modusa/devtools/docs/source/tools/fourier_tranform.rst +0 -8
- modusa/devtools/docs/source/tools/index.rst +0 -13
- modusa/devtools/docs/source/tools/math_ops.rst +0 -8
- modusa/devtools/docs/source/tools/plotter.rst +0 -8
- modusa/devtools/docs/source/tools/youtube_downloader.rst +0 -8
- modusa/io/__init__.py +0 -5
- modusa/io/audio_loader.py +0 -184
- modusa/io/base.py +0 -43
- modusa/signals/__init__.py +0 -3
- modusa/signals/audio_signal.py +0 -540
- modusa/signals/base.py +0 -27
- modusa/signals/frequency_domain_signal.py +0 -376
- modusa/signals/spectrogram.py +0 -564
- modusa/signals/time_domain_signal.py +0 -412
- modusa/tools/fourier_tranform.py +0 -24
- modusa-0.2.23.dist-info/RECORD +0 -70
- {modusa-0.2.23.dist-info → modusa-0.3.1.dist-info}/WHEEL +0 -0
- {modusa-0.2.23.dist-info → modusa-0.3.1.dist-info}/entry_points.txt +0 -0
- {modusa-0.2.23.dist-info → modusa-0.3.1.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -8,45 +8,36 @@ from typing import Any
|
|
|
8
8
|
from pathlib import Path
|
|
9
9
|
import yt_dlp
|
|
10
10
|
|
|
11
|
-
class YoutubeDownloader(ModusaTool):
|
|
12
|
-
"""
|
|
13
|
-
Download highest quality audio/video from YouTube.
|
|
14
|
-
|
|
15
|
-
Note
|
|
16
|
-
----
|
|
17
|
-
- The engine uses `yt_dlp` python package to download content from YouTube.
|
|
18
11
|
|
|
12
|
+
def download(url, content_type, output_dir):
|
|
19
13
|
"""
|
|
14
|
+
Downloads audio/video from YouTube.
|
|
15
|
+
|
|
16
|
+
.. code-block:: python
|
|
17
|
+
|
|
18
|
+
# To download audio
|
|
19
|
+
import modusa as ms
|
|
20
|
+
audio_fp = ms.download(
|
|
21
|
+
url="https://www.youtube.com/watch?v=lIpw9-Y_N0g",
|
|
22
|
+
content_type="audio",
|
|
23
|
+
output_dir=".")
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
url: str
|
|
28
|
+
Link to the YouTube video.
|
|
29
|
+
content_type: str
|
|
30
|
+
"audio" or "video"
|
|
31
|
+
output_dir: str | Path
|
|
32
|
+
Directory to save the YouTube content.
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
34
|
+
Returns
|
|
35
|
+
-------
|
|
36
|
+
Path
|
|
37
|
+
File path of the downloaded content.
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _download_audio(url: str, output_dir: str | Path):
|
|
35
|
-
"""
|
|
36
|
-
Download the highest quality audio from a given YouTube URL.
|
|
37
|
-
|
|
38
|
-
Parameters
|
|
39
|
-
----------
|
|
40
|
-
url: str
|
|
41
|
-
URL for the YouTube video.
|
|
42
|
-
output_dir:
|
|
43
|
-
Directory where the audio will be saved.
|
|
44
|
-
|
|
45
|
-
Returns
|
|
46
|
-
-------
|
|
47
|
-
Path
|
|
48
|
-
Path to the downloaded audio file.
|
|
49
|
-
"""
|
|
39
|
+
"""
|
|
40
|
+
if content_type == "audio":
|
|
50
41
|
output_dir = Path(output_dir)
|
|
51
42
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
52
43
|
|
|
@@ -59,25 +50,8 @@ class YoutubeDownloader(ModusaTool):
|
|
|
59
50
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
60
51
|
info = ydl.extract_info(url, download=True)
|
|
61
52
|
return Path(info['requested_downloads'][0]['filepath'])
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
@validate_args_type()
|
|
65
|
-
def _download_video(url: str, output_dir: str | Path):
|
|
66
|
-
"""
|
|
67
|
-
Download the highest quality video from a YouTube URL using yt-dlp.
|
|
68
|
-
|
|
69
|
-
Parameters
|
|
70
|
-
----------
|
|
71
|
-
url: str
|
|
72
|
-
URL for the YouTube video.
|
|
73
|
-
output_dir:
|
|
74
|
-
Directory where the video will be saved.
|
|
75
|
-
|
|
76
|
-
Returns
|
|
77
|
-
-------
|
|
78
|
-
Path
|
|
79
|
-
Path to the downloaded audio file
|
|
80
|
-
"""
|
|
53
|
+
|
|
54
|
+
elif content_type == "video":
|
|
81
55
|
output_dir = Path(output_dir)
|
|
82
56
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
83
57
|
|
|
@@ -91,49 +65,8 @@ class YoutubeDownloader(ModusaTool):
|
|
|
91
65
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
92
66
|
info = ydl.extract_info(url, download=True)
|
|
93
67
|
return Path(info['requested_downloads'][0]['filepath'])
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
@validate_args_type()
|
|
97
|
-
def download(url: str, content_type: str, output_dir: str | Path) -> Path:
|
|
98
|
-
"""
|
|
99
|
-
Downloads audio/video from YouTube.
|
|
100
|
-
|
|
101
|
-
.. code-block:: python
|
|
102
|
-
|
|
103
|
-
# To download audio
|
|
104
|
-
from modusa.io import YoutubeDownloader
|
|
105
|
-
audio_fp = YoutubeDownloader.download(
|
|
106
|
-
url="https://www.youtube.com/watch?v=lIpw9-Y_N0g",
|
|
107
|
-
content_type="audio",
|
|
108
|
-
output_dir="."
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
# To download video
|
|
112
|
-
from modusa.engines import YoutubeDownloaderEngine
|
|
113
|
-
video_fp = YoutubeDownloader.download(
|
|
114
|
-
url="https://www.youtube.com/watch?v=lIpw9-Y_N0g",
|
|
115
|
-
content_type="audio",
|
|
116
|
-
output_dir="."
|
|
117
|
-
)
|
|
68
|
+
else:
|
|
69
|
+
raise excp.InputValueError(f"`content_type` can either take 'audio' or 'video' not {content_type}")
|
|
118
70
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
url: str
|
|
122
|
-
Link to the YouTube video.
|
|
123
|
-
content_type: str
|
|
124
|
-
"audio" or "video"
|
|
125
|
-
output_dir: str | Path
|
|
126
|
-
Directory to save the YouTube content.
|
|
127
|
-
|
|
128
|
-
Returns
|
|
129
|
-
-------
|
|
130
|
-
Path
|
|
131
|
-
File path of the downloaded content.
|
|
132
|
-
|
|
133
|
-
"""
|
|
134
|
-
if content_type == "audio":
|
|
135
|
-
return YoutubeDownloader._download_audio(url=url, output_dir=output_dir)
|
|
136
|
-
elif content_type == "video":
|
|
137
|
-
return YoutubeDownloader._download_video(url=url, output_dir=output_dir)
|
|
138
|
-
else:
|
|
139
|
-
raise excp.InputValueError(f"`content_type` can either take 'audio' or 'video' not {content_type}")
|
|
71
|
+
|
|
72
|
+
|
modusa/utils/excp.py
CHANGED
|
@@ -28,6 +28,12 @@ class InputValueError(ModusaBaseError):
|
|
|
28
28
|
Any Input type error.
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
+
class OperationNotPossibleError(ModusaBaseError):
|
|
32
|
+
"""
|
|
33
|
+
Any errors if there is an operations
|
|
34
|
+
failure.
|
|
35
|
+
"""
|
|
36
|
+
|
|
31
37
|
class ImmutableAttributeError(ModusaBaseError):
|
|
32
38
|
"""Raised when attempting to modify an immutable attribute."""
|
|
33
39
|
pass
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# This contains categorised NumPy functions
|
|
4
|
+
# This is useful while handling np operations on modusa signals
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
SHAPE_PRESERVING_FUNCS = {
|
|
9
|
+
np.sin, np.cos, np.tan,
|
|
10
|
+
np.sinh, np.cosh, np.tanh,
|
|
11
|
+
np.arcsin, np.arccos, np.arctan,
|
|
12
|
+
np.exp, np.expm1, np.log, np.log2, np.log10, np.log1p,
|
|
13
|
+
np.abs, np.negative, np.positive,
|
|
14
|
+
np.square, np.sqrt, np.cbrt,
|
|
15
|
+
np.floor, np.ceil, np.round, np.rint, np.trunc,
|
|
16
|
+
np.clip, np.sign,
|
|
17
|
+
np.add, np.subtract, np.multiply, np.true_divide, np.floor_divide
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
REDUCTION_FUNCS = {
|
|
21
|
+
np.sum, np.prod,
|
|
22
|
+
np.mean, np.std, np.var,
|
|
23
|
+
np.min, np.max,
|
|
24
|
+
np.argmin, np.argmax,
|
|
25
|
+
np.median, np.percentile,
|
|
26
|
+
np.all, np.any,
|
|
27
|
+
np.nanmean, np.nanstd, np.nanvar, np.nansum
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
CONCAT_FUNCS = {
|
|
31
|
+
np.concatenate, np.stack, np.hstack, np.vstack, np.dstack,
|
|
32
|
+
np.column_stack, np.row_stack
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
X_NEEDS_ADJUSTMENT_FUNCS = {
|
|
36
|
+
np.diff,
|
|
37
|
+
np.gradient,
|
|
38
|
+
np.trim_zeros,
|
|
39
|
+
np.unwrap,
|
|
40
|
+
np.fft.fft, np.fft.ifft, np.fft.fftshift, np.fft.ifftshift,
|
|
41
|
+
np.correlate, np.convolve
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
modusa/utils/plot.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
from modusa.models.s1d import S1D
|
|
4
|
+
from modusa.models.s2d import S2D
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
import numpy as np
|
|
7
|
+
from collections import defaultdict
|
|
8
|
+
import itertools
|
|
9
|
+
|
|
10
|
+
def _in_notebook() -> bool:
|
|
11
|
+
"""
|
|
12
|
+
To check if we are in jupyter notebook environment.
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
from IPython import get_ipython
|
|
16
|
+
shell = get_ipython()
|
|
17
|
+
return shell and shell.__class__.__name__ == "ZMQInteractiveShell"
|
|
18
|
+
except ImportError:
|
|
19
|
+
return False
|
|
20
|
+
|
|
21
|
+
def plot_multiple_signals(
|
|
22
|
+
*args,
|
|
23
|
+
loc = None,
|
|
24
|
+
x_lim: tuple[float, float] | None = None,
|
|
25
|
+
highlight_regions: list[tuple[float, float, str]] | None = None,
|
|
26
|
+
vlines: list[float, ...] | None = None,
|
|
27
|
+
) -> plt.Figure:
|
|
28
|
+
"""
|
|
29
|
+
Plots multiple instances of uniform `Signal1D` and `Signal2D`
|
|
30
|
+
with proper formatting and time aligned.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
loc: tuple[int]
|
|
35
|
+
- The len should match the number of signals sent as args.
|
|
36
|
+
- e.g. (0, 1, 1) => First plot at ax 0, second and third plot at ax 1
|
|
37
|
+
- Default: None => (0, 1, 2, ...) all plots on a new ax.
|
|
38
|
+
highlight_regions: list[tuple[float, float, str]]
|
|
39
|
+
-
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
assert len(args) >= 1, "No signal provided to plot"
|
|
44
|
+
signals = args
|
|
45
|
+
|
|
46
|
+
for signal in signals:
|
|
47
|
+
if not isinstance(signal, (S1D, S2D)):
|
|
48
|
+
raise TypeError(f"Invalid signal type {type(signal)}")
|
|
49
|
+
|
|
50
|
+
if loc is None: # => We will plot all the signals on different subplots
|
|
51
|
+
loc = tuple([i for i in range(len(args))]) # Create (0, 1, 2, ...) that serves as ax number for plots
|
|
52
|
+
else: # Incase loc is provided, we make sure that we do it for each of the signals
|
|
53
|
+
assert len(args) == len(loc)
|
|
54
|
+
|
|
55
|
+
# Make sure that all the elements in loc do not miss any number in between (0, 1, 1, 2, 4) -> Not allowed
|
|
56
|
+
assert min(loc) == 0
|
|
57
|
+
max_loc = max(loc)
|
|
58
|
+
for i in range(max_loc):
|
|
59
|
+
if i not in loc:
|
|
60
|
+
raise ValueError(f"Invalid `loc` values, it should not have any missing integer in between.")
|
|
61
|
+
|
|
62
|
+
# Create a dict that maps subplot to signals that need to be plotted on that subplot e.g. {0: [signal1, signal3], ...}
|
|
63
|
+
subplot_signal_map = defaultdict(list)
|
|
64
|
+
for signal, i in zip(args, loc):
|
|
65
|
+
subplot_signal_map[i].append(signal)
|
|
66
|
+
|
|
67
|
+
# We need to create a figure with right configurations
|
|
68
|
+
height_ratios = []
|
|
69
|
+
height_1d_subplot = 0.4
|
|
70
|
+
height_2d_subplot = 1
|
|
71
|
+
n_1d_subplots = 0
|
|
72
|
+
n_2d_subplots = 0
|
|
73
|
+
for l, signals in subplot_signal_map.items():
|
|
74
|
+
|
|
75
|
+
# If there is any 2D signal, the subplot will be 2D
|
|
76
|
+
if any(isinstance(s, S2D) for s in signals):
|
|
77
|
+
n_2d_subplots += 1
|
|
78
|
+
height_ratios.append(height_2d_subplot)
|
|
79
|
+
|
|
80
|
+
# If all are 1D signal, the subplot will be 1D
|
|
81
|
+
elif all(isinstance(s, S1D) for s in signals):
|
|
82
|
+
n_1d_subplots += 1
|
|
83
|
+
height_ratios.append(height_1d_subplot)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
n_subplots = n_1d_subplots + n_2d_subplots
|
|
87
|
+
fig_width = 15
|
|
88
|
+
fig_height = n_1d_subplots * 2 + n_2d_subplots * 4 # This is as per the figsize height set in the plotter tool
|
|
89
|
+
fig, axs = plt.subplots(n_subplots, 2, figsize=(fig_width, fig_height), width_ratios=[1, 0.01], height_ratios=height_ratios) # 2nd column for cbar
|
|
90
|
+
|
|
91
|
+
if n_subplots == 1:
|
|
92
|
+
axs = [axs] # axs becomes list of one pair [ (ax, cbar_ax) ]
|
|
93
|
+
|
|
94
|
+
# We find the x axis limits as per the max limit for all the signals combined, so that all the signals can be seen.
|
|
95
|
+
if x_lim is None:
|
|
96
|
+
x_min = min(np.min(signal.x.values) for signal in args)
|
|
97
|
+
x_max = max(np.max(signal.x.values) for signal in args)
|
|
98
|
+
x_lim = (x_min, x_max)
|
|
99
|
+
|
|
100
|
+
for l, signals in subplot_signal_map.items():
|
|
101
|
+
# Incase we have plot multiple signals in the same subplot, we change the color
|
|
102
|
+
fmt_cycle = itertools.cycle(['k-', 'r-', 'g-', 'b-', 'm-', 'c-', 'y-'])
|
|
103
|
+
|
|
104
|
+
# For each subplot, we want to know if it is 2D or 1D
|
|
105
|
+
if any(isinstance(s, S2D) for s in signals): is_1d_subplot = False
|
|
106
|
+
else: is_1d_subplot = True
|
|
107
|
+
|
|
108
|
+
if is_1d_subplot: # All the signals are 1D
|
|
109
|
+
for signal in signals:
|
|
110
|
+
fmt = next(fmt_cycle)
|
|
111
|
+
if len(signals) == 1: # highlight region works properly only if there is one signal for a subplot
|
|
112
|
+
signal.plot(axs[l][0], x_lim=x_lim, highlight_regions=highlight_regions, show_grid=True, vlines=vlines, fmt=fmt, legend=signal._title)
|
|
113
|
+
else:
|
|
114
|
+
y, x = signal._x._values, signal._y._values
|
|
115
|
+
signal.plot(axs[l][0], x_lim=x_lim, show_grid=True, vlines=vlines, fmt=fmt, legend=signal.title, y_label=signal.y.label, x_label=signal.x.label, title="")
|
|
116
|
+
|
|
117
|
+
# Remove the colorbar column (if the subplot is 1d)
|
|
118
|
+
axs[l][1].remove()
|
|
119
|
+
|
|
120
|
+
if not is_1d_subplot: # Atleast 1 signal is 2D, we we have a 2D subplot
|
|
121
|
+
for signal in signals:
|
|
122
|
+
if len(signals) == 1: # Only one 2D signal is to be plotted
|
|
123
|
+
signal.plot(axs[l][0], x_lim=x_lim, show_colorbar=True, cax=axs[l][1], highlight_regions=highlight_regions, vlines=vlines)
|
|
124
|
+
else:
|
|
125
|
+
if isinstance(signal, S1D):
|
|
126
|
+
fmt = next(fmt_cycle)
|
|
127
|
+
signal.plot(axs[l][0], x_lim=x_lim, show_grid=True, vlines=vlines, fmt=fmt, legend=signal.title, y_label=signal.y.label, x_label=signal.x.label, title="")
|
|
128
|
+
elif isinstance(signal, S2D):
|
|
129
|
+
signal.plot(axs[l][0], x_lim=x_lim, show_colorbar=True, cax=axs[l][1], vlines=vlines, x_label=signal.x.label, y_label=signal.y.label, title="")
|
|
130
|
+
|
|
131
|
+
# We set the xlim, this will align all the signals automatically as they are on the same row
|
|
132
|
+
for l in range(n_subplots):
|
|
133
|
+
axs[l][0].set_xlim(x_lim)
|
|
134
|
+
|
|
135
|
+
if _in_notebook():
|
|
136
|
+
plt.tight_layout()
|
|
137
|
+
plt.close(fig)
|
|
138
|
+
return fig
|
|
139
|
+
else:
|
|
140
|
+
plt.tight_layout()
|
|
141
|
+
plt.show()
|
|
142
|
+
return fig
|
|
@@ -1,30 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: modusa
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: A modular signal analysis python library.
|
|
5
5
|
Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
8
|
Requires-Dist: numpy>=2.2.6
|
|
9
9
|
Requires-Dist: matplotlib>=3.10.3
|
|
10
10
|
Requires-Dist: yt-dlp>=2025.6.30
|
|
11
|
-
Requires-Dist: librosa==0.
|
|
11
|
+
Requires-Dist: librosa==0.11.0
|
|
12
12
|
Requires-Dist: IPython>=8.0.0
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
|
|
15
15
|
# modusa
|
|
16
16
|
|
|
17
|
-
[**modusa**](https://meluron-toolbox.github.io/modusa/) is a
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Core Components
|
|
22
|
-
|
|
23
|
-
- ⚙️ **modusa Signals**
|
|
24
|
-
- 🧩 **modusa Plugins**
|
|
25
|
-
- 📊 **modusa Genetators**
|
|
26
|
-
- 📥 **modusa I/O**
|
|
27
|
-
- ♻️ **modusa Engines**
|
|
17
|
+
[**modusa**](https://meluron-toolbox.github.io/modusa/) is a library with utility tools especially for audio signals.
|
|
28
18
|
|
|
29
19
|
---
|
|
30
20
|
|
|
@@ -32,17 +22,15 @@ Description-Content-Type: text/markdown
|
|
|
32
22
|
|
|
33
23
|
> modusa is under active development. You can install the latest version via:
|
|
34
24
|
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
cd modusa
|
|
38
|
-
pdm install
|
|
25
|
+
```
|
|
26
|
+
pip install modusa
|
|
39
27
|
```
|
|
40
28
|
|
|
41
29
|
---
|
|
42
30
|
|
|
43
31
|
## Tests
|
|
44
32
|
|
|
45
|
-
```
|
|
33
|
+
```
|
|
46
34
|
pytest tests/
|
|
47
35
|
```
|
|
48
36
|
|
|
@@ -55,6 +43,23 @@ If you like the direction, consider ⭐ starring the repo and opening issues or
|
|
|
55
43
|
|
|
56
44
|
---
|
|
57
45
|
|
|
46
|
+
## Few useful command
|
|
47
|
+
|
|
48
|
+
To push doc changes
|
|
49
|
+
```
|
|
50
|
+
ghp-import -n -p -f docs/build/html
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
To create a dist
|
|
54
|
+
```
|
|
55
|
+
pdm build
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
To upload on pypi
|
|
59
|
+
```
|
|
60
|
+
twine upload dist/*
|
|
61
|
+
```
|
|
62
|
+
|
|
58
63
|
## About
|
|
59
64
|
|
|
60
65
|
**modusa** is developed and maintained by [meluron](https://www.github.com/meluron),
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
modusa-0.3.1.dist-info/METADATA,sha256=cErfyykQ9YH87Zjs2TjmBM1iV_jIMHUF4BAU97q09lU,1368
|
|
2
|
+
modusa-0.3.1.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
|
|
3
|
+
modusa-0.3.1.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
|
|
4
|
+
modusa-0.3.1.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
|
|
5
|
+
modusa/.DS_Store,sha256=_gm6qJREwfMi8dE7n5S89_RG46u5t3xHyD-smNhtNoM,6148
|
|
6
|
+
modusa/__init__.py,sha256=AALG_17vibpDZbo0MymvGoQroaLp3uVm_onZaESONQA,257
|
|
7
|
+
modusa/config.py,sha256=bTqK4t00FZqERVITrxW_q284aDDJAa9aMSfFknfR-oU,280
|
|
8
|
+
modusa/decorators.py,sha256=8zeNX_wE37O6Vp0ysR4-WCZaEL8mq8dyCF_I5DHOzks,5905
|
|
9
|
+
modusa/devtools/generate_docs_source.py,sha256=qqxr3UgTeM4iotarQGRN_q2QXwAzGH7ha9bVjs8D4GQ,3409
|
|
10
|
+
modusa/devtools/generate_template.py,sha256=0sT_5-SjMLXyvePRDaIxr1RCz_9v6zFH9OoJqpuD2zI,5204
|
|
11
|
+
modusa/devtools/list_authors.py,sha256=FWBQKOLznVthvMYMASrx2Gw5lqKHEOccQpBisDZ53Dw,24
|
|
12
|
+
modusa/devtools/list_plugins.py,sha256=g-R5hoaCzHfClY_Sfa788IQ9CAKzQGTfyqmthXDZQqw,1729
|
|
13
|
+
modusa/devtools/main.py,sha256=zIB7x6km4RkV3A9P26NWpQberLn_3PWKbABxqAmzlzI,1993
|
|
14
|
+
modusa/devtools/templates/generator.py,sha256=ATEEgf0UtQ_eM_iA7colVBrlilIqViYC1CzNVUlXzRM,449
|
|
15
|
+
modusa/devtools/templates/io.py,sha256=yYU41zMpE204xRsqBxsRqLs3sH1LF6KgtJvzCNKNbhY,388
|
|
16
|
+
modusa/devtools/templates/model.py,sha256=iwmXadLMA4IAMgOEktdCWKZsceLgaaZkTWcJHqjQZzI,954
|
|
17
|
+
modusa/devtools/templates/plugin.py,sha256=MWqrxBxfRKVw2zjEgfAG0RYUAMjuazhqC5PXIb0gJi4,868
|
|
18
|
+
modusa/devtools/templates/test.py,sha256=CjZ_oqwJFhltNYzqfK1pcz1ShgeJXZLOnYpmOawfASs,244
|
|
19
|
+
modusa/devtools/templates/tool.py,sha256=2iQfHbFKtTELPvNoX42rHr9_5lXRrXpwxb9z5OL96Xc,435
|
|
20
|
+
modusa/generators/__init__.py,sha256=xQUsOObRhTEPzdZsBGd4nT_9AWaL8uE_bisFAN_Wp9Q,236
|
|
21
|
+
modusa/generators/audio.py,sha256=91CnBDPZhagfJOx-cDoBBj3NrE92m70PmFmv7T8aQco,4477
|
|
22
|
+
modusa/generators/audio_waveforms.py,sha256=x-r4_kDi2xieQNBCo11qY2uk2bFcvzeNOppfJnj2oYs,6105
|
|
23
|
+
modusa/generators/base.py,sha256=Kd3eAYOU8PDE28hz0uXfnrmgYSK2lGgHcr5NqeExxbE,938
|
|
24
|
+
modusa/generators/ftds.py,sha256=BkELukm5zbDwUxQVoylrlT9irIUUB2ZGfBc5pH5LUDc,6704
|
|
25
|
+
modusa/generators/s1d.py,sha256=M05oU22qkuLd9ycTSoOyfDtC4w2DEBebRZ4VTkUJRQo,5756
|
|
26
|
+
modusa/generators/s2d.py,sha256=kU67dZj4tdIDSUFJeheXm_JKbyHpZZOGmW5jya6w0wo,6874
|
|
27
|
+
modusa/generators/s_ax.py,sha256=4CTFp_KwYnl4HDno-ATpTXOfKR9WEVOV45nwuk2OoVk,2221
|
|
28
|
+
modusa/generators/t_ax.py,sha256=X-XOJuGWw99dPAVsCVzNTfBFr81Vw56aZlGDmcl5q3k,1478
|
|
29
|
+
modusa/generators/tds.py,sha256=eGvzcjXyWaw5NVzM3D098r3xkoMcX8Ma9YoDUdL30Mo,5960
|
|
30
|
+
modusa/main.py,sha256=v9oOhnPcbw8ULfkKRoantEfHw7MqOETJwXC-odx3dnA,25
|
|
31
|
+
modusa/models/__init__.py,sha256=G8sNOnBnTKqPmC4Z46ximBhc_pfBOF_G6AIfxT8DFzw,271
|
|
32
|
+
modusa/models/__pycache__/signal1D.cpython-312.pyc.4443461152,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
modusa/models/audio.py,sha256=IcNx3h8tb5Jt6KZug_TQKM5iufVk3i7Ug37iKG4gsJ0,2411
|
|
34
|
+
modusa/models/base.py,sha256=1qAXj69VsmrjGqShl5b27Jvt7OADHmPY0L9fBtpB_1E,1621
|
|
35
|
+
modusa/models/data.py,sha256=ds5zM0NOCwGImdxNdx27OnVpgKZ6kXUJMYBUqFWshXY,11368
|
|
36
|
+
modusa/models/ftds.py,sha256=5rd-3h1tzuy3OdD-pb66T0trPo77AvseZt3dy1zdZpg,16182
|
|
37
|
+
modusa/models/s1d.py,sha256=Hm2woUn9wcuwq1RYuEwlAWQPOLoRtnJoFD0mofW67mo,15550
|
|
38
|
+
modusa/models/s2d.py,sha256=10XXpZveFW6OY-v7O3xRy6xDNS5lzJi9UjJMqywyuYE,16782
|
|
39
|
+
modusa/models/s_ax.py,sha256=kKUOwZU9wV-w1ZJyOmdkcLMGtSOXA2gYzZ5f1FsHSEg,10793
|
|
40
|
+
modusa/models/t_ax.py,sha256=ZUhvZPUW1TkdZYuUd6Ucm-vsv0JqtZ9yEe3ab67Ma6w,8022
|
|
41
|
+
modusa/models/tds.py,sha256=FAGfibjyyE_lkEuQp-vSCuqQnopOjmy_IXqUjRlg9kc,11677
|
|
42
|
+
modusa/plugins/__init__.py,sha256=r1Bf5mnrVKRIwxboutY1iGzDy4EPQhqpk1kSW7iJj_Q,54
|
|
43
|
+
modusa/plugins/base.py,sha256=Bh_1Bja7fOymFsCgwhXDbV6ys3D8muNrPwrfDrG_G_A,2382
|
|
44
|
+
modusa/tmp.py,sha256=zPwgFVk5Oh6Rp6GUCbWJdkmwo6vYvhSqI35QVhW5xQM,3180
|
|
45
|
+
modusa/tools/__init__.py,sha256=jOFL7PJ1IztN6F7aMdrVKNMTid2yUmoSlSST-WFf0Cc,199
|
|
46
|
+
modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
|
|
47
|
+
modusa/tools/audio_loader.py,sha256=DrCzq0pdiQrUDIG-deLJGcu8EaylO5yRtwT4lr8WSf8,2166
|
|
48
|
+
modusa/tools/audio_player.py,sha256=GP04TWW4jBwQBjANkfR_cJtEy7cIhvbu8RTwnf9hD6E,2817
|
|
49
|
+
modusa/tools/base.py,sha256=C0ESJ0mIfjjRlAkRbSetNtMoOfS6IrHBjexRp3l_Mh4,1293
|
|
50
|
+
modusa/tools/math_ops.py,sha256=ZZ7U4DgqT7cOeE7_Lzi_Qq-48WYfwR9_osbZwTmE9eg,8690
|
|
51
|
+
modusa/tools/plotter.py,sha256=HaiIyP0Ll-Rk8Nw54g-R-AY9aAZxSAtnviYFnfuln_w,10552
|
|
52
|
+
modusa/tools/youtube_downloader.py,sha256=hB_X8-7nOHXOlxg6vv3wyhBLoAsWyomrULP6_uCQL7s,1698
|
|
53
|
+
modusa/utils/.DS_Store,sha256=nLXMwF7QJNuglLI_Gk74F7vl5Dyus2Wd74Mgowijmdo,6148
|
|
54
|
+
modusa/utils/__init__.py,sha256=1oLL20yLB1GL9IbFiZD8OReDqiCpFr-yetIR6x1cNkI,23
|
|
55
|
+
modusa/utils/config.py,sha256=cuGbqbovx5WDQq5rw3hIKcv3CnE5NttjacSOWnP1yu4,576
|
|
56
|
+
modusa/utils/excp.py,sha256=L9vhaGjKpv9viJYdmC9n5ndmk2GVbUBuFyZyhAQZmWY,906
|
|
57
|
+
modusa/utils/logger.py,sha256=K0rsnObeNKCxlNeSnVnJeRhgfmob6riB2uyU7h3dDmA,571
|
|
58
|
+
modusa/utils/np_func_cat.py,sha256=TyIFgRc6bARRMDnZxlVURO5Z0I-GWhxRONYyIv-Vwxs,1007
|
|
59
|
+
modusa/utils/plot.py,sha256=s_vNdxvKfwxEngvJPgrF1PcmxZNnNaaXPViHWjyjJ-c,5335
|
|
60
|
+
modusa-0.3.1.dist-info/RECORD,,
|