# Tutorial on how to use praat() # Aaron Albin (www.aaronalbin.com) # This document walks through all the different things PraatR's core function 'praat()' can do, using simple toy examples. # By the end of this tutorial, you should be comfortable with how PraatR works so you can begin to apply it to your own research. # ---------------------------- # Getting everything set up # ---------------------------- # (1) Before beginning this tutorial, be sure to install PraatR as described on the PraatR homepage: # http://www.aaronalbin.com/praatr/ # (2) Make a new folder called 'Tutorial' in a convenient place on your computer (e.g. your desktop). # Make sure the path to this folder does not have a space in it. # (3) Download the demo file tone.wav and put it inside this folder: # http://www.aaronalbin.com/praatr/tone.wav ############################ # 1. Using full file paths # ############################ # At present, PraatR has several restrictions regarding paths to files on your computer. # First, it is not recommended you rely on R's "working directory" functionality. # Instead, you should always provide the full paths to the files you are working with. # For example, assume your working directory is "C:/Users/MyUsername/Desktop/" and you want to work with a file "tone.wav". # In this case, you should tell PraatR "C:/Users/MyUsername/Desktop/tone.wav" rather than just saying "tone.wav". # To make things simpler for us during this tutorial, we will make a function to do this for us. # First, adjust the 'DataDirectory' line of code below so it points to the place where you downloaded the sample data in 'Getting everything set up' #2 above. # Make sure it ends with a slash ("/")! # This should look something like the following: # - Windows: "C:/Users/MyUsername/Desktop/Tutorial/" # - Mac: "/Users/MyUsername/Desktop/Tutorial/" # - Linux: "/home/myusername/Desktop/Tutorial/" # Once that's adjusted, go ahead and run the following code. FullPath = function(FileName){ DataDirectory = "C:/Users/MyUsername/Desktop/Tutorial/" return( paste(DataDirectory,FileName,sep="") ) } # End function # Let's try it out: FullPath("tone.wav") # [1] "C:/Users/MyUsername/Desktop/Tutorial/tone.wav" # If you've done everything so far correctly, this file should exist on your computer. # Let's check that. file.exists( FullPath("tone.wav") ) # [1] TRUE # In your own uses of PraatR, you can adjust this FullPath() function to suit your own needs by pointing to whatever folder your data is in. ################################### # 2. Other notes about file paths # ################################### # There are also two other important restrictions regarding file paths in PraatR. # (1) File paths cannot contain any spaces. # This applies to both the folder path as well as the name of the file itself. # Thus, neither of the following would be acceptable. # - "C:/Users/John Doe/Desktop/Tutorial/tone.wav" (Folder path has a space) # - "C:/Users/JohnDoe/Desktop/Tutorial/my soundfile.wav" (Filename has a space) # This may mean you will need to rename the folder, move your files to another temporary folder, or rename the files before using PraatR. # (2) Make sure no file path has a sequence of two underscores ('__') in it. # This is used as a 'reserved character' of sorts by PraatR. ##################### # 3. Loading PraatR # ##################### # PraatR can be loaded as you would any other package, e.g. by using the library() function at the top of your script: library("PraatR") # The core of PraatR is the function praat(), which invokes Praat and has it execute a command. # This is done invisibly ('behind the scenes'), so you won't see the Praat program pop up on your screen. # Of all the arguments to praat(), only two are obligatory: # (1) 'command', specifying what Praat should do # (2) 'input', specifying what file on your computer Praat should do this to # For the full list of what commands are possible in PraatR, see the 'Supported Commands' page of the PraatR website: # http://www.aaronalbin.com/praatr/commands.html # All of the possible commands supported in PraatR can be broadly classified into four types: # (1) Play: Play audio # (2) Create: Create a new file # (3) Modify: Modify an existing file # (4) Query: Obtain information about a file # Below, each of these four kinds of command will be introduced in turn. ###################### # 4. 'Play' commands # ###################### # The following example has Praat read in the the soundfile 'tone.wav' and then execute the 'Play' command on it, thus playing the audio. praat( command="Play", input=FullPath("tone.wav") ) # You should now hear a 400-millisecond pure (sine wave) tone. # If you don't hear it, try adjusting your volume. # For brevity, the name of the first argument, 'command', can be omitted (as long as it is listed first). # Thus, the following does the same thing as above. praat( "Play", input=FullPath("tone.wav") ) # You should hear the same sound again. # All of the other arguments to the function should be explicitly provided (e.g. 'input=...' above). # If you ever run into a bug, first double-check to make sure you have named all of the arguments. ########################################## # 5. 'Create' commands and saving output # ########################################## # A 'Create' command takes one kind of input and converts it to another one (which is often, but not always, of a different Praat object class). # For such commands, in addition to the input, you will also need to specify an output as well, indicating where the resulting file should be saved. # The file path provided for this 'output' argument must follow the same rules discussed above for the 'input' argument (hence FullPath() can be used here too). # In the following example, the 'tone.wav' soundfile is converted into a Matrix object, which is then saved on your hard drive. # (This matrix is just an alternate storage format for the same sequence of numbers making up the waveform in the WAV file.) praat( "Down to Matrix", input=FullPath("tone.wav"), output=FullPath("tone_text.Matrix") ) # Now check the 'Tutorial' folder where tone.wav' is stored; you should see a new file 'tone_text.Matrix' there. # To see its contents, you can open in a text editor (like Notepad or TextWrangler). # The output can be saved as any of the three standard file types Praat uses when exporting data: "text file", "short text file", or "binary file". # By default, the data is saved in the (long) 'text file' format (hence the filename above: "tone_text"). # To change this, simply provide a 'filetype' argument and set it to "text", "short text", or "binary". # ("short" is also accepted as an abbreviation for "short text".) # The following two examples do the same thing as the previous one except it saves the result in short text and binary formats. praat( "Down to Matrix", input=FullPath("tone.wav"), output=FullPath("tone_short.Matrix"), filetype="short" ) # Same as filetype="short text" praat( "Down to Matrix", input=FullPath("tone.wav"), output=FullPath("tone_binary.Matrix"), filetype="binary" ) # As before, you should now see two new files created in the folder. # If you open the short text format in a text editor, you will see the same information represented as the text-format file above but with fewer labels. # The 'binary'-format file, on the other hand, cannot be viewed in that way; it is only readable by a computer program like Praat (or PraatR). # Note the difference in file size between the three: file.info(FullPath("tone_text.Matrix"))$size # ~757 KB file.info(FullPath("tone_short.Matrix"))$size # ~327 KB file.info(FullPath("tone_binary.Matrix"))$size # ~141 KB # Thus, if you want to save space on your hard drive, "binary" is the best option. ################################ # 6. Special export file-types # ################################ # In addition to these standard three file types, additional 'special' file types are available for certain commands. # For example, let's say we want to take the mono (one-channel) soundfile 'tone.wav' and make it into a stereo (two-channel) soundfile. # To do so, we would take the string of numbers in the original channel and duplicate it in both channels. # We could do that with the following: praat( "Convert to stereo", input=FullPath("tone.wav"), output=FullPath("tone_stereo.txt") ) # Note output is .txt # Since 'filetype' was not specified, the output is in (long) text format. # This not only takes up a large space on the hard drive... file.info(FullPath("tone_stereo.txt"))$size # ~1513 KB # ... but it also means the file can only be read by Praat (and PraatR). # To save the output in the more standard WAV format, simply provide set the 'filetype' argument to 'WAV' (all caps!): praat( "Convert to stereo", input=FullPath("tone.wav"), output=FullPath("tone_stereo.wav"), filetype="WAV" ) # Note output is .wav # When you specify the name of your output file, be sure to use the correct file extension so you don't get confused! # For the full list of which file types are allowed for which commands, see the #4 at the top of the 'Supported Commands' page of the PraatR website: # http://www.aaronalbin.com/praatr/commands.html # Note that soundfiles can be output in all 17 different file formats Praat supports, including .aiff, .aifc, .au, .nist, .flac, and .kay. # Text data can also be output in multiple formats. # For example, we can create a matrix out of the (original mono) tone.wav file, like we did above, but this time save it in two new formats: praat( "Down to Matrix", input=FullPath("tone.wav"), output=FullPath("tone_HeaderlessSpreadsheet.txt"), filetype="headerless spreadsheet" ) praat( "Down to Matrix", input=FullPath("tone.wav"), output=FullPath("tone_MatrixText.txt"), filetype="matrix text" ) # If you want, you can open these files in a text editor and see how they compare to the original files we made (e.g. 'tone_text.Matrix'). ######################### # 7. Over-writing files # ######################### # Try running the code to make the stereo version of tone.wav again: praat( "Convert to stereo", input=FullPath("tone.wav"), output=FullPath("tone_stereo.wav"), filetype="WAV" ) # You should see an error message telling you that the file you provided for 'output' file already exists. # This is because PraatR defaults to *not* overwriting a file that already exists (to protect you from accidentally losing data). # This can easily be overriden by specifying 'overwrite=TRUE'. praat( "Convert to stereo", input=FullPath("tone.wav"), output=FullPath("tone_stereo.wav"), filetype="WAV", overwrite=TRUE ) # This should now run OK without displaying an error message. # If you check the 'date modified' timestamp for that file in your operating system, you can see it has indeed been over-written. ######################## # 8. 'Modify' commands # ######################## # The previous few sections illustrated 'Create' commands, which takes a file as input and creates another file as output. # Another kind of command is a 'Modify' command, changes some attribute about that same file. # For example, the following command takes the 'tone.wav' file and reverses it (i.e. flip-flops its time domain so it would 'play backwards'). praat( "Reverse", input=FullPath("tone.wav"), filetype="WAV" ) # Note that no 'output' was specified for the above command. # This is because Modify commands default to over-writing the same file (i.e. overwrite=TRUE). # If you want the modified object to be be saved to a separate file instead, simply provide an 'output' argument. praat( "Reverse", input=FullPath("tone.wav"), output=FullPath("tone_reversed.wav"), filetype="WAV" ) # If you check in the folder with your data files, you can see that indeed a new, separate file has been created. ################################### # 9. Specifying a single argument # ################################### # All of the commands we have been working with up to this point were very simple, e.g. "Convert to stereo" or "Reverse". # However, the vast majority of Praat's functionality has parameters you can specify for more flexible analyses. # For example, we need to tell Praat the pitch range in an F0 analysis or the maximum formant in a formant analysis. # To do this in PraatR, set 'arguments' to be a list() of the relevant parameters for the command. # (Make sure you use wrap all the arguments in the R function 'list()', not with 'c()'!) # The following example illustrates how this works. # It executes the Modify command 'Scale intensity...' on our soundfile 'tone.wav'. # This command has one argument - the new average intensity in decibels (dB) sound pressure level (SPL). # By setting this to 38.5 dB, the soundfile will be made much quieter (exactly half its original intensity of 77 dB). praat("Scale intensity...", arguments=list(38.5), input=FullPath("tone.wav"), output=FullPath("tone_quiet.wav"), filetype="WAV" ) # If you play the two side-by-side, you can hear the difference: praat( command="Play", input=FullPath("tone.wav") ) # Original praat( command="Play", input=FullPath("tone_quiet.wav") ) # Half volume # To see an example of what the 'arguments' list for a given command should look like, consult the list of supported commands: # http://www.aaronalbin.com/praatr/commands.html # To determine exactly what each of a given command's arguments are, you can check the pop-up menu for that command inside Praat. # For the above example, in the Praat objects window, you could select a Sound object, hit the "Modify" button on the right, and pick "Scale intensity..." to see that the argument is listed as "New average intensity (dB SPL)". # You could also check the documentation in the official Praat manual. # If you put "site:http://www.fon.hum.uva.nl/praat/manual/" at the beginning of a Google search, you should be able to find a page for almost any of Praat's commands that are implemented in PraatR. # The relevant page for the above example is 'Sound: Scale intensity...': # http://www.fon.hum.uva.nl/praat/manual/Sound__Scale_intensity___.html # There, under 'Settings', the argument is again listed as 'New average intensity (dB SPL)'. # Boolean/logical variables can be specified either as TRUE or FALSE (the R way) or as the character strings "yes" or "no" (the Praat way). # (Do not use 1 or 0 for this purpose.) # This is illustrated in the following example, which takes our 'tone.wav' file and generates a Spectrum object from it. # This command's argument is 'Fast', whose behavior is described on the relevant manual page: # http://www.fon.hum.uva.nl/praat/manual/Sound__To_Spectrum___.html # The first command below uses TRUE and the second uses "yes"; both run just fine. praat( "To Spectrum...", arguments=list(TRUE), input=FullPath("tone.wav"), output=FullPath("tone.Spectrum"), filetype="binary" ) praat( "To Spectrum...", arguments=list("yes"), input=FullPath("tone.wav"), output=FullPath("tone.Spectrum"), filetype="binary", overwrite=TRUE ) ##################################### # 10. Specifying multiple arguments # ##################################### # Of course, most commands in Praat have more than one argument. # For such commands, just include all of the relevant arguments together in the list. # Since we are using list() rather than c(), it is perfectly safe to mix different R classes together. # The following example makes the time range between exactly 0.1 and 0.2 seconds all zeros (i.e. pure silence). # Note how the arguments list mixes numbers and character strings. praat( "Set part to zero...", arguments=list( 0.1, 0.2, "at exactly these times" ), input=FullPath("tone.wav"), output=FullPath("tone_zeroed.wav")) # If we listen to the soundfile, we can hear the brief silence in the middle, making it sound like two beeps (of different durations). praat( "Play", input=FullPath("tone_zeroed.wav") ) # For commands with multiple arguments like the one above, you must provide *all* of the arguments. # Thus, you could NOT use 'list(0.1,0.2)' and expect that Praat to use its default value for the third parameter. # In addition, the arguments must be in the correct order. # Thus, something like 'list( "at exactly these times", 0.1, 0.2 )' would not work. # To help remind you which argument is which, you can optionally name the items in your argument list (to anything as long as it conforms to R syntax). # For example, the following will do the same thing as the command above: praat( "Set part to zero...", arguments=list( TimeStart=0.1, TimeEnd=0.2, Cut="at exactly these times" ), input=FullPath("tone.wav"), output=FullPath("tone_zeroed.wav"), overwrite=TRUE) # Note, however, that these names are ignored by PraatR. # As such, be careful not to name your arguments and then put them in the wrong order. # Finally, due to how the details of how PraatR works, none of the arguments can... # - be an empty character string ("") # - contain a space (" "), or # - contain a sequence of two underscores ("__"). # For the majority of the things PraatR is normally used for, these restrictions will not matter. # They should only become relevant when working with TextGrids, in which case these restrictions would be something to keep in mind. ######################## # 11. 'Query' commands # ######################## # The final type of command supported in PraatR is a 'Query' command, which retrieves information about a file and brings it directly into R. # The following command tells us how long our 'tone.wav' soundfile is: praat( "Get total duration", input=FullPath("tone.wav") ) # [1] "0.4 seconds" # Depending on the command, non-numeric information may be included in the output (e.g. the units 'seconds' in the above example). # To trim off everything but the core numeric information, specify simplify=TRUE: praat("Get total duration", input=FullPath("tone.wav"), simplify=TRUE ) # [1] "0.4" # Query commands always bring information into R as a character string. # This is true even for the second version above, with 'simplify=TRUE'. # To save and work with this information, you simply need to pass the result to as.numeric(), as in the following: as.numeric( praat("Get total duration", input=FullPath("tone.wav"), simplify=TRUE ) ) # [1] 0.4 # The fact the result lacks the quotes indicates that it is numeric. # This can then be stored in a variable and manipulated further. ########################## # 12. Order of arguments # ########################## # Recall from above that all of the arguments to praat() should be explicitly labeled (arguments=..., input=..., etc.) with the sole exception of 'command'. # If you omit these labels, you will need to follow the following default order of arguments: # [command, arguments, input, output, overwrite, filetype, simplify]. # Take, for example, the following command, which returns the timestamp of the 100th sample in the waveform. # Instead of labeling all the arguments like this... praat( "Get time from sample number...", arguments=list(100), input=FullPath("tone.wav") ) # ...you can safely omit them like this: praat( "Get time from sample number...", list(100), FullPath("tone.wav") ) # PraatR will assume you are using the default order of arguments, [command, arguments, input], and successfully execute the command. # Nonetheless, it is probably best to always label the arguments. # One advantage is that doing so lets you provide the arguments in whatever order you like. # Thus, the following will also work, where 'input' and 'arguments' have been switched: praat( "Get time from sample number...", input=FullPath("tone.wav"), arguments=list(100) ) # Labeling the arguments can also help prevent coding errors. # For example, if you omit 'input=' in a 'Play' command, it will not work, since praat() is expecting 'arguments' to be in the second position. praat( "Play", FullPath("tone.wav") ) # In order for it to work, you need to either add in an empty list... praat( "Play", list(NULL), FullPath("tone.wav") ) # ...or add in the label 'input=': praat( "Play", input=FullPath("tone.wav") ) ########################## # 13. Supported commands # ########################## # At present, PraatR can process 100 of Praat's different object classes. # To these, 972 different commands can be applied, for a total of 2163 unique object-command combinations. # All of these are listed on the 'Supported Commands' page of the PraatR website: # http://www.aaronalbin.com/praatr/commands.html # Let's say you want to take a soundfile and create a Spectrum object from it (like we did up above in the section "Specifying a single argument"). # To find out how to do this, you would first search through the alphabetical 'table of contents' at the top for the object class you are starting from. # In this case, since our desired operation begins with a soundfile, we would locate the word 'Sound'. # When you click on the link, you jump to a table of all possible commands that can be applied to a 'Sound' object. # Along the left-hand side of the table, the different commands are classified as 'Create', 'Modify', 'Play', or 'Query' (in that order). # Here, we are interested in a 'Create' command. # Then, look through the relevant rows for the command you are interested in - here, "To Spectrum...". # The next column gives you an example of what the arguments list would look like - here, 'list("yes")'. # The last column lists any available special output filetypes for that command - here, none. # The entire Supported Commands database is stored inside the PraatR package. # Every time you use praat(), the command you supply will be checked against this database. # If the command is not recognized by PraatR, an error message will alert you to the problem. # The supplied command name must match the database exactly. # As such, make sure the capitalization and punctuation match verbatim. # In particular, make sure to double-check whether the command's name ends with an ellipsis ("..."). # (Generally speaking, any command that requires arguments will end with an ellipsis.) # The following will not work because the ellipsis has been omitted. praat( "Get time from sample number", arguments=list(100), input=FullPath("tone.wav") ) ################## # 14. Conclusion # ################## # This concludes the tour of PraatR's basic functionality. # As with most other R functions, you can retrieve a help file for praat() by typing one of the following at the R console: ?praat help("praat") # The help file provides a brief summary about how each argument works. # If you ever forget a detail about how PraatR works, rather than digging back through this tutorial, you may find it convenient to check there to refresh your memory. ############################################### # 15. Example of a real application of PraatR # ############################################### # This tutorial has focused on demonstrating the full range of PraatR's functionality. # However, the actual analyses performed above were not particularly useful ones for speech scientists. # To see an example of how PraatR can be used in one common analysis task (formant extraction and analysis), download and work through this Example Application script: # http://www.aaronalbin.com/praatr/ExampleApplication.r