Post by mrfretless5 on Jun 18, 2022 23:24:00 GMT
I have been thinking about this situation, often many Synth AU sounds get cut off abruptly when I want to stop playing a loop/sequence/clip, but I wanted to decrease volume "gradually" (lets say over 4-5 seconds) over-time.
For example, the Note Off I would want to replace with a fade out is : B4 28 00
Is there a way to do this with SB? or am I thinking about this in a wrong way?
I found another thread that showed something similar that looked like this:
The OP wanted to start with this line below, but decrease gradually the velocity
B0 11 07 = B0 1F 00 #foot controller to mute mixer (volume 0)
# Loop with one variable for the CC value (64 down to 0) and another to pace the fade (linearly) by delaying each CC
IF M0 == B0 11 07
# I0 = cc value, I1 = delay in ms
ASS I0 = 40 0
IF I0 < FFFF +L # loop while I0 >= 0
SND B0 1F I0 +DI1 # send CC with value + delay
MAT I0 = I0 - 1 # decrement CC value (I0)
MAT I1 = I1 + A # add 10ms to next CC
XX = XX +B
In my case the Note Off is "B4 28 00", so I guess the script should start like this:
IF M0 == B4 28 00
Not sure about hoe the SND line should look like, because in my case I want to lower the volume of the note...
Does this make sense, any idea how to make this happen?
Thanks in advance
Post by mrfretless5 on Jun 18, 2022 23:59:04 GMT
This is what I have so far...
IF M0 == 84 28 00 # Event is E1 (28) Note Off
ASS I0 = 7F 0
IF I0 < FFFF +L # Loop while I0>0
SND 94 28 I0 +DI1 # Send note with value + delay
MAT I0 = I0 - 1
MAT I1 = I1 + A
XX = XX +B
This delays the Note Off, but I don't perceive a "gradual" fade out
Is there a way to do a Fade out using StreamByter?
Post by uncledave on Jun 19, 2022 0:51:33 GMT
Sending repeated Note Ons with lower velocity has no effect, because the note is already sounding and you cannot play the same note twice. You would need to fade the actual volume. Many apps respond to CC# 7, "volume". Of course, you'd need to know the starting value, and raise it back up for the next use.
Does the app respond to aftertouch (Channel Pressure)? Modulating that might work, depending on how it's configured in the target app.
Also, I don't believe it makes sense to embed those remapping rules in procedural code. Use the Block keyword to block the original note off. Also, you should eventually send a delayed Note Off, otherwise the synth thinks there's a hung note.
Post by uncledave on Jun 19, 2022 22:45:16 GMT
Here's a sample which works. When the trigger arrives, it begins lowering a CC from 127 to zero over 5 seconds. When it reaches zero, it sends the note off trigger, and raises the CC back to 127 2 seconds later. It uses the ability to send an internal SysEx message to manage the loop, so there's no need to stack up multiple pending messages. The factory BlueVelvet patch is an example of this. Once triggered, Sub TakeStep adjusts the CC and sends the SysEx message to trigger the next step, which calls TakeStep again. The cycle stops when the value becomes small. I've used aliases for most variables and constants, trying to make it clear. The setup is shown after the script.
A particular advantage of this method is that the complete fade sequence is not cast in stone. Other events could arrive and alter the sequence, maybe fade back up, or cut sharply.
Set Name CCFade
Alias $5 valueStep # change in value each step
Alias $5 decayTime # fade time in sec
Alias $40 triggerNote # this note off starts fade
Alias 8 ccNumber # CC to control
Alias $127 nominalValue # start and end CC value
# this internal SysEx message uses the arbitrary index 17
define repeatEvent F0 7D 17 F7
# saved values
Ass J00 = 0 0 0 0 0 0 0 0
Alias J00 balanceRemaining
Alias J01 delayTime
Alias J02 holdNote
Alias J03 holdValue
# returns the cycle delay in ms to go from start to 0 in steps
# of pStep in pDecay seconds. Using precision register for
# large numbers.
Sub CalcDelayTime pResult pStep pStart pDecay
Mat P00 = $1000 * pDecay
Mat P00 = P00 * pStep
Mat P00 = P00 / pStart
Ass pResult = P00
# check before subtract to avoid negative
If balanceRemaining >= valueStep
Mat balanceRemaining = balanceRemaining - valueStep
Send B0 ccNumber balanceRemaining
Send repeatEvent +I +DdelayTime
Send 80 holdNote 0
# delay fade up in case of note decay
Send B0 ccNumber holdValue +D2000
Sub BeginFade pNote pStart
Ass balanceRemaining = pStart
Ass holdValue = pStart
CalcDelayTime delayTime valueStep pStart decayTime
Ass holdNote = pNote
End # Initialization ——————————————————————————
If M0 == 80 triggerNote
BeginFade M1 nominalValue # start the fade sequence
If M0 == repeatEvent
TakeStep # continue fading
The keyboard is routed into the script, and on to the instrument and AUM's MIDI Control. MIDI control for the fader is configured as shown. AUM conveniently sets the range to the default fader level (71%), so when we send 127, it sets the fader back to the default value (not maximum). Note that AUM has default mappings for the faders, which you can use or override as desired.