Praat Interpreter: Variables and Expressions

library(pladdrr)

Introduction

The pladdrr package provides complete access to Praat’s interpreter system, enabling you to:

  • Evaluate Praat expressions directly from R
  • Manage persistent variables across expressions
  • Work with all 5 Praat variable types (numeric, string, vector, matrix, string array)
  • Query the global Praat object list

This vignette demonstrates how to use the interpreter for computational tasks without requiring Praat scripts.

Standalone Expression Evaluation

The simplest way to use the interpreter is through standalone expression evaluation functions. These create temporary interpreters and return results immediately.

Numeric Expressions

# Basic arithmetic
praat_eval_numeric("2 + 2")
#> [1] 4
praat_eval_numeric("sqrt(16) + 2^3")
#> [1] 12

# Trigonometric functions
praat_eval_numeric("sin(pi/2)")
#> [1] 1
praat_eval_numeric("cos(0)")
#> [1] 1

# Complex calculations
praat_eval_numeric("log10(1000)")
#> [1] 3

String Expressions

# String concatenation
praat_eval_string('"Hello" + " " + "World"')
#> [1] "Hello World"

# String functions
praat_eval_string('left$("testing", 4)')
#> [1] "test"
praat_eval_string("string$(42)")
#> [1] "42"

Vector Expressions

# Create vectors
vec <- praat_eval_vector("{ 1, 2, 3, 4, 5 }")
vec
#> [1] 1 2 3 4 5

# Vector with decimals
vec2 <- praat_eval_vector("{ 1.1, 2.2, 3.3 }")
vec2
#> [1] 1.1 2.2 3.3

Matrix Expressions

# Create 2x2 matrix
mat <- praat_eval_matrix("{{ 1, 2 }, { 3, 4 }}")
mat
#>      [,1] [,2]
#> [1,]    1    2
#> [2,]    3    4

# Matrix dimensions are preserved
dim(mat)
#> [1] 2 2

String Array Expressions

# Create string arrays
names <- praat_eval_string_array('{ "Alice", "Bob", "Charlie" }')
names
#> [1] "Alice"   "Bob"     "Charlie"

Persistent Interpreter with State

For more complex workflows, use the PraatInterpreter R6 class which maintains state between operations.

Creating an Interpreter

# Create a persistent interpreter instance
interp <- PraatInterpreter$new()

Setting Variables

The interpreter automatically detects variable types and adds appropriate Praat suffixes:

# Numeric variables (no suffix)
interp$set_variable("x", 42)
interp$set_variable("pi_value", 3.14159)

# String variables ($ suffix auto-added)
interp$set_variable("name", "John")
interp$set_variable("greeting", "Hello")

# Vector variables (# suffix auto-added)
interp$set_variable("data", c(1.5, 2.5, 3.5, 4.5))

# Matrix variables (## suffix auto-added)
interp$set_variable("matrix", matrix(1:6, nrow = 2, ncol = 3))

# String array variables ($# suffix auto-added)
interp$set_variable("names", c("alpha", "beta", "gamma"))

Getting Variables

Retrieve variables using Praat suffix notation:

# Get numeric variable
interp$get_variable("x")
#> [1] 42

# Get string variable (must include $ suffix)
interp$get_variable("name$")
#> [1] "John"

# Get vector (# suffix)
interp$get_variable("data#")
#> [1] 1.5 2.5 3.5 4.5

# Get matrix (## suffix)
interp$get_variable("matrix##")
#>      [,1] [,2] [,3]
#> [1,]    1    3    5
#> [2,]    2    4    6

# Get string array ($# suffix)
interp$get_variable("names$#")
#> [1] "alpha" "beta"  "gamma"

Using Variables in Expressions

Variables can be used directly in expressions:

# Set some variables
interp$set_variable("a", 10)
interp$set_variable("b", 20)

# Use in arithmetic
result <- interp$eval("a + b")
result
#> [1] 30

result <- interp$eval("a * b")
result
#> [1] 200

# String operations with variables
interp$set_variable("first", "hello")
interp$set_variable("second", "world")

result <- interp$eval('first$ + " " + second$')
result
#> [1] "hello world"

Vector and Matrix Operations

# Create a vector
interp$set_variable("vec", c(1, 2, 3, 4, 5))

# Get vector size
size <- interp$eval("size(vec#)")
size
#> [1] 5

# Sum vector
total <- interp$eval("sum(vec#)")
total
#> [1] 15

# Mean of vector
mean_val <- interp$eval("mean(vec#)")
mean_val
#> [1] 3

# Create a matrix
interp$set_variable("mat", matrix(1:4, nrow = 2, ncol = 2))

# Query matrix dimensions
rows <- interp$eval("numberOfRows(mat##)")
cols <- interp$eval("numberOfColumns(mat##)")
c(rows = rows, cols = cols)
#> rows cols 
#>    2    2

Praat Variable Type Reference

Praat uses suffix notation to distinguish variable types:

R Type Praat Suffix Example Variable Set Get
Numeric scalar (none) x set_variable("x", 42) get_variable("x")
String $ name$ set_variable("name", "test") get_variable("name$")
Numeric vector # data# set_variable("data", c(1,2,3)) get_variable("data#")
Numeric matrix ## mat## set_variable("mat", matrix(...)) get_variable("mat##")
String array $# names$# set_variable("names", c("a","b")) get_variable("names$#")

Key Points:

  • When setting variables, omit the suffix - it’s added automatically
  • When getting variables, include the appropriate suffix
  • Use variables in expressions with their full suffix notation

Object Management

Query Praat’s global object list (useful when objects are created through other means):

# Get count of objects
count <- praat_object_count()
count
#> [1] 0

# List all objects (returns data frame)
objects <- praat_list_objects()
objects
#> [1] id       name     class    selected
#> <0 rows> (or 0-length row.names)

# Also available via R6 instance
count2 <- interp$object_count()
objects2 <- interp$list_objects()

Note: In library mode (without GUI), object creation commands like Create Sound... are not available. The object management functions are ready for use when GUI actions are enabled or when working with objects created through pladdrr’s direct API (e.g., sound_load(), pitch_create(), etc.).

Practical Example: Statistical Calculations

# Create an interpreter for a statistical workflow
stats <- PraatInterpreter$new()

# Set up data
stats$set_variable("values", c(12.5, 15.3, 11.8, 14.2, 13.7, 16.1))

# Calculate statistics using Praat functions
n <- stats$eval("size(values#)")
mean_val <- stats$eval("mean(values#)")
stdev <- stats$eval("stdev(values#)")

# Results
cat("Sample size:", n, "\n")
#> Sample size: 6
cat("Mean:", mean_val, "\n")
#> Mean: 13.93333
cat("Std Dev:", stdev, "\n")
#> Std Dev: 1.630542

# Calculate z-scores manually
stats$set_variable("mean", mean_val)
stats$set_variable("sd", stdev)

# For each value, could calculate (x - mean) / sd
# This demonstrates variable persistence across multiple operations

Performance Considerations

  • Standalone functions (praat_eval_*) create temporary interpreters - use for one-off calculations
  • Persistent interpreters (PraatInterpreter$new()) reuse state - use for workflows with multiple related operations
  • Variable overhead is minimal
  • Type conversion between R and Praat is automatic and efficient

Best Practices

  1. Use persistent interpreters for workflows: When you need multiple related calculations, create one interpreter instance and reuse it

  2. Name variables clearly: Since Praat and R variables are separate, use descriptive names to avoid confusion

  3. Remember suffix notation: When getting variables or using them in expressions, always include the appropriate suffix

  4. Leverage type auto-detection: Let set_variable() automatically determine the correct Praat type from your R object

  5. Check object types: Use class(), dim(), etc. to verify R objects before setting as Praat variables

Summary

The Praat interpreter integration provides:

  • Access to Praat’s expression evaluation
  • All 5 variable types (numeric, string, vector, matrix, string array)
  • Persistent state management via PraatInterpreter
  • Automatic type detection and conversion between R and Praat
  • Object list queries
  • R6 and standalone functional APIs

The interpreter can be combined with pladdrr’s other API functions for phonetic analysis workflows.

See Also

  • vignette("getting-started") - Introduction to pladdrr
  • vignette("formant-analysis") - Formant extraction workflows
  • ?PraatInterpreter - R6 class documentation
  • ?praat_eval_numeric - Expression evaluation functions