Praat Script Syllable Nuclei
###########################################################################
# #
# Praat Script Syllable Nuclei #
# Copyright (C) 2008 Nivja de Jong and Ton Wempe #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see http://www.gnu.org/licenses/ #
# #
###########################################################################
# updated 09.17.2010 by Nivja de Jong, Hugo Quené, Ingrid Persoon
# + adapted to also run on MAC-computers
# + refer to objects by unique identifier, not by name
# + keep track of all created intermediate objects, select these explicitly,
# then Remove
# + programming of checking loop for mindip adjusted
###########################################################################
# counts syllables of all sound utterances in a directory
# NB unstressed syllables are sometimes overlooked
# NB filter sounds that are quite noisy beforehand
# NB use Ignorance Level/Intensity Median (dB) = 0 for unfiltered sounds,
# use 2 for filtered sounds
# NB use Minimum dip between peaks (dB) = 2 for unfiltered sounds,
# use 4 for filtered sounds
form Counting Syllables in Sound Utterances
real Ignorance_Level/Intensity_Median_(dB) 0 or 2
real Minimum_dip_between_peaks_(dB) 2 or 4
boolean display_name yes
sentence directory C:/directorywithsoundfiles
endform
# shorten variables
iglevel = 'ignorance_Level/Intensity_Median'
mindip = 'minimum_dip_between_peaks'
Create Strings as file list... list 'directory$'/*.wav
numberOfFiles = Get number of strings
for ifile to numberOfFiles
select Strings list
fileName$ = Get string... ifile
Read from file... 'directory$'/'fileName$'
obj$ = selected$("Sound")
soundid = selected("Sound")
originaldur = Get total duration
Subtract mean
# Use intensity to get threshold
To Intensity... 50 0 yes
intid = selected("Intensity")
start = Get time from frame number... 1
nframes = Get number of frames
end = Get time from frame number... 'nframes'
# estimate noise floor
minint = Get minimum... 0 0 Parabolic
# estimate noise max
maxint = Get maximum... 0 0 Parabolic
#get median of Intensity: limits influence of high peaks
medint = Get quantile... 0 0 0.5
# estimate Intensity threshold
threshold = medint + iglevel
if threshold < minint
threshold = minint
endif
Down to Matrix
matid = selected("Matrix")
# Convert intensity to sound
To Sound (slice)... 1
sndintid = selected("Sound")
intdur = Get finishing time
intmax = Get maximum... 0 0 Parabolic
# estimate peak positions (all peaks)
To PointProcess (extrema)... Left yes no Sinc70
ppid = selected("PointProcess")
numpeaks = Get number of points
# fill array with time points
for i from 1 to numpeaks
t'i' = Get time from index... 'i'
endfor
# fill array with intensity values
select 'sndintid'
peakcount = 0
for i from 1 to numpeaks
value = Get value at time... t'i' Cubic
if value > threshold
peakcount += 1
int'peakcount' = value
timepeaks'peakcount' = t'i'
endif
endfor
# fill array with valid peaks: only intensity values if preceding
# dip in intensity is greater than mindip
select 'intid'
validpeakcount = 0
precedingtime = timepeaks1
precedingint = int1
for p to peakcount-1
following = p + 1
followingtime = timepeaks'following'
dip = Get minimum... 'precedingtime' 'followingtime' None
diffint = abs(precedingint - dip)
if diffint > mindip
validpeakcount += 1
validtime'validpeakcount' = timepeaks'p'
endif
precedingtime = timepeaks'following'
precedingint = Get value at time... timepeaks'following' Cubic
endfor
# Look for only voiced parts
select 'soundid'
To Pitch (ac)... 0.02 30 4 no 0.03 0.25 0.01 0.35 0.25 450
pitchid = selected("Pitch")
voicedcount = 0
for i from 1 to validpeakcount
querytime = validtime'i'
value = Get value at time... 'querytime' Hertz Linear
if value <> undefined
voicedcount = voicedcount + 1
voicedpeak'voicedcount' = validtime'i'
endif
endfor
# calculate time correction due to shift in time for Sound object versus
# intensity object
timecorrection = originaldur/intdur
# Insert voiced peaks in second Tier
select 'soundid'
To TextGrid... "syllables" syllables
textgridid = selected("TextGrid")
for i from 1 to voicedcount
position = voicedpeak'i' * timecorrection
Insert point... 1 position 'i'
endfor
# write textgrid to textfile
Write to text file... 'directory$'/'obj$'.syllables.TextGrid
# clean up before next sound file is opened
select 'intid'
plus 'matid'
plus 'ppid'
plus 'sndintid'
plus 'soundid'
plus 'textgridid'
plus 'pitchid'
Remove
endfor