modusa 0.4.30__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.
modusa/__init__.py CHANGED
@@ -11,4 +11,7 @@ from modusa.tools import dist_plot, hill_plot, plot, fig
11
11
  # Synthsizing related
12
12
  from modusa.tools import synth_f0
13
13
 
14
- __version__ = "0.4.30" # This is dynamically used by the documentation, and pyproject.toml; Only need to change it here; rest gets taken care of.
14
+ # Audio features related
15
+ from modusa.tools import stft
16
+
17
+ __version__ = "0.4.31" # This is dynamically used by the documentation, and pyproject.toml; Only need to change it here; rest gets taken care of.
modusa/tools/__init__.py CHANGED
@@ -16,4 +16,7 @@ from .plotter import Fig as fig
16
16
  from .plotter import dist_plot, hill_plot, plot
17
17
 
18
18
  # Synthesizing related
19
- from .synth import synth_f0
19
+ from .synth import synth_f0
20
+
21
+ # Audio features
22
+ from .audio_stft import stft
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env python3
2
+
3
+ #---------------------------------
4
+ # Author: Ankit Anand
5
+ # Date: 23/10/25
6
+ # Email: ankit0.anand0@gmail.com
7
+ #---------------------------------
8
+
9
+ import numpy as np
10
+
11
+ def stft(y, sr, winlen=None, hoplen=None, gamma=None):
12
+ """
13
+ Compute spectrogram with just numpy.
14
+
15
+ Parameters
16
+ ----------
17
+ y: ndarray
18
+ - Audio signal.
19
+ sr: int
20
+ - Sampling rate of the audio signal.
21
+ winlen: int
22
+ - Window length in samples.
23
+ - Default: None => set at 0.064 sec
24
+ hoplen: int
25
+ - Hop length in samples.
26
+ - Default: None => set at one-forth of winlen
27
+ gamma: int | None
28
+ - Log compression factor.
29
+ - Add contrast to the plot.
30
+
31
+ Returns
32
+ -------
33
+ ndarray:
34
+ - Spectrogram matrix, complex is gamma is None else real
35
+ ndarray:
36
+ - Frequency bins in Hz.
37
+ ndarray:
38
+ - Timeframes in sec.
39
+ """
40
+
41
+ if winlen is None:
42
+ winlen = 2 ** int(np.log2(0.064 * sr))
43
+ if hoplen is None:
44
+ hoplen = int(winlen * 0.25)
45
+
46
+ # Estimating the shape of the S matrix
47
+ M = int(np.ceil(winlen / 2))
48
+ N = int(np.ceil((y.size - winlen) / hoplen))
49
+
50
+ # Initialize the S matrix
51
+ S = np.empty((M, N), dtype=np.complex64) # M X N => freq bin X time frame
52
+
53
+ # We will need a hann window
54
+ hann = np.hanning(winlen)
55
+
56
+ # Get the frames
57
+ frames = np.lib.stride_tricks.sliding_window_view(y, window_shape=winlen)[::hoplen] # frame X chunk
58
+
59
+ # Apply window to the frame
60
+ frames_windowed = frames * hann # frame X chunk
61
+
62
+ # Compute fft for each frame
63
+ S = np.fft.rfft(frames_windowed, n=winlen, axis=1).T # transpose to match shape (freq_bins, frame)
64
+
65
+ # Magnitude spectrogram
66
+ Sf = np.fft.rfftfreq(winlen, d=1/sr) # Frequency bins (Hz)
67
+ St = np.arange(N) * hoplen / sr # Time bins (sec)
68
+
69
+ if gamma is not None:
70
+ S = np.log1p(gamma * np.abs(S))
71
+
72
+ return S, Sf, St
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modusa
3
- Version: 0.4.30
3
+ Version: 0.4.31
4
4
  Summary: A modular signal analysis python library.
5
5
  Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
6
6
  License: MIT
@@ -1,21 +1,22 @@
1
1
  LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
2
2
  README.md,sha256=Ybe2rcDecfSCiUpec2n7btQvgyi4R9JG0bfdwSWijWk,981
3
- modusa-0.4.30.dist-info/METADATA,sha256=6uwfk2M5n8Nm403plD97tZhsFlDjsrCWCGe5Q6uViLM,1443
4
- modusa-0.4.30.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
5
- modusa-0.4.30.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
6
- modusa-0.4.30.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
7
- modusa/__init__.py,sha256=Q5A97PDmbcNLEwJZKg3W660TcVyJbbJfTvjct8Y_X9s,450
3
+ modusa-0.4.31.dist-info/METADATA,sha256=6xtxTdA9YYiKzG3pMSmeMk8C18gvlWS7ZJ0GuddrESY,1443
4
+ modusa-0.4.31.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
5
+ modusa-0.4.31.dist-info/entry_points.txt,sha256=fmKpleVXj6CdaBVL14WoEy6xx7JQCs85jvzwTi3lePM,73
6
+ modusa-0.4.31.dist-info/licenses/LICENSE.md,sha256=JTaXAjx5awk76VArKCx5dUW8vmLEWsL_ZlR7-umaHbA,1078
7
+ modusa/__init__.py,sha256=OlPmjLOhldc42ytXjXkv0zMoJd8B4lndGcG2Pt2olLc,506
8
8
  modusa/fonts/NotoSansDevanagari-Regular.ttf,sha256=CEqU2J61Sq-5OgVuFUJcNP2Fn2NCh1Fl0wSDezvPwtI,221084
9
9
  modusa/images/icon.png,sha256=UgGXlL4xjdIYxqO1en3iQfNN1BFsazxpT7NiPZSDu70,13321
10
- modusa/tools/__init__.py,sha256=9tIk1j1lMJ8Ka04ppLwEad_RU-s1Ok9CRalfNhai01A,453
10
+ modusa/tools/__init__.py,sha256=08f7kU1ZTuvYuMTYodv_OK_29AeCspPu4FzTVbbnPm4,500
11
11
  modusa/tools/ann_loader.py,sha256=m6Qu6jXnQ8LfUhKItoHSaHlGxUyzUJlGEyu4_50qJ8w,3099
12
12
  modusa/tools/ann_saver.py,sha256=rB2gP1rD69PkSnBZrzc_83ylb7eAyqyCMjn9Bh16VaM,650
13
13
  modusa/tools/audio_converter.py,sha256=415qBoPm2sBIuBSI7m1XBKm0AbmVmPydIPPr-uO8D3c,1778
14
14
  modusa/tools/audio_loader.py,sha256=xmeodrJqJV5j9-lrUPk3W9-bdEA4-6RvTAn8pIErUN0,4084
15
15
  modusa/tools/audio_player.py,sha256=kyBUnodkOE9Ox-hKHkfPeGAQ1RPTddbZYXO1ezz6-9w,2494
16
16
  modusa/tools/audio_recorder.py,sha256=cADeeUpPcDIYBIuuVZvWqulDkv7TavkpL3o3SO9QyKc,2787
17
+ modusa/tools/audio_stft.py,sha256=vy1J-qFUVIkOh5Y1-dyy3zAh26n0IaMtO2D9EMbtITU,1742
17
18
  modusa/tools/plotter.py,sha256=QfF8kCi79nS-J5lQyEuH_BbAmTo-PdfjDbnK9yTAmRE,30863
18
19
  modusa/tools/synth.py,sha256=tfCjTAucTDwb0yOHHnrNO7EFsuH7tNb1PwvS2xwmhK0,1222
19
20
  modusa/tools/youtube_downloader.py,sha256=Ij7fipSlRpsf0pFOwRY-j7Yf2PMp0kpWMhyMQchR0e0,1574
20
- pyproject.toml,sha256=zBJWAUi45I8BE-MxTX-ZYMBzNpvhiYE8zcKUviuHNFc,1414
21
- modusa-0.4.30.dist-info/RECORD,,
21
+ pyproject.toml,sha256=fCgN1j7fzWdYCCNut4pUfqpSfGccBEeGc8pjRXyz0RM,1414
22
+ modusa-0.4.31.dist-info/RECORD,,
pyproject.toml CHANGED
@@ -16,7 +16,7 @@ dependencies = [
16
16
  ]
17
17
  requires-python = ">=3.11"
18
18
  readme = "README.md"
19
- version = "0.4.30"
19
+ version = "0.4.31"
20
20
 
21
21
  [project.license]
22
22
  text = "MIT"