# I like to live in danger.
select all
nocheck Remove
clearinfo

# General parameters.
total_steps    = 10
duration       = 0.7 ; s
intensity      = 70  ; dB
pitch          = 100 ; Hz
samples        = 20
output_folder$ = "stimuli_vowels/"

# Parameters for vowel 1 model (/æ/).
v1_F1 = 748
v1_F2 = 1746
v1_F3 = 2460

appendInfoLine: 1, tab$, v1_F1

# Parameters for vowel 2 model (/ɛ/)
v2_F1 = 569
v2_F2 = 1965
v2_F3 = 2636

# Common parameters:
unique_bandwith  = 50 ; bad model! why?
unique_amplitude = 10 ; bad model! why?

# Magnitude of random variability:
int_noise   = 0.3 ; dB
pitch_noise = 1 ; Hz
f1_noise    = 10 ; Hz
f2_noise    = 15 ; Hz
f3_noise    = 20 ; Hz

# Creating empty KlattGrids.
for i from 1 to total_steps
	vowel_step[i] = Create KlattGrid: "vowel_" + string$(i), 0.0, duration, 3, 0, 0, 0, 0, 0, 0	
endfor

# Calculating distance in time between contiguous samples.
duration_step = duration / samples

# Calculating acoustic values for each step and populating KlattGrids.
for i from 1 to samples
	# Calculating values by sample common to both vowels.
		current_time_sample[i] = duration_step * (i - 1)
		current_voicing_amp[i] = intensity + randomUniform(-int_noise, int_noise)
		current_pitch[i]       = pitch     + randomUniform(-pitch_noise, pitch_noise)
	
	# First step from vowel continuum.
		selectObject: vowel_step[1]
		Add voicing amplitude point: current_time_sample[i], current_voicing_amp[i]
		Add pitch point: current_time_sample[i], current_pitch[i]
    current_f1_v1[i] = v1_F1 + randomUniform(-f1_noise, f1_noise)
    current_f2_v1[i] = v1_F2 + randomUniform(-f2_noise, f2_noise)
    current_f3_v1[i] = v1_F3 + randomUniform(-f3_noise, f3_noise)
    Add oral formant frequency point: 1, current_time_sample[i], current_f1_v1[i]
    Add oral formant frequency point: 2, current_time_sample[i], current_f2_v1[i]
    Add oral formant frequency point: 3, current_time_sample[i], current_f3_v1[i]
    # (Comment the next 3 lines out to see what happens)
    Add oral formant bandwidth point: 1, current_time_sample[i], unique_bandwith
    Add oral formant bandwidth point: 2, current_time_sample[i], unique_bandwith
    Add oral formant bandwidth point: 3, current_time_sample[i], unique_bandwith
    Add oral formant amplitude point: 1, current_time_sample[i], unique_amplitude
    Add oral formant amplitude point: 2, current_time_sample[i], unique_amplitude
    Add oral formant amplitude point: 3, current_time_sample[i], unique_amplitude
	
	# Last step from vowel continuum.
		selectObject: vowel_step[total_steps]
		Add voicing amplitude point: current_time_sample[i], current_voicing_amp[i]
		Add pitch point: current_time_sample[i], current_pitch[i]
    current_f1_v2[i] = v2_F1 + randomUniform(-f1_noise, f1_noise)
    current_f2_v2[i] = v2_F2 + randomUniform(-f2_noise, f2_noise)
    current_f3_v2[i] = v2_F3 + randomUniform(-f3_noise, f3_noise)
    Add oral formant frequency point: 1, current_time_sample[i], current_f1_v2[i]
    Add oral formant frequency point: 2, current_time_sample[i], current_f2_v2[i]
    Add oral formant frequency point: 3, current_time_sample[i], current_f3_v2[i]
    Add oral formant bandwidth point: 1, current_time_sample[i], unique_bandwith
    Add oral formant bandwidth point: 2, current_time_sample[i], unique_bandwith
    Add oral formant bandwidth point: 3, current_time_sample[i], unique_bandwith
    Add oral formant amplitude point: 1, current_time_sample[i], unique_amplitude
    Add oral formant amplitude point: 2, current_time_sample[i], unique_amplitude
    Add oral formant amplitude point: 3, current_time_sample[i], unique_amplitude
	
	# Intermediate steps.
		step_f1[i] = (current_f1_v1[i] - current_f1_v2[i]) / (total_steps - 1)
		step_f2[i] = (current_f2_v1[i] - current_f2_v2[i]) / (total_steps - 1)
		step_f3[i] = (current_f3_v1[i] - current_f3_v2[i]) / (total_steps - 1)
		for f from 1 to total_steps - 2
			current_f1_step[i] = current_f1_v1[i] - (step_f1[i] * f)

      if i == 1
        appendInfoLine: f + 1, tab$, current_f1_step[i]
      endif

			current_f2_step[i] = current_f2_v1[i] - (step_f2[i] * f)
			current_f3_step[i] = current_f3_v1[i] - (step_f3[i] * f)
			selectObject: vowel_step [f + 1]
			Add voicing amplitude point: current_time_sample[i], current_voicing_amp[i]
			Add pitch point: current_time_sample[i], current_pitch[i]
      Add oral formant frequency point: 1, current_time_sample[i], current_f1_step[i]
      Add oral formant frequency point: 2, current_time_sample[i], current_f2_step[i]
      Add oral formant frequency point: 3, current_time_sample[i], current_f3_step[i]
      Add oral formant bandwidth point: 1, current_time_sample[i], unique_bandwith
      Add oral formant bandwidth point: 2, current_time_sample[i], unique_bandwith
      Add oral formant bandwidth point: 3, current_time_sample[i], unique_bandwith
      Add oral formant amplitude point: 1, current_time_sample[i], unique_amplitude
      Add oral formant amplitude point: 2, current_time_sample[i], unique_amplitude
      Add oral formant amplitude point: 3, current_time_sample[i], unique_amplitude
		endfor
endfor

appendInfoLine: total_steps, tab$, v2_F1

# Synthesize KattGrids into Sound objects.
for i from 1 to total_steps
	selectObject: vowel_step[i]
	final_step_id[i] = To Sound
  # Add fade in and out.
  Fade in:  1, 0, 0.1, "yes"
	Fade out: 1, 0.6, 0.1, "yes"
endfor

# Scaling intensity of all steps.
nocheck selectObject: undefined
for i from 1 to total_steps
	plusObject: final_step_id[i]
endfor
Scale intensity: intensity

# Saving resulting stimuli into output folder.
createDirectory: output_folder$
for i from 1 to total_steps
	selectObject: final_step_id[i]
	filler$ = if i < 10 then "0" else "" fi
  Save as WAV file: output_folder$ + "step_" + filler$ + string$(i) + ".wav"
endfor

# Final selection.
nocheck selectObject: undefined
for i from 1 to total_steps
	plusObject: final_step_id[i]
endfor
