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.
Files changed (24) hide show
  1. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/PKG-INFO +3 -1
  2. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/pyproject.toml +2 -1
  3. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/__init__.py +1 -1
  4. lingualabpy-0.0.6/src/lingualabpy/cli/plot_sound.py +55 -0
  5. lingualabpy-0.0.6/src/lingualabpy/plot.py +23 -0
  6. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/LICENSE +0 -0
  7. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/README.md +0 -0
  8. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/audio/__init__.py +0 -0
  9. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/audio/metrics.py +0 -0
  10. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/audio/triming.py +0 -0
  11. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/__init__.py +0 -0
  12. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/audio_metrics.py +0 -0
  13. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/audio_triming.py +0 -0
  14. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/docx2json.py +0 -0
  15. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/cli/jsons2csv.py +0 -0
  16. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/io.py +0 -0
  17. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/resources/FilledPauses.praat +0 -0
  18. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/resources/syllablenucleiv3.praat +0 -0
  19. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/text/__init__.py +0 -0
  20. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/text/parser.py +0 -0
  21. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/text/textgrid.py +0 -0
  22. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/tools/__init__.py +0 -0
  23. {lingualabpy-0.0.5 → lingualabpy-0.0.6}/src/lingualabpy/tools/data.py +0 -0
  24. {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.5
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"
@@ -4,7 +4,7 @@
4
4
  """lingualabpy"""
5
5
  from __future__ import annotations
6
6
 
7
- __version__ = "0.0.5"
7
+ __version__ = "0.0.6"
8
8
 
9
9
  default_config = {
10
10
  "participant_col": "participant_id",
@@ -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