surge-synthesizer / surge

Synthesizer plug-in (previously released as Vember Audio Surge)
https://surge-synthesizer.github.io/
GNU General Public License v3.0
3.17k stars 400 forks source link

Modulate integer parameters #235

Open esaruoho opened 5 years ago

esaruoho commented 5 years ago

would be lovely if we could map LFO and SLFO to FM2's M1 Ratio and M2 Ratio. and also map LFO to HP, FX1 Send, FX2 Send. (note, SLFO can already be mapped to HP FX1 Send, FX2 Send.)

What is strange is that FM3's M1 Ratio and M2 Ratio can be mapped, but not FM2's. musical_typing_-_inst_1_and_untitled_-_tracks

esaruoho commented 5 years ago

is this something that's easy to fix in FM2 ? fm3 vs fm2

esaruoho commented 5 years ago

here's a better image: FM3 on the left, FM2 on the right: screenshot_08_01_2019__12_10

baconpaul commented 5 years ago

Just adding a few notes as I read the code here.

  1. That menu is configured in resources/data/configuration.xml where the FM2 maps to type=6 and the FM3 maps to type=5.
  2. Those ids map to the sub3_osctypes in SurgeStorage.h, where 5 is ot_FM and 6 is ot_FM2. So FM2 is FM2 but FM3 is FM.
  3. This leads to Oscillator.cpp instantiating an FM2Oscillator for the FM2, and an FMOscillator for the FM3.

I don't know why FM3 is called FM3 but hey.

The difference between the two oscillators ::init_ctrltypes method is that M1 Ratio and M2 Ratio are a ct_fmratio in FMOscillator (FM3) and a ct_fmratio_int in FM2Oscillator (FM2)

So the questions I think you are asking after you unwind the code a bit are

  1. Should a ct_fmratio_int be LFO bindable?
  2. Should FM2 us ct_fmartio_int rather than ct_fmratio?

I do not know the answer to those questions. But am tired of reading through the code so will leave this here as a breadcrumb to a future investigator on this issue.

baconpaul commented 5 years ago

Hmm. In FMOscillator (which is FM3), it uses p[1] (which is M1 ratio) as follows

   RM1.set_rate(min(M_PI, (double)pitch_to_omega(pitch + driftlfo) *
                              localcopy[oscdata->p[1].param_id_in_scene].f));

In FM2 it does this

   RM1.set_rate(min(M_PI, (double)pitch_to_omega(pitch + driftlfo) *
                                  (double)localcopy[oscdata->p[1].param_id_in_scene].i +
                              shift));

p[1] isn't read anywhere else in FMOscillator.cpp. So it seems FM2 just casts away the int-y-ness anyway.

I don't know if this is an error or a feature. What's the musical or sonic difference between FM2 and FM3? Is it intentional that one of the ratios is integral and the other is continuous?

esaruoho commented 5 years ago

@kurasu spoke and mentioned it is meant to be and not a bug.

the int ratios is so they're harmonic
so it still sounds like a pure tone and not just havoc
and the modulation system only deals with continuous
parameters, so unless that changes i wouldn't worry 
about this
sense-amr commented 5 years ago

yeah she still isnt automatable as far as i can see .. latest nightly .. 11032019

sense-amr commented 5 years ago

@esaruoho was it addressed and fixed? or still waiting to get to this ?

esaruoho commented 5 years ago

It was not fixed. Still is not.

baconpaul commented 5 years ago

The ‘fix’ is to allow modulation of int parameters in surge with continuous modulations and round to the nearest int. That’s the correct name for this issue too really.

The interim ‘fix’ is to use FM3 which has M1 and M2 be floats rather than into.

baconpaul commented 5 years ago

Just some running notes to myself since this is tricky and want to record as I go

SurgeSynthesizer::isValidModulation contains the p->valtype != vt_float check. We get the full parameter there so we can check specifically for fmratioint if we want there. If we do that you get the first step to visual drag the modulation but it doesn't stick.

+   if (p->valtype != ((valtypes)vt_float) && p->ctrltype != ct_fmratio_int)
+   {
+      std::cout << "Cannot modulate " << p->name << " because it isn't a float" << std::endl;
       return false;
+   }

that diff basically lets you start. That lets you drag the second handle but (1) the underlying modulation status doesn't stick and (2) the display of amount modulating stays at zero. So now we have to go find where else it assumes float in the modulation architecture.

mkruselj commented 3 years ago

@baconpaul I did a bit more digging.

Parameter::get_modulation_f01() has an if (valtype != vt_float) return 0;, and same with Parameter::set_modulation_f01(), so commenting those out at least makes the modulation amount stick around. Still doesn't actually work (gotta round the modulation and cast to int), but this is at least a step closer to making it happen.

baconpaul commented 3 years ago

yeah that's the place to start but it's a rather long journey figuring out what the modulation means (namely how and where to round) is the slightly tricky bit that's around line 3279 of SurgeSynthesizer and you can apply it there

and then the final hard part is: most of the things aren't stable under int modulation so what you really want to do is have a modulatable int and a non-modulatable int

and then you get the ui problem of how to modulate the things we have replaced as menus and buttons

baconpaul commented 3 years ago

oh and you have to do the voice side also into the local copy of the modulation

mkruselj commented 3 years ago

Oh and there's also scaling to min/max, because modulation output is [-1, 1]... Sheesh.

baconpaul commented 3 years ago

yeah its one of those things that is quite hard to get right even though each step is pretty clear.

sense-amr commented 3 years ago

whats the latest Surge innovations folks ?

On Sun, Mar 7, 2021 at 1:40 AM Paul notifications@github.com wrote:

yeah its one of those things that is quite hard to get right even though each step is pretty clear.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/surge-synthesizer/surge/issues/235#issuecomment-791963549, or unsubscribe https://github.com/notifications/unsubscribe-auth/AALPGEZ3SO4E2O44QV5AMUDTCI5F3ANCNFSM4GOUQDRQ .

-- Best..

Sense :: neural networks are formed when we allow ourselves to feel ::

Latest Video: https://www.youtube.com/playlist?list=PL91KJT-XwVma-ah4fjILEE61CRqMtXxZc

Latest Album: https://senseaudio.bandcamp.com/album/inside https://senseaudio.bandcamp.com/album/a-slow-but-sure-demise

Sense videos: https://www.youtube.com/user/senseTUBE https://www.youtube.com/playlist?list=PL91KJT-XwVmblQpiVaf36OOVPjYsR44be Sense FPV Videos: https://www.youtube.com/playlist?list=PL91KJT-XwVma-ah4fjILEE61CRqMtXxZc

Sense Wordpress: https://senseaudio.wordpress.com/

Sense Music can be found here/

Music Listening / Licensing http://senseaudio.bandcamp.com/ https://open.spotify.com/artist/6688Ksg7oVmURszh8ot3FU http://soundcloud.com/sense http://hearthis.at/sense

Discogs: http://discogs.com/artist/Sense

mkruselj commented 3 years ago

Feel free to check the nightlies!