sound = selected ("Sound")
sound$ = selected$ ("Sound")
grid = selected ("TextGrid")
### input form
selectObject: grid
n_tiers = Get number of tiers
duration = 0
beginPause: "Isochronous Segments"
comment: "Select interval tier:"
optionMenu: "Tier number", 1
# present only interval tiers;
# remember if no interval tier was found
found_itier = 0
for i to n_tiers
is_itier = Is interval tier: i
if is_itier
found_itier = 1
option: string$ (i)
endif
endfor
# present dummy option if no interval tier was found
# (to enable canceling)
if found_itier = 0
option: "-"
comment: "No interval tier found. Aborting."
endif
comment: "Target segments are labeled with: (no spaces)"
word: "Label", "s"
comment: "Specify desired duration in seconds; if the desired duration"
comment: "corresponds to the mean duration of all target segments specify 0,"
comment: "otherwise specify a positive real number:"
real: "Duration (s)", duration
clicked = endPause: "Cancel", "OK", 2, 1
if clicked = 1 or found_itier = 0 or duration < 0
exitScript ()
endif
tier_number = number (tier_number$)
### create manipulation object
selectObject: sound
start_time = Get start time
end_time = Get end time
m_object = To Manipulation: 0.01, 75, 600
### calculate mean duration of targets or apply input duration
selectObject: grid
n_intervals = Get number of intervals: tier_number
t_intervals = Count intervals where: tier_number, "is equal to", label$
if duration = 0
sum_dur = Get total duration of intervals where: tier_number, "is equal to", label$
target_dur = sum_dur / t_intervals
else
target_dur = duration
endif
### create vectors to collect duration ratios (default=1) and boundaries
tmp# = zero# (n_intervals)
dur_ratios# = tmp# + 1
boundaries# = zero# (n_intervals + 1)
boundaries# [1] = start_time
### create duration tier and add default start and end point
dur_tier = Create DurationTier: "durtier", start_time, end_time
Add point: start_time, 1
Add point: end_time, 1
### loop through intervals and add points to duration tier
### at start and end of interval
for i to n_intervals
selectObject: grid
i_label$ = Get label of interval: tier_number, i
i_start = Get start time of interval: tier_number, i
i_end = Get end time of interval: tier_number, i
i_dur = i_end - i_start
if i_label$ = label$
# calculate and set duration ratio for target segments
dur_ratios# [i] = target_dur / i_dur
@setPoints: i, dur_ratios# [i]
else
# set duration ratio to 1 for non-targets
@setPoints: i, 1
endif
endfor
### apply duration tier and create resynthesis
selectObject: dur_tier, m_object
Replace duration tier
removeObject: dur_tier
selectObject: m_object
m_sound = Get resynthesis (overlap-add)
Rename: sound$ + "_modified"
### create and populate Textgrid for manipulated sound
m_grid = To TextGrid: "duration-ratio", ""
for i from 2 to size (boundaries#) - 1
Insert boundary: 1, boundaries# [i]
endfor
for i to n_intervals
Set interval text: 1, i, fixed$ (dur_ratios# [i], 3)
endfor
removeObject: m_object
selectObject: m_sound, m_grid
### write new boundary to vector and add duration points
### at the start and end of interval
procedure setPoints: .i, .ratio
if .i < n_intervals
boundaries# [.i+1] = boundaries# [.i] + i_dur * .ratio
endif
selectObject: dur_tier
# set start point slightly to the right of the left interval bounday
# and end point slightly to the left of the right interval boundary
# (we can't add two points at the exact same point of time)
Add point: i_start + 0.000001, .ratio
Add point: i_end - 0.000001, .ratio
endproc