################################################################################### # modifyFormants-vocalic.praat (Written by Kyuchul Yoon, kyoon@kyungnam.ac.kr) # ================================================================================ # Given, for example, a syllable, this script resynthesizes it, but with formant # frequency values modified by the user. # Resynthesis based on the source-filter theory of speech production. # Source signal extracted by inverse-filtering the LPC(burg) and the target sound. # Filter signal extracted by Formant (burg) algorithm implemented in Praat. # ================================================================================ # In order for the formant values to be modified, the user needs to specify the # center frequency of the formants. ################################################################################### form Specify the parameters word inputSound_(with_dot_wav) ga.wav natural resampleFreq_(in_Hz) 11000 real vowelOnset_(in_sec) 0.13 real vowelOffset_(in_sec) 0.64 real newF1_(in_Hz) 1000 real newF2_(in_Hz) 1700 real newF3_(in_Hz) 3000 comment Resynthesize sound file will have a "resynVocalic-" prefix word logFile log-vocalic.txt endform # Following the Praat manual, LPC prediction order is set to 10 (five formants) lpcPredictionOrder = 10 outputSound$ = "resynVocalic-" + inputSound$ fileappend 'logFile$' Filename'tab$'vowelOnset'tab$'vowelOffset'tab$'location ...'tab$'oldF1'tab$'oldF2'tab$'oldF3'tab$'oldF4'tab$'newF1 ...'tab$'newF2'tab$'newF3'tab$'newF4'newline$' Read from file... 'inputSound$' # Extract the source Resample... resampleFreq 50 Rename... soundObj To LPC (burg)... lpcPredictionOrder 0.025 0.005 50 Rename... lpcObj plus Sound soundObj Filter (inverse) Rename... sourceObj # Extract the filter (formant tier object) select Sound soundObj To Formant (burg)... 0 5 5500 0.025 50 Down to FormantTier Rename... formantTierObj Copy... copyFormantTierObj # Now, query the formantTier object for the number of indices in between # the vowelOnset and vowelOffset select FormantTier formantTierObj vowelOnsetIndex = Get nearest index from time... vowelOnset vowelOffsetIndex = Get nearest index from time... vowelOffset numOfIndices = vowelOffsetIndex-vowelOnsetIndex # Store the formant/bandwidth values into array variables f1, f2, f3, f4/b1, b2, b3, b4 for i from 0 to numOfIndices select FormantTier formantTierObj realIndex = vowelOnsetIndex+i timeOfIndex = Get time from index... realIndex f1'i' = Get value at time... 1 timeOfIndex f2'i' = Get value at time... 2 timeOfIndex f3'i' = Get value at time... 3 timeOfIndex b1'i' = Get bandwidth at time... 1 timeOfIndex b2'i' = Get bandwidth at time... 2 timeOfIndex b3'i' = Get bandwidth at time... 3 timeOfIndex # Since the LPC prediction order is 10, we also need information about F4, F5/B4, B5 f4'i' = Get value at time... 4 timeOfIndex f5'i' = Get value at time... 5 timeOfIndex b4'i' = Get bandwidth at time... 4 timeOfIndex b5'i' = Get bandwidth at time... 5 timeOfIndex endfor # Finally, prepare the formant/bandwidth series, i.e. F1 B1 F2 B2 F3 B3 F4 B4 F5 B5 # to be added to the FormantTier object for i from 0 to numOfIndices select FormantTier formantTierObj realIndex = vowelOnsetIndex+i timeOfIndex = Get time from index... realIndex # Get the formant/bandwidth series for the current index frame f1dummy = f1'i' f2dummy = f2'i' f3dummy = f3'i' f4dummy = f4'i' f5dummy = f5'i' b1dummy = b1'i' b2dummy = b2'i' b3dummy = b3'i' b4dummy = b4'i' b5dummy = b5'i' f1b1$ = "'newF1'" + " " + "'b1dummy'" f2b2$ = "'newF2'" + " " + "'b2dummy'" f3b3$ = "'newF3'" + " " + "'b3dummy'" f4b4$ = "'f4dummy'" + " " + "'b4dummy'" f5b5$ = "'f5dummy'" + " " + "'b5dummy'" formantBandwidthSeries$ = f1b1$ + " " + f2b2$ formantBandwidthSeries$ = formantBandwidthSeries$ + " " + f3b3$ formantBandwidthSeries$ = formantBandwidthSeries$ + " " + f4b4$ formantBandwidthSeries$ = formantBandwidthSeries$ + " " + f5b5$ # Store the whole information into the log file fileappend 'logFile$' 'inputSound$''tab$''vowelOnset''tab$''vowelOffset' ...'tab$''timeOfIndex''tab$''f1dummy:0''tab$''f2dummy:0''tab$''f3dummy:0''tab$' ...'newF1:0''tab$''newF2:0''tab$''newF3:0''newline$' # Remove the index frame Remove point... realIndex Add point... timeOfIndex 'formantBandwidthSeries$' endfor # Now, resynthesize the source and the modified formant tier object select Sound sourceObj plus FormantTier formantTierObj Filter Rename... resynthesizedObj Write to WAV file... 'outputSound$' # Clean up select Sound soundObj plus LPC lpcObj plus Sound sourceObj plus Formant soundObj plus FormantTier formantTierObj plus FormantTier copyFormantTierObj Remove ################# END OF SCRIPT ###################