RobinSchmidt / RS-MET

Codebase for RS-MET products (Robin Schmidt's Music Engineering Tools)
Other
56 stars 6 forks source link

Just finished my analog very natural sounding ADSRs #79

Closed elanhickler closed 7 years ago

elanhickler commented 7 years ago

Here are the interesting bits, the attack and decay shape

image

This ADSR is linear until you engage feedback, then the entire envelop morphs into very natural curves. The only problem I have is that I'd like to scale the decay/release times to be powers of 10 longer as feedback increases. If you know how to solve this at the top of your head let me know. feedbackAmt is 1.e-6 to 1, but as you can see I also scale it back for decay release by multiplying that by .01, so we get a range of near 0 to .01. I think at .01 the decay speed should be *1000 or something.

here's a demo of BasicOscillator and LinearADSR classes:

http://www.elanhickler.com/_/envelope_test_basic_oscillator.mp3

At some point I will make a loop function, and turning up the feedback will then give you chaotic retriggering, self-oscillator type sounds, it will scream and sound like soft sync I am sure.

Edit: I just went through some of your code for AnalogEnvelope, it is WAYYY TOO COMPLICATED! I tried to use that for SpiralGenerator and gave up. Jeez man. Haha. You also have some unecessary stuff that should be handled outside the envelope like scaling/amplitude/velocity/note on/off.

RobinSchmidt commented 7 years ago

I'd like to scale the decay/release times to be powers of 10 longer as feedback increases. If you know how to solve this at the top of your head let me know

i think:

actualAttack = dialedAttack * pow(10, feedback)

can probably be optimized as:

actualAttack = dialedAttack exp(feedback log(10))

exp is (a lot) cheaper than pow, log(10) should be a defined constant (or constexpr or whatever). ...but really, just from the top of my head. no guarantees

http://www.elanhickler.com/_/envelope_test_basic_oscillator.mp3

sounds good

I just went through some of your code for AnalogEnvelope, it is WAYYY TOO COMPLICATED! You also have some unecessary stuff that should be handled outside the envelope

hmm..apparently, i found it convenient to handle it directly there, back then. i may consider handling it outside when i drag it into rapt. maybe a simpler envelope could be factored out and the more complicated one realized as subclass.

RobinSchmidt commented 7 years ago

btw.: what happens if feedback gets negative? is that useful, too?

elanhickler commented 7 years ago

heehee I forgot to try that. I will ASAP and let you know.

RobinSchmidt commented 7 years ago

maybe it bends into the other direction then? that would be my first guess

elanhickler commented 7 years ago

Yeah, it increases to infinity like an amplifier, nothing interesting really happens unless you like decay also being an attack stage. With the right settings it will actually decay with the opposite of exponential curve, but... what I could do instead is just use a different equation instead of using negative feedback to get the same result and avoid infinite amplification.

RobinSchmidt commented 7 years ago

ha! i just randomly opened RS-MET/Temp/Ideas.txt file again and what do i find there:

SmoothedValue:
-see class juce::LinearSmoothedValue
-generalize to an update equation: x[n+1] = a*x[n] + b
-allows for linear and exponential smoothing and anything between
-general term is: 
 x[n] = a^n * x[0] + b * sum_{k=0}^{n-1} a^n 
      = a^n * x0   + b * n * a^n 
      = a^n * (x0 + b*n)
-maybe we can have a kind of "exponentiality" parameter p between 0..1
 with 0, we have linear scaling (a = 1), with 1 exponential (b = 0)
 maybe a = 1-p, b = p * c (for some suitable c, maybe 1/N (?) where N 
 is the desired number of updates to reach the target)

i think, the idea quite similar to what happens in your env.

elanhickler commented 7 years ago

I think I will use the S curve equation for the LFO ADSR, seems like that would be most organic for something like vibrato slowly coming in, it also reminds me of a curve for flute/blown isntruments.

(1-current_val)*current_val*feedbackAmt;

Yeah my ADSR is really unweildly, I'd have to have a knob per stage instead of one feedback knob to make it more controllable. The timings are completely whack with feedback no matter what i do, I mean, once you have a bit of feedback, timings become short even if you set, for example, attack time to 10000. Ultimately I'd need a solution where feedback is reduced as you increase timings or something.

Anyway, what i created is is good enough for now.

RobinSchmidt commented 7 years ago

http://www.elanhickler.com/_/envelope_test_basic_oscillator.mp3

..could probably turned into a nice "pizzicato-string" patch. ...one of my favourite sounds. like this:

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

:-) ...with a bit of a lot of reverb

elanhickler commented 7 years ago

omg I just thought of something... of course!

Intead of having feedback be controlled by a knob while decay time is controlled by another knob... have the feedback BEEEE the timing control!!!!!!!!!

So with more decay you become more linear, less decay you become more snappy/exponential. Then i think the feedback knob can still be utilized to make the longer decay times more exponential. So it's almost like i'm doing the reverse of what I'm doign now. Decay time = decay feedback amount. Feedback amount = decay time, or something.

elanhickler commented 7 years ago

Yep, that worked. Envelope responds much better to user controls and by increasing feedback knob you change the entire shape of the envelope, and it becomes snappier in a nice natural way.