---
title: "Converting a Praat TextGrid collection"
author: "Jonathan Harrington"
date: "WiSe 2021"
output: 
  bookdown::html_document2:
    number_sections: TRUE
    toc: true
    theme: flatly
    highlight: pygments
---

<style>
div.gray {background-color: #e8e8e8; border-radius: 5px; padding: 20px;}
body {font-size: 16pt;}
h1 {font-size: 24pt;}
h2 {font-size: 22pt;}
p.caption {font-size: 12pt; text-align: justify;}
code.sourceCode {font-size: 16pt;}
</style>


# Objective
The aim is to get from a `Praat TextGrid` to an Emu database format as exemplified by Fig. \@ref(fig:figpraat):

```{r figpraat, fig.align="center", fig.cap="An utterance fragment in Praat and in Emu", echo=FALSE}
knitr::include_graphics("./img/figpraat.png")
```

# Preliminaries and starting up R

The assumption is that you have a project called `emu2021` and that it contains the following directories. 
![](img/emu2021.png)

If not, please see 
[1. Preliminaries here](https://www.phonetik.uni-muenchen.de/~jmh/lehre/sem/ws2122/Emuintro/creating_database.html#preliminaries)

Start up R in the project you are using for this course.

```{r}
library(tidyverse)
library(emuR)
library(wrassp)
```

In `R`, store the path to the directory `testsample` as `sourceDir` in exactly the following way:

```{r}
sourceDir = "./testsample"
```

And also store in `R` the path to *emu_databases* as `targetDir`:

```{r}
targetDir = "./emu_databases"
```


# Converting Praat TextGrids
The directory `/testsample/praat` on your computer contains a `Praat` style database with `.wav` files and .`Textgrid` files

Define the path to this database in `R` and check you can see these files with then`list.files()` function:

```{r}
path.praat = file.path(sourceDir, "praat")
list.files(path.praat)
```

The emuR function for converting the TextGridCollection to an Emu database and then storing the latter in `targetDir` (defined above) is `convert_TextGridCollection()`. It works like this:

```{r, eval=FALSE}
# only execute once!
convert_TextGridCollection(path.praat, 
                           dbName = "praat",
                           targetDir = targetDir)
```

The converted `Praat` database can now be loaded:

```{r}
praat_DB = load_emuDB(file.path(targetDir, "praat_emuDB"))
```

and its properties examined as before:

```{r, eval=FALSE}
summary(praat_DB)
```

![](img/praatDB.png)

And it can of course be viewed:

```{r, eval=FALSE}
serve(praat_DB, useViewer = F)
```

# Calculating pitch with `wrassp`
The task is to calculate the pitch from each of the utterance's waveforms for the `praat_DB` database created above. First, find the full path names of all of the `.wav` files. They are here:

```{r}
praat_wav_paths = list.files(path.praat, pattern = ".*wav$", recursive = T, full.names = T)
praat_wav_paths
```

The signal processing package `wrassp` will now be used to calculate the pitch for each of these `.wav` files. To see the full range of signal processing routines available, enter:
```{r}
?wrassp
```
There are two possible routines that are needed here for calculating pitch: `ksvF0` and `mhsF0`. 

Here's how to use `mhsF0` with the default settings. The output is going to be stored in `path.praat` (i.e. in `/testsample/praat` on you computer).

```{r, eval=FALSE}
# only execute once!
mhsF0(praat_wav_paths, outputDirectory = path.praat)
```

As the figure below shows, the pitch files have should now all been dumped in `path.praat` i.e. in `/testsample/praat`


$~$


![](img/pitchfiles.png)


$~$

# Adding the calculated pitch files to the database

These calculated pitch files now need to be added to  `praat_DB`. This is done with the `add_files()` function. The parameter `targetSessionName` can be omitted in this case, because all of the  bundles are stored in the session directory `0000`. This can be verified with:

```{r}
list_bundles(praat_DB)
```

Now add the pitch files to `praat_DB`:
```{r, eval=FALSE}
# only execute once!
add_files(praat_DB, 
          dir = path.praat, 
          fileExtension = "pit", 
          targetSessionName = "0000")
```

Having added the files, they need to be *defined*. The information required is:

- a `track name`. This can be anything and it is needed when referring to these signal files in `R`. 
- the `file extension`. This is `pit` as already established above.
- the `columnName`. This is the name of the column in the `.pit` files in which the fundamental frequency data is stored. This type of information (as well as information about the extension) is given by `wrasspOutputInfos`. In this case, append `$mhsF0` since this was the name of the signal processing routine that has been used to calculate the pitch data:


```{r}

wrasspOutputInfos$mhsF0
```

The column name is given by `$tracks` which in this case is `pitch`. Putting all this together, and using `"pitch"` for the the name of the track gives:

```{r, eval=FALSE}
# only execute once!
add_ssffTrackDefinition(praat_DB,
                        name = "pitch",
                        columnName = "pitch",
                        fileExtension = "pit")
```

```{r, eval=FALSE}
summary(praat_DB)
```

![](img/praatDB2.png)

# Displaying the pitch files in the webapp

The signals that are currently displayed for this `praat_DB` database can be seen with the function `get_signalCanvasesOrder()` as follows:


```{r}
get_signalCanvasesOrder(praat_DB, perspectiveName = "default")
```
which confirms that what is seen when viewing the database with the `serve()` function is the waveform (`OSCI`) and the spectrogram. The pitch data created above now needs to be added using the function `set_signalCanvasesOrder`. The second argument should always be `"default"`, thus:

```{r, eval=FALSE}
set_signalCanvasesOrder(praat_DB, perspectiveName = "default",
                        order = c("OSCI", "SPEC",  "pitch"))
serve(praat_DB, useViewer = F)
```

# Adding an event tier

The next task is to add an event tier that can be used for labelling tones. Here the tier is called "Tone". So far, the only  only existing time tier is `ORT` as confirmed by:

```{r, eval=FALSE}
list_levelDefinitions(praat_DB)
```

In order to add a new tier called `Tone` as an `EVENT` tier:
```{r, eval=FALSE}
# only execute once!
add_levelDefinition(praat_DB, "Tone", "EVENT")
```

Display `Tone` so that it is above the `ORT` tier and so directly underneath the signals:

```{r, eval=FALSE}
get_levelCanvasesOrder(praat_DB, perspectiveName = "default")
```

![](img/ort.png)

```{r, eval=FALSE}
set_levelCanvasesOrder(praat_DB, 
                       perspectiveName = "default", 
                       order = c("Tone", "ORT"))
```
# Labelling some tones

Add two tone labels H* at pitch peak of *morgens* and *ruhig* in `wetter1` as in Fig. \@ref(fig:figpraat) and save the result.

```{r, eval=FALSE}
serve(praat_DB, useViewer=F)
```

The tones are to be linked to words within which they occur in time. To do this, define a hierarchical relationship such that `ORT` dominates `Tone`:

```{r, eval=FALSE}
list_linkDefinitions(praat_DB)
```

![](img/null.png)

```{r, eval=FALSE}
# only execute once!
add_linkDefinition(praat_DB, 
                   type = "ONE_TO_MANY", 
                   superlevelName = "ORT", 
                   sublevelName = "Tone")
```

```{r}
list_linkDefinitions(praat_DB)
```

Inspect the hierarchy:

```{r, eval=FALSE}
summary(praat_DB)
```

![](img/praatDB3.png)

```{r, eval=FALSE}
# switch to hierarchy view
serve(praat_DB, useViewer = F)
```
# Automatically linking event and segment times
This makes use of the `autobuild_linkFromTimes` function in order to  link the tones to the corresponding words:

```{r, eval=FALSE}
# only execute once!
autobuild_linkFromTimes(praat_DB,
                        superlevelName = "ORT",
                        sublevelName = "Tone")

# switch to hierarchy view
serve(praat_DB, useViewer = F)
```
