surge-synthesizer / surge

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

Tempo sync on modulation #1948

Open baconpaul opened 4 years ago

baconpaul commented 4 years ago

Right now TempoSync works like this

  1. Temposync a parm
  2. When you edit the param, bound_value sets you to the right fraction
  3. Then apply modulation
  4. Then in-dsp multiply by ratio

So in short, rate = ratio * ( quantize(value) + mod )

this means if you set to 1/8 note and modulate you move off an 1/8 note. Fine

But there's another mode where you quantize the modulation. So rate = ratio * ( quatize( value + mod ) ) so you hop from 1/8 to 1/4 tripelet next or whatever. And once you have that you can do lots of things

To do this

  1. Add a quantization function to storage which by default returns val * ts_ratio
  2. Add a new mode to parameter for ts_modquantization and menu and streaming and a can function
  3. Modify said quantization function to do the right thing. Use it in bound value.
  4. Apply can_ts_mod to LFO rate. Use said function everywhere we check temposync
  5. Test test test
  6. March across other params
K0rrid0r commented 4 years ago

I'm putting my version of explaining it here as i don't have the "know how" how to implement it in code, but i think you will perfectly understand in a very clear way what i mean now @baconpaul once you read this.

Korridor 4:55 AM yesterday How would one go on implementing forced quantized timing movements in a LFO when the source signal is free and not quantized to anything?

Lets say LFO1 is set to tempo sync in 'straight' timing and then it's rate is being modulated by LFO2 with a sine wave that is not tempo synced nor in any timing or in another timing. (the important thing in this example is that it's not a S&H signal, random stepped, random noise stepped or a step seq signal that is doing the modulation, I'm going to explain why soon)

What I'm after is a forced quantized movement that jumps LFO1 from one quantized state to next quantized state within the 'straight' timing numbers (in this example). If we can choose which timing steps to involve in the movement of the rate slider of LFO1 it would be even better and more advanced, but for the sake of the example we want to travel within the timings in DAW bpm tempo sync and within 'straight'.

So, LFO2 sends a sine waveform and will only move LFO1 slider when the amplitude of the sine wave of LFO2 is hitting these timing values within the code and chosen timing, lets say

surge straight timing

So why do i chose to have this example with a sine wave first of all and not involving S&H signal, random stepped, random noise stepped or a step seq signal that is doing the modulation? That is because the nature of a free sine wave is interesting in the relation to the timing intervals to create a 'random' yet not random signal effect of LFO1.

Lets now involve a third LFO, LFO3 is sending another sine wave to LFO2 rate slider to create a more complex signal that LFO1 is receiving. And lets involve a fourth LFO, LFO4 is sending another sine wave to LFO3 etc.

Lets say we choose to have all 11 remaining LFOs modulating each others rates with sine wave signals just to have a "bag of semi random signals" that all have one goal task, namely to give LFO1 a very complex signal to work with.

If one can imagine now how LFO1 would behave according to this system, it would sound very complex and LFO1 would behave almost life like, like its deciding "stuff" on its own, but its not ofc. We just want it to sound like it does. Now we also take the output of LFO1 and link it back to one of our other LFOs between LFO2-12, to achieve an even more complex yet 'take forever possibly days or years to come back to the same state that was initialized upon PLAY in the DAW.

I have done many systems like this involving much more LFOs all modulating each other in this exact way (but without the benefit of the timing quantization).

Have have --cheated-- when i have done this and created the quantized states with DAW tempo synced S&H signals, random stepped, random noise stepped or a step seq modulating the LFOs to create a "turing like" signal behavior. To 'cheat' in this way according to the rules of this example can of course sound epic and will sound very complex to, but we are leaving the task of quantization to the algorithm of 'random' which in a philosophical sense is not that interesting if you want to achieve something that sounds really 'organic' and 'life like' and have it created by itself and by -yourself-, your own LFO2-12 values you have chosed are what you rely on. as an interesting source for an outcome.

Here is an example of a system like this that is closed on itself and only answer to itself, forever in a semi random way.

https://www.youtube.com/watch?v=S4TKuZfRWlM

Look at how the dials are achieving a "call and response" effect. This is what i want to 'take' values from and apply on LFO1 with this feature. Right there one will create something that sounds perfect timed and quantized and sound like it was produced in an extremely advanced way.

Here i explain a system like this in more detail. Please watch it to further understand the philosophy of what i mean and how it is used to create a whole track by just attaching values from the 'chaos system' at the right places, a whole track is created by almost not doing anything.

https://www.youtube.com/watch?v=Hhxs3o_bXRs

I hope you understand how powerful a feature like this would be. And now once we have it settled, we can of course introduce tempo synced S&H signals, random stepped, random noise stepped or a step seq in the signal flow to have more variation. But i thought it was interesting to base the values of LFO2-12 in floating values and no 'still' values just because we were going to introduce it later from LFO1 anyway, and that value would be based on the values received from LFO2-12 whcih makes the whole thing to me very philosophical and interesting.

LFO1 would act very robotic like, it would sound like a language almost.

baconpaul commented 4 years ago

Very interesting and yeah totally compatible with what I wrote as an implementation plan.

I like this idea a lot and now I see how to make it non impossible I might give it a try

Always been interested in music which is long phrasing’s.

Only trick will be some things are not stable under sudden jumps. Lfo rate is but I think other things may pop and click. So to my plan above also add a “can-temposyncmod” so we can port control by control

K0rrid0r commented 4 years ago

But before this is done. This LFO deform + S&H + rate thing issue that we have discussed in Slack with Surge crashing/freezing/shutting/clipping off needs to be fixed. otherwise this is not going to work at all. Ill write an issue now.

baconpaul commented 4 years ago

I think they are separate issues - but agree we need to get to the bottom of that one too!

K0rrid0r commented 4 years ago

So last night in sleep i was continuously thinking about this tempo sync on modulation and figured out a few things that needs to work in order for this to sound good and not just "doing it's task". I will continue to use LFO1 as the example candidate.

.1 The phase of the waveform in LFO1 needs to be able to reset itself to starting position every time it latches onto a new timing division, this could be an option you choose to have on/off otherwise we force people into having a certain sound/travelling within timings when using this feature. However, in most cases what i think most people would want including myself is a reset of the waveform of LFO1 to starting position. This will allow for a sound if applied to anything to sound very exact and correctly timed. Otherwise it will just scan through the timings and it will create a different function and if applied, sound all together something that will just resemble the waveform of LFO2 (if this is going very fast)

This is what I'm experiencing right now with the step increment formula (from Fruity Formula Controller) i found in FL Studio, that is finds the spots on the LFO rate (Fruity Peak Controller) where the different timings are but it dosen't reset the waveform when reaching a new timing.

.2 Another important and probably essential option that we briefly discussed in slack to have within this is the option to choose timing divisions that LFO1 will latch onto when receiving signal from LFO2. For a good sound i imagine actually most people would --not-- want LFO1 to scan through all timings available, straight, dotted and triplets. It does not sound good and rhythmically will not sound correct nor good, it will sound extremely chaotic only, which of course could be something one wants. But the option to choose timings to latch onto is important to be creative and have something unique and rhythmically "fit".

Side note: combining timings from especially straight and dotted is really wanted.

So one option is to have these options in the pop up right click dialog that appears when you right click the LFO rate under "Tempo sync". The options that needs to be addressed are the following.

Most important . Reset waveform phase when reaching a new timing . Choose straight, dotted or triplet timings to latch onto

Less important . Free latching (meaning it just latches to all timings after each other in accordance to incoming waveform signal) . Random latching of chosen timings in accordance to incoming waveform signal (needs a magnitude to know how much random it would be in relation to the base of the waveform and also if it would be bipolar or unipolar, so maybe that is not so important in this) (a timed random within something that potentially is also random (LFO2-12))

Here is an example of what it could look like, imagine a few timings are chosen in the list of dotted also when entering it.

temposync modulation example of layout

What also needs to be addressed in the code is how to highlight a "few options in a dialog list" without the dialog goes away upon first click, but this is just changing a few lines of code i guess, how those particular dialogs of straight, dotted and triplet would specifically behave.

mkruselj commented 4 years ago

What also needs to be addressed in the code is how to highlight a "few options in a dialog list" without the dialog goes away upon first click, but this is just changing a few lines of code i guess

Famous last words! (It rarely is as easy as that unless the API of VSTGUI already provides this through an argument or something. Which I am not entirely sure it does.)

K0rrid0r commented 4 years ago

Still needs to be able to work in order to have the function I'm describing for musical "niceness!, and you know what i know, we are on different levels of understanding code, i was just imaging that such a thing would be something more easy then the rest of what this whole modulation feature is requiring in code change. But i might be wrong maybe the dialog highlighting is much harder then i can imagine.

Believe me i really thought about this feature for years in detail!

baconpaul commented 4 years ago

vstgui works with multi-checks in menus. we would just do it that way.