Direct Access to Praat C Functionality from R
The pladdrr package gives R users direct access to Praat functionality through a consistent object-oriented interface, enabling conversion of Praat scripts into self-contained R implementations.
Direct access to Praat's C code base from R is achieved through Rcpp Modules and generated methods associated with Praat Objects of several types (38 Rcpp Modules in total):
We have extended the media handling capabilities substantially to include all formats supported by the libav C library (using the av R package), which is most audio and video formats and containers in mainstream use today. Media loading defaults to using Praat's native routines. However, if the format is not natively supported by Praat, the package falls back to the libav library, loading and converting formats in memory.
To provide optimized processing, the package leverages optimizations from the C/C++ code bases, including
The package provides three tiers of access to Praat's methods, with Tier 1 being most human friendly, Tier 2 provides more direct access to the C routines of Praat, and Tier 3 offers batch and parallel processing for common use cases. Tier 4 provides some abilities for parallel / batch processing of files, if beneficial. We provide coding agent friendly documentation of the package's capabilities in inst/agents/AGENT_GUIDE.md.
The pladdrr package is developed to fill our own internal needs and is designed to support the development of R-based implementations of Praat scripts for use in R workflows and scripts. The package exposes all modules we have found a use for in our re-implementation efforts, but extensions to new Object type will require separate development effort.
We do not expose a fully working interpreter that has been extensively tested. Further, we have opted to not expose the full graphics system of Praat to the user to avoid inclusion of platform specific graphics libraries that are not the core functionality uniquely contributed by Praat. Instead, we plan to make use of the already excellent plotting functionality of R for visualization.
This package was developed to serve our specific needs and does not suit everyone. If our needs do not overlap with yours, please consider these alternative routes to do what you want:
reticulate package. It provides all functionality of Praat as far as we can tell, but cannot produce for instance PDF versions of a Praat drawing.browseVignettes("pladdrr") after installation for packaged articlesinst/examples/ for end-to-end workflowshelp(package = "pladdrr") for the installed reference index# Install devtools if needed
if (!require("devtools")) install.packages("devtools")
# Install the 'av' package for audio I/O. Our fork is recommended for all users who also want to use reindeer
devtools::install_github("humlab-speech/av")
# Install pladdrr from GitHub
devtools::install_github("humlab-speech/pladdrr")
xcode-select --install)brew install ffmpeg
sudo apt-get install libavfilter-dev
For full functionality:
# Visualization (used in examples)
install.packages("ggplot2")
# Data manipulation (used in vignettes)
install.packages("dplyr")
library(pladdrr)
# Create a Sound object with a pure tone
sound <- Sound$create_tone(frequency = 440, duration = 1.0, sampling_rate = 44100)
# Extract pitch
pitch <- sound$to_pitch(time_step = 0.01, pitch_floor = 75, pitch_ceiling = 600)
mean_f0 <- pitch$get_mean(from_time = 0, to_time = 0, unit = "hertz")
# Extract formants (standard)
formant <- sound$to_formant_burg(
time_step = 0.01,
max_number_of_formants = 5,
maximum_formant = 5500,
window_length = 0.025,
pre_emphasis_from = 50
)
# Get formant values at a specific time
f1 <- formant$get_value_at_time(formant_number = 1, time = 0.5, unit = "hertz")
f2 <- formant$get_value_at_time(formant_number = 2, time = 0.5, unit = "hertz")
# Voice quality analysis
harmonicity <- sound$to_harmonicity_cc(time_step = 0.01, min_pitch = 75)
hnr <- harmonicity$get_mean(from_time = 0, to_time = 0)
# Robust formant tracking with FormantPath
fp <- sound$to_formant_path(
time_step = 0.005,
formant_ceiling = 5500,
num_steps_up_down = 2L # Test 5 different ceilings
)
formant_robust <- fp$extract_formant() # Get optimal track
# MFCC extraction for speech recognition (v4.6.8)
mfcc <- sound$to_mfcc(
num_coefficients = 13, # Standard for ASR
analysis_width = 0.025, # 25ms window
time_step = 0.01 # 10ms hop
)
# Speech synthesis with KlattGrid
kg <- KlattGrid_createFromVowel(
duration = 0.5,
f0start = 120, # Pitch in Hz
f1 = 730, b1 = 80, # F1 + bandwidth
f2 = 1090, b2 = 120, # F2 + bandwidth
f3 = 2440, b3 = 150 # F3 + bandwidth
)
synthetic_vowel <- kg$to_sound()
All Praat objects are exposed to as R objects with methods that mirror Praat's native commands:
# Create Sound objects
sound <- Sound$create_tone(frequency = 440, duration = 2.0, sampling_rate = 44100)
# Praat: "To Pitch..." → R: to_pitch()
pitch <- sound$to_pitch(time_step = 0.01, pitch_floor = 75, pitch_ceiling = 600)
# Praat: "Get mean..." → R: get_mean()
mean_f0 <- pitch$get_mean(from_time = 0, to_time = 0, unit = "hertz")
# Chain operations
intensity <- sound$to_intensity(minimum_pitch = 100, time_step = 0.0, subtract_mean = TRUE)
mean_db <- intensity$get_mean(from_time = 0, to_time = 0)
# Create a TextGrid with one interval tier (tiers must exist at creation time)
tg <- TextGrid$create(tmin = 0, tmax = 2.0, tier_names = "words")
# Add boundaries
tg$insert_boundary(tier = 1, time = 0.5)
tg$insert_boundary(tier = 1, time = 1.0)
tg$insert_boundary(tier = 1, time = 1.5)
# Set labels
tg$set_interval_text(tier = 1, interval_number = 1, text = "the")
tg$set_interval_text(tier = 1, interval_number = 2, text = "quick")
tg$set_interval_text(tier = 1, interval_number = 3, text = "brown")
# Query intervals
n_intervals <- tg$get_number_of_intervals(tier = 1)
label <- tg$get_interval_text(tier = 1, interval_number = 2)
# Process multiple files
library(pladdrr)
process_file <- function(wav_path) {
sound <- Sound$new(wav_path)
# Extract multiple features
pitch <- sound$to_pitch()
formant <- sound$to_formant_burg()
intensity <- sound$to_intensity()
# Return data frame
data.frame(
file = basename(wav_path),
mean_f0 = pitch$get_mean(),
f1 = formant$get_value_at_time(1, sound$get_total_duration() / 2),
f2 = formant$get_value_at_time(2, sound$get_total_duration() / 2),
mean_intensity = intensity$get_mean()
)
}
# Process corpus
results <- lapply(wav_files, process_file)
corpus_data <- do.call(rbind, results)
See inst/examples/ for complete, real-world workflows:
The package includes 38 Rcpp modules covering 20+ Praat object types with 500+ methods:
See vignette("integrated-phonetic-analysis") for complete workflow examples.
16 vignettes are available covering analysis workflows, resynthesis, formant tracking, speech synthesis, and migration guides. Highlights:
# Complete phonetic analysis workflow
vignette("integrated-phonetic-analysis", package = "pladdrr")
# Vowel acoustics research pipeline
vignette("vowel-space-analysis", package = "pladdrr")
# TextGrid annotation and corpus processing
vignette("textgrid-workflows", package = "pladdrr")
Run browseVignettes("pladdrr") for the full list.
Ten complete, real-world examples in inst/examples/:
Run examples:
# View example code
file.show(system.file("examples", "07_comprehensive_phonetic_analysis.R", package = "pladdrr"))
# Run example (after installing pladdrr)
source(system.file("examples", "07_comprehensive_phonetic_analysis.R", package = "pladdrr"))
C++ compilation errors:
Error: C++17 standard requested but CXX17 is not defined
Solution: Update your compiler. On macOS: xcode-select --install. On Linux: install GCC >= 7.
Missing FFmpeg:
Error in loadNamespace(name) : there is no package called 'av'
Solution: Install FFmpeg libraries first:
brew install ffmpeg
sudo apt-get install libavfilter-dev
Module loading errors:
Error: package or namespace load failed for 'pladdrr'
Solution: Reinstall with a clean build:
remove.packages("pladdrr")
devtools::install_github("humlab-speech/pladdrr", force = TRUE)
"Praat error occurred" (generic message):
Starting in v4.7.0, error messages include the actual Praat error. If you see generic errors, update to the latest version.
NA values in analysis:
This is expected for:
Use na.rm = TRUE when computing statistics:
mean(pitch$get_values_vector(), na.rm = TRUE)
Memory issues with large files:
Use LongSound for files too large for memory:
longsound <- LongSound$open("large_file.wav")
# Extract only the portion you need
sound_segment <- longsound$extract_part(tmin = 0, tmax = 10)
$get_values_vector()) instead of loopsto_power_cepstrum()$get_peak_prominence(); reserve calculate_cpps_ultra() for smoothed CPPScalculate_cpps_ultra() over standard APIfredrik.nylen@umu.se
To cite pladdrr in publications, run citation("pladdrr") in R, or use:
Nylén, Fredrik, Skotare, Tomas & von Boer, Johan (2026). pladdrr: Direct Access to the Core Algorithms of Praat. R package version 5.0.6. https://doi.org/10.5281/zenodo.21884217
Please also cite Praat itself:
Boersma, Paul & Weenink, David (2024). Praat: doing phonetics by computer [Computer program]. Version 6.4, retrieved from https://praat.org/
Contributions are welcome. See CONTRIBUTING.md for how to get a working build (the vendored Praat sources are tracked directly in this repo, and GSL is required) and what a good pull request looks like.
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
pladdrr is licensed under GPL-3 (GNU General Public License version 3 or later).
This package includes components from several third-party projects:
All third-party components are compatible with GPL-3. For full licensing details, see:
LICENSE - Copyright and GPL-3 license declarationinst/COPYRIGHTS - Third-party component attributionsCOPYING - Complete GPL-3 license textFor questions and feedback, please open an issue on GitHub.