praatio.praat_scripts API documentation

# praatio.praat_scripts

Python wrappers for various praat scripts contained in /praatScripts.

see examples/auto_segment_speech.py, examples/get_pitch_and_formants.py, klatt_resynthesis.py

View Source

      1"""
      2Python wrappers for various praat scripts contained in /praatScripts.
      3
      4see **examples/auto_segment_speech.py**, **examples/get_pitch_and_formants.py**,
      5**klatt_resynthesis.py**
      6"""
      7
      8import os
      9from os.path import join
     10import io
     11import csv
     12from typing import List, Optional, Tuple
     13
     14from praatio import audio
     15from praatio import data_points
     16from praatio.utilities import constants
     17from praatio.utilities import utils
     18
     19SILENCE_LABEL = "silent"
     20SOUND_LABEL = "sound"
     21
     22
     23def changeGender(
     24    praatEXE: str,
     25    wavFN: str,
     26    outputWavFN: str,
     27    pitchFloor: float,
     28    pitchCeiling: float,
     29    formantShiftRatio: float,
     30    pitchMedian: float = 0.0,
     31    pitchRange: float = 1.0,
     32    duration: float = 1.0,
     33    scriptFN: Optional[str] = None,
     34) -> None:
     35    """Changes the speech formants in a file using praat's change gender function
     36
     37    PitchMedian = 0.0; no change in median pitch
     38    PitchRange = 1.0; no change in pitch range
     39
     40    Uses the following praat command:
     41    https://www.fon.hum.uva.nl/praat/manual/Sound__Change_gender___.html
     42    """
     43    if scriptFN is None:
     44        scriptFN = join(utils.scriptsPath, "change_gender.praat")
     45
     46    #  Praat crashes on exit after resynthesis with a klattgrid
     47    utils.runPraatScript(
     48        praatEXE,
     49        scriptFN,
     50        [
     51            wavFN,
     52            outputWavFN,
     53            pitchFloor,
     54            pitchCeiling,
     55            formantShiftRatio,
     56            pitchMedian,
     57            pitchRange,
     58            duration,
     59        ],
     60    )
     61
     62
     63def changeIntensity(
     64    praatEXE: str,
     65    wavFN: str,
     66    outputWavFN: str,
     67    newIntensity: float,
     68    scriptFN: Optional[str] = None,
     69) -> None:
     70    """Changes the intensity of the wavFN (in db)
     71
     72    Uses the following praat command:
     73    https://www.fon.hum.uva.nl/praat/manual/Sound__Scale_intensity___.html
     74    """
     75    if scriptFN is None:
     76        scriptFN = join(utils.scriptsPath, "change_intensity.praat")
     77
     78    #  Praat crashes on exit after resynthesis with a klattgrid
     79    utils.runPraatScript(praatEXE, scriptFN, [wavFN, outputWavFN, newIntensity])
     80
     81
     82def getFormants(
     83    praatEXE: str,
     84    inputWavFN: str,
     85    outputTxtFN: str,
     86    maxFormant: float,
     87    stepSize: float = 0.01,
     88    window_length: float = 0.025,
     89    preemphasis: float = 50,
     90    scriptFN: Optional[str] = None,
     91    undefinedValue: Optional[str] = None,
     92) -> List:
     93    """Get F1, F2, and F3 for the audio file
     94
     95    maxFormant = 5500 for females, 5000 for males, <8000 for children
     96
     97    Uses the following praat command:
     98    https://www.fon.hum.uva.nl/praat/manual/Sound__To_Formant__burg____.html
     99    """
    100    if scriptFN is None:
    101        scriptFN = join(utils.scriptsPath, "get_formants.praat")
    102
    103    argList = [
    104        inputWavFN,
    105        outputTxtFN,
    106        stepSize,
    107        maxFormant,
    108        window_length,
    109        preemphasis,
    110        -1,
    111        -1,
    112    ]
    113    utils.runPraatScript(praatEXE, scriptFN, argList)
    114
    115    # Load the output
    116    path, fn = os.path.split(outputTxtFN)
    117    with open(os.path.join(path, fn), "r", encoding="utf-8") as fd:
    118        csvFile = csv.reader(fd)
    119        dataList = [row for row in csvFile]
    120
    121    # The new praat script includes a header
    122    if dataList[0][0] == "time":
    123        dataList = dataList[1:]
    124
    125    # Handle undefined values, convert values to float
    126    returnList = []
    127    for row in dataList:
    128        keep = True
    129        for i in range(1, 4):
    130            if "--" in row[i]:
    131                if undefinedValue is not None:
    132                    row[i] = undefinedValue
    133                else:
    134                    keep = False
    135                    break
    136
    137        if keep is True:
    138            returnList.append([float(val) for val in row])
    139
    140    return returnList
    141
    142
    143def getPulses(
    144    praatEXE: str,
    145    inputWavFN: str,
    146    outputPointTierFN: str,
    147    minPitch: float,
    148    maxPitch: float,
    149    scriptFN: Optional[str] = None,
    150) -> data_points.PointObject1D:
    151    """Gets the pitch/glottal pulses for an audio file.
    152
    153    Uses the following praat command:
    154    http://www.fon.hum.uva.nl/praat/manual/Sound___Pitch__To_PointProcess__peaks____.html
    155    """
    156    if scriptFN is None:
    157        scriptFN = join(utils.scriptsPath, "get_pulses.praat")
    158
    159    argList = [inputWavFN, outputPointTierFN, minPitch, maxPitch]
    160    utils.runPraatScript(praatEXE, scriptFN, argList)
    161
    162    # Load the output
    163    pointObj = data_points.open1DPointObject(outputPointTierFN)
    164
    165    return pointObj
    166
    167
    168def getSpectralInfo(
    169    praatEXE: str,
    170    inputWavFN: str,
    171    inputTGFN: str,
    172    outputCSVFN: str,
    173    tierName: str,
    174    spectralPower: int = 2,
    175    spectralMoment: int = 3,
    176    scriptFN: Optional[str] = None,
    177) -> Tuple[List, List]:
    178    """Extracts various spectral measures from an audio file
    179
    180    Measures include: center_of_gravity, standard_deviation
    181    skewness, kertosis, central_movement
    182
    183    Uses the following praat command:
    184    http://www.fon.hum.uva.nl/praat/manual/Spectrum.html
    185    """
    186    if scriptFN is None:
    187        scriptFN = join(utils.scriptsPath, "get_spectral_info.praat")
    188
    189    argList = [
    190        inputWavFN,
    191        inputTGFN,
    192        outputCSVFN,
    193        tierName,
    194        spectralPower,
    195        spectralMoment,
    196    ]
    197    utils.runPraatScript(praatEXE, scriptFN, argList)
    198
    199    # Load the output
    200    with io.open(outputCSVFN, "r", encoding="utf-8") as fd:
    201        data = fd.read()
    202
    203    dataList = data.rstrip().split("\n")
    204    dataListOfLists = [row.split(",") for row in dataList]
    205    titleRow, mainDataListOfLists = dataListOfLists[0], dataListOfLists[1:]
    206
    207    return titleRow, mainDataListOfLists
    208
    209
    210def resynthesizePitch(
    211    praatEXE: str,
    212    inputWavFN: str,
    213    pitchFN: str,
    214    outputWavFN: str,
    215    minPitch: float,
    216    maxPitch: float,
    217    scriptFN: Optional[str] = None,
    218    pointList: Optional[List] = None,
    219) -> None:
    220    """Resynthesizes the pitch in a wav file with the given pitch contour file
    221
    222    The pitch track to use can optionally be passed in as pointList.  If
    223    so, it will be saved as pitchFN for praat to be able to use.
    224
    225    Uses the following praat command:
    226    https://www.fon.hum.uva.nl/praat/manual/Manipulation.html
    227    """
    228    if scriptFN is None:
    229        scriptFN = join(utils.scriptsPath, "resynthesize_pitch.praat")
    230
    231    if pointList is not None:
    232        dur = audio.QueryWav(inputWavFN).duration
    233        pointObj = data_points.PointObject2D(
    234            pointList, constants.DataPointTypes.PITCH, 0, dur
    235        )
    236        pointObj.save(pitchFN)
    237
    238    utils.runPraatScript(
    239        praatEXE, scriptFN, [inputWavFN, pitchFN, outputWavFN, minPitch, maxPitch]
    240    )
    241
    242
    243def resynthesizeDuration(
    244    praatEXE: str,
    245    inputWavFN: str,
    246    durationTierFN: str,
    247    outputWavFN: str,
    248    minPitch: float,
    249    maxPitch: float,
    250    scriptFN: Optional[str] = None,
    251) -> None:
    252    """Resynthesizes the duration in a wav file with the given duration tier
    253
    254    Uses the following praat command:
    255    https://www.fon.hum.uva.nl/praat/manual/Manipulation.html
    256    """
    257    if scriptFN is None:
    258        scriptFN = join(utils.scriptsPath, "resynthesize_duration.praat")
    259
    260    utils.runPraatScript(
    261        praatEXE,
    262        scriptFN,
    263        [inputWavFN, durationTierFN, outputWavFN, minPitch, maxPitch],
    264    )
    265
    266
    267def annotateSilences(
    268    praatEXE: str,
    269    inputWavPath: str,
    270    outputTGPath: str,
    271    minPitch: float = 100,
    272    timeStep: float = 0.0,
    273    silenceThreshold: float = -25.0,
    274    minSilDur: float = 0.1,
    275    minSoundDur: float = 0.1,
    276    silentLabel: str = SILENCE_LABEL,
    277    soundLabel: str = SOUND_LABEL,
    278    scriptFN: Optional[str] = None,
    279) -> None:
    280    """Marks the silences and non-silences of an audio file
    281
    282    Uses the praat command:
    283    https://www.fon.hum.uva.nl/praat/manual/Sound__To_TextGrid__silences____.html
    284    """
    285    if scriptFN is None:
    286        scriptFN = join(utils.scriptsPath, "annotate_silences.praat")
    287
    288    utils.runPraatScript(
    289        praatEXE,
    290        scriptFN,
    291        [
    292            inputWavPath,
    293            outputTGPath,
    294            minPitch,
    295            timeStep,
    296            silenceThreshold,
    297            minSilDur,
    298            minSoundDur,
    299            silentLabel,
    300            soundLabel,
    301        ],
    302    )

SILENCE_LABEL = 'silent'
SOUND_LABEL = 'sound'
def changeGender( praatEXE: str, wavFN: str, outputWavFN: str, pitchFloor: float, pitchCeiling: float, formantShiftRatio: float, pitchMedian: float = 0.0, pitchRange: float = 1.0, duration: float = 1.0, scriptFN: Optional[str] = None) -> None: View Source

    24def changeGender(
    25    praatEXE: str,
    26    wavFN: str,
    27    outputWavFN: str,
    28    pitchFloor: float,
    29    pitchCeiling: float,
    30    formantShiftRatio: float,
    31    pitchMedian: float = 0.0,
    32    pitchRange: float = 1.0,
    33    duration: float = 1.0,
    34    scriptFN: Optional[str] = None,
    35) -> None:
    36    """Changes the speech formants in a file using praat's change gender function
    37
    38    PitchMedian = 0.0; no change in median pitch
    39    PitchRange = 1.0; no change in pitch range
    40
    41    Uses the following praat command:
    42    https://www.fon.hum.uva.nl/praat/manual/Sound__Change_gender___.html
    43    """
    44    if scriptFN is None:
    45        scriptFN = join(utils.scriptsPath, "change_gender.praat")
    46
    47    #  Praat crashes on exit after resynthesis with a klattgrid
    48    utils.runPraatScript(
    49        praatEXE,
    50        scriptFN,
    51        [
    52            wavFN,
    53            outputWavFN,
    54            pitchFloor,
    55            pitchCeiling,
    56            formantShiftRatio,
    57            pitchMedian,
    58            pitchRange,
    59            duration,
    60        ],
    61    )

Changes the speech formants in a file using praat's change gender function

PitchMedian = 0.0; no change in median pitch PitchRange = 1.0; no change in pitch range

Uses the following praat command: https://www.fon.hum.uva.nl/praat/manual/Sound__Change_gender___.html

def changeIntensity( praatEXE: str, wavFN: str, outputWavFN: str, newIntensity: float, scriptFN: Optional[str] = None) -> None: View Source

    64def changeIntensity(
    65    praatEXE: str,
    66    wavFN: str,
    67    outputWavFN: str,
    68    newIntensity: float,
    69    scriptFN: Optional[str] = None,
    70) -> None:
    71    """Changes the intensity of the wavFN (in db)
    72
    73    Uses the following praat command:
    74    https://www.fon.hum.uva.nl/praat/manual/Sound__Scale_intensity___.html
    75    """
    76    if scriptFN is None:
    77        scriptFN = join(utils.scriptsPath, "change_intensity.praat")
    78
    79    #  Praat crashes on exit after resynthesis with a klattgrid
    80    utils.runPraatScript(praatEXE, scriptFN, [wavFN, outputWavFN, newIntensity])

Changes the intensity of the wavFN (in db)

Uses the following praat command: https://www.fon.hum.uva.nl/praat/manual/Sound__Scale_intensity___.html

def getFormants( praatEXE: str, inputWavFN: str, outputTxtFN: str, maxFormant: float, stepSize: float = 0.01, window_length: float = 0.025, preemphasis: float = 50, scriptFN: Optional[str] = None, undefinedValue: Optional[str] = None) -> List: View Source

     83def getFormants(
     84    praatEXE: str,
     85    inputWavFN: str,
     86    outputTxtFN: str,
     87    maxFormant: float,
     88    stepSize: float = 0.01,
     89    window_length: float = 0.025,
     90    preemphasis: float = 50,
     91    scriptFN: Optional[str] = None,
     92    undefinedValue: Optional[str] = None,
     93) -> List:
     94    """Get F1, F2, and F3 for the audio file
     95
     96    maxFormant = 5500 for females, 5000 for males, <8000 for children
     97
     98    Uses the following praat command:
     99    https://www.fon.hum.uva.nl/praat/manual/Sound__To_Formant__burg____.html
    100    """
    101    if scriptFN is None:
    102        scriptFN = join(utils.scriptsPath, "get_formants.praat")
    103
    104    argList = [
    105        inputWavFN,
    106        outputTxtFN,
    107        stepSize,
    108        maxFormant,
    109        window_length,
    110        preemphasis,
    111        -1,
    112        -1,
    113    ]
    114    utils.runPraatScript(praatEXE, scriptFN, argList)
    115
    116    # Load the output
    117    path, fn = os.path.split(outputTxtFN)
    118    with open(os.path.join(path, fn), "r", encoding="utf-8") as fd:
    119        csvFile = csv.reader(fd)
    120        dataList = [row for row in csvFile]
    121
    122    # The new praat script includes a header
    123    if dataList[0][0] == "time":
    124        dataList = dataList[1:]
    125
    126    # Handle undefined values, convert values to float
    127    returnList = []
    128    for row in dataList:
    129        keep = True
    130        for i in range(1, 4):
    131            if "--" in row[i]:
    132                if undefinedValue is not None:
    133                    row[i] = undefinedValue
    134                else:
    135                    keep = False
    136                    break
    137
    138        if keep is True:
    139            returnList.append([float(val) for val in row])
    140
    141    return returnList

Get F1, F2, and F3 for the audio file

maxFormant = 5500 for females, 5000 for males, <8000 for children

Uses the following praat command: https://www.fon.hum.uva.nl/praat/manual/Sound__To_Formant__burg____.html

def getPulses( praatEXE: str, inputWavFN: str, outputPointTierFN: str, minPitch: float, maxPitch: float, scriptFN: Optional[str] = None) -> praatio.data_classes.data_point.PointObject1D: View Source

    144def getPulses(
    145    praatEXE: str,
    146    inputWavFN: str,
    147    outputPointTierFN: str,
    148    minPitch: float,
    149    maxPitch: float,
    150    scriptFN: Optional[str] = None,
    151) -> data_points.PointObject1D:
    152    """Gets the pitch/glottal pulses for an audio file.
    153
    154    Uses the following praat command:
    155    http://www.fon.hum.uva.nl/praat/manual/Sound___Pitch__To_PointProcess__peaks____.html
    156    """
    157    if scriptFN is None:
    158        scriptFN = join(utils.scriptsPath, "get_pulses.praat")
    159
    160    argList = [inputWavFN, outputPointTierFN, minPitch, maxPitch]
    161    utils.runPraatScript(praatEXE, scriptFN, argList)
    162
    163    # Load the output
    164    pointObj = data_points.open1DPointObject(outputPointTierFN)
    165
    166    return pointObj

Gets the pitch/glottal pulses for an audio file.

Uses the following praat command: http://www.fon.hum.uva.nl/praat/manual/Sound___Pitch__To_PointProcess__peaks____.html

def getSpectralInfo( praatEXE: str, inputWavFN: str, inputTGFN: str, outputCSVFN: str, tierName: str, spectralPower: int = 2, spectralMoment: int = 3, scriptFN: Optional[str] = None) -> Tuple[List, List]: View Source

    169def getSpectralInfo(
    170    praatEXE: str,
    171    inputWavFN: str,
    172    inputTGFN: str,
    173    outputCSVFN: str,
    174    tierName: str,
    175    spectralPower: int = 2,
    176    spectralMoment: int = 3,
    177    scriptFN: Optional[str] = None,
    178) -> Tuple[List, List]:
    179    """Extracts various spectral measures from an audio file
    180
    181    Measures include: center_of_gravity, standard_deviation
    182    skewness, kertosis, central_movement
    183
    184    Uses the following praat command:
    185    http://www.fon.hum.uva.nl/praat/manual/Spectrum.html
    186    """
    187    if scriptFN is None:
    188        scriptFN = join(utils.scriptsPath, "get_spectral_info.praat")
    189
    190    argList = [
    191        inputWavFN,
    192        inputTGFN,
    193        outputCSVFN,
    194        tierName,
    195        spectralPower,
    196        spectralMoment,
    197    ]
    198    utils.runPraatScript(praatEXE, scriptFN, argList)
    199
    200    # Load the output
    201    with io.open(outputCSVFN, "r", encoding="utf-8") as fd:
    202        data = fd.read()
    203
    204    dataList = data.rstrip().split("\n")
    205    dataListOfLists = [row.split(",") for row in dataList]
    206    titleRow, mainDataListOfLists = dataListOfLists[0], dataListOfLists[1:]
    207
    208    return titleRow, mainDataListOfLists

Extracts various spectral measures from an audio file

Measures include: center_of_gravity, standard_deviation skewness, kertosis, central_movement

Uses the following praat command: http://www.fon.hum.uva.nl/praat/manual/Spectrum.html

def resynthesizePitch( praatEXE: str, inputWavFN: str, pitchFN: str, outputWavFN: str, minPitch: float, maxPitch: float, scriptFN: Optional[str] = None, pointList: Optional[List] = None) -> None: View Source

    211def resynthesizePitch(
    212    praatEXE: str,
    213    inputWavFN: str,
    214    pitchFN: str,
    215    outputWavFN: str,
    216    minPitch: float,
    217    maxPitch: float,
    218    scriptFN: Optional[str] = None,
    219    pointList: Optional[List] = None,
    220) -> None:
    221    """Resynthesizes the pitch in a wav file with the given pitch contour file
    222
    223    The pitch track to use can optionally be passed in as pointList.  If
    224    so, it will be saved as pitchFN for praat to be able to use.
    225
    226    Uses the following praat command:
    227    https://www.fon.hum.uva.nl/praat/manual/Manipulation.html
    228    """
    229    if scriptFN is None:
    230        scriptFN = join(utils.scriptsPath, "resynthesize_pitch.praat")
    231
    232    if pointList is not None:
    233        dur = audio.QueryWav(inputWavFN).duration
    234        pointObj = data_points.PointObject2D(
    235            pointList, constants.DataPointTypes.PITCH, 0, dur
    236        )
    237        pointObj.save(pitchFN)
    238
    239    utils.runPraatScript(
    240        praatEXE, scriptFN, [inputWavFN, pitchFN, outputWavFN, minPitch, maxPitch]
    241    )

Resynthesizes the pitch in a wav file with the given pitch contour file

The pitch track to use can optionally be passed in as pointList. If so, it will be saved as pitchFN for praat to be able to use.

Uses the following praat command: https://www.fon.hum.uva.nl/praat/manual/Manipulation.html

def resynthesizeDuration( praatEXE: str, inputWavFN: str, durationTierFN: str, outputWavFN: str, minPitch: float, maxPitch: float, scriptFN: Optional[str] = None) -> None: View Source

    244def resynthesizeDuration(
    245    praatEXE: str,
    246    inputWavFN: str,
    247    durationTierFN: str,
    248    outputWavFN: str,
    249    minPitch: float,
    250    maxPitch: float,
    251    scriptFN: Optional[str] = None,
    252) -> None:
    253    """Resynthesizes the duration in a wav file with the given duration tier
    254
    255    Uses the following praat command:
    256    https://www.fon.hum.uva.nl/praat/manual/Manipulation.html
    257    """
    258    if scriptFN is None:
    259        scriptFN = join(utils.scriptsPath, "resynthesize_duration.praat")
    260
    261    utils.runPraatScript(
    262        praatEXE,
    263        scriptFN,
    264        [inputWavFN, durationTierFN, outputWavFN, minPitch, maxPitch],
    265    )

Resynthesizes the duration in a wav file with the given duration tier

Uses the following praat command: https://www.fon.hum.uva.nl/praat/manual/Manipulation.html

def annotateSilences( praatEXE: str, inputWavPath: str, outputTGPath: str, minPitch: float = 100, timeStep: float = 0.0, silenceThreshold: float = -25.0, minSilDur: float = 0.1, minSoundDur: float = 0.1, silentLabel: str = 'silent', soundLabel: str = 'sound', scriptFN: Optional[str] = None) -> None: View Source

    268def annotateSilences(
    269    praatEXE: str,
    270    inputWavPath: str,
    271    outputTGPath: str,
    272    minPitch: float = 100,
    273    timeStep: float = 0.0,
    274    silenceThreshold: float = -25.0,
    275    minSilDur: float = 0.1,
    276    minSoundDur: float = 0.1,
    277    silentLabel: str = SILENCE_LABEL,
    278    soundLabel: str = SOUND_LABEL,
    279    scriptFN: Optional[str] = None,
    280) -> None:
    281    """Marks the silences and non-silences of an audio file
    282
    283    Uses the praat command:
    284    https://www.fon.hum.uva.nl/praat/manual/Sound__To_TextGrid__silences____.html
    285    """
    286    if scriptFN is None:
    287        scriptFN = join(utils.scriptsPath, "annotate_silences.praat")
    288
    289    utils.runPraatScript(
    290        praatEXE,
    291        scriptFN,
    292        [
    293            inputWavPath,
    294            outputTGPath,
    295            minPitch,
    296            timeStep,
    297            silenceThreshold,
    298            minSilDur,
    299            minSoundDur,
    300            silentLabel,
    301            soundLabel,
    302        ],
    303    )

Marks the silences and non-silences of an audio file

Uses the praat command: https://www.fon.hum.uva.nl/praat/manual/Sound__To_TextGrid__silences____.html