function extremes_Hz = getExtremes(self)
a = self.ratio();
alpha = (a^(1/(1-1/a))) / exp(1);
p = self.stable_rel;
extremes_Hz = [ 0, 0 ];
switch self.peak
case "low"
extremes_Hz(1) = self.pitch_Hz * a^(-p) * alpha^(p-1);
case "high"
extremes_Hz(1) = self.pitch_Hz * alpha^(p-1);
end% switch
extremes_Hz(2) = a*extremes_Hz(1);
end
fminsearch
function err = errorfun(a, v)
extremes_Hz = [ a, v.ratio() * a ];
v = v.recalc(extremes_Hz);
m = mean(v.modCycle_Hz, "g");
err = (v.pitch_Hz - m)^2;
end
addpath ../experiment;
v = Vibrato();
fprintf("Analytic f_0: %d\n", v.extremes_Hz(1));
[ a, err ] = fminsearch(@(a) errorfun(a, v), 300);
fprintf("Estimated f_0: %d\nerror: %d\n", a, err);
#> Analytic f_0: 489.133
#> Estimated f_0: 489.13
#> error: 1.20039e-05
\[y = a\sqrt{x} + b\]
function err = errorfun(params, data)
a = params(1); b = params(2);
y_hat = a*sqrt(data.x) + b;
err = sum((data.y-y_hat).^2);
end
data.x = 1:50;
data.y = 5*sqrt(data.x) + 1;
[ params, err ] = fminsearch(@(params) errorfun(params, data), [ 1, 0 ]);
fprintf("a: %d\nb: %d\nError: %d", params(1), params(2), err);
#> a: 4.99997
#> b: 1.00012
#> Error: 1.61518e-07
duration_s = 0.5; fs_Hz = 48000;
t_s = linspace(0, duration_s, duration_s*fs_Hz+1);
s = []; nextStartPhase = 0;
for f = [ 400, 600, 800 ]
phase_rad = nextStartPhase + 2*pi*f*t_s;
a = sin(phase_rad(1:end-1));
nextStartPhase = mod(phase_rad(end), 2*pi);
s = [ s, a ];
end
audiowrite("soundsamples/sound3.wav", s, fs_Hz);
Mesz, B. A., & Eguia, M. C. (2009). The pitch of vibrato tones: A model based on instantaneous frequency decomposition. Annals of the New York Academy of Sciences, 1169(1, III), 126—130. https://doi.org/10.1111/j.1749-6632.2009.04767.x