1 Preliminaries

If you have not already done so, please follow the setup instructions

Assuming that the above setup instructions have been followed, now download and unzip testsample

in the directory where you have located your project. I will assume that this directory name (without the path) is emu2021 as in setup section 5).

Create a directory called emu_databases on your computer and put it into the emu2021 directory which should now look like this:

2 Starting up R and accessing the above directories

library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5     ✓ purrr   0.3.4
## ✓ tibble  3.1.4     ✓ dplyr   1.0.7
## ✓ tidyr   1.1.3     ✓ stringr 1.4.0
## ✓ readr   2.0.1     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(emuR)
## 
## Attaching package: 'emuR'
## The following object is masked from 'package:base':
## 
##     norm
library(wrassp)

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

sourceDir = "./testsample"

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

targetDir = "./emu_databases"

3 Creating an Emu database from scratch

This assumes you have downloaded testsample and created sourceDir and targetDir as defined earlier.

Store the path to the directory german:

path.german = file.path(sourceDir, "german")

Check which files are in this database:

list.files(path.german)
## [1] "K01BE001.txt" "K01BE001.wav" "K01BE002.txt" "K01BE002.wav"

List only the full path of the wav files:

list.files(path.german, pattern = ".*wav$", recursive = T, full.names = T)
## [1] "./testsample/german/K01BE001.wav" "./testsample/german/K01BE002.wav"

Create an empty database:

# only execute once!
create_emuDB(name = "german", 
             targetDir = targetDir)

Load the database and store its characteristics:

german_DB = load_emuDB(file.path(targetDir, "german_emuDB"))
## INFO: Checking if cache needs update for 1 sessions and 2 bundles ...
## INFO: Performing precheck and calculating checksums (== MD5 sums) for _annot.json files ...
## INFO: Nothing to update!

What’s in the database? Nothing!

summary(german_DB)

Import wav files into this empty database:

# only execute once!
import_mediaFiles(german_DB, dir = path.german)

Inspect the database again:

summary(german_DB)

List available bundles. (See section 5.1 of the Emu SDMS for details about sessions and bundles).

lbund = list_bundles(german_DB, sessionPattern = "0000")
lbund
## # A tibble: 2 × 2
##   session name    
##   <chr>   <chr>   
## 1 0000    K01BE001
## 2 0000    K01BE002

Display the wav and spectrogram data for these two utterances.

serve(german_DB, useViewer = F)

Add a tier for phonetic labelling. The tier needs a name (here called Phon). The type is SEGMENT because the annotation units have start and end times. The other possibilities are EVENT (for e.g., marking tone targets) and ITEM. Please see section 4 of the Emu SDMS manual for the important difference between SEGMENT, EVENT, and ITEM tiers.

# only execute once!
add_levelDefinition(german_DB, 
                    name = "Phon", 
                    type = "SEGMENT")

Set things up to display the newly created Phon tier.

get_levelCanvasesOrder(german_DB, 
                       perspectiveName = "default")

The above gives NULL because no time tiers (of type SEGMENT or EVENT) have been specified for display. Set to display the Phon tier.

set_levelCanvasesOrder(german_DB, 
                       perspectiveName = "default", 
                       order = "Phon")

Now try:

serve(german_DB, useViewer = F)

The Phon tier should be visible. Annotate some segments as in the figure below e.g. /O, a/ for the vowels of Sonne and lacht in K01BE002 and save the annotations. Please see section 9.2.1 of the EMU-SDMS manual on how to annotate from time signals.

An utterance with two annotations from `german_DB`

Figure 3.1: An utterance with two annotations from german_DB

Some information about annotating in Emu

The procedure for entering annotations into Emu is not immediately intuitive especially if you are used to Praat.

  1. One way to get started is put the mouse at some desired point in the waveform or spectrogram window, then left click, then carriage return. This should draw a vertical line. Let’s call the time of this line t1.

  2. Hold the shift key down and while keeping the shift key held down sweep somewhere to the right to a later point in time that we will call t2. Keep holding the shift key down while left clicking with the mouse at your desired time (t2). Now let go of the shift key and enter carriage return. These actions should have made a segment between times t1 and t2.

  3. Making other segments is now much easier. Just put the mouse at the desired point on the waveform/spectrogram and left click followed by carriage return. If the position of this new mouse location was after t2 (at say t3), it will make a segment from t2 to t3. If the mouse was before t1 (at say t0), then the new segment will be from t0 to t1.

  4. To delete a segment, put the mouse over a segment boundary (at a vertical line, if you can see it) and enter backspace. If you did this at time t1, and had created t0 as above, then the segment whose original time was from t1 to t2 is now from t0 to t2.

  5. To enter a label, put the mouse on the Phon tier inside a pair of segment boundaries and enter carriage return. The segment on the Phon tier will now show up bright yellow. Type in some text and enter carriage return to make the annotation.

  6. You can move any boundary by hovering the mouse over the boundary, holding down the shift key and moving the mouse from left ot right.

  7. If you don’t want to save the annotations, just click on another utterance name. Otherwise, left click on the current utterance name which is now highlighted in red.

Assuming you have managed to annotate the segments as in Fig. 3.1 above, the segments should now be accessible in R with query():

query(german_DB, "Phon =~ .*")
# A tibble: 3 × 16
#  labels start   end db_uuid         session bundle start_item_id end_item_id level attribute
#  <chr>  <dbl> <dbl> <chr>           <chr>   <chr>          <int>       <int> <chr> <chr>    
#1 "O"    1029. 1114. 385071b1-abe8-… 0000    K01BE…            22          22 Phon  Phon     
#2 ""     1114. 1216. 385071b1-abe8-… 0000    K01BE…            24          24 Phon  Phon     
#3 "a"    1216. 1285. 385071b1-abe8-… 0000    K01BE…            25          25 Phon  Phon

3.1 Adding word annotations

The next task is to add orthographic labels as ITEM annotations. This should be done if either (a) the start and end times are of no concern and/or (b) a word’s start and end time are inherited from segments. There are three steps:

Define the tier:

# only execute once!
add_levelDefinition(german_DB, 
                    name = "ORT", 
                    type = "ITEM")

Define how it is linked with a time-based tier (here with Phon). See section 4 of the Emu SDMS manual for the difference between ONE-TO-MANY and MANY-TO-MANY.

# only execute once!
add_linkDefinition(german_DB, 
                   type = "ONE_TO_MANY", 
                   superlevelName = "ORT", 
                   sublevelName = "Phon")

Check the hierarchical links:

list_linkDefinitions(german_DB)
## NULL

3.1.1 Adding annotations by direct entry into the hierarchy window

Open the hierarchy window for utterance K01BE001, click on the blue and white + sign next to ORT. Each time you do so, a node appears. You can enter annotation text for any node by positioning the mouse over it and then left click to bring up a green rectangle (see figure below) into which you can enter text, followed by carriage return. To delete a node, move the mouse over it and enter y. Further details: see figure below.

If you have done something as in the above figure, you should be able to access the annotations in R. Notice the NA under start and end times. This is because they are timeless i.e. unlinked to any annotations of a time (SEGMENT or EVENT) tier.

query(german_DB, "ORT=~.*")
# labels start   end db_uuid         session bundle start_item_id end_item_id level attribute
#  <chr>  <dbl> <dbl> <chr>           <chr>   <chr>          <int>       <int> <chr> <chr>    
#1 Adding    NA    NA 0e662e73-b6c7-… 0000    K01BE…             3           3 ORT   ORT      
#2 some      NA    NA 0e662e73-b6c7-… 0000    K01BE…             5           5 ORT   ORT      
#3 text      NA    NA 0e662e73-b6c7-… 0000    K01BE…             6           6 ORT   ORT 

3.1.2 Via R

You can also add timeless annotations (in this case to the ORT tier) with the function create_itemsInLevel() after making an appropriatedata-frame in R. In this example, the words ‘die Sonne lacht’ will be added to the second utterance.

# these are the words of the second sentence stored as a character vector `w`
w = c("die", "Sonne", "lacht")
w
## [1] "die"   "Sonne" "lacht"

Make a data-frame with the following information:

What session do the labels belong to?

sess = rep("0000", length(w))

What bundle to the labels belong to?

bundle = rep("K01BE002", length(w))

What’s the name of the tier? This will be ORT as created above.

lev = rep("ORT", length(w))

What order do the annotations occur in? This is 1, 2, 3 for die Sonne lacht.

inds = 1:length(w)

Put all the above information into a data-frame as follows:

newItems_ORT = data.frame(session = sess, 
                          bundle = bundle, 
                          level = lev, 
                          start_item_seq_idx = inds,
                          attribute = lev, 
                          labels = w,
                          stringsAsFactors = F)
newItems_ORT
##   session   bundle level start_item_seq_idx attribute labels
## 1    0000 K01BE002   ORT                  1       ORT    die
## 2    0000 K01BE002   ORT                  2       ORT  Sonne
## 3    0000 K01BE002   ORT                  3       ORT  lacht

Add these word annotations to the database:

# only execute once!
create_itemsInLevel(german_DB, newItems_ORT)
serve(german_DB, useViewer = F)

Look at hierarchy for the second utterance. The word annotations in the ORT tier should now be visible. These can be linked manually in the Emu-WebApp so that the word labels are accessible in Emu-R. Please see 9.2.2 Working with hierarchical annotations of the Emu SDMS manual for details on how to annotate hierarchically.

Some information about annotating hierarchically Adding hierarchical links and annotations is not difficult. The present task is to add links from O and from a at the Phon tier to Sonne and to lacht respectively at the ORT tier. To do this for the first of these, hover the mouse over Sonne (the node will turn blue), hold down the shift key, and sweep the mouse to O (whose node will also turn blue), release the shift key, and the link is made. If you want to delete the link, hover the mouse over it (the link will then turn bright yellow) and hit backspace. You can add new nodes at the ORT tier as follows. Move the mouse over lacht, then enter n and carriage return. This will create a new node before lacht (between Sonne and lacht). If you enter m instead of n in the above operation, a new node will be created after lacht. To edit or play a node at the ORT tier, left click on the node. you can enter or modify text in the green panel. To denote a node at the ORT tier, hover over it and enter ‘y’. See figure below.

If you have annotated as in the above figure and saved it, the words and their times will be accessible (note that the times at the ORT tier and the same as the times at the Phon tier, because each word only dominates one segment (and inherits its times from those). Note also that die has no times, because it hasn’t been linked to any annotations at the Phon tier

# get all annotations at the `ORT` tier for bundle `K01BE002`
text.s = query(german_DB, "ORT =~ .*", bundlePattern = "K01BE002")
text.s
# A tibble: 3 × 16
#  labels start   end db_uuid         session bundle start_item_id end_item_id level attribute
#  <chr>  <dbl> <dbl> <chr>           <chr>   <chr>          <int>       <int> <chr> <chr>    
#1 die      NA    NA  0e662e73-b6c7-… 0000    K01BE…            11          11 ORT   ORT      
#2 Sonne  1031. 1121. 0e662e73-b6c7-… 0000    K01BE…            12          12 ORT   ORT      
#3 lacht  1282. 1399. 0e662e73-b6c7-… 0000    K01BE…            13          13 ORT   ORT