--- title: "Normalizing Formant Tracks" fig-width: 5 fig-height: 3 out-width: 80% knitr: opts_chunk: crop: !expr 'rlang::is_installed(c("magick"))' collapse: true comment: '#>' format: html: toc: true html-math-method: mathjax embed-resources: true theme: none minimal: true vignette: > %\VignetteIndexEntry{Normalizing Formant Tracks} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} --- ```{r} #| eval: !expr 'rlang::is_installed("magick")' #| echo: false knitr::knit_hooks$set(crop = knitr::hook_pdfcrop) ``` ```{r} #| label: setup library(tidynorm) ``` ```{r} #| eval: !expr 'rlang::is_installed(c("ggplot2"))' library(ggplot2) ``` Tidynorm normalizes vowel formant tracks by 1. Converting them to Discrete Cosine Transform coefficients. 2. Directly normalizing the DCT coefficients. 3. Applying the inverse DCT. ## Token IDs In order to do this successfully, each vowel token needs to be uniquely identifiable with a token id, or a token id in combination with other columns. For example, in `tidynorm::speaker_tracks` the column `speaker` combined with the column `id` identifies each unique vowel formant track. ```{r} speaker_tracks ``` For most normalization procedures, we'll want to group the data by the speaker column anyway, and in those cases it's sufficient to pass `id` to the `.token_id_col` argument of `norm_track_*` functions. We can Lobanov normalize these speakers' formant tracks with `norm_track_lobanov()`. ```{r} normed_tracks <- speaker_tracks |> norm_track_lobanov( # identify the formant columns F1:F3, # provide speaker grouping .by = speaker, # provide token id .token_id_col = id, # provide an optional time column .time_col = t ) ``` ```{r} #| fig-align: center #| out-width: 80% #| eval: !expr 'rlang::is_installed(c("ggplot2"))' normed_tracks |> ggplot( aes(F2_z, F1_z) ) + geom_path( aes( group = interaction(speaker, id) ), alpha = 0.3 ) + scale_y_reverse() + scale_x_reverse() + facet_wrap(~speaker) + coord_cartesian( xlim = c(3.5, -3.5), ylim = c(3.5, -3.5) ) + theme( aspect.ratio = 1 ) ```