Skip to main content

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"

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.10

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for praatfan-gpl 0.1.10
File
praatfan_gpl-0.1.10-cp39-abi3-win_arm64.whl CPython 3.9 abi3 Windows ARM64 Details
praatfan_gpl-0.1.10-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
praatfan_gpl-0.1.10-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.10-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
praatfan_gpl-0.1.10-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
praatfan_gpl-0.1.10-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 10.0 MB

Release files / praatfan_gpl-0.1.10-cp39-abi3-win_arm64.whl

Download URL praatfan_gpl-0.1.10-cp39-abi3-win_arm64.whl
Size 1.3 MB
Tags CPython 3.9 Windows ARM64 abi3
SHA-256 checksum
How to use checksums
b776dc4e4836654995c5832fd92abd18c52e32d7f542b394ffe7da406210151f
BLAKE2b-256 checksum
How to use checksums
f237e6205a2caa8a03e6276c0e5ef31ef159ca9f3d6e3cb1fb301029bf8117bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / praatfan_gpl-0.1.10-cp39-abi3-win_amd64.whl

Download URL praatfan_gpl-0.1.10-cp39-abi3-win_amd64.whl
Size 1.7 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
dc9942e5679433e667fafdf747984e9ccd696b723cff01b60c3756f54d9415c0
BLAKE2b-256 checksum
How to use checksums
d2b930e971e632a7b15c2b198bb0a58645c90270f37afe2566f856ffaeba84f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / praatfan_gpl-0.1.10-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL praatfan_gpl-0.1.10-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 2.1 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
afc636cea2aa885e0ab081f25f7cb3acf70728c008abb80494f95d735da0b769
BLAKE2b-256 checksum
How to use checksums
bb13302a7c0030e9cd438a32898d2200866f606888e4823d9b8e4e96fad165b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / praatfan_gpl-0.1.10-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL praatfan_gpl-0.1.10-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.6 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
c2910e8434db5b11d1cbb1069bce0af26bc8bfc6b79d061b296072ac9ead45d8
BLAKE2b-256 checksum
How to use checksums
c6223d05d50851fbbc7832d1f88a80acd65876d6d58e2eb0f09d18390df8006b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / praatfan_gpl-0.1.10-cp39-abi3-macosx_11_0_arm64.whl

Download URL praatfan_gpl-0.1.10-cp39-abi3-macosx_11_0_arm64.whl
Size 1.4 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0ca85c4fa9cfe8140c142b46157f080a606bd697573b81e73d390e09433a3f69
BLAKE2b-256 checksum
How to use checksums
cb77861492bb63f5b09e821c8cb45c7e0861c1cd1158ea3ca528f0df8bf1b1ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Release files / praatfan_gpl-0.1.10-cp39-abi3-macosx_10_12_x86_64.whl

Download URL praatfan_gpl-0.1.10-cp39-abi3-macosx_10_12_x86_64.whl
Size 1.8 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
67a7f1d7f73c851c6ffa6cd66847cd330429d7c28c55397e9b096c4bbdadd4df
BLAKE2b-256 checksum
How to use checksums
3091d81b9dbef9ca6f5ac111a9bb660b6f74ea4ac3402f4d4e7ed1cc5c5987b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.3

Security for praatfan-gpl 0.1.10

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page