Praat notes

From Helpful
Jump to navigation Jump to search

Language units large and small

Marked forms of words - Inflection, Derivation, Declension, Conjugation · Diminutive, Augmentative

Groups and categories and properties of words - Syntactic and lexical categories · Grammatical cases · Correlatives · Expletives · Adjuncts

Words and meaning - Morphology · Lexicology · Semiotics · Onomasiology · Figures of speech, expressions, phraseology, etc. · Word similarity · Ambiguity · Modality ·

Segment function, interaction, reference - Clitics · Apposition· Parataxis, Hypotaxis· Attributive· Binding · Coordinations · Word and concept reference

Sentence structure and style - Agreement · Ellipsis· Hedging

Phonology - Articulation · Formants· Prosody · Sound change · Intonation, stress, focus · Diphones · Intervocalic · Glottal stop · Vowel_diagrams · Elision · Ablaut_and_umlaut · Phonics

Analyses, models, processing, software - Minimal pairs · Concordances · Linguistics software · Some_relatively_basic_text_processing · Word embeddings · Semantic similarity ·· Speech processing · Praat notes

Unsorted - Contextualism · · Text summarization · Accent, Dialect, Language · Pidgin, Creole · Natural language typology · Writing_systems · Typography, orthography · Digraphs, ligatures, dipthongs · More linguistic terms and descriptions · Phonetic scripts


Initial Praat setup

Installing Praat

Praat is a single executable.

In principle, you can download it, put it wherever, and run it.


There is no data kept alongside it that can get lost -- because instead of that, your personal data goes into your specific user account instead. See #The_Praat_preferences_folder, except you often don't need to think about that until #Tweaking_and_extending_praat)

"The phonetic font is not available" (maybe optional)

Praat wants there to be a font that covers all IPA characters in Unicode, so it can show them when you annotate those.


Praat comes from a time where you likely needed to install the fonts called SIL Doulos and/or SIL Charis to get IPA characters to display.


These days there are other fonts that cover most of IPA already, so it may work without these fonts, and if it works without doing that, you can ignore the warning.

Yet it's not a guarantee, so Praat still plays safe and still complains if you don't have those fonts installed. If it doesn't work, or you just want it to be quiet, you could install those fonts. (See also: how to install fonts (in general))


Everyday Praat

How Praat thinks: The list

The main praat window, a.k.a. the object window, primarily shows you the list of objects.


Things become objects in that lest when you

  • record sound (see New menu)
  • load files
  • create new list items based on existing list items (via some action or command)


You would be forgiven to think this is a project, where you can save the collection of everything you see.

You cannot. The list it will not be remembered between runs of Praat.

Instead, it is intended purely as scratch space. You can save items on the list, but not save the list itself.


Objects and object combinations

We often work thinking in terms of Objects - the things already in the main window's list.

A Sound is an object that contains audio.
A TextGrid is an object that contains text over time.
...and so on


For many objects, when you select just that object, you will get a View & Edit button.

That button would open a window for it to, well, view and possibly edit it.
e.g. try View & Edit on a Sound


Also, specific combinations of objects

  • brings up some specific new buttons
  • hides buttons that do not apply to this combination

For example, select a Sound 'and a TextGrid.

You will now get a View & Edit that is different: it happens to combines the sound view and the textgrid view -- meant for annotating sounds
and yes, it allows you to do that for any Sound-Textgrid combination, but it only makes sense when they are related, e.g. when you created such a TextGrid from the Sound:
select the Sound, then click AnnotateTo Textgrid...


Notes:

  • Sometimes nothing makes sense for the combination you have selected
  • There are also hints -- e.g. when you select only a TextGrid, there is a button named View & Edit with Sound? which, if clicked, just tells you to select both.
there are many possible combinations not hinted at -- just some of the most common ones

Object types

There are quite a few object types.

Many of which you may never use.

You do not need to know this yes -- you'll learn them as you use them -- but roughly in order of how quickly you will probably see or need it:


Some more commonly used object types:

Sound
Sound object, View and Edit window
waveform
typically mono, but can be multi-channel
(PCM data, though you don't often get its values directly)
View & Edit shows waveform and spectrogram
as the legend hints:
blue trace is pitch (note it's on a different Y axes from the shown spectrogram, because it'd otherwise be at the bottom)
red dots are formant places
green/yellow is intensity
pulses are shown in the waveform
https://www.fon.hum.uva.nl/praat/manual/Sound.html

There is also a LongSound[1], for things that won't necessarily fit in fast memory, but this is usually no concern these day


TextGrid
TextGrid, here with only interval tiers (none of them phonetic)
There is a specific editor for showing a combination of Sound and TextGrid, which makes a lot of sense while manually annotating (select both objects, then View & Edit)
lets you annotate text
usually shown together with the Sound it is annotating
either annotating text with
a time range - start and end time
a point in time
https://www.fon.hum.uva.nl/praat/manual/TextGrid.html


Strings
ordered list of strings
https://www.fon.hum.uva.nl/praat/manual/Strings.html
Table

Table[2]

Matrix

Matrix[3]


Pitch
Pitch
periodicity candidates over time, with relative certainty
in regularly spaced frames (...unlike the evidence it draws from - so each frame's estimate may come from varying amount of pulses. Pitch objects show it regular, PitchTiers do not(verify))
may be analyzed separately, from Sound objects; there are varied methods (the one shown here is intentionally a messier variant)
https://www.fon.hum.uva.nl/praat/manual/Pitch.html


PitchTier
PitchTier
basically a set of (timestamp, pitch_in_hz)
probably extracted via a Manipulation object
Praat itself, if asked about pitch at a point, interpolates between these points (and extends outwards before the first and after the last value)
can also be altered (and drawn) to resynthesize LPC/PSOLA type things with different vocal pitch
https://www.fon.hum.uva.nl/praat/manual/PitchTier.html


Manipulation
Manipulation
LPC/PSOLA style speech analysis of Sound object (a specific model which happens to e.g. separate pitch, duration)
View & Edit shows
pulses (if you extract this, it becomes a PointProcess)
estimated pitch (extracted as PitchTier)
duration (extracted as DurationTier)
contains a little more
in particular the original Sound, e.g. for comparison's sake
https://www.fon.hum.uva.nl/praat/manual/Manipulation.html


More specific and/or lesser-used object types

Window grouping

The praat picture window

Picture window (without anything drawn)

Mainly used for making plots from data.

which can then be saved as raster (PNG) or vector (EPS, PDF).


You won't need this until you do, so can close it.

  • I've seen people making startup scripts to immediately close it
  • You can also start Praat with --hide-picture (which seems to do the same)


Automation and scripting

As hinted at above, you can automate Praat.

  • The most basic form of this is to
do what you want to automate in the graphical interface (which Praat itself records as commands),
tell it to paste that sequence of things into a script.
That script is now equivalent to that series of graphical interface interactions, like a recipe that should be repeated exactly.
  • On top of that, there is a scripting language that lets you write more complex thing in.

For more on both, see #Praat_scripting_notes below.


Common tasks

Recording sound

Usually: NewRecord Mono Sound

You can record one or more fragments, and Save it to the List.


💤 Why Mono?

Most microphones are mono, and a lot of sound analysis works on mono.

Stereo has directional effects when you listen to both at once. This absolutely has its uses -- in particular, if you are recording less for sound analysis, and more for a person to transcribe it to text later, know that a lifetime of having two ears makes people decent at separating multiple voices from any sound recorded in any vaguely spatial way. This is part of why many portable recorders have two mics mounted on them.

Also, it is good science to only vary the things you intend to study, and stereo effects can boost or suppress frequencies, and will sound different in speaker versus headphones, and other such details. This is easily overstated, as the comb/filtering effects usually amount to at most a few decibels, but mono will make your life slightly simpler, so is generally preferred.


"Recording interfaces tend to have two input channels. What happens when you ask for mono?"

Turns out this depends on the driver/sound system and the recording software. You may just get the first/left, you may get a mix of both, Praat in the cross-OS sense cannot guarantee just one, so be sure to turn down any channels you are not using, to avoid their noise.


Big aside: On levels/gain, noise, and scaling

tl;dr:

  • Praat scales spectrogram intensities and waveform amplitudes to whatever is loudest
great for visibility of what is there
bad for an indication of actual levels
not great for an indication of present noise


🛈 To set up reasonable recording levels, before you hit record (and note this should be similar to any "gain staging in 5 minutes" intro)

Hit record in Praat, tell your subject to talk at reasonably loud levels, and look at the green/yellow/red indicator

A signal so loud it distorted: This "flat against the floor (and ceiling, out of view)" is digital clipping, and implies significant signal distortion. You want to avoid that, by keeping the maximum amplitude well under the maximum

If

  • it doesnt move, increase the input/mic sensitivity until it does
  • if it barely noves, probably still increase it a little more
  • it frequently gets into yellow, probably also lower it a bit
  • it goes into the red, certainly lower it because it's going to distort
  • for a quick setup, the aim is to get it to be middling, not to get it to be the loudest (in that this way you're leaving space for people to be a little louder than planned, without it necessarily distorting)

A little more technically: this scale is linear with pressure (not logarithmic/decibel as many other things do).

This means half the meter is -6dB below the max, quarter is -12dB, and (at the regular window size) ten pixels is -30dB, and one pixel is -50dB

💤 This puts levels into the right order, but isn't perfect advice

Aside from hardware reasons, also very pragmatic details such as people focusing on a test, then comfortably re-settling (further away) for the real thing.

So when doing serious recording, consider starting with a sanity check: make a quick recording and listen to it (headphones are often better than speakers), and check the waveform for flat, clipped tops.

...because one annoying footnote is sometimes, some part of the chain reduces volume -- and might do so after clipping has happened.

  • This is annoying in that it invalidates simple "red means bad, below is all good" advice, and gives you one more thing to check
  • If you can't get Praat to extend over roughly halfway no matter what you do, then maybe something in your setup is trying to be smart ...after the signal had already distorted. The only way to be entirely sure is to record something very loud (e.g. blow into the mic) and inspect whether the waveform clips.


💤 "Why do recording levels matter?"

Mainly because whenever your recording levels were much lower than they could be, the noise is higher.

If this comes from a limitation of hardware or situation, so be it - work with what you have.

If this can be improved by your attention and turning one knob before hitting record time, it is worth that attention.


Same sound, same microphone model, with different input gain. Note that:
- All four of these sections apply helpful scaling -- meaning none of them compare directly.
- if there is stronger difference between signal and background noise, Praat can more easily ignore it in analysis

When Praat visualizes audio, as a waveform or as a spectrogram, it will scale up whatever you already recorded. Praat effectively hides this difference.

Which is great in that once you have settled your recording, then you will always see a waveform and spectrogram with whatever is the strongest signal, regardless of exactly how strong it is.

But which is terrible in that these displays become a bad way to judge how strong or noisy a recording is, and whether you might want to re-record it.


💤 "But why do low levels make it noisy?"

In a perfect world, it wouldn't. But even the fanciest of recorders have an imperfection we call a 'noise floor': noise that is always there, and at a fixed level, no matter what you do.

Very quiet, but still there.

We can talk about engineering details of how and why all day, but much more practically: The moment you press "record" you accepted that blend of input signal and noise. While you can amplify what you have afterwards, that noise comes up right along with the signal -- noise is by nature inseparable.

It turns out that because this floor happens to be fixed, you can make it less relevant before hitting record: Your job is to ensure that microphone's level is well above that noise floor before it is digitised -- but not so high that the signal distorts (It's actually even more complex than that. Audio nerds get the gritty details sort of wrong all the time, but for a given setup, doing the bet you can is fairly easy)

The image on the right has two recordings of the same sound (two identical mics, same recording interface), but one had approximately 45dB less input gain.

What is clearly clearly signal in one, starts falling into the background noise in the other. This recording is actually still viable, but it is recognizably noisier, and the analysis is starting to get distracted by the noise.


...but as mentioned, Praat's "let's do the best with what you have" stance ends up putting wildly different scaling on all these waveform and spectrogram views.



💤 Another angle to illustrate the "praat shows you something regardless of how loud it actually is" effect, to yourself
two taps
  • record some gentle taps on the microphone but otherwise be quiet.
  • View & Edit the sound
you should see only the taps, and an otherwise quiet waveform
  • remove the taps from the sound: select with mouse, SoundSet selection to zero
it will suddenly show loud everywhere that isn't the zeroed-out reasons
Sound view which shows whatever is the full range in the current view
Sound view which shows whatever is the full range in the current view
  • undo that, then go to SoundSound Scaling, and in particular compare 'by whole' (the default) and 'fixed range'
    • 'by whole' (the detault) - looks for the loudest sample in the whole sound
    • 'by window' - looks for the loudest part within the currentlyzoomed area (if stereo: max of both channels)
    • 'by window and channel' - by maximum used range (if stereo: individually)
    • 'fixed height' - seems to be "amount around calculated average", (so if you say 2 you basically see the whole thing - but might hide a DC offset - not that you generally care about that)
    • 'fixed range' - seems to be "give min and max (average implied)", (so if you say -1 and 1, you see the whole thing)

If you set SoundSound Scaling to "by window", and then scroll around, you will get an effect like the image on the right: no matter how quiet, it will show it in full view. If you move around, it will change the scale as you scroll. The spectrogram does something similar, though is configured separately.


Viewing your recording

Sound object, View and Edit window

Select the Sound, press the View & Edit button.

More basic things you may want to do is zooming in and out, scrolling around, cutting pieces off the edge - mainly see the Edit and Time menus (and maybe learn the keyboard shortcuts)

The green, blue, and red lines and dots on the spectrogram are basic analysis of speech intensity, pitch, and formants.


💤 The spectrogram is already tuned to show voices. You usually don't need to tweak this, but if you care to know what this is:


Spectrogram → Spectrogram settings

View Range - Normally 0Hz to 5kHz (even when you recorded more) - there's almost nothing interesting to show speech-wise above that, and zooming down to this range makes the pitch movement more visible.
Window length is about the tradeoff between frequency resolution and time resolution (read up on STFT if you care). The default (0.005s) is a good tradeoff for many tasks.

Higher (0.015s) may sometimes make e.g. separate formants more visible -- yet makes them harder to place in time precisely.

Dynamic range as a concept relates the loudest to the softest levels. Here, it means "Praat determines the maximum in a recording, and this settles how much lower considered quiet enough to not be worth showing". The default 70dB usually shows most signal and some of the background noise, lowering to 50 will remove noise but also quieter signal, 30 does so fairly aggressively.


Spectrogram → Spectrogram advanced settings

Maximum is the energy level (you can ignore the units) to treat as the loudest to show (black). By default this field is ignored, because autoscaling handles this (...within a zoom level, so scrolling will make it vary - if you want to inspect in detail, you might care to turn off autoscaling).
Pre-emphasis considers that the loudness of speech's components (vowels mostly) typically falls approximately -6 dB per increasing octave. If we amplify higher frequencies, just for the visualisation, we can show a wider frequency range with roughly equal visibility. The default is +6dB per octave. Higher than that puts more focus on higher sounds. (identity-gain point at 1000 Hz?)
Dynamic compression you can think of as someone turning up a volume knob whenever the recording gets quiet.
this has use if, say, one speaker is significantly quieter than another; chances this will put them at more similar levels
but if you have strong recordings already, all this really does is around the silences between words - i.e. taking the background noise and making it louder.
The setting is a fraction, how much to amplify any part towards the level of everything else. You rarely want to make this higher than 0.5 or so (because that's often around 20dB).


https://www.fon.hum.uva.nl/praat/manual/Advanced_spectrogram_settings___.html

Annotating your recording

Create a TextGrid to put useful things on

To create an empty TextGrid of the same length as a given Sound:

  • Select Sound
  • Find the Button: AnnotateTo TextGrid

You can always add tiers later, so you might start with just one:

All tier names:                  MyName
Which of these are point tiers:  


💤 Those default values have a specific plan. If you want to understand what that means...
All tier names:                  Mary John bell
Which of these are point tiers:  bell

...actually mean, read on:


You can have multiple, independent 'tracks' of information, called tiers. Having is very useful when there distinct things worth noting, e.g. what one speaker says as plain , what another speaker says as plain text, and a beep that they use to alternate speaking. (And later probably also one speaker's phonetic transcription, another's transcription, and so on)


Some of those pieces of information are marked as taking some time (e.g. each word), and sometimes we mark things that are a point in time (e.g. the beep/bell), which is why each tier can be either an

  • interval tier
consists of segments that always covers the whole recording (but many are unlabeled and thereby considered empty)
inserting something at a time will split the segment that is currently there into two
you can optionally label each segment (you might e.g. start by marking the silences)
you can select the segments
  • point tier (sometimes 'text tier')
inserting a point adds a specific points in time
you can optionally label each point
you can select the labels


Now that we grasp that, let's say we know there are two people speaking in our recording, and a beep at the start of each response.

Now look at that form again.

  • Tier names - space-separated list. Settles the amount of tiers and their tiers at the same time
  • Which of these are point tiers? - repeat the names of tiers you want to be point tiers. Any not mentioned will become interval tiers

And we can figure that:

All tier names:                  Mary John bell
Which of these are point tiers:  bell

actually means:

create Mary as an interval tier
create John as an interval tier
create bell as a point tier

Editing TextGrid

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

If you did the above, you have a Sound and a TextGrid of the same time length.


Viewing and editing:

  • zooming (CtrlI and CtrlO)
  • scrolling (PgUp and PgDn) (...if not zoomed out to be looking at everything)


Editing those annotations

Once it it your task to do more than a little annotation work, it helps to get comfortable with Praat key shortcuts.


A mix of keyboard and mouse seems to be most convenient in that you can click in waveform or spectrogram:

  • mouse-click chooses a point in time,
  • mouse-drag lets you move an interval or point

...you can do a lot with keyboard only.

See the menu, but some if it includes:

  • The selection is a not-yet recorded interval which can be useful
    • Up and Down to move the whole thing left or right
    • ShiftUp and ShiftDown to move its start
    • CtrlUp anbd CtrlDown to move its start
    • ...or, in a point tier, you just move a single point, which you can make a real marker with Enter
  • AltUp and AltDown base selection on previous or next interval/point in tier
  • and then
    • Enter to split in current tier
      • in an interval tier, we split the current interval at selection start and end (whichever didn't exist already, and can't split two at once)
      • in a point tier, makes point at current position
    • Ctrl1, Ctrl2 - like Enter, but in specific/other tiers - first tier, second tier, etc...


  • Altbackspace - remove point / merge interval with previous

Other views/editors

Pitch editor

https://www.fon.hum.uva.nl/praat/manual/PitchEditor.html

How do I...

How do I shorten the length of a textgrid?

Less everyday

What are pulses

Praat scripting notes

Starting from history mechanism

A note on syntax changes

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Praat's scripting language has seen changes over the last decades (mostly shifts around the early 2000s and 2010s; since 2015ish or so it has been quite stable), both to add features, but also alter things to increase consistency.

In general, you will probably be happier writing your scripts in the newer style (and scripts generated from history will do this automatically), and the documentation will primarily mention the new style.

...there are many scripts and various tutorials out there written for the older style - or some mix, and because Praat cares specifically about not breaking old scripts, it tends to leaves in whatever old behaviour doesn't conflict with new behaviour.

This is great for old scripts -- but also leads to confusion.


Point is, if you find examples that are not written like you have learned, this is probably the reason.

And if they do not work at all, that is often not your fault -- though it should be pointed out that Praat cares about backwards compatibility a lot, to not break older scripts. Which is exactly why older style still tend to work perfectly fine.

And once you dig into scripting more, you may wish to know about these changes to be able to understand scripts and/or rewrite them.


On ..., :, and nothing

single quotes

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Older scripting styles relied more heavily on single quotes (') to do variable substitution and more - basically meaning "don't just hand along the variable, act as if its contents are right here".

Say, if tier is a numeric value containing 1, then

tierNames'tier'$ = "test"

is entirely equivalent to writing

tierNames1$ = "test"


In fact, that particular case let us imitate a dictionary(/associative array) before Praat introduced its own, in that you could do:

for tier from 1 to 5
  tierNames'tier'$ = "test"
endfor
appendInfoLine( tierNames3$ )

In modern praat, we have the functionally equivalent, and somewhat easier to explain:

for tier from 1 to 5
  tierNames$[tier] = "test"
endfor
appendInfoLine( tierNames$[3] )


In modern praat, singlequotes are still there, but you often just see them pasting together strings, e.g.

"'temporaryDirectory$'\test.txt"

but note that this usually is equivalent to a "add strings together" style

temporaryDirectory$+"\test.txt"

Since you can usually do something equivalent, and similarly readable, you don't need them, and if they seem confusing, you can probably avoid them completely.

Deprecated commands

There are some newer commands, where older ones still work (to not break old scripts), but are no longer documented (to not encourage use anymore)

For example appendFile, deleteFile replacing the older fileappend, filedelete (which had some confusing variants)


Data types and structures

Basic types

There are two basic types:


string

variable names that end with a $ are strings, e.g. test$ = "foo"
Strings meant literally should be in doublequotes (") (singlequotes are also a thing, but mean something else that you probably can avoid completely in modern praat)


numeric

floating point (double precision)
variable with no symbol at the end can be numeric, e.g. test = 4 (or object; see also #Also_reference-able)
(there is no integer type, but due to the way floating point works, integers store fine up to a very large number)

Structures involving basic types

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

array structures

you can mix numeric and string in a single array (yet it is usually less confusing to have it contain just one type)
for i from 1 to 3
  square [i] = i * i
endfor
note that for numeric things, you may prefer vector. (one reason is that the above seems implemented using an associative array, not a list. That is, it in essence declared the three variables square[1], square[2], square[3], and square does not exist. Or rather it can, as a different, unrelated (numeric) variable)


dictionary/hash structures

which praat seems to consider as pretty similar to arrays, but
which allows strings for indexing instead of numbers
created via individual assignment (lists)
age ["John"] = 36
age ["Babs"] = 39


numeric vectors

numeric-only, with a fixed size (that you can fetch with size())
variables that end with a # are (numeric) vectors; functions that end with # return them
can create e.g. with zero# (10) or e.g. some random numbers


string vectors

string-only, with a fixed size (that you can fetch with size())
variables that end with a $# are string vectors vectors, functions that end with $# return them
can create e.g. with empty$# (10)
probably less useful and common than numeric vectors


matrices

two-indexed array of numbers, often thought of as a 2D thing, like a table but that may only contain numbers.
variables ending with ## are treated with matrices
can create e.g. with zero## (3,3)
size cannot be fetched, you have to remember it (verify)


See also:

Also reference-able

String operations

Type conversion and formatting

More on vectors

String vectors

More on matrices

On paths

Control, and reuse

Conditions

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


 if i < 20  and  word$ = "STIM"
   ; do this
 elsif i = 20  and  not word$ = "STIM"
   ; do that
 else
   ; do this
 endif

For numbers: Operators:

a < b   less than 
a > b   greater than 
a <= b  less than or equal 
a >= b  greater than or equal
a = b   equal   (== also works, meant for programmers with that habit)
a <> b  not equal

For strings,

equal is "same string", not equal is "not same string"
the others basically answer questions like "if I were to sort these in a per-charcter alphabetic list, would it come before or after"
e.g. a$ < b$ will tell you if a would precede b
e.g. a$ >= b$ will tell you if a would come after b or is the same value.


you can use and, or, and not

If you use more than one and/or, and do not immediately understand what operator precedence is, it is recommended you use brackets to make it unambiguous to you and to praat which grouping/order of evaluation you intend.

For example, you would write

(a or b) and c
; or
a or (b and c)
; ...instead of 
a or b and c

Repeating things - for, while, and repeat

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

To repeat for all numbers in a series you can use for:

numFiles = 10    ; often actually read out from somwhere
for n from 1 to numFiles
  appendInfoLine: n
endfor


Often more flexibly, you can repeat until a condition is met. There is both:

Loops made from while and repeat (...and note that the only real difference between these two is that repeat always does it at least once (because its condition is at the end, not the start), and while wouldn't)

repeat
  [statements]
until [condition]

and

while [condition]
  [statements]
endwhile


Example: numbers with steps

n = 1
repeat
  appendInfoLine: n
  n = n + 2
until n > 10

or

n = 10
while n >= 0
  appendInfoLine: n
  n = n - 3           ; or, slightly shorter: n -= 3
endwhile


Slightly more interesting example(from docs): "roll two six-sided sice until it's two sixes, counting how many rolls that took":

throws = 0
repeat
  eyes = randomInteger(1, 6) + randomInteger(1, 6) 
  throws = throws + 1
until eyes = 12
writeInfoLine: "It took me ", throws, " trials to throw 12 with two dice."


A slightly more applied example: "on an assumed-to-be-interval tier (here 2, you might make it a parameter), given a start position (here 1), keep looking at the next interval until the interval's label is a period", intended as a "skip to end of sentence"

tiernum = 2
i = 1
repeat
  label$ = Get label of interval: tiernum, i
  appendInfoLine(label$)
  i = i + 1 
until label$ = "."


See also:

built-in functions

You may find use in some of the built-in functions

Callings things

Functions

Is there a list?

"Is there a list of commands?"

Sort of.


As to functions, most helper functions are listed here

...but there are a bunch of further that exist, and are only mentioned in a "relevant to only this part" way (TODO: examples)



As to commands, menu item or object based, are listed in the documentation. (Not always equally helpfully -- say, the documentation for Create Sound as pure tone doesn't tell you about the parameters, but they're obvious if you run it from the UI once (in NewSound)


For menu commands, there is PraatSettingsButtons.

this lists all visible menu items
this lists menu commands that are hidden (currently, which starts with those that are hidden by default until you start editing this)
this also has all your custom additions

However, as mentioned in the : and ... section there are only mostly, not fully the same

(more technically: this is the combination of Praat's default state, plus whatever your Buttons file changes)


For actions commands on Objects, pretty much everything you can do is in the buttons.

Say, how would you know know how to find the label in a tier?

You would know to look under Query that appears when you select any TextGrid - and e.g. this page lists most of what can appear there, based on the type of object
It may not be immediatelly clear that for interval tier it's Get label of interval and for point tiers it's the combination of Get nearest index from and Get label of point, but you'll probably manage.

There isn't a single list of just every one of these that exists, though(verify)


Notes:

  • Some commands will, when not assigned, output to the info window.
this is mainly for historical reasons, such as testing that same thing via the UI.


As just mentioned, there are commands that are not anywhere in the UI (hidden commands)

This seems to be done for a mix of reasons, such as

  • some things intended to be used by startup scripts, e.g. add/show/hide commands.
  • backwards compatibility
For example, there are now six specific "To Pitch (methodname)..." flavours in the UI which map to same-named column commands, but there is a "To Pitch:" that is hidden because today you would use a specific method, but it's kept around to not break old scripts.(verify)
  • not clutter with rarely used things

To see which of the registered actions are shown or hidden, go FileSettingButtons

-->

Procedures

Defining procedures

Try something like:

procedure getFormants: formantNum
  ; get formant Hz value at equally spaced points (timewise)
  steps = 10
  start = 0.1         ; try to avoid undefined at the start
  dur = Get end time
  dur = dur - 0.2     ; try to avoid undefined at the end (0.1 from start + 0.1 from end)
  # get formants at each timewise quartile (including start and end)
  for f from 0 to steps
    val = Get value at time: formantNum, start + f*(dur/steps), "hertz", "Linear"
    appendInfoLine: formantNum, tab$, fixed$(start + f*(dur/steps), 3), tab$, fixed$(val, 2), tab$
  endfor
endproc

Assuming you've created a Formant object from a Sound object, you can now:

clearinfo
appendInfoLine: "frmnt#", tab$, "time" , tab$, "Hz", tab$
@getFormants: 1
@getFormants: 2
@getFormants: 3
@getFormants: 4

(in a real example, you might make more of those things parameters to make the procedure more flexible)



"Do I have to pass arguments?"

Consider the difference between:

procedure playChromatic
   semi_mult = 2^(1/12)
   freq = frequency
   for i in 0 to 12
       freq *= semi_mult
       Create Sound as pure tone: "note", 1, 0, 0.2, 44100, freq, 0.2, 0.01, 0.01
       Play
       Remove
   endfor
endproc

frequency = 440
@playChromatic

frequency = 416
@playChromatic
procedure playChromatic: frequency
   semi_mult = 2^(1/12)
   freq = frequency
   for i in 0 to 12
       freq *= semi_mult
       Create Sound as pure tone: "note", 1, 0, 0.2, 44100, freq, 0.2, 0.01, 0.01
       Play
       Remove
   endfor
endproc

@playChromatic: 440

@playChromatic: 416

Since variables are available everywhere anyway, frequency is also available to it in the first example.

So there is very little functional difference -- it's just that the second makes it a lot clearer which variables are relevant to that procedure call.


For the same "available everywhere" reason, it is easy to leave a variable altered, not like you found it. The freq = frequency specifically copies the value into another variable (even better would be a local variable, as explained below), to avoid altering the first. Say, had we written it like:

procedure playChromatic
   semi_mult = 2^(1/12)
   for i in 0 to 12
       frequency *= semi_mult
       Create Sound as pure tone: "note", 1, 0, 0.2, 44100, freq, 0.2, 0.01, 0.01
       Play
       Remove
   endfor
endproc

frequency = 440
@playChromatic

...then a writeInfoLine( frequency ) after all that would write 880 (plus rounding error), not 440.


-->

Returning stuff?

On scope, and returning, and including

External things

Forms (and script parameters)

Here there is a choice of "do we explain from the perspective of how you use it" or "do we explain it from how praat thinks about it", because both are potentially useful, but they are different stories.


Script form

Script pause

either way: describing individual items

Those lines inside form or beginPause will specify:

  • the field name
controls what is shown
controls what the variable will be called
  • field type
controls the type that is stored
may further restrict that value
  • default value



Field types

Returns string:

word     - string without spaces
sentence - string with spaces
text     - string with spaces (full width with its label on a previous line)
infile
outfile
folder

Returns number

real     
positive    real > 0
integer
natural     integer >= 1

boolean
choice
option

Returns numeric vectors:

realvector
positivevector
integervector
naturalvector

Returns nothing:

comment


Aside from what they return, they also change the way the form presents each item.


The translation from the field name to the variable it will store in is something like:

  • seems to preserve only alphanumeric, and remove anything else (notably symbols)
  • underscores instead of spaces
  • lowercased the first letter (but none of the others)
  • removed final parenthesized parts (and spaces that leaves)


Most of them take two variables: variable name and a default value. Exceptions include option, and the vectors


If you want to see most of them at once, try:

 clearinfo
 
 beginPause:  "testing all"
   comment:   "only shown"
 
   real:      "rl",     "-1.2"
   positive:  "ps",     "1.2"
   integer:   "int",    "0"
   natural:   "nat",    "1"
 
   word:      "wrd",    "word"
   sentence:  "snt",    "sentence"
   text:      "txt",    "text"
 
   boolean:   "bl",     0
   choice:    "ch",     1
     option:  "one"
     option:  "two"
 
   optionmenu:    "om", 1
     option:  "one"
     option:  "two"
 
   infile:    "inf",    "in.txt"
   outfile:   "outf",   "out.txt"
   folder:    "fld",    "."
 
   realvector:     "rv", "(whitespace-separated)", "1 1.2 1.4"
 ; commented out because they're the same idea
 ; and would make the dialog very high:
 ;   positivevector: "pv", "(formula)",              "{1,2,3}"
 ;   integervector:  "iv", "(whitespace-separated)", "1,2,3"
 ;   naturalvector:  "nv", "(formula)",              "{1,2,3}"
 
 clicked = endPause: "No", "Button 2", "Yes", 3, 1
 
 
 appendInfoLine: "clicked: ", clicked
 appendInfoLine:  "" 
 appendInfoLine: rl 
 appendInfoLine: ps 
 appendInfoLine: int 
 appendInfoLine: nat 
 appendInfoLine:  "" 
 appendInfoLine: wrd$
 appendInfoLine: snt$
 appendInfoLine: txt$
 appendInfoLine:  "" 
 appendInfoLine: bl
 appendInfoLine: ch
 appendInfoLine:  "" 
 appendInfoLine: inf$
 appendInfoLine: outf$
 appendInfoLine: fld$
 appendInfoLine:  "" 
 appendInfoLine: rv#
; appendInfoLine: pv#
; appendInfoLine: iv#
; appendInfoLine: nv#




See also: https://www.fon.hum.uva.nl/praat/manual/Scripting_6_1__Arguments_to_the_script.html


runScript and forms

If you mention a form in a script, then aside from saying how to presenting a GUI window when run directly), it also defines the way it takes parameters (without a GUI window) if run by something else.

For example, if a script contains:

form FormTitle
  real: "x", "1.0"
  real: "y", "2.0"
endform
writeInfoLine: x + y

Then running it interactively will pop up that form, while a

runScript: "thatscript.praat", 1.0, 2.0

would put those arguments into x and y (because that is the order of declarations in that form), skip presenting the form, and run the rest of the script.


See also:

Other praat scripts

Differences between using procedures, forms, objects, and scripts

Objects, the list, and selections

Common functions and approaches

Processing a bunch of files

Writing cleaner scripts - style

Comment librally

Indent to guide the eye

Name things well

Avoid long lines

Files

Text files, short text files, binary files

Many data-style objects (including some cases you may never use, like Sound objects) have a structured representation that can be saved as

  • a text file
which contains a little more than necessary but is human-readable.
  • a short text file, which basically omits the variable names,
but is stable enough that parsers should have no trouble (no idea if there were breaking changes over time)
  • a binary format, which is a little more compact.


Some thing have futher forms, e.g.

  • PitchTier and DurationTier has
    • PitchTier/DurationTier Spreadsheet file (not unlike their short text form)
    • headerless spreadsheet file (basically TSV)


While the text formats look parseable by yourself, try to avoid that when it is easy because the format has changed. Praat will know how to handle that, but your or other's libraries may break over time.


Logging to the info window

We generally use appendInfo, appendInfoLine - add to window content, without or with going to the next line

useful if you want to build up a single line of output from distinct parts of your code


People may well clear the info window at the start of a script, often using clearinfo

(if scripts write out useful things to check later, clearing is not always ideal if you script may ever be called by other scripts, but you/others can worry about that at that time. For quick scripts it can keep the output clean, though.).


There is also writeInfo, writeInfoLine which 'replaces all info window content with this (again, without or with going to the next line)

(again, overwriting might be more annoying than useful for debug reasons)


You can hand in multiple things to be printed.

For example:

appendInfoLine: minimum, tab$, maximum

is equivalent to:

 appendInfo: minimum, tab$, maximum, newline$


See also:

Interactions outside of praat

Running Praat scripts from Praat

Praat running external commands

You running praat commands or praat scripts from the UI or CLI

Other things telling Praat to do things

Things that work on the same files, but do not interact

praatio

parselmouth

How do I use my scripts in praat?

Pointing buttons and menus at scripts

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

If you want

How do I get those every time I run Praat?

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.


Scripts run from other scripts?

}}

-->


More notes on extending praat

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

Because history can stand some disentangling

  • Manually adding a script in te GUI in a way that shows up in the buttons file
  • creating a plugin that contains your stuff


Also, let's try to avoid some relevant confusion.

  • This page tries to separate the term 'buttons' (to the right of the object list) from 'menu' (above)
but keep in mind Praat refers to the buttons to the right of the object lists as a "dynamic menu" (and the buttons to be part of that dynamic menu) (this seems to be part of a history of some confusing naming)
also note that "action command" is also used for the buttons (especially in that the way for plugins to add buttons is "Add action command")


  • Praat uses the term 'dynamic' to mean 'varies with the object selection', and 'fixed' to mean things that do not.
You might then think that 'dynamic' means 'is a button', and 'fixed' means 'is in the menus',
and yes, mostly -- except that (only) the Save menu is actually dynamic (and uses a different command to items to it).


Pointing buttons and menus at scripts

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

There are some commands that add menu items / action buttons.

Keeping in mind the menu/button and dynamic/fixed details:


Script command to register this UI-only near-equivalent where does it add comments
Add action command: Script window, File menu, Add to dynamic menu... -- but note this is permanent main praat window's buttons Button can be hidden or grayed out (see details below).
Add menu command: Script-window, File menu, Add to fixed menu... -- but note this is permanent Existing menus of the main praat window (or Picture window), menus of object-specific editor windows (for TextGrid, Sound, etc)(verify)


Example: Add action command

This article/section is a stub — some half-sorted notes, not necessarily checked, not necessarily correct. Feel free to ignore, or tell me about it.

For example, make a playreverse.praat containing:

;Play     ; remove comment for forward _and_ backward
Reverse   ; note this alters the existing sound
Play
Reverse   ; two reverses put it back to normal


Now, doing this to to a selection of multiple Sound objects might do something, but not what you intended, so you decide to require a selection of a single sound:

Add action command: "Sound", 1, "", 0, "", 0, "Reverse play", "Play", 0, "C:\path\to\that\playreverse.praat"

The "Play" in there is the argument for 'After command', which places that button more sensibly: after the existing "Play" button.


This



Example: Add menu command

For example, say we create simplersine.praat just to have fewer fields to fill in:

form: "Simpler sine"
  natural: "Hz", "220"
endform

# named variables help clarify what we're doing but aren't necessary
name$          = "sine_'hz'Hz"
channels       = 1
start_time     = 0
end_time       = 1
sine_frequency = 220
sample_rate    = 44100
Create Sound from formula: name$, channels, start_time, end_time, sample_rate, "1/2 * sin(2*pi*'hz'*x)"

Then we can add that like:

Add menu command: "Objects", "New", "Create SimplerSine...", "Sound", 1, "C:\path\to\that\simplersine.praat"

(that "Sound",1 tell it to go to the right menu. If we specified "", 0 it would go within New directly which works fine but is a little less organized)


The documentation describes those arguments as roughly:

  • Window - "Objects" or "Picture"
  • Menu
for Window="Objects", one of: "Praat", "New", "Open", "Help", (or "Goodies", "Settings", or "Technical", which are now positioned as submenus of Praat) menu (for Objects → Save menu, you need to use Add action command instead, because (only) this menu acually depends on the current selection)
for Windw="Picture", one of: the "File", "Edit", "Margins", "World", "Select", "Pen", "Font", or "Help".
  • Command - label for the menu item
(you can also add a separator instead of an actual menu item)
  • After command - lets you place it in relation to an existing menu item
  • Depth - lets you nest menus
  • Script - absolute path to the script to run

The Praat preferences folder

Praat's interface starts with some defaults, and can be altered and extended, in a way that is specific to your own user account, because that customization is stored in your own account.

The directory containing that configuration and plugins is at:

  • In Windows: %USERPROFILE%\Praat
  • In OSX: ~/Library/Preferences/Praat Prefs/
  • In Linux: ~/.praat-dir/


This contains:

  • Preferences file[4] (exact filename varies between operating systems)
mostly contains a whole bunch of defaults
  • Buttons file[5] (exact filename varies between operating systems)
Most Praat menu items and buttons are can be hidden (or shown if they are hidden by default), and this is stored here
You can register new buttons in a way that gets recorded here -- but a lot of the time, the plugin way is cleaner.


https://www.fon.hum.uva.nl/praat/manual/preferences_folder.html

Praat plugin notes

Praat plugin

At a lower level, if

...then that praat script will get run at Praat startup.

For example, if I put the following

beginPause: "This is an annoying window"
clicked = endPause: "Okay", "Well done", 2

...inside such a setup.praat, then I will get an annoying startup window every time I start Praat.


In most cases, that setup script only contains commands that add buttons and menus.

(pointing at specific praat scripts to run when clicked, that praat won't touch until you do)

The point would be that these get included at startup


See also:

Plugin manager?

Writing cleaner scripts - structure

Consider "return" values

Consider working on object copies

Fine tuning feedback

Giving useful error messages

Sometimes you expect to occasionally be asked weird things that could lead praat to complain.

You can either work around such a case, or just give a more useful error message, by testing for it.

For example, you can test for a thing you know would go wrong, and stop:

starting_time = 0.23
finishing_time = 0.2
if finishing_time <= starting_time
  ; stop just as hard as before, but now tell the user _why_
  exitScript: "The starting time (", starting_time, ") has to be before the finishing time (", finishing_time, ")"
  ; (alternatively, you could swap the values and continue)
endif

Checking absolutely everything may be more work than it's worth, but it's often worth if for the more likely mistakes (and for things that do weird things instead of failing).

On undefined

Numeric values can take one special value, that of undefined, and there are cases where

  • expressions would evaluate to something that is a problem, e.g. dividing by 0
  • commands would reasonably answer that,
e.g. you querying for values outside the timespan of the object
e.g. you asking for values only exist for parts, e.g. when you ask a Pitch object for mean frequency in a small timeslice where it did not detect any (e.g. Get mean: 0.0, 0.1, "Hertz")

Sometimes undefined is the sensible answer. Writing out a pitch over time as a table in 0.2sec freagments? Then yes, there are plenty of slices where there is no pitch, so it answering undefined (which prints out as --undefined--) is just correct (though if you're writing out a csv/tsv then maybe you want it to be numeric, e.g. 0 or -1, so that whatever you load that into won't complain)

In other cases, e.g. when you feed values into an expression, this is something it would soon trip over, and you might want to test specifically for undefined (which is itself a special value that you can directly compare against).

selectObject: "Pitch hallo"
meanPitch = Get mean: 0.0, 0.2, "Hertz"
if meanPitch = undefined
  ; complain about lack of initial pitch, or do nothing, or itentionally replace it with -1
else
  ; process as usual
endif


(programmers: it's NaN, though in binary files it might be written as infinity)


See also https://www.fon.hum.uva.nl/praat/manual/undefined.html

Removing feedback

While you generally want to see warnings and errors, if you are building a complex interface you might want it to not randomly pop up things.


Say, instead of

Remove

...which would fail if there is nothing to remove, you can write:

nocheck Remove


Instead of

Save as WAV file: "hello.wav"

...which might warn about clipping, you can suppress that warning by writing:

nowarn Save as WAV file: "hello.wav"


Instead of

pitch = To Pitch (raw cc): 0, 75, 600, 15, "no", 0.03, 0.45, 0.01, 0.35, 0.14

...which will pop up a progress window, however brief the work, you can write:

pitch = noprogress To Pitch (raw cc): 0, 75, 600, 15, "no", 0.03, 0.45, 0.01, 0.35, 0.14


https://www.fon.hum.uva.nl/praat/manual/Scripting_6_8__Messages_to_the_user.html

Writing portable scripts

Consider putting useful function in a file you can include

Debugging - when scripts don't do the right thing

You can stare at the entirety of your script for a long time, and not see what's wrong.


Instead, we recommend narrowing it down.

Chances are good that there is a a single step that does something you were not expecting - a variable (or file) will not contain what you think it should. Often, subsequent evaluation will still work, but probably on strange and meaningless values.

So you want the find the first occurence of weirdness.


This still involves some guesswork, but making it a puzzle is often a less frustrating approach.

Think of a particular variable whose value (or expression of values) might be a good indicator of something relevant and wrong. (this may take some experimenting, as the problem may not be exactly the one you hypothesized).

Now appendInfoLine that out.

At multiple spots, e.g. after every time a line alters its contents.

Just printing out a lot of things may feel dumb, but chances are that this will let you quickly narrow down the place it starts to go weird, and chances are the line right above that might lead you to an "ohhhhh."


💤 Consider a few assertions

If you found a problem, know it is very subtle, and anticipate it happening again when working on this script in the future, you could consider putting in little "please check my assumption about the value in this variable".

Assertions in general programming mean "if this evaluates as true, do nothing; if this evaluates as false, complain and stop" (in this case also testing for both false and undefined - see also notes on undefined).

Assertions are little typing. But they do not add a useful message. But they are fairly little typing.

Say, a sound shouldn't ever be completely zero, but if it is it might lead to some weird behaviour, can you can stop that right at the start:

power = Get power
assert power > 0


If you also want to test for either 0 or undefined (which can't happen for Get power(verify) but ignore that), it seems that you may need to write:

assert power != undefined and power > 0


Drawing

Technical notes

Praat and decibels

💤 For context

For almost any hardware recording setup, you cannot know the mic sensitivity sensitivities and all the applied gains and volumes, meaning that you can rarely relate a recorded sound to how the original absolute recording level in dB SPL.

You can only ensure it's at a reasonable level. And often do.


Praat seems to take the approach that "since you ensured a gain for a reasonable level, and that this is a recording of people talking, we're assuming it's at roughly this absolute level".

This is wrong almost by definition.

...but probably by at most 20dB in most voiced speech in most recordings.

Which makes it useful if you have a roughly sense for decibels SPL -- if it reports around 70dB you know it's probably talking, and if you see 30dB it's probably not.


But please be aware that as a result, any measurement (e.g. a third of a Sound's Query > menu) involving Pascals or decibels are somewhat wrong by default.

If you want to know what it corresponds to, you have to do a real-world measurement to correct it by. Using something that reports in absolute units, and in practice the only device you'll find that does so (has been calibrated against something absolute) is a sound pressure level meter (...most phone apps are wrong. Some only a little, but how could you tell?).


(other Praat fields pretend less - e.g. Annotate > To TextGrid (silences)... ask for a negative, "below maximum" dB (so dBFS). For you as the end user this is just as much guessing in the end, but when you gained to -10..-20dB, its default -25dB is not unreasonable, though a little lower may work better)



Plugin and toolkit examples

Praat 'toolkits' aren't really special, but we tend to call plugins that if they are a more interesting, coherent collection of tools.

...which may not always be installed as plugins, just "does a useful thing when you run this .praat"


Praat vocal toolkit

Praat Vocal Toolkit [6]



ProsodyPro notes

http://www.homepages.ucl.ac.uk/~uclyyix/ProsodyPro/

Not a plugin in the sense of 'adds buttons to the interface', more of a script that when run, initiates a semi-automated annotation.

Unsorted

Scripting exercise