modusa 0.4.29__py3-none-any.whl → 0.4.31__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.
Files changed (58) hide show
  1. modusa/__init__.py +12 -8
  2. modusa/tools/__init__.py +11 -3
  3. modusa/tools/ann_saver.py +30 -0
  4. modusa/tools/audio_recorder.py +0 -1
  5. modusa/tools/audio_stft.py +72 -0
  6. modusa/tools/youtube_downloader.py +1 -4
  7. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/METADATA +2 -2
  8. modusa-0.4.31.dist-info/RECORD +22 -0
  9. pyproject.toml +2 -2
  10. modusa/config.py +0 -18
  11. modusa/decorators.py +0 -176
  12. modusa/devtools/generate_docs_source.py +0 -92
  13. modusa/devtools/generate_template.py +0 -144
  14. modusa/devtools/list_authors.py +0 -2
  15. modusa/devtools/list_plugins.py +0 -60
  16. modusa/devtools/main.py +0 -45
  17. modusa/devtools/templates/generator.py +0 -24
  18. modusa/devtools/templates/io.py +0 -24
  19. modusa/devtools/templates/model.py +0 -47
  20. modusa/devtools/templates/plugin.py +0 -41
  21. modusa/devtools/templates/test.py +0 -10
  22. modusa/devtools/templates/tool.py +0 -24
  23. modusa/generators/__init__.py +0 -13
  24. modusa/generators/audio.py +0 -188
  25. modusa/generators/audio_waveforms.py +0 -236
  26. modusa/generators/base.py +0 -29
  27. modusa/generators/ftds.py +0 -298
  28. modusa/generators/s1d.py +0 -270
  29. modusa/generators/s2d.py +0 -300
  30. modusa/generators/s_ax.py +0 -102
  31. modusa/generators/t_ax.py +0 -64
  32. modusa/generators/tds.py +0 -267
  33. modusa/models/__init__.py +0 -14
  34. modusa/models/audio.py +0 -90
  35. modusa/models/base.py +0 -70
  36. modusa/models/data.py +0 -457
  37. modusa/models/ftds.py +0 -584
  38. modusa/models/s1d.py +0 -578
  39. modusa/models/s2d.py +0 -619
  40. modusa/models/s_ax.py +0 -448
  41. modusa/models/t_ax.py +0 -335
  42. modusa/models/tds.py +0 -465
  43. modusa/plugins/__init__.py +0 -3
  44. modusa/plugins/base.py +0 -100
  45. modusa/tools/_plotter_old.py +0 -629
  46. modusa/tools/audio_saver.py +0 -30
  47. modusa/tools/base.py +0 -43
  48. modusa/tools/math_ops.py +0 -335
  49. modusa/utils/__init__.py +0 -1
  50. modusa/utils/config.py +0 -25
  51. modusa/utils/excp.py +0 -49
  52. modusa/utils/logger.py +0 -18
  53. modusa/utils/np_func_cat.py +0 -44
  54. modusa/utils/plot.py +0 -142
  55. modusa-0.4.29.dist-info/RECORD +0 -65
  56. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/WHEEL +0 -0
  57. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/entry_points.txt +0 -0
  58. {modusa-0.4.29.dist-info → modusa-0.4.31.dist-info}/licenses/LICENSE.md +0 -0
@@ -1,236 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
-
4
- from modusa import excp
5
- from modusa.decorators import validate_args_type
6
- from modusa.generators.base import ModusaGenerator
7
- from modusa.models.audio_signal import AudioSignal
8
- import numpy as np
9
-
10
- class AudioWaveformGenerator(ModusaGenerator):
11
- """
12
- Generates different kinds of audio waveforms particulary helpful
13
- in teaching signal processing concepts and testing out newly
14
- created tools.
15
- """
16
-
17
- #--------Meta Information----------
18
- _name = "Audio Waveform Generator"
19
- _description = "Generates different kind of audio waveforms."
20
- _author_name = "Ankit Anand"
21
- _author_email = "ankit0.anand0@gmail.com"
22
- _created_at = "2025-07-07"
23
- #----------------------------------
24
-
25
- @staticmethod
26
- def generate_example() -> "AudioSignal":
27
- """
28
- Generates a simple sine wave audio signal as an example.
29
-
30
- Returns
31
- -------
32
- AudioSignal
33
- A 600 Hz sine wave lasting 2 seconds, sampled at 10,000 Hz.
34
- """
35
-
36
- sr = 10000 # Hz
37
- duration = 2 # sec
38
- freq = 600 # Hz
39
-
40
- t = np.arange(0, duration, 1 / sr)
41
- y = np.sin(2 * np.pi * freq * t)
42
-
43
- signal = AudioSignal(y=y, sr=sr, title="Example") # assuming AudioSignal accepts y and t
44
-
45
- return signal
46
-
47
-
48
- @staticmethod
49
- def generate_random(duration: float = 1.0, sr: int = 10000) -> "AudioSignal":
50
- """
51
- Generates a random audio signal of given duration and sample rate.
52
-
53
- Parameters
54
- ----------
55
- duration : float, optional
56
- Duration of the signal in seconds (default is 1.0).
57
- sr : int, optional
58
- Sampling rate in Hz (default is 10,000).
59
-
60
- Returns
61
- -------
62
- AudioSignal
63
- A randomly generated signal of the specified duration and sample rate.
64
- """
65
- num_samples = int(duration * sr)
66
- t = np.linspace(0, duration, num=num_samples, endpoint=False)
67
- y = np.random.uniform(low=-1.0, high=1.0, size=num_samples) # use uniform [-1, 1] for audio-like signal
68
-
69
- signal = AudioSignal(y=y, t=t, title="Random")
70
-
71
- return signal
72
-
73
- @staticmethod
74
- @validate_args_type()
75
- def generate_sinusoid(
76
- A: float | int = 1.0,
77
- f: float | int = 10.0,
78
- phi: float | int = 0.0,
79
- duration: float | int = 1.0,
80
- sr: int = 1000,
81
- ) -> "AudioSignal":
82
- """
83
- Generates a sinusoid audio signal with specified
84
- amplitude, frequency, phase, duration, and sample rate.
85
-
86
- Parameters
87
- ----------
88
- A : float
89
- Amplitude of the sinusoid (default: 1.0)
90
- f : float
91
- Frequency in Hz (default: 10.0)
92
- phi : float
93
- Phase in radians (default: 0.0)
94
- duration : float
95
- Duration of the signal in seconds (default: 1.0)
96
- sr : int
97
- Sampling rate in Hz (default: 1000)
98
-
99
- Returns
100
- -------
101
- AudioSignal
102
- A sinusoidal signal with the given parameters.
103
- """
104
- A, f, phi, duration, sr = float(A), float(f), float(phi), float(duration), int(sr)
105
-
106
- t = np.arange(0, duration, 1 / sr)
107
- y = A * np.sin(2 * np.pi * f * t + phi)
108
-
109
- signal = AudioSignal(y=y, sr=sr, title=f"Sinusoid ({f} Hz)")
110
-
111
- return signal
112
-
113
- @staticmethod
114
- @validate_args_type()
115
- def generate_square(
116
- A: float | int = 1.0,
117
- f: float | int = 10.0,
118
- phi: float | int = 0.0,
119
- duration: float | int = 1.0,
120
- sr: int = 1000,
121
- ) -> "AudioSignal":
122
- """
123
- Generates a square wave audio signal with specified
124
- amplitude, frequency, phase, duration, and sample rate.
125
-
126
- Parameters
127
- ----------
128
- A : float
129
- Amplitude of the square wave (default: 1.0)
130
- f : float
131
- Frequency in Hz (default: 10.0)
132
- phi : float
133
- Phase in radians (default: 0.0)
134
- duration : float
135
- Duration of the signal in seconds (default: 1.0)
136
- sr : int
137
- Sampling rate in Hz (default: 1000)
138
-
139
- Returns
140
- -------
141
- AudioSignal
142
- A square wave signal of the specified parameters.
143
- """
144
- A, f, phi, duration, sr = float(A), float(f), float(phi), float(duration), int(sr)
145
- t = np.arange(0, duration, 1 / sr)
146
-
147
- y = A * np.sign(np.sin(2 * np.pi * f * t + phi))
148
-
149
- signal = AudioSignal(y=y, sr=sr, title=f"Square ({f} Hz)")
150
-
151
- return signal
152
-
153
-
154
- @staticmethod
155
- @validate_args_type()
156
- def generate_sawtooth(
157
- A: float | int = 1.0,
158
- f: float | int = 10.0,
159
- phi: float | int = 0.0,
160
- duration: float | int = 1.0,
161
- sr: int = 1000,
162
- ) -> "AudioSignal":
163
- """
164
- Generates a sawtooth wave AudioSignal with specified amplitude, frequency, phase, duration, and sample rate.
165
-
166
- Parameters
167
- ----------
168
- A : float
169
- Amplitude of the sawtooth wave (default: 1.0)
170
- f : float
171
- Frequency in Hz (default: 10.0)
172
- phi : float
173
- Phase in radians (default: 0.0)
174
- duration : float
175
- Duration of the signal in seconds (default: 1.0)
176
- sr : int
177
- Sampling rate in Hz (default: 1000)
178
-
179
- Returns
180
- -------
181
- AudioSignal
182
- A sawtooth wave signal of the specified parameters.
183
- """
184
- A, f, phi, duration, sr = float(A), float(f), float(phi), float(duration), int(sr)
185
- t = np.arange(0, duration, 1 / sr)
186
-
187
- # Convert phase from radians to fractional cycle offset
188
- phase_offset = phi / (2 * np.pi)
189
- y = A * (2 * ((f * t + phase_offset) % 1) - 1)
190
-
191
- signal = AudioSignal(y=y, sr=sr, title=f"Sawtooth ({f} Hz)")
192
- return signal
193
-
194
-
195
- @staticmethod
196
- @validate_args_type()
197
- def generate_triangle(
198
- A: float | int = 1.0,
199
- f: float | int = 10.0,
200
- phi: float | int = 0.0,
201
- duration: float | int = 1.0,
202
- sr: int = 1000,
203
- ) -> "AudioSignal":
204
- """
205
- Generates a triangle wave AudioSignal with specified
206
- amplitude, frequency, phase, duration, and sample rate.
207
-
208
- Parameters
209
- ----------
210
- A : float
211
- Amplitude of the triangle wave (default: 1.0)
212
- f : float
213
- Frequency in Hz (default: 10.0)
214
- phi : float
215
- Phase in radians (default: 0.0)
216
- duration : float
217
- Duration of the signal in seconds (default: 1.0)
218
- sr : int
219
- Sampling rate in Hz (default: 1000)
220
-
221
- Returns
222
- -------
223
- AudioSignal
224
- A triangle wave signal of the specified parameters.
225
- """
226
- A, f, phi, duration, sr = float(A), float(f), float(phi), float(duration), int(sr)
227
- t = np.arange(0, duration, 1 / sr)
228
- phase_offset = phi / (2 * np.pi) # Convert radians to cycle offset
229
-
230
- # Triangle wave formula: 2 * abs(2 * frac(x) - 1) - 1 scaled to amplitude
231
- y = A * (2 * np.abs(2 * ((f * t + phase_offset) % 1) - 1) - 1)
232
-
233
- signal = AudioSignal(y=y, sr=sr, title=f"Triangle ({f} Hz)")
234
-
235
- return signal
236
-
modusa/generators/base.py DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
- from modusa import excp
4
- from modusa.decorators import validate_args_type, immutable_property
5
- from modusa.models.base import ModusaSignal
6
- from abc import ABC, abstractmethod
7
- from typing import Any
8
-
9
- class ModusaGenerator(ABC):
10
- """
11
- Base class for any type of signal generators for modusa framework.
12
-
13
- Note
14
- ----
15
- - This class is intended to be subclassed by any Generator related tools built for the modusa framework.
16
- - In order to create a generator tool, you can use modusa-dev CLI to generate an generator template.
17
- - It is recommended to treat subclasses of ModusaGenerator as namespaces and define @staticmethods with control parameters, rather than using instance-level __init__ methods.
18
-
19
-
20
- """
21
-
22
- #--------Meta Information----------
23
- _name = ""
24
- _description = ""
25
- _author_name = "Ankit Anand"
26
- _author_email = "ankit0.anand0@gmail.com"
27
- _created_at = "2025-07-04"
28
- #----------------------------------
29
-
modusa/generators/ftds.py DELETED
@@ -1,298 +0,0 @@
1
- #!/usr/bin/env python3
2
-
3
-
4
- from modusa import excp
5
- from modusa.decorators import validate_args_type
6
- from .base import ModusaGenerator
7
- from modusa.models.data import Data
8
- from modusa.models.s_ax import SAx
9
- from modusa.models.t_ax import TAx
10
- from modusa.models.ftds import FTDS
11
- import numpy as np
12
-
13
- class FTDSGen(ModusaGenerator):
14
- """
15
- Provides user friendly APIs to generate instances of different
16
- `FTDS` instances.
17
- """
18
-
19
- #--------Meta Information----------
20
- _name = ""
21
- _description = ""
22
- _author_name = "Ankit Anand"
23
- _author_email = "ankit0.anand0@gmail.com"
24
- _created_at = "2025-07-27"
25
- #----------------------------------
26
-
27
- @staticmethod
28
- def from_array(
29
- M: np.ndarray | list | float | int | np.generic,
30
- f: np.ndarray | list | float | int | np.generic | None = None,
31
- sr: int | float = 1.0,
32
- t0: int | float = 0.0,
33
- M_label: str = "M",
34
- f_label: str = "Feature",
35
- t_label: str = "Time (sec)",
36
- title: str = "Feature Time Domain Signal"
37
- ) -> FTDS:
38
- """
39
- Create `FDTS` instance from basic data structures.
40
-
41
- .. code-block:: python
42
-
43
- import modusa as ms
44
- M = ms.ftds.from_array([1, 2, 3])
45
- print(M)
46
- M.print_info()
47
-
48
- Parameters
49
- ----------
50
- M: np.ndarray | list | float | int | np.generic
51
- - Data values.
52
- f: np.ndarray | list | float | int | np.generic | None
53
- - y axis values.
54
- - Default: None → Creates an integer indexing.
55
- sr: int | float
56
- - Sampling rate / Frame rate.
57
- - Default: 1.0
58
- t0: int | float
59
- - Start timestamp.
60
- - Default: 0.0
61
- M_label: str
62
- - Label for the data.
63
- - Default: "M"
64
- f_label: str
65
- - Feature label for the signal.
66
- - Default: "Feature"
67
- t_label: str
68
- - Time label for the signal.
69
- - Default: "Time (sec)"
70
- title: str
71
- - Title for the signal.
72
- - Default: "Feature Time Domain Signal"
73
- Returns
74
- -------
75
- FTDS
76
- An instance of FTDS.
77
- """
78
- assert isinstance(M, (np.ndarray, list, float, int, np.generic))
79
- assert isinstance(f, (np.ndarray, list, float, int, np.generic)) or f is None
80
- assert isinstance(sr, (int, float)) and isinstance(t0, (int, float))
81
- assert isinstance(M_label, str) and isinstance(f_label, str) and isinstance(t_label, str) and isinstance(title, str)
82
-
83
- if isinstance(M, (float, int, np.generic)): M = [[M]] # Convert to list of 1 element
84
- if isinstance(f, (float, int, np.generic)): f = [f] # Convert to list of 1 element
85
-
86
- M = np.asarray(M)
87
- assert M.ndim == 2
88
-
89
- if f is None: f = np.arange(M.shape[0])
90
- else: f = np.asarray(f)
91
- assert f.ndim == 1
92
- assert f.shape[0] == M.shape[0], "Shape mismatch"
93
-
94
- sr = float(sr)
95
- t0 = float(t0)
96
-
97
- M = Data(values=M, label=M_label)
98
- f = SAx(values=f, label=f_label)
99
- t = TAx(n_points=M.shape[1], sr=sr, t0=t0, label=t_label)
100
-
101
- return FTDS(M=M, f=f, t=t, title=title)
102
-
103
- @classmethod
104
- def zeros(cls, shape, f=None, sr=1.0, t0=0.0) -> FTDS:
105
- """
106
- Create `FTDS` instance with all zeros.
107
-
108
- .. code-block:: python
109
-
110
- import modusa as ms
111
- M = ms.ftds.zeros((10, 5))
112
- print(M)
113
- M.print_info()
114
-
115
- Parameters
116
- ----------
117
- shape: tuple[int, int]
118
- - Shape of the signal with zeros.
119
- - Must be 1 dimensional
120
- - E.g. (10, 5)
121
- Returns
122
- -------
123
- FTDS
124
- An instance of FTDS.
125
- """
126
- assert isinstance(shape, tuple)
127
- M = np.zeros(shape)
128
-
129
- return cls.from_array(M=M, f=f, sr=sr, t0=t0, title="Zeros")
130
-
131
- @classmethod
132
- def zeros_like(cls, signal: FTDS) -> FTDS:
133
- """
134
- Create `FTDS` instance similar to `signal`
135
- but with all entries being zeros.
136
-
137
- .. code-block:: python
138
-
139
- import modusa as ms
140
- signal = ms.ftds.from_array([[1, 2, 3], [4, 5, 6]])
141
- M = ms.ftds.zeros_like(signal)
142
- print(M)
143
- M.print_info()
144
-
145
- Parameters
146
- ----------
147
- signal: FTDS
148
- - Reference signal to create zeros like that.
149
- Returns
150
- -------
151
- FTDS
152
- An instance of FTDS.
153
- """
154
-
155
- assert signal.__class__ in [FTDS]
156
-
157
- M = np.zeros(signal.shape)
158
- f = signal._f
159
- t = signal._t
160
-
161
- M_label = signal._M_label
162
- f_label = signal._f_label
163
- t_label = signal._t_label
164
- title = signal._title
165
-
166
- return cls.from_array(M=M, f=f, t=t, M_label=M_label, f_label=f_label, t_label=t_label, title=title)
167
-
168
-
169
- @classmethod
170
- def ones(cls, shape: tuple[int, int]) -> FTDS:
171
- """
172
- Create `FTDS` instance with all ones.
173
-
174
- .. code-block:: python
175
-
176
- import modusa as ms
177
- M = ms.ftds.ones((10, 5))
178
- print(M)
179
- M.print_info()
180
-
181
- Parameters
182
- ----------
183
- shape: tuple[int, int]
184
- - Shape of the signal with ones.
185
- - Must be 1 dimensional
186
- - E.g. (10, 5)
187
- Returns
188
- -------
189
- FTDS
190
- An instance of FTDS.
191
- """
192
- assert isinstance(shape, tuple)
193
- M = np.ones(shape)
194
-
195
- return cls.from_array(M=M, title="Ones")
196
-
197
- @classmethod
198
- def ones_like(cls, signal: FTDS) -> FTDS:
199
- """
200
- Create `FTDS` instance similar to `signal`
201
- but with all entries being ones.
202
-
203
- .. code-block:: python
204
-
205
- import modusa as ms
206
- signal = ms.ftds.from_array([[1, 2, 3], [4, 5, 6]])
207
- M = ms.ftds.ones_like(signal)
208
- print(M)
209
- M.print_info()
210
-
211
- Parameters
212
- ----------
213
- signal: FTDS
214
- - Reference signal to create ones like that.
215
- Returns
216
- -------
217
- FTDS
218
- An instance of FTDS.
219
- """
220
-
221
- assert signal.__class__ in [FTDS]
222
-
223
- M = np.ones(signal.shape)
224
- f = signal._f
225
- t = signal._t
226
-
227
- M_label = signal._M_label
228
- f_label = signal._f_label
229
- t_label = signal._t_label
230
- title = signal._title
231
-
232
- return cls.from_array(M=M, f=f, t=t, M_label=M_label, f_label=f_label, t_label=t_label, title=title)
233
-
234
- @classmethod
235
- def random(cls, shape: tuple[int, int]) -> FTDS:
236
- """
237
- Create `FTDS` instance with random entries.
238
-
239
- .. code-block:: python
240
-
241
- import modusa as ms
242
- M = ms.ftds.random((10, 5))
243
- print(M)
244
- M.print_info()
245
-
246
- Parameters
247
- ----------
248
- shape: tuple[int, int]
249
- - Shape of the signal with random values.
250
- - Must be 1 dimensional
251
- - E.g. (10, 5)
252
- Returns
253
- -------
254
- FTDS
255
- An instance of FTDS.
256
- """
257
- assert isinstance(shape, tuple)
258
- M = np.random.random(shape)
259
-
260
- return cls.from_array(M=M, title="Random")
261
-
262
- @classmethod
263
- def random_like(cls, signal: FTDS) -> FTDS:
264
- """
265
- Create `FTDS` instance similar to `signal`
266
- but with random entries.
267
-
268
- .. code-block:: python
269
-
270
- import modusa as ms
271
- signal = ms.ftds.from_array([[1, 2, 3], [4, 5, 6]])
272
- M = ms.ftds.random_like(signal)
273
- print(M)
274
- M.print_info()
275
-
276
- Parameters
277
- ----------
278
- signal: FTDS
279
- - Reference signal.
280
- Returns
281
- -------
282
- FTDS
283
- An instance of FTDS with random values.
284
- """
285
-
286
- assert signal.__class__ in [FTDS]
287
-
288
- M = np.random.random(signal.shape)
289
- f = signal._f
290
- t = signal._t
291
-
292
- M_label = signal._M_label
293
- f_label = signal._f_label
294
- t_label = signal._t_label
295
- title = signal._title
296
-
297
- return cls.from_array(M=M, f=f, t=t, M_label=M_label, f_label=f_label, t_label=t_label, title=title)
298
-