I have been wondering if anyone wrote a kind of automatic tuner for supercollider physical model synths, that accounts for inharmonicity in the model and results in stretched octaves etc.? If I am reading OteyPiano model correctly, while it accounts for density and modulus it does not touch actually tuning a collection of synths. So this makes me wonder did anyone write some tuning model that accounts for inharmonicity of produced sound?
something like this ?
(
var ratios = (1..16);
SynthDef(\modal, {
var tFreq = \tFreq.kr(1);
var trig = Impulse.ar(tFreq);
var freq = \freq.kr(200);
var inharmonicity = (1 + (ratios * ratios * \inharmonicity.kr(0.01))).sqrt;
var freqs = freq * ratios * inharmonicity;
var amps = (log2(ratios) * \tilt.kr(-3)).dbamp;
var decays = \decay.kr(3) / ratios;
var excEnv = Decay2.ar(trig, \tAtk.kr(0.001), \tDec.ar(0.05));
var exc = Hasher.ar(Sweep.ar) * -15.dbamp * excEnv;
var sig = DynKlank.ar(Ref([freqs, amps, decays]), exc, 1, 0, \decayScale.kr(1));
sig = sig * \amp.kr(-20.dbamp);
sig = Pan2.ar(sig, \pan.kr(0));
Out.ar(\out.kr(0), sig);
}).add;
)
Synth(\modal, [\inharmonicity, 0.05]);
Something like the following process tuning a stretched octave.
- get FFT of
Synth(\piano, freq)
- get FFT of
Synth(\piano, 2*freq)
Depending on whether the partial around the octave above for 1. is above or below the actual fundamental for 2*freq, binary search for octavefreq close to the actual fundamental of 2*freq (eliminates the beating) until within certain error. This would return the frequency of the new octave.
This assumes that the Synth in question has a partial around octave above.
But maybe your code does something similar to that as I dont get how to use it.
Digging around a bit more I think I might have a useful candidate in a combination of FFTPeak together with Sweep to get the actual frequency.