-
Notifications
You must be signed in to change notification settings - Fork 7
/
Make_Fricative_Continuum_v13.txt
537 lines (446 loc) · 14.6 KB
/
Make_Fricative_Continuum_v13.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# # ## ### ##### ######## ############# ##################### ##################################
# Create synthetic fricative continuum
# version 13
# by Matthew B. Winn
# January 2020
#
# this script filters white noise to create fricatives according to the dimensions that you specify
# frequency interpolation can be linear, logarithmic, Bark scale, or Greenwood (cochlear spacing)
#
# # ## ### ##### ######## ############# ##################### ##################################
form Input Enter specifications for Fricative continuum settings
comment Enter parameter levesl for continuum endpoints in the Left and Right columns
optionmenu steps: 7
option 2
option 3
option 4
option 5
option 6
option 7
option 8
option 9
option 10
option 11
option 12
option 13
option 14
option 15
#comment PEAK FREQUENCIES
real left_peak1 2300
real right_peak1End 3700
real left_peak2 3100
real right_peak2End 5100
real left_peak3 5100
real right_peak3End 6700
optionmenu interpolation: 2
option Linear interpolation
option Logarithmic interpolation
option Use Greenwood function
option Use Bark scale
comment BANDWIDTHS (slope in dB / octave)
real left_bw1 36
real right_bw1End 56
real left_bw2 28
real right_bw2End 48
real left_bw3 48
real right_bw3End 48
comment RELATIVE AMPLITUDES (relative to second peak)
integer left_amp1 5
integer right_amp1End -13
integer left_amp3 -6
integer right_amp3End -5
#comment fricative duration, rise time and fall time
real left_duration 200
real right_durationEnd 200
real left_risetime 150
real right_risetimeEnd 150
real left_falltime 40
real right_falltimeEnd 40
real left_intensity 70
real right_intensityEnd 70
#comment filename prefix for steps and full items w/vowels:
sentence left_prefix Step_
sentence right_fullPrefix VowelName_
#comment append fricative to another soundfile in the list?
optionmenu append: 2
option No - create isolated fricatives
option Yes - fricative at the beginning
option Yes - friative at the end
optionmenu samplerate: 1
option 44100 Hz
option 22050 Hz
option 16000 Hz
boolean draw 1
endform
#
#
##
###
#####
########
#############
#####################
##################################
# First, convert variables from form,
# and establish some other variables;
# scroll to the bottom of the script for details
call convertVariables
call makeContinuumValues
# Make the continuum
for thisStep from 1 to steps
# first, lookup the relevant continuum values
call assignVariableLevels
# yields: peak1, peak2, peak3, bw1, bw2, bw3,
# yields: amp1, amp2, amp3
# yields: duration, risetime, falltime, intensity
# create broadband noise to filter
Create Sound from formula... Noise 1 0 duration samplerate randomGauss(0,0.1)
for thisPeak from 1 to numpeaks
select Sound Noise
temp_int = Get intensity (dB)
# adjust the intensity for this peak
new_int = temp_int + amp'thisPeak'
Copy... Noise_temp
Scale intensity... new_int
# filter the sound around the center frequency
call filterOctaveRolloff Noise_temp peak'thisPeak' bw'thisPeak' 'prefix$''thisStep'_peak'thisPeak'
# cleanup temp
select Sound Noise_temp
Remove
# create exponential curve for amplitude envelope
# power by which cosine envelope is shaped is detemined
# by which peak is being modulated;
# higher peaks have slightly slower-onset envlopes
power = 0.5+(thisPeak/2)
call applyEnvelope "'prefix$''thisStep'_peak'thisPeak'" risetime falltime power
endfor
# put all the peaks together
call blend3Peaks "'prefix$''thisStep'_peak1" "'prefix$''thisStep'_peak2" "'prefix$''thisStep'_peak3" 'prefix$''thisStep'
# scale the final intensity of this continuum step
# (intensity determined from assignVariableLevels procedure)
call scaleIntensity "'prefix$''thisStep'" intensity
# cleanup
call removePeakFiles
endfor
# attach the vowel, if necessary
if append > 0
call appendVowel
endif
# draw pretty pictures
if draw = 1
call drawSpectra
endif
# disable saving for now
# (You can alway manually save it)
#call saveInfoWindow "'outDirectory$'" Continuum_info
##################################
#####################
#############
########
#####
###
##
#
#
procedure filterOctaveRolloff .name$ .cf .rolloff.per.octave .newname$
select Sound '.name$'
Filter (formula)... if x > 1 then self*10^(-(abs((log10(x/.cf)/log10(2)))*.rolloff.per.octave)/20) else self fi
Rename... '.newname$'
endproc
procedure drawSpectra
Erase all
select Sound 'prefix$'1
for thisFricative from 2 to steps
plus Sound 'prefix$''thisFricative'
endfor
numberOfSelectedSounds = numberOfSelected ("Sound")
for thisSelectedSound to numberOfSelectedSounds
sound'thisSelectedSound' = selected("Sound",thisSelectedSound)
endfor
for thisSound from 1 to numberOfSelectedSounds
coolgradient = ('thisSound'-1)/('numberOfSelectedSounds'-1)
r = coolgradient
g = 0.0
b = 1-coolgradient
Colour... {'r','g','b'}
select sound'thisSound'
name$ = selected$("Sound")
To Spectrum... yes
Cepstral smoothing... 'smoothing'
Rename... 'name$'_smooth
select Spectrum 'name$'
Remove
select Spectrum 'name$'_smooth
Draw... drawHzLow drawHzHigh drawDBLow drawDBHigh yes
select Spectrum 'name$'_smooth
Remove
endfor
# x-axis (frequency) labels
Marks bottom every: 1, 1000, "yes", "yes", "no"
endproc
procedure saveInfoWindow outputDirectory$ outputFileName$
# first delete the file if it already exists
filedelete 'outputDirectory$'/'outputFileName$'.txt
# create the file
fappendinfo 'outputDirectory$'/'outputFileName$'.txt
endproc
procedure getVowelInfo
if append = 0
#take no action
print 'newline$'
numchannels = 1
else
#pause Select the soundfile to combine with the fricatives
vowel$ = selected$("Sound")
numchannels = Get number of channels
v_samplerate = Get sampling frequency
print 'vowel$' was used as the vowel'newline$'
endif
endproc
procedure appendVowel
pause select all vowels to add
numberOfSelectedSounds = numberOfSelected ("Sound")
for thisSelectedSound to numberOfSelectedSounds
vowel'thisSelectedSound' = selected("Sound",thisSelectedSound)
endfor
for thisVowel from 1 to numberOfSelectedSounds
select vowel'thisVowel'
call getVowelInfo
vowel$ = selected$("Sound")
if append = 0
#take no action
print 'newline$'
elsif append = 1
select Sound 'vowel$'
Convert to mono
Resample... samplerate 50
Rename... vowel2
for thisFricative from 1 to steps
select Sound 'prefix$''thisFricative'
plus Sound vowel2
Concatenate
# use this line for a simple filename
# Rename... 'fullPrefix$''thisFricative'
# use this line instead to maintain the original vowel filename in the ultimate name
Rename... 'prefix$''thisFricative'_'vowel$'
endfor
select Sound vowel2
plus Sound 'vowel$'_mono
Remove
elsif append = 2
for thisFricative from 1 to steps
select Sound 'vowel$'
Convert to mono
Resample... samplerate 50
Rename... vowel2
select Sound 'prefix$''thisFricative'
Copy... Fricative2
select Sound vowel2
plus Sound Fricative2
Concatenate
# use this line for a simple filename
# Rename... 'fullPrefix$''thisFricative'
# use this line instead to maintain the original vowel filename in the ultimate name
Rename... 'prefix$''thisFricative'_'vowel$'
select Sound Fricative2
plus Sound vowel2
plus Sound 'vowel$'_mono
Remove
endfor
endif
endfor
endproc
procedure removePeakFiles
select Sound 'prefix$''thisStep'_peak1
plus Sound 'prefix$''thisStep'_peak2
plus Sound 'prefix$''thisStep'_peak3
plus Sound Noise
Remove
endproc
procedure scaleIntensity .name$ .intensity
select Sound '.name$'
Scale intensity... '.intensity'
endproc
procedure applyEnvelope .name$ .risetime .falltime .power
select Sound '.name$'
.start = Get start time
.end = Get end time
Formula... if x<('.risetime')
...then self * ((cos((x-('.risetime' - '.start'))/'.risetime' * pi/2))^'.power')
...else self endif
endif
Formula... if x>('.end' - '.falltime')
...then self * cos((x-(.end - '.falltime'))/'.falltime' * pi/2)
...else self endif
endif
endproc
procedure blend3Peaks .sound1$ .sound2$ .sound3$ .newname$
select Sound '.sound1$'
Copy... '.newname$'
Formula... self [col] + Sound_'.sound2$' [col] + Sound_'.sound3$' [col]
endproc
procedure assignVariableLevels
for thisPeak from 1 to numpeaks
peak'thisPeak' = peak'thisPeak'_'thisStep'
bw'thisPeak' = bw'thisPeak'_'thisStep'
amp'thisPeak' = amp'thisPeak'_'thisStep'
endfor
duration = duration'thisStep'
risetime = risetime'thisStep'
falltime = falltime'thisStep'
intensity = intensity'thisStep'
endproc
procedure makeContinuumValues
clearinfo
if steps >1
for n from 1 to numpeaks
# navigate among four different interpolation types
if interpolation = 1; linear
call makeContinuum0dec steps peak'n'Start peak'n'End "peak'n'_" yes
elsif interpolation = 2; logarithmic
peak'n'Start = log10(peak'n'Start)
peak'n'End = log10(peak'n'End)
call makeContinuum3dec steps peak'n'Start peak'n'End "peak'n'_" no
for .thisLogStep from 1 to steps
peak'n'_'.thisLogStep' = 10^(peak'n'_'.thisLogStep')
tempvariable = peak'n'_'.thisLogStep'
print peak'n'_'.thisLogStep''tab$''tempvariable:0''newline$'
endfor
print 'newline$'
elsif interpolation = 3;Greenwood
# cochlea parameters
aA = 165.4
a = 2.1
length = 35
k = 0.88
apicalCochlearPositionPeak'n' = log10((peak'n'Start/'aA')+'k')*'length'/'a'
basalCochlearPositionPeak'n' = log10((peak'n'End/'aA')+'k')*'length'/'a'
call makeContinuum3dec steps apicalCochlearPositionPeak'n' basalCochlearPositionPeak'n' "cochlearPosition'n'_" no
for .thisGreenwoodStep from 1 to steps
peak'n'_'.thisGreenwoodStep' = 'aA'*((10^('a'*cochlearPosition'n'_'.thisGreenwoodStep'/'length'))-'k')
tempvariable = peak'n'_'.thisGreenwoodStep'
print peak'n'_'.thisGreenwoodStep''tab$''tempvariable:0''newline$'
endfor
print 'newline$'
elsif interpolation = 4; Use Bark scale
## uses the Hz to Bark conversion from Traunmuller (1990);
## Hz to bark: 26.81/(1+(1960/f)) - 0.53
## bark to Hz: f = 1960 / [26.81 / (z + 0.53) - 1]
# H. Traunmüller (1990) "Analytical expressions for the tonotopic sensory scale"
# J. Acoust. Soc. Am. 88: 97-100.
bark'n'Start = 26.81/(1+(1960/peak'n'Start)) - 0.53
bark'n'End = 26.81/(1+(1960/peak'n'End)) - 0.53
call makeContinuum3dec steps bark'n'Start bark'n'End "barkPeak'n'_" no
for .thisBarkStep from 1 to steps
peak'n'_'.thisBarkStep' = 1960 / (26.81 / (barkPeak'n'_'.thisBarkStep' + 0.53) - 1)
tempvariable = peak'n'_'.thisBarkStep'
print peak'n'_'.thisBarkStep''tab$''tempvariable:0''newline$'
endfor
print 'newline$'
endif
endfor
for n from 1 to numpeaks
call makeContinuum3dec steps bw'n'Start bw'n'End "bw'n'_" yes
endfor
for n from 1 to numpeaks
call makeContinuum3dec steps amp'n'Start amp'n'End "amp'n'_" yes
endfor
endif
# establish continuum values and print them to the info window
call makeContinuum3dec steps durationStart durationEnd duration 1
call makeContinuum3dec steps risetimeStart risetimeEnd risetime 1
call makeContinuum3dec steps falltimeStart falltimeEnd falltime 1
call makeContinuum3dec steps intensityStart intensityEnd intensity 1
endproc
procedure makeContinuum0dec .steps .low .high .prefix$ .printvalues
for thisStep from 1 to .steps
# calculate the value
temp = (('thisStep'-1)*('.high'-'.low')/('.steps'-1))+'.low'
# assign the value to a variable name specified by the procedure arguments
'.prefix$''thisStep' = temp
#.value = step_'.prefix$''thisStep'
.value = '.prefix$''thisStep'
if .printvalues = 1
print '.prefix$''thisStep''tab$''.value:0' 'newline$'
endif
endfor
print 'newline$'
endproc
procedure makeContinuum3dec .steps .low .high .prefix$ .printvalues
for thisStep from 1 to .steps
temp = (('thisStep'-1)*('.high'-'.low')/('.steps'-1))+'.low'
'.prefix$''thisStep' = temp
.value = '.prefix$''thisStep'
if .printvalues = 1
print '.prefix$''thisStep''tab$''.value:3' 'newline$'
endif
endfor
print 'newline$'
endproc
procedure convertVariables
yes = 1
no = 0
numpeaks = 3
# add one to the steps variable since the 'first' option is 2
steps = steps+1
#-----------------------
peak1Start = left_peak1
peak1End = right_peak1End
peak2Start = left_peak2
peak2End = right_peak2End
peak3Start = left_peak3
peak3End = right_peak3End
#-----------------------
bw1Start = left_bw1
bw1End = right_bw1End
bw2Start = left_bw2
bw2End = right_bw2End
bw3Start = left_bw3
bw3End = right_bw3End
#-----------------------
amp1Start = left_amp1
amp1End = right_amp1End
amp3Start = left_amp3
amp3End = right_amp3End
amp2Start = 0
amp2End = 0
temporaryintensity = 50
#-----------------------
# convert ms to seconds
durationStart = left_duration/1000
durationEnd = right_durationEnd/1000
#-----------------------
# convert ms to seconds
risetimeStart = left_risetime/1000
risetimeEnd = right_risetimeEnd/1000
falltimeStart = left_falltime/1000
falltimeEnd = right_falltimeEnd/1000
#-----------------------
intensity = left_intensity
intensityStart = left_intensity
intensityEnd = right_intensityEnd
#-----------------------
prefix$ = "'left_prefix$'"
fullPrefix$ = "'right_fullPrefix$'"
#-----------------------
append = append-1
##### 0 means no vowel/word to append
##### 1 means fricative comes first
##### 2 means fricative comes second
#-----------------------
# options for drawing spectra
smoothing = 300
drawHzLow = 0
drawHzHigh = 10000
drawDBLow = 5
drawDBHigh = 40
# these options will be overridden if you select a vowel to concatenate (so that both the vowel and fricative have the same samplerate)
# so... only concern these if you are creating isolated fricatives.
if samplerate = 1
samplerate = 44100
elsif samplerate = 2
samplerate = 22050
else
samplerate = 16000
endif
endproc