Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PointProcess class #43

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fe4b29a
Initial commit for PointProcess.cpp
hokiedsp Feb 15, 2021
5430ad6
Fix compilation failure on GCC 7.5, and turn test_pointprocess.py int…
YannickJadoul Feb 15, 2021
a4a73b1
Add TimeFunction mixin to PointProcess
YannickJadoul Feb 15, 2021
1b4323d
Added more functions
hokiedsp Feb 16, 2021
0b9927c
Fixed docstring arguments
hokiedsp Feb 16, 2021
98843c8
Added full docstrings (sans xtors)
hokiedsp Feb 17, 2021
7898ccd
Wrapped docstrings in parselmouth namespace
hokiedsp Feb 17, 2021
187901d
#define does not like raw string literals
hokiedsp Feb 17, 2021
96ee016
Fixed `Create Poisson process...` doc link
hokiedsp Feb 17, 2021
af61ab5
Fix docstring line length
hokiedsp Feb 17, 2021
82aeb7b
Removed PointProcess.get_time_points()
hokiedsp Feb 18, 2021
9e992ba
Completed PointProcess pytest
hokiedsp Feb 20, 2021
ee30949
Added a new constructor specifying time points
hokiedsp Feb 20, 2021
b713f35
Moved `PointProcess.from_xxx` to `Pitch`
hokiedsp Feb 21, 2021
b791b8f
- Added transplant_domain(), to_matrix(), to_text_grid(),
hokiedsp Feb 21, 2021
b0cab61
Dropped <execution> dependence
hokiedsp Feb 21, 2021
0ebfef8
Revert unrelated indentation issues and minor style fixes
YannickJadoul Feb 24, 2021
88726f8
Right, PointProcess is not a subclass of Sampled
YannickJadoul Feb 24, 2021
06c4b34
Minor fixes to PointProcess methods, and consolidating the tests
YannickJadoul Feb 27, 2021
fde5fe5
Added Sound.to_point_process_xxx methods
hokiedsp Feb 27, 2021
ddd936e
Fixed case inconsistency
hokiedsp Feb 27, 2021
7a36460
Added #include once guard
hokiedsp Feb 27, 2021
b817d42
Fix header headers
YannickJadoul Feb 28, 2021
417b51e
Added PointProcess-related docstrings to Sound
hokiedsp Feb 28, 2021
ef8aae9
Fix Sound: To PointProcess links to Praat docs
YannickJadoul Feb 28, 2021
cd54b38
Fix some warnings/issues in the docstrings
YannickJadoul Feb 28, 2021
a9811bf
Fixed to_pointprocess docstring mixup
hokiedsp Feb 28, 2021
ccd77b5
Convert default values in docstrings to new format
YannickJadoul Feb 28, 2021
35970e7
More docstring tweaks
YannickJadoul Feb 28, 2021
6726281
Added PointProcess.get_jitter and PointProcess.get_shimmer, made sure…
YannickJadoul Mar 4, 2021
dff9aa9
Add Sound.Channel utility class
YannickJadoul Apr 1, 2021
9a61aec
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
'sphinx.ext.coverage',
'sphinx_copybutton',
'nbsphinx',
'pybind11_docstrings',
'praat_manual']

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -135,6 +134,9 @@
'numpy': ('https://numpy.org/doc/stable/', None),
'tgt': ('https://textgridtools.readthedocs.io/en/stable/', None)}

# Napoleon configuration
napoleon_preprocess_types = True

default_role = 'py:obj'
nitpicky = True
nitpick_ignore = [('py:class', 'pybind11_builtins.pybind11_object'),
Expand All @@ -143,6 +145,8 @@
('py:class', 'NonNegative'),
('py:class', 'numpy.float64'),
('py:class', 'numpy.complex128'),
('py:class', 'positive'),
('py:class', 'readonly'),
('py:obj', 'List')]


Expand Down
12 changes: 0 additions & 12 deletions docs/pybind11_docstrings.py

This file was deleted.

3 changes: 3 additions & 0 deletions src/parselmouth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Thing_declare(Intensity);
Thing_declare(Matrix);
Thing_declare(MFCC);
Thing_declare(Pitch);
Thing_declare(PointProcess);
Thing_declare(Sampled);
Thing_declare(SampledXY);
Thing_declare(TextGrid);
Expand Down Expand Up @@ -119,6 +120,7 @@ using PraatBindings = Bindings<PraatError,
PraatWarning,
PraatFatal,
ValueInterpolation,
PeakInterpolation,
WindowShape,
AmplitudeScaling,
SignalOutsideTimeDomain,
Expand All @@ -139,6 +141,7 @@ using PraatBindings = Bindings<PraatError,
Spectrum,
Spectrogram,
Pitch,
PointProcess,
Intensity,
Harmonicity,
Formant,
Expand Down
1 change: 1 addition & 0 deletions src/parselmouth/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ target_sources(parselmouth PRIVATE
Matrix.cpp
MFCC.cpp
Pitch.cpp
PointProcess.cpp
Sampled.cpp
SampledXY.cpp
Sound.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/parselmouth/Parselmouth.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum class kSound_windowShape;
enum class kSounds_convolve_scaling;
enum class kSounds_convolve_signalOutsideTimeDomain;
enum class kVector_valueInterpolation;
enum class kVector_peakInterpolation;

namespace parselmouth::detail {

Expand Down Expand Up @@ -94,6 +95,7 @@ namespace parselmouth {
enum class SoundFileFormat;

using ValueInterpolation = kVector_valueInterpolation;
using PeakInterpolation = kVector_peakInterpolation;
using WindowShape = kSound_windowShape;
using AmplitudeScaling = kSounds_convolve_scaling;
using SignalOutsideTimeDomain = kSounds_convolve_signalOutsideTimeDomain;
Expand Down
42 changes: 37 additions & 5 deletions src/parselmouth/Pitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include "Parselmouth.h"

#include "Pitch_docstrings.h"

#include "TimeClassAspects.h"

#include "utils/praat/MelderUtils.h"
Expand All @@ -27,6 +29,7 @@

#include <praat/fon/Matrix_and_Pitch.h>
#include <praat/fon/Pitch.h>
#include <praat/fon/Pitch_to_PointProcess.h>
#include <praat/fon/Pitch_to_Sound.h>

#include <pybind11/numpy.h>
Expand Down Expand Up @@ -148,7 +151,7 @@ PRAAT_CLASS_BINDING(Pitch) {
"from_time"_a = std::nullopt, "to_time"_a = std::nullopt, "sampling_frequency"_a = 44100.0, "round_to_nearest_zero_crossing"_a = true);

def("count_voiced_frames",
&Pitch_countVoicedFrames);
&Pitch_countVoicedFrames);

def("get_value_at_time",
[](Pitch self, double time, kPitch_unit unit, kVector_valueInterpolation interpolation) {
Expand Down Expand Up @@ -228,18 +231,47 @@ PRAAT_CLASS_BINDING(Pitch) {
&Pitch_interpolate);

def("smooth",
args_cast<_, Positive<_>>(Pitch_smooth),
"bandwidth"_a = 10.0);
args_cast<_, Positive<_>>(Pitch_smooth),
"bandwidth"_a = 10.0);

def("subtract_linear_fit",
&Pitch_subtractLinearFit,
"unit"_a = kPitch_unit::HERTZ);
"unit"_a = kPitch_unit::HERTZ);

def("kill_octave_jumps",
&Pitch_killOctaveJumps);
&Pitch_killOctaveJumps);

// TODO To PitchTier: depends on PitchTier

// TODO Not sure what to do with this, yet
def("to_point_process",
[](Pitch self, Sound sound, std::string method, bool include_maxima, bool include_minima) {
if (sound) {
if (method == "cc")
return Sound_Pitch_to_PointProcess_cc(sound, self);
else if (method == "peaks")
return Sound_Pitch_to_PointProcess_peaks(sound, self, include_maxima, include_minima);
else
throw std::invalid_argument("Unknown method specified.");
} else {
return Pitch_to_PointProcess(self);
}
},
"sound"_a = nullptr, "method"_a = "cc", "include_maxima"_a = true, "include_minima"_a = false,
TO_POINT_PROCESS_DOCSTRING);

// NEW1_Sound_Pitch_to_PointProcess_cc
def("to_point_process_cc",
[](Pitch self, Sound sound) { return Sound_Pitch_to_PointProcess_cc(sound, self); },
"sound"_a.none(false),
TO_POINT_PROCESS_CC_DOCSTRING);

// NEW1_Sound_Pitch_to_PointProcess_peaks
def("to_point_process_peaks",
[](Pitch self, Sound sound, bool include_maxima, bool include_minima) { return Sound_Pitch_to_PointProcess_peaks(sound, self, include_maxima, include_minima); },
"sound"_a.none(false), "include_maxima"_a = true, "include_minima"_a = false,
TO_POINT_PROCESS_PEAKS_DOCSTRING);

def("to_matrix",
&Pitch_to_Matrix);

Expand Down
115 changes: 115 additions & 0 deletions src/parselmouth/Pitch_docstrings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright (C) 2021 Yannick Jadoul and contributors
*
* This file is part of Parselmouth.
*
* Parselmouth is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Parselmouth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Parselmouth. If not, see <http://www.gnu.org/licenses/>
*/

#pragma once
#ifndef INC_PARSELMOUTH_PITCH_DOCSTRINGS_H
#define INC_PARSELMOUTH_PITCH_DOCSTRINGS_H

namespace parselmouth {

constexpr auto TO_POINT_PROCESS_DOCSTRING =
R"(Create a `PointProcess` from a `Pitch` object.

Returns a new PointProcess instance by interpreting the acoustic
periodicity contour in the `Pitch` object as the frequency of an
underlying point process (such as the sequence of glottal closures in
vocal-fold vibration).

The unvoiced intervals in the ``pitch`` object is transferred to the point
process object, and the voiced intervals are further divided into each
phonation cycles.

Parameters
----------
sound : parselmouth.Sound, optional
Sound object containing the target sound waveform. If omitted,
`PointProcess` is created only from the pitch contour. Analyzing the
samples in the `Sound` object improves the accuracy of the resulting
point process.

method : {"cc", "peaks"}, default "cc"
Specify the Sound-assisted generation method:

"cc"
Cross-correlation method. The fundamental periods of voice are
identified by cross-correlating the sound samples.

"peaks"
Peak-picking method. The fundamental periods of voice are
identified by peak-picking the sound samples. Typically, less
accurate than the cross-correlation method.

include_maxima : bool, default True
True to include the absolute maximum (for ``method="peaks"`` only).

include_minima : bool, default False
True to include the absolute minimum (for ``method="peaks"`` only).

See Also
--------
:praat:`Pitch: To PointProcess`
hokiedsp marked this conversation as resolved.
Show resolved Hide resolved
:praat:`Sound & Pitch: To PointProcess (cc)`
:praat:`Sound & Pitch: To PointProcess (peaks)...`
)";

constexpr auto TO_POINT_PROCESS_CC_DOCSTRING =
R"(Create a `PointProcess` using cross-correlation.

Returns a new `PointProcess` instance, generated from the specified `Sound`
and `Pitch` instances using the cross-correlation method. The resulting
instance contains voiced and unvoiced intervals according to ``pitch``
object, and the voiced intervals are further divided into fundamental
periods of voice, identified by cross-correlating the sound samples.

Parameters
----------
sound : parselmouth.Sound
Sound object containing the target sound waveform.

See Also
--------
:praat:`Sound & Pitch: To PointProcess (cc)`
)";

constexpr auto TO_POINT_PROCESS_PEAKS_DOCSTRING =
R"(Create a `PointProcess` using peak-picking.

Returns a new PointProcess instance, generated from the specified `Sound`
and `Pitch` instances using the peak-picking method. The resulting
instance contains voiced and unvoiced intervals according to ``pitch``
object, and the voiced intervals are further divided into fundamental
periods of voice, identified by peak-picking the sound samples.

The periods that are found in this way are much more variable than those
found by `Pitch.to_point_process_cc()` and therefore less useful for
analysis and subsequent overlap-add synthesis.

Parameters
----------
sound : parselmouth.Sound
Sound object containing the target sound waveform.

See Also
--------
:praat:`Sound & Pitch: To PointProcess (peaks)...`
)";

} // namespace parselmouth

#endif // INC_PARSELMOUTH_PITCH_DOCSTRINGS_H
Loading
Loading