praatfan-gpl
Praat-compatible acoustic analysis in Python, powered by Rust.
This package provides exact reimplementations of Praat's acoustic analysis algorithms, designed to produce bit-accurate output matching Praat/parselmouth.
Installation
pip install praatfan-gpl
Building from source
Requires Rust and maturin:
cd python
pip install maturin
maturin develop --release
Quick Start
import praatfan_gpl as pc
# Load an audio file
sound = pc.Sound.from_file("speech.wav")
# Or create from numpy array
import numpy as np
samples = np.sin(2 * np.pi * 440 * np.arange(44100) / 44100)
sound = pc.Sound(samples, 44100.0)
# Compute pitch (F0)
pitch = sound.to_pitch(0.01, 75.0, 600.0)
print(f"Pitch at 0.5s: {pitch.get_value_at_time(0.5, 'hertz', 'linear')}")
# Get all pitch values as numpy array
f0_values = pitch.values() # NaN for unvoiced frames
times = pitch.times()
# Compute formants
formant = sound.to_formant_burg(
time_step=0.01,
max_num_formants=5,
max_formant_hz=5500.0, # Use 5000 for female speakers
window_length=0.025,
pre_emphasis_from=50.0
)
# Get F1, F2 at specific time
f1 = formant.get_value_at_time(1, 0.5, "hertz", "linear")
f2 = formant.get_value_at_time(2, 0.5, "hertz", "linear")
# Get all F1 values
f1_values = formant.formant_values(1) # numpy array
# Compute intensity
intensity = sound.to_intensity(100.0, 0.01)
db_values = intensity.values()
# Compute spectrum (single-frame FFT)
spectrum = sound.to_spectrum(fast=True)
cog = spectrum.get_center_of_gravity(2.0)
std = spectrum.get_standard_deviation(2.0)
# Compute spectrogram
spectrogram = sound.to_spectrogram(
effective_analysis_width=0.005,
max_frequency=5000.0,
time_step=0.002,
frequency_step=20.0,
window_shape="gaussian"
)
spec_data = spectrogram.values() # 2D numpy array [freq, time]
# Compute harmonicity (HNR)
hnr = sound.to_harmonicity_ac(0.01, 75.0, 0.1, 1.0)
# Or cross-correlation method:
hnr_cc = sound.to_harmonicity_cc(0.01, 75.0, 0.1, 1.0)
API Reference
Sound
# Loading
Sound.from_file(path) # Load from WAV, MP3, FLAC, OGG
Sound(samples, sample_rate) # From numpy array
# Properties
sound.sample_rate # Sample rate in Hz
sound.duration # Duration in seconds
sound.num_samples # Number of samples
sound.start_time, sound.end_time # Time bounds
# Methods
sound.samples() # Get samples as numpy array
sound.get_value_at_time(time) # Linear interpolation
sound.extract_part(start, end, ...) # Extract segment
sound.pre_emphasis(from_freq) # High-pass filter
sound.rms(), sound.peak() # Amplitude measures
# Analysis
sound.to_pitch(dt, floor, ceil) # Pitch extraction
sound.to_formant_burg(...) # Formant analysis
sound.to_intensity(min_pitch, dt) # Intensity contour
sound.to_spectrum(fast) # Single-frame FFT
sound.to_spectrogram(...) # Time-frequency analysis
sound.to_harmonicity_ac/cc(...) # HNR analysis
# Speech-referenced variants (robust on long recordings — see below)
sound.to_pitch_ac_referenced(dt, floor, ceil, *, reference_peak=None)
sound.to_pitch_cc_referenced(dt, floor, ceil, *, reference_peak=None)
sound.to_harmonicity_ac_referenced(dt, min_pitch, silence, ppw, *, reference_peak=None)
sound.to_harmonicity_cc_referenced(dt, min_pitch, silence, ppw, *, reference_peak=None)
Speech-referenced normalization (long recordings)
Praat references each frame's amplitude against the whole-file peak. On utterance-length audio that peak is the speech peak, which is correct. On long conversational recordings (e.g. 10-minute Buckeye files) the peak is set by whatever is loudest anywhere — a click, laugh, or interviewer burst — so every quiet voiced frame's relative intensity drops and gets misclassified as silent, which then NaN-gates downstream formants and HNR.
The *_referenced methods substitute a robust amplitude reference for the
whole-file peak. The plain to_pitch / to_harmonicity_* methods are
unchanged and remain bit-exact with Praat.
import praatfan_gpl as pg
# Estimate one reference per recording, then share it across pitch and HNR.
# Standards are frame-level robust statistics over speech-active frames, so a
# short loud burst cannot dominate them:
ref = pg.estimate_speech_reference(samples, sample_rate)
ref.reference_peak # 75th-pct of per-frame peak |x| — a typical-speech peak
ref.std # median per-frame RMS (z-norm scale)
ref.mean # median per-frame mean (DC reference)
ref.speech_mask # per-frame bool, hop_s=0.01 grid
ref.frame_times # frame centers (s)
ref.speech_fraction # fraction of frames in the speech mask
pitch = sound.to_pitch_ac_referenced(0.01, 75.0, 600.0,
reference_peak=ref.reference_peak)
hnr = sound.to_harmonicity_cc_referenced(0.01, 75.0, 0.1, 1.0,
reference_peak=ref.reference_peak)
# Or pass reference_peak=None (the default) to have each call estimate the
# reference internally.
The estimator definition and constants are shared across the praatfan package
family (praatfan, praatfan-rust, praatfan-gpl), so a reference_peak
computed by one package is interchangeable with the others.
Pitch
pitch.get_value_at_time(time, unit, interp) # Query pitch
pitch.values() # All values (NaN=unvoiced)
pitch.times() # Frame times
pitch.num_frames, pitch.time_step # Frame info
pitch.pitch_floor, pitch.pitch_ceiling # Analysis parameters
Formant
formant.get_value_at_time(n, time, unit, interp) # Fn frequency
formant.get_bandwidth_at_time(n, time, unit, interp) # Fn bandwidth
formant.formant_values(n) # All Fn values
formant.bandwidth_values(n) # All Bn values
formant.times() # Frame times
Intensity
intensity.get_value_at_time(time, interp) # Query dB
intensity.values() # All values
intensity.times() # Frame times
intensity.min(), intensity.max(), intensity.mean()
Spectrum
spectrum.get_band_energy(f_min, f_max) # Energy in band (Pa² s)
spectrum.get_center_of_gravity(power) # Spectral centroid
spectrum.get_standard_deviation(power) # Spectral spread
spectrum.get_skewness(power) # Spectral skewness
spectrum.get_kurtosis(power) # Spectral kurtosis
spectrum.num_bins, spectrum.df # Frequency info
Spectrogram
spectrogram.values() # 2D array [freq, time]
spectrogram.get_time_from_frame(i) # Frame time
spectrogram.get_frequency_from_bin(i) # Bin frequency
spectrogram.num_frames, spectrogram.num_freq_bins
spectrogram.time_step, spectrogram.freq_step
Harmonicity
harmonicity.get_value_at_time(time, interp) # Query HNR (dB)
harmonicity.values() # All values
harmonicity.times() # Frame times
harmonicity.min(), harmonicity.max(), harmonicity.mean()
Unit Options
- Pitch units:
"hertz","mel","semitones","erb" - Frequency units:
"hertz","bark","mel","erb" - Interpolation:
"nearest","linear","cubic" - Window shapes:
"gaussian","hanning","hamming","rectangular"
Threading
Pitch, harmonicity, intensity, formant (including FormantPath), spectrogram and resampling spread their frames across all CPU cores. Results are bit-identical to a single-threaded run, whatever the thread count. Every analysis releases the GIL while it runs, so other Python threads keep going.
- Thread count: each call uses every core unless you set
RAYON_NUM_THREADS(e.g.RAYON_NUM_THREADS=1) before importing the package. If you already run files in parallel across processes (multiprocessing, joblib, a job array), set it to avoid oversubscribing: N processes × all cores each is slower than either alone. - fork(): safe. A child forked after the parent has run an analysis
(Python
multiprocessing's default on Linux) builds a fresh thread pool on its first call instead of deadlocking on the parent's.
Comparison with parselmouth
praatfan-gpl aims for bit-accurate compatibility with Praat/parselmouth:
import parselmouth
import praatfan_gpl as pc
import numpy as np
sound_pm = parselmouth.Sound("speech.wav")
sound_pc = pc.Sound.from_file("speech.wav")
# Formant comparison
formant_pm = sound_pm.to_formant_burg(0.01, 5, 5500, 0.025, 50)
formant_pc = sound_pc.to_formant_burg(0.01, 5, 5500.0, 0.025, 50.0)
for t in np.arange(0, sound_pm.duration, 0.01):
f1_pm = formant_pm.get_value_at_time(1, t)
f1_pc = formant_pc.get_value_at_time(1, t, "hertz", "linear")
if f1_pm is not None and f1_pc is not None:
assert abs(f1_pm - f1_pc) < 1.0 # Within 1 Hz
License
GPL-3.0 (same as Praat).
Citing
If you use praatfan-gpl in published work, please cite Praat, Parselmouth,
and — if you use FormantPath — Weenink (2015):
- Boersma, P. & Weenink, D. (2024). Praat: doing phonetics by computer. https://www.fon.hum.uva.nl/praat/
- Jadoul, Y., Thompson, B., & de Boer, B. (2018). "Introducing Parselmouth: A Python interface to Praat." Journal of Phonetics, 71, 1–15.
- Weenink, D. (2015). "Improved formant frequency measurements of short segments." Proceedings of ICPhS 2015, Glasgow.
Metadata
Release files for praatfan-gpl 0.1.13
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| praatfan_gpl-0.1.13-cp39-abi3-win_arm64.whl | CPython 3.9 | abi3 | Windows ARM64 | Details |
| praatfan_gpl-0.1.13-cp39-abi3-win_amd64.whl | CPython 3.9 | abi3 | Windows x86-64 | Details |
| praatfan_gpl-0.1.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| praatfan_gpl-0.1.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.9 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| praatfan_gpl-0.1.13-cp39-abi3-macosx_11_0_arm64.whl | CPython 3.9 | abi3 | macOS 11.0+ ARM64 | Details |
| praatfan_gpl-0.1.13-cp39-abi3-macosx_10_12_x86_64.whl | CPython 3.9 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 10.5 MB
Release files / praatfan_gpl-0.1.13-cp39-abi3-win_arm64.whl
| Download URL | praatfan_gpl-0.1.13-cp39-abi3-win_arm64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.9 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
e8016cee941313ed654da4e4da4da14b6b588349bf3b3871cccd71d3ded69ae9
|
|
BLAKE2b-256 checksum How to use checksums |
5ba2b78911bd84e6c48e33b5948838705bd27506549803b08cea674f93a4dc22
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / praatfan_gpl-0.1.13-cp39-abi3-win_amd64.whl
| Download URL | praatfan_gpl-0.1.13-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
1a8766a70c90c90fa4fcfc5052ea65ebe4f28efa67865162e186ff2f3169f9ef
|
|
BLAKE2b-256 checksum How to use checksums |
b136522a503ec2aa74ce84340bf2e221f7cd9094d9d68dd10d99def4a46abaac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / praatfan_gpl-0.1.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | praatfan_gpl-0.1.13-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 2.2 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
bf891eb49158927c8307dadfa39f1d3d4c9660ed453442b9c7ef390823c2cb6a
|
|
BLAKE2b-256 checksum How to use checksums |
f936af6df4bc4100029fc4276f236bb028aab3038ee902e45e93cf1981715414
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / praatfan_gpl-0.1.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | praatfan_gpl-0.1.13-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
fe87b8c74f2ae4e7214fed5eec91d89676f6525d161ab4f2cc8369707567e26d
|
|
BLAKE2b-256 checksum How to use checksums |
d4ac8bd380753fdf87262315ce70df75027d950f91eb94e8253013106018693c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / praatfan_gpl-0.1.13-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | praatfan_gpl-0.1.13-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
bf9b6a3190234867ece3d2e02529a23164ccca34a6c75d35077dc3977f74dc64
|
|
BLAKE2b-256 checksum How to use checksums |
9f236e1897abad92d50578b704f5db72833f398c56e11ce15b77b7766c650bd8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / praatfan_gpl-0.1.13-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | praatfan_gpl-0.1.13-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
1b56684878814af76eb91c942ea2d2c670e95f15264b8336e3fce1b8980b9dd3
|
|
BLAKE2b-256 checksum How to use checksums |
39884b6e41f5f7c68b5f64a4c27cfbd5d97fe9c8562357d6dd1b2e22851b7bdc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Security for praatfan-gpl 0.1.13
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.