lingualabpy 0.0.5__tar.gz → 0.0.6__tar.gz
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.
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/PKG-INFO +3 -1
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/pyproject.toml +2 -1
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/__init__.py +1 -1
- lingualabpy-0.0.6/src/lingualabpy/cli/plot_sound.py +55 -0
- lingualabpy-0.0.6/src/lingualabpy/plot.py +23 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/LICENSE +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/README.md +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/audio/__init__.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/audio/metrics.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/audio/triming.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/__init__.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/audio_metrics.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/audio_triming.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/docx2json.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/jsons2csv.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/io.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/resources/FilledPauses.praat +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/resources/syllablenucleiv3.praat +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/text/__init__.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/text/parser.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/text/textgrid.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/tools/__init__.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/tools/data.py +0 -0
- {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/tools/interval.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lingualabpy
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: Tools and utilities from the LINGUA laboratory
|
|
5
5
|
Author-email: Christophe Bedetti <christophe.bedetti@umontreal.ca>
|
|
6
6
|
Requires-Python: >=3.8.1
|
|
@@ -19,6 +19,8 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Requires-Dist: click
|
|
22
|
+
Requires-Dist: matplotlib
|
|
23
|
+
Requires-Dist: opencv-python
|
|
22
24
|
Requires-Dist: pandas
|
|
23
25
|
Requires-Dist: praat-parselmouth
|
|
24
26
|
Requires-Dist: praat-textgrids
|
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
|
28
28
|
requires-python = ">=3.8.1"
|
|
29
29
|
dynamic = ["version"]
|
|
30
30
|
|
|
31
|
-
dependencies = ["click", "pandas", "praat-parselmouth", "praat-textgrids", "pydub", "python-docx"]
|
|
31
|
+
dependencies = ["click", "matplotlib", "opencv-python", "pandas", "praat-parselmouth", "praat-textgrids", "pydub", "python-docx"]
|
|
32
32
|
|
|
33
33
|
[project.optional-dependencies]
|
|
34
34
|
test = ["pytest", "pytest-cov"]
|
|
@@ -42,6 +42,7 @@ lingualabpy_audio_metrics = "lingualabpy.cli.audio_metrics:main"
|
|
|
42
42
|
lingualabpy_audio_triming = "lingualabpy.cli.audio_triming:main"
|
|
43
43
|
lingualabpy_docx2json = "lingualabpy.cli.docx2json:main"
|
|
44
44
|
lingualabpy_jsons2csv = "lingualabpy.cli.jsons2csv:main"
|
|
45
|
+
lingualabpy_plot_sound = "lingualabpy.cli.plot_sound:main"
|
|
45
46
|
|
|
46
47
|
[project.urls]
|
|
47
48
|
Documentation = "https://github.com/lingualab/lingualabpy"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import cv2
|
|
2
|
+
import os
|
|
3
|
+
import click
|
|
4
|
+
from parselmouth import Sound
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from lingualabpy.plot import draw_pitch, draw_spectrogram
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.command()
|
|
12
|
+
@click.option("--output", default=None, help="")
|
|
13
|
+
@click.argument("audiofile", nargs=1, type=click.Path(exists=True))
|
|
14
|
+
def main(audiofile, output):
|
|
15
|
+
if not output:
|
|
16
|
+
output = Path(audiofile).stem + ".png"
|
|
17
|
+
|
|
18
|
+
sound = Sound(audiofile)
|
|
19
|
+
|
|
20
|
+
pitch = sound.to_pitch()
|
|
21
|
+
|
|
22
|
+
# If desired, pre-emphasize the sound fragment before calculating the spectrogram
|
|
23
|
+
pre_emphasized_snd = sound.copy()
|
|
24
|
+
pre_emphasized_snd.pre_emphasize()
|
|
25
|
+
spectrogram = pre_emphasized_snd.to_spectrogram(
|
|
26
|
+
window_length=0.03, maximum_frequency=8000
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# amplitude figure
|
|
30
|
+
tmp_amplitude_png = "tmp_amplitude.png"
|
|
31
|
+
amplitude = plt.figure()
|
|
32
|
+
plt.plot(sound.xs(), sound.values.T)
|
|
33
|
+
plt.xlim([sound.xmin, sound.xmax])
|
|
34
|
+
plt.xlabel("time [s]")
|
|
35
|
+
plt.ylabel("amplitude")
|
|
36
|
+
amplitude.set_figwidth(sound.xmax / 4)
|
|
37
|
+
plt.savefig(tmp_amplitude_png)
|
|
38
|
+
|
|
39
|
+
# spectro pitch figure
|
|
40
|
+
tmp_spectro_pitch_png = "tmp_spectro_pitch.png"
|
|
41
|
+
spectro_pitch = plt.figure()
|
|
42
|
+
draw_spectrogram(spectrogram)
|
|
43
|
+
plt.twinx()
|
|
44
|
+
draw_pitch(pitch)
|
|
45
|
+
plt.xlim([sound.xmin, sound.xmax])
|
|
46
|
+
spectro_pitch.set_figwidth(sound.xmax / 4)
|
|
47
|
+
plt.savefig(tmp_spectro_pitch_png)
|
|
48
|
+
|
|
49
|
+
# concatenation
|
|
50
|
+
fig_concat = cv2.vconcat(
|
|
51
|
+
[cv2.imread(tmp_amplitude_png), cv2.imread(tmp_spectro_pitch_png)]
|
|
52
|
+
)
|
|
53
|
+
cv2.imwrite(output, fig_concat)
|
|
54
|
+
os.remove(tmp_amplitude_png)
|
|
55
|
+
os.remove(tmp_spectro_pitch_png)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def draw_spectrogram(spectrogram, dynamic_range=70):
|
|
6
|
+
X, Y = spectrogram.x_grid(), spectrogram.y_grid()
|
|
7
|
+
sg_db = 10 * np.log10(spectrogram.values)
|
|
8
|
+
plt.pcolormesh(X, Y, sg_db, vmin=sg_db.max() - dynamic_range, cmap="afmhot")
|
|
9
|
+
plt.ylim([spectrogram.ymin, spectrogram.ymax])
|
|
10
|
+
plt.xlabel("time [s]")
|
|
11
|
+
plt.ylabel("frequency [Hz]")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def draw_pitch(pitch):
|
|
15
|
+
# Extract selected pitch contour, and
|
|
16
|
+
# replace unvoiced samples by NaN to not plot
|
|
17
|
+
pitch_values = pitch.selected_array["frequency"]
|
|
18
|
+
pitch_values[pitch_values == 0] = np.nan
|
|
19
|
+
plt.plot(pitch.xs(), pitch_values, "o", markersize=5, color="w")
|
|
20
|
+
plt.plot(pitch.xs(), pitch_values, "o", markersize=2)
|
|
21
|
+
plt.grid(False)
|
|
22
|
+
plt.ylim(0, pitch.ceiling)
|
|
23
|
+
plt.ylabel("fundamental frequency [Hz]")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|