This guide explains the 3-tier performance API in pladdrr and how to choose the right level for your needs.
pladdrr provides three API tiers, each trading interface simplicity for lower per-call overhead:
┌─────────────────────────────────────────────────────────┐
│ TIER 1: High-Level API (Sound, Pitch, Formant, etc.) │
│ - Full object-oriented interface │
│ - Method chaining: sound$to_pitch()$get_mean() │
│ - Best for: Interactive analysis, small datasets │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ TIER 2: Direct API (*_direct functions) │
│ - Accept XPtr directly, skip object dispatch │
│ - Best for: Tight loops, repeated queries │
│ - Reduces per-call R dispatch overhead │
└─────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ TIER 3: Batch/Parallel API (*_batch, *_parallel) │
│ - Designed for bulk operations │
│ - Best for: Large datasets, production workflows │
│ - Replaces many R->C crossings with one per call │
└─────────────────────────────────────────────────────────┘
It depends entirely on how much work each call does relative to the R-to-C++ boundary it crosses.
to_pitch(),
to_formant_burg(), calculate_cpps_fast() — is
dominated by the underlying DSP work, and the tier you call it through
makes little practical difference. The different CPPS entry points
(sound$to_powercepstrogram()$get_cpps(),
calculate_cpps_fast(), calculate_cpps_ultra())
all compute the same value using the same core algorithm.Rule of thumb: reach for a batch or direct function when you are
about to write a loop over query points or files. Switching analysis
entry points for a single call is not expected to help — measure your
own workload with system.time() if you’re unsure.
When to use: Interactive analysis, exploration, small datasets (<100 files)
Characteristics: - Intuitive object-oriented interface - Method chaining - Full error checking and validation - Easy to read and maintain
library(pladdrr)
wav_file <- system.file("extdata", "test.wav", package = "pladdrr")
# Load sound
sound <- Sound(wav_file)
# Extract pitch (returns Pitch object)
pitch <- sound$to_pitch(pitch_floor = 75, pitch_ceiling = 300)
# Query statistics
mean_f0 <- pitch$get_mean(0, 0, "hertz")
sd_f0 <- pitch$get_standard_deviation(0, 0, "hertz")
# Method chaining
mean_f1 <- sound$to_formant()$get_mean(1, 0, 0, "hertz")Adequate for most use cases. Only reach for Tier 2/3 if profiling your own code shows a bottleneck.
When to use: Processing >100 files, tight loops, production code
Characteristics: - Functions accept external pointers (XPtr) directly - Skip R6 object dispatch overhead - Return raw values or pointers - Require manual pointer extraction
# Extract pointer once
sound_ptr <- sound$.xptr
# Direct conversion (returns XPtr, not Pitch object)
pitch_ptr <- to_pitch_direct(sound_ptr,
time_step = 0,
pitch_floor = 75,
pitch_ceiling = 300)
# Get statistics in one call
stats <- get_pitch_stats_direct(pitch_ptr)
# Returns: list(min, max, mean, stdev, median, q25, q75, count_voiced)
# Get F1-F4 in one call
formant_ptr <- to_formant_direct(sound_ptr)
formants <- get_formants_direct(formant_ptr, time = 0.5)
# Returns: c(F1 = 500, F2 = 1500, F3 = 2500, F4 = 3500)Conversion: - to_pitch_direct() -
Create Pitch - to_formant_direct() - Create Formant -
to_intensity_direct() - Create Intensity -
to_harmonicity_direct() - Create Harmonicity -
to_spectrum_direct() - Create Spectrum -
to_spectrogram_direct() - Create Spectrogram -
to_ltas_direct() - Create LTAS -
to_point_process_direct() - Create PointProcess
Queries: - get_pitch_stats_direct() -
All pitch statistics at once - get_formants_direct() -
F1-F4 at time point - get_pitch_value_direct() - Single
pitch value - get_intensity_value_direct() - Single
intensity value - get_formant_value_direct() - Single
formant value
When to use: Large datasets (>100 files), production pipelines
Process multiple sounds in a single C++ call:
# In practice `files` would be a vector of paths to distinct recordings, e.g.
# list.files("audio/", pattern = "\\.wav$", full.names = TRUE). This example
# repeats the bundled test file to keep the vignette self-contained.
files <- rep(wav_file, 3)
# Load multiple sounds
sounds <- lapply(files, Sound)
# Tier 1 approach: one R->C crossing per sound
pitches <- lapply(sounds, function(s) s$to_pitch())
# Tier 3 approach: one R->C crossing for the whole list
pitches <- sound_to_pitch_batch(sounds)Available batch functions: -
sound_to_pitch_batch() - Batch pitch extraction -
sound_to_pitch_ac_batch() - Batch autocorrelation pitch -
sound_to_pitch_cc_batch() - Batch cross-correlation pitch -
sound_to_formant_batch() - Batch formant extraction -
sound_to_intensity_batch() - Batch intensity extraction
Extract values at multiple time points in one call:
# Tier 1 approach: one R->C crossing per time point
times <- seq(0.1, 1.0, by = 0.01)
f0_values <- vapply(times, function(t) {
pitch$get_value_at_time(t, "hertz")
}, numeric(1))
# Tier 3 approach: one R->C crossing for the whole vector
f0_values <- get_pitch_at_times(pitch, times)Vectorized query functions: -
get_pitch_at_times() - Batch pitch queries -
get_formants_at_times() - Batch F1-F4 queries -
get_intensity_at_times() - Batch intensity queries
Distribute file-level work across multiple CPU cores:
# Analyze files in parallel. In practice `files` is a vector of paths to
# distinct recordings, e.g. list.files("audio/", pattern = "\\.wav$",
# full.names = TRUE); this example repeats the bundled test file.
files <- rep(wav_file, 4)
# Simple parallel analysis
results <- analyze_files_parallel(files, function(sound) {
pitch <- sound$to_pitch()
list(
mean_f0 = pitch$get_mean(0, 0, "hertz"),
sd_f0 = pitch$get_standard_deviation(0, 0, "hertz")
)
}, n_cores = 2)
#> Processing 4 files using 2 cores (2 thread(s)/worker)
# Convenience functions
pitches <- extract_pitch_parallel(files, n_cores = 2)
#> Processing 4 files using 2 cores (2 thread(s)/worker)
formants <- extract_formant_parallel(files, n_cores = 2)
#> Processing 4 files using 2 cores (2 thread(s)/worker)
intensities <- extract_intensity_parallel(files, n_cores = 2)
#> Processing 4 files using 2 cores (2 thread(s)/worker)Parallel functions: -
analyze_files_parallel() - Generic parallel file processing
- process_sounds_parallel() - Parallel processing of loaded
sounds - extract_pitch_parallel() - Parallel pitch
extraction - extract_formant_parallel() - Parallel formant
extraction - extract_intensity_parallel() - Parallel
intensity extraction - benchmark_parallel() - Measure your
own workload across core counts
The examples below use system.time() so you can measure
each approach against your own files and hardware — the numbers vary too
much by machine, file size, and workload to be worth quoting here.
sound <- Sound(wav_file)
# Tier 1: Standard API
system.time({
pitch <- sound$to_pitch()
mean_f0 <- pitch$get_mean(0, 0, "hertz")
sd_f0 <- pitch$get_standard_deviation(0, 0, "hertz")
min_f0 <- pitch$get_minimum(0, 0, "hertz")
max_f0 <- pitch$get_maximum(0, 0, "hertz")
})
#> user system elapsed
#> 0.013 0.000 0.006
# measure on your own data
# Tier 2: Direct API
system.time({
pitch_ptr <- to_pitch_direct(sound$.xptr)
stats <- get_pitch_stats_direct(pitch_ptr)
})
#> user system elapsed
#> 0.011 0.000 0.004
# fewer crossings; measure on your own data# In practice `files` is a vector of paths to distinct recordings, e.g.
# list.files("audio/", full.names = TRUE)[1:100]; this example repeats the
# bundled test file to keep the vignette self-contained and fast to build.
files <- rep(wav_file, 20)
# Tier 1: Sequential
system.time({
sounds <- lapply(files, Sound)
pitches <- lapply(sounds, function(s) s$to_pitch())
})
#> user system elapsed
#> 0.207 0.008 0.103
# measure on your own data
# Tier 3: Batch
system.time({
sounds <- lapply(files, Sound)
pitches <- sound_to_pitch_batch(sounds)
})
#> user system elapsed
#> 0.210 0.006 0.099
# scales with cores; measure on your own data
# Tier 3: Parallel (2 cores)
system.time({
pitches <- extract_pitch_parallel(files, n_cores = 2)
})
#> Processing 20 files using 2 cores (2 thread(s)/worker)
#> user system elapsed
#> 0.374 0.305 1.254
# includes file I/O; measure on your own datasound <- Sound(wav_file)
formant <- sound$to_formant()
times <- seq(0.1, 0.5, by = 0.001)
# Tier 1: Loop
system.time({
f1_values <- vapply(times, function(t) {
formant$get_value_at_time(1, t, "hertz")
}, numeric(1))
})
#> user system elapsed
#> 0.013 0.000 0.013
# one R->C crossing per time point
# Tier 3: Vectorized
system.time({
f1_values <- get_formants_at_times(formant, times, formant_numbers = 1)
})
#> user system elapsed
#> 0.001 0.000 0.000
# one R->C crossing for the whole vector — this is where batching pays offAre you processing < 10 files?
├─ YES → Use Tier 1 (standard API)
└─ NO ↓
Are you processing < 100 files?
├─ YES → Use Tier 2 (direct API) if profiling shows it helps
└─ NO ↓
Are you processing > 100 files?
├─ Single machine → Use Tier 3 batch + parallel
└─ Cluster → Use Tier 2 direct + your cluster manager
Don’t prematurely optimize. Use the standard API first:
# Good: Clear and maintainable
pitch <- sound$to_pitch()$smooth()
mean_f0 <- pitch$get_mean(0, 0, "hertz")Only move to Tier 2/3 when: - Profiling your own code shows a bottleneck - You’re processing >100 files - Runtime matters for your workflow
# Tier 1: Multiple individual queries
f1 <- formant$get_value_at_time(1, 0.5, "hertz")
f2 <- formant$get_value_at_time(2, 0.5, "hertz")
f3 <- formant$get_value_at_time(3, 0.5, "hertz")
f4 <- formant$get_value_at_time(4, 0.5, "hertz")
# Tier 2: Single batch query
formants <- get_formants_direct(formant, time = 0.5)# Avoid: Repeated single-value queries in a loop
for (time in times) {
val <- get_pitch_value_direct(pitch, time)
}
# Prefer: One call for the whole vector of times
# (get_pitch_at_times() takes the Pitch object itself, not an XPtr — it
# extracts the pointer internally)
values <- get_pitch_at_times(pitch, times)Not all workloads scale linearly with core count, and small files can
make parallelization overhead outweigh any benefit. Use
benchmark_parallel() to test a range of core counts on a
representative subset of your own files before committing to a setting
for a full run:
# Test different core counts on a subset
benchmark_results <- benchmark_parallel(
files[1:10], # Use subset for a quick test
function(s) s$to_pitch()$get_mean(0, 0, "hertz"),
core_counts = c(1, 2) # extend to c(1, 2, 4, 8) etc. up to your machine's cores
)
#> Testing with 1 core(s)...
#> Using single core (set n_cores > 1 for parallel processing)
#> Testing with 2 core(s)...
#> Processing 10 files using 2 cores (2 thread(s)/worker)
print(benchmark_results)
#> cores time_sec speedup
#> 1 1 0.05549240 1.0000000
#> 2 2 0.07753968 0.7156645
# Inspect the returned table to see where returns diminish on your machine# Define the per-file constants *inside* the worker function rather than
# capturing them from the enclosing environment. On Windows (and on macOS,
# where analyze_files_parallel() also uses a PSOCK cluster to avoid known
# fork/event-loop issues), each worker is a separate R process that only
# receives the function and file path — free variables referenced from the
# calling environment are not automatically exported and would error with
# "object not found" unless passed via clusterExport() or defined locally
# like this.
analyze_files_parallel(files, function(sound) {
start_times <- c(0.1, 0.3)
end_times <- c(0.2, 0.4)
analysis_times <- seq(0.01, 0.05, by = 0.01)
# Use batch operations within each worker
parts <- sound$extract_parts_batch(start_times, end_times)
formants <- sound_to_formant_batch(parts)
# Vectorized queries
lapply(formants, function(f) {
get_formants_at_times(f, analysis_times)
})
}, n_cores = 2)
#> Processing 20 files using 2 cores (2 thread(s)/worker)
#> [[1]]
#> [[1]][[1]]
#> [[1]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[1]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[1]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[1]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[1]][[2]]
#> [[1]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[1]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[1]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[1]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[2]]
#> [[2]][[1]]
#> [[2]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[2]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[2]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[2]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[2]][[2]]
#> [[2]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[2]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[2]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[2]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[3]]
#> [[3]][[1]]
#> [[3]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[3]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[3]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[3]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[3]][[2]]
#> [[3]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[3]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[3]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[3]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[4]]
#> [[4]][[1]]
#> [[4]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[4]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[4]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[4]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[4]][[2]]
#> [[4]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[4]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[4]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[4]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[5]]
#> [[5]][[1]]
#> [[5]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[5]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[5]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[5]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[5]][[2]]
#> [[5]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[5]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[5]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[5]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[6]]
#> [[6]][[1]]
#> [[6]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[6]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[6]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[6]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[6]][[2]]
#> [[6]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[6]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[6]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[6]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[7]]
#> [[7]][[1]]
#> [[7]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[7]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[7]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[7]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[7]][[2]]
#> [[7]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[7]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[7]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[7]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[8]]
#> [[8]][[1]]
#> [[8]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[8]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[8]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[8]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[8]][[2]]
#> [[8]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[8]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[8]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[8]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[9]]
#> [[9]][[1]]
#> [[9]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[9]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[9]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[9]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[9]][[2]]
#> [[9]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[9]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[9]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[9]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[10]]
#> [[10]][[1]]
#> [[10]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[10]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[10]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[10]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[10]][[2]]
#> [[10]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[10]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[10]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[10]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[11]]
#> [[11]][[1]]
#> [[11]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[11]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[11]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[11]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[11]][[2]]
#> [[11]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[11]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[11]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[11]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[12]]
#> [[12]][[1]]
#> [[12]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[12]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[12]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[12]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[12]][[2]]
#> [[12]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[12]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[12]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[12]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[13]]
#> [[13]][[1]]
#> [[13]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[13]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[13]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[13]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[13]][[2]]
#> [[13]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[13]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[13]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[13]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[14]]
#> [[14]][[1]]
#> [[14]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[14]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[14]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[14]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[14]][[2]]
#> [[14]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[14]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[14]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[14]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[15]]
#> [[15]][[1]]
#> [[15]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[15]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[15]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[15]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[15]][[2]]
#> [[15]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[15]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[15]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[15]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[16]]
#> [[16]][[1]]
#> [[16]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[16]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[16]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[16]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[16]][[2]]
#> [[16]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[16]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[16]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[16]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[17]]
#> [[17]][[1]]
#> [[17]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[17]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[17]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[17]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[17]][[2]]
#> [[17]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[17]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[17]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[17]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[18]]
#> [[18]][[1]]
#> [[18]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[18]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[18]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[18]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[18]][[2]]
#> [[18]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[18]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[18]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[18]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[19]]
#> [[19]][[1]]
#> [[19]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[19]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[19]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[19]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[19]][[2]]
#> [[19]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[19]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[19]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[19]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379
#>
#>
#>
#> [[20]]
#> [[20]][[1]]
#> [[20]][[1]]$F1
#> [1] NA NA 420.8500 420.7663 421.1240
#>
#> [[20]][[1]]$F2
#> [1] NA NA 464.7808 464.6990 465.0480
#>
#> [[20]][[1]]$F3
#> [1] NA NA 2999.369 2975.049 3042.348
#>
#> [[20]][[1]]$F4
#> [1] NA NA 4205.872 4190.150 4248.532
#>
#>
#> [[20]][[2]]
#> [[20]][[2]]$F1
#> [1] NA NA 421.0817 421.0195 420.9680
#>
#> [[20]][[2]]$F2
#> [1] NA NA 465.0067 464.9466 464.8963
#>
#> [[20]][[2]]$F3
#> [1] NA NA 3031.412 3089.364 3011.475
#>
#> [[20]][[2]]$F4
#> [1] NA NA 4239.889 4211.581 4289.379macOS/Linux: - Uses mclapply()
(fork-based parallelism) - Shares memory between processes
Windows: - Uses parLapply()
(socket-based parallelism) - Creates separate R processes - May need to
export objects explicitly
Memory constraints: - Each core loads files
independently - With 4 cores and 100MB files, plan for roughly 400MB RAM
- Reduce n_cores if you hit memory limits
If parallelizing or batching your own workload isn’t helping, check:
htop or Task Manager
to see whether cores are saturated| Tier | Use Case | Functions | Learning Curve |
|---|---|---|---|
| 1 | Interactive, <10 files | sound$to_pitch() |
Easy |
| 2 | Loops, 10-100 files | to_pitch_direct() |
Medium |
| 3 | Production, >100 files | sound_to_pitch_batch() |
Medium |
| 3+ | Large datasets | extract_pitch_parallel() |
Easy |
vignette("getting-started") - Introduction to
pladdrr?analyze_files_parallel - Parallel processing
documentation?get_pitch_stats_direct - Direct API reference