sfztools / sfizz

SFZ parser and synth c++ library, providing a JACK standalone client
https://sfz.tools/sfizz/
BSD 2-Clause "Simplified" License
418 stars 57 forks source link

Smooth CC formula #48

Closed jpcima closed 4 years ago

jpcima commented 4 years ago

I have studied effects of bend_smooth, and I share some results. In SFZ specs, smoothcc under Modulators is a "see also" to opcode bend_smooth.

The experiment is to load a sine tone and modulate midi pitch bend with a ramp lfo. The results were observed on spectrogram in real-time. Then, it was matched to a faust program which plays a sine modulated with identical LFO and range.

:warning: note that the smooth filter must be applied on the CC values, not cents values which are result of the conversion following.

The smoothing filter is one-pole LPF which is defined by a time-constant tau. (cf. faust basics.lib) pole = exp(-1.0/(tau*Fs))

These are approximate results measured visually. tau is observed starting at 0, varying +3 ms by bend_smooth unit.

#bend_smooth        tau measured (ms)
10                 30
20                 70
30                 90
40                 120
50                 160
60                 180
70                 220
80                 230
90                 270
100                300

Capture du 2020-02-09 00-28-52

paulfd commented 4 years ago

So it's a straightforward lowpass filter with this constant then? Thanks for the investigation. For this one the nice part is that it's not modulated at all so it's much simpler..

jpcima commented 4 years ago

Yes, I was not expecting anything more complicated.. as it turned out, the model was fitting on the first attempt.

paulfd commented 4 years ago

⚠️ note that the smooth filter must be applied on the CC values, not cents values which are result of the conversion following.

Re-reading all of this, this is going to be a bit annoying I think.

jpcima commented 4 years ago

Yes but also it makes more sense implementation-wise. It's cheaper to apply filtering once per CC rather than modulation sink where it's applied to.

Btw these measurements are 1. pitchbend only, 2. ARIA

I'll try to get a new set measurements based on cakewalk, and by use of CC values.

paulfd commented 4 years ago

Well except you can't really apply it per CC, since different regions might have different inertia parameters. You're kind of forced to compute it for each target.

At least for the current state of the modifiers now it would be simpler to apply it after conversion 😄

jpcima commented 4 years ago

You could still precompute it, per-CC and inertia and curve. Anyway I'll try later to check how the information above holds on cakewalk.

paulfd commented 4 years ago

For sure but then is it in general cheaper to apply a possibly nonlinear function (e.g. exp or log functions mainly) to a full envelope rather than building the envelope out of points from the nonlinear functions? You can do cheap multiplicative ramps using simd so right now I went with the latter.

Note that having a "multiplicative" filter could be a way to solve this dilemma 😁

jpcima commented 4 years ago

Note that having a "multiplicative" filter could be a way to solve this dilemma

Not possible, however: since you will be repeating these identical instructions for all CC, you could SIMD then in "vertical" manner and handle the filters 4 at a time by SSE.

(it's the same kind of vertical processing I hope to do to speed up strings after finalizing)

paulfd commented 4 years ago

Todo to finish implementation: