<effect>
  <name>ADSR</name>
  <enabled>true</enabled>
  <numIns>2</numIns>
  <numOuts>2</numOuts>
  <code>if (&lt;EnveloperON&gt; == 1) then
    agate = lfo(1, &lt;Enveloper_speed&gt;,2)
    aretrig init 1
    aenv adsr140 agate, aretrig, &lt;Enveloper_attack&gt;, &lt;Enveloper_decay&gt;, &lt;Enveloper_sustain&gt;, &lt;Enveloper_release&gt;
    aout1   =   ain1 * aenv
    aout2   =   ain2 * aenv
    aout1   ntrpol    ain1, aout1, &lt;Enveloper_mix&gt;                              ; create a dry/wet mix
    aout2   ntrpol    ain2, aout2, &lt;Enveloper_mix&gt; 
else
    aout1   =   ain1
    aout2   =   ain2
endif</code>
  <comments>
DESCRIPTION:

Envelopers imposes ADSR envelopes on the incoming signal. All controllers are automatable.
Based on UDOs from Steven Yi: https://github.com/kunstmusik/libsyi/


CONTROLLERS:

ON/OFF                          -       bypass
speed                           -       frequency of imposed envelopes 
attack/decay/sustain/release    -       those parameters can be changed at k-rate
mix                             -       mix direct signal with effect    

---

version 1.01, july 2020
- added BSB information comments

version 1.0, May 2020
- initial version by Menno Knevel
       
</comments>
  <opcodeList>
    <udo>
      <opcodeName>adsr140_calc_coef</opcodeName>
      <outTypes>k</outTypes>
      <inTypes>kk</inTypes>
      <codeBody>  
  knum_samps, kratio xin
  xout exp( -log((1.0 + kratio) / kratio) / knum_samps)
    
</codeBody>
      <comments></comments>
    </udo>
    <udo>
      <opcodeName>adsr140</opcodeName>
      <outTypes>a</outTypes>
      <inTypes>aakkkk</inTypes>
      <codeBody>agate, aretrig, kattack, kdecay, ksustain, krelease xin
kstate init 0  ; 0 = attack, 1 = decay, 2 = sustain
klasttrig init -1
kval init 0.0
asig init 0
kindx = 0
kattack_base init 0
kdecay_base init 0
krelease_base init 0
kattack_samps init 0
kdecay_samps init 0
krelease_samps init 0
kattack_coef init 0
kdecay_coef init 0
ksustain_coef init 0
klast_attack init -1
klast_decay init -1
klast_release init -1
if (klast_attack != kattack) then
  klast_attack = kattack
  if(kattack &gt; 0) then
    kattack_samps = kattack * sr
    kattack_coef = adsr140_calc_coef(kattack_samps, 0.3)
    kattack_base = (1.0 + 0.3) * (1 - kattack_coef)
  else 
    kattack_samps = 0 
    kattack_coef = 0 
    kattack_base = 0 
  endif
endif
if (klast_decay != kdecay) then
  klast_decay = kdecay
  kdecay_samps = kdecay * sr
  kdecay_coef = adsr140_calc_coef(kdecay_samps, 0.0001)
  kdecay_base = (ksustain - 0.0001) * (1.0 - kdecay_coef)
endif
if (klast_release != krelease) then
  klast_release = krelease
  krelease_samps = krelease * sr
  krelease_coef = adsr140_calc_coef(krelease_samps, 0.0001)
  krelease_base =  -0.0001 * (1.0 - krelease_coef)
endif
while (kindx &lt; ksmps) do
  if (agate[kindx] &gt; 0) then
    kretrig = aretrig[kindx]
    if (kretrig &gt; 0 &amp;&amp; klasttrig &lt;= 0) then
      kstate = 0
    endif
    klasttrig = kretrig
    if (kstate == 0) then
      if(kattack &lt;= 0) then
        kval = 1.0
        kstate = 1
      else
        kval = kattack_base + (kval * kattack_coef)
        if(kval &gt;= 1.0) then
          kval = 1.0
          kstate = 1
        endif
        asig[kindx] = kval
      endif
    elseif (kstate == 1) then
      kval = kdecay_base + (kval * kdecay_coef)
      if(kval &lt;= ksustain) then
        kval = ksustain
        kstate = 2
      endif
      asig[kindx] = kval 
    else
      asig[kindx] = ksustain
    endif
  else ; in a release state
    kstate = 0
    if (kval == 0.0) then
      asig[kindx] = 0
    else 
    ; releasing
      kval = krelease_base + (kval * krelease_coef)
    if(kval &lt;= 0.0) then
      kval = 0.0
    endif
    asig[kindx] = kval  
    endif
  endif
  kindx += 1
od
xout asig
</codeBody>
      <comments></comments>
    </udo>
  </opcodeList>
  <graphicInterface editEnabled='false'>
    <gridSettings>
      <width>5</width>
      <height>5</height>
      <gridStyle>DOT</gridStyle>
      <snapGridEnabled>true</snapGridEnabled>
    </gridSettings>
    <bsbObject type='blue.orchestra.blueSynthBuilder.BSBGroup'>
      <objectName></objectName>
      <x>0</x>
      <y>0</y>
      <groupName>Group</groupName>
      <backgroundColor>0x00000033</backgroundColor>
      <borderColor>0x000000ff</borderColor>
      <labelTextColor>0xffffffff</labelTextColor>
      <titleEnabled>true</titleEnabled>
      <width>20</width>
      <height>20</height>
      <bsbObject type='blue.orchestra.blueSynthBuilder.BSBGroup'>
        <objectName></objectName>
        <x>10</x>
        <y>10</y>
        <groupName>ReverbSC</groupName>
        <backgroundColor>0x4d8080ff</backgroundColor>
        <borderColor>0x000000ff</borderColor>
        <labelTextColor>0xffffffff</labelTextColor>
        <titleEnabled>false</titleEnabled>
        <width>170</width>
        <height>20</height>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBKnob' version='2'>
          <objectName>Enveloper_sustain</objectName>
          <x>110</x>
          <y>40</y>
          <comment>can be changed at k-rate</comment>
          <automationAllowed>true</automationAllowed>
          <minimum>0.0</minimum>
          <maximum>1.0</maximum>
          <value>0.0</value>
          <knobWidth>40</knobWidth>
          <randomizable>true</randomizable>
          <valueDisplayEnabled>false</valueDisplayEnabled>
          <label>sustain</label>
          <labelEnabled>true</labelEnabled>
          <font>
            <name>System Regular</name>
            <size>12.0</size>
          </font>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBKnob' version='2'>
          <objectName>Enveloper_decay</objectName>
          <x>60</x>
          <y>40</y>
          <comment>can be changed at k-rate</comment>
          <automationAllowed>true</automationAllowed>
          <minimum>0.0</minimum>
          <maximum>1.0</maximum>
          <value>0.15000000000000002</value>
          <knobWidth>40</knobWidth>
          <randomizable>true</randomizable>
          <valueDisplayEnabled>false</valueDisplayEnabled>
          <label>decay</label>
          <labelEnabled>true</labelEnabled>
          <font>
            <name>System Regular</name>
            <size>12.0</size>
          </font>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBLabel' version='2'>
          <objectName></objectName>
          <x>20</x>
          <y>5</y>
          <label>speed</label>
          <font>
            <name>System Regular</name>
            <size>12.0</size>
          </font>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBHSlider' version='2'>
          <objectName>Enveloper_speed</objectName>
          <x>10</x>
          <y>10</y>
          <comment>frequency of imposed envelopes </comment>
          <automationAllowed>true</automationAllowed>
          <minimum>0.0</minimum>
          <maximum>60.0</maximum>
          <bdresolution>0.01</bdresolution>
          <value>18.0</value>
          <sliderWidth>190</sliderWidth>
          <randomizable>true</randomizable>
          <valueDisplayEnabled>false</valueDisplayEnabled>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBLabel' version='2'>
          <objectName></objectName>
          <x>215</x>
          <y>10</y>
          <label>mix</label>
          <font>
            <name>System Regular</name>
            <size>12.0</size>
          </font>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBKnob' version='2'>
          <objectName>Enveloper_release</objectName>
          <x>160</x>
          <y>40</y>
          <comment>can be changed at k-rate</comment>
          <automationAllowed>true</automationAllowed>
          <minimum>0.0</minimum>
          <maximum>1.0</maximum>
          <value>0.0</value>
          <knobWidth>40</knobWidth>
          <randomizable>true</randomizable>
          <valueDisplayEnabled>false</valueDisplayEnabled>
          <label>release</label>
          <labelEnabled>true</labelEnabled>
          <font>
            <name>System Regular</name>
            <size>12.0</size>
          </font>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBKnob' version='2'>
          <objectName>Enveloper_attack</objectName>
          <x>10</x>
          <y>40</y>
          <comment>can be changed at k-rate</comment>
          <automationAllowed>true</automationAllowed>
          <minimum>0.0</minimum>
          <maximum>1.0</maximum>
          <value>0.0</value>
          <knobWidth>40</knobWidth>
          <randomizable>true</randomizable>
          <valueDisplayEnabled>false</valueDisplayEnabled>
          <label>attack</label>
          <labelEnabled>true</labelEnabled>
          <font>
            <name>System Regular</name>
            <size>12.0</size>
          </font>
        </bsbObject>
        <bsbObject type='blue.orchestra.blueSynthBuilder.BSBVSlider' version='2'>
          <objectName>Enveloper_mix</objectName>
          <x>210</x>
          <y>20</y>
          <comment>mix direct signal with effect   </comment>
          <automationAllowed>true</automationAllowed>
          <minimum>0.0</minimum>
          <maximum>1.0</maximum>
          <bdresolution>0.01</bdresolution>
          <value>1.0</value>
          <sliderHeight>75</sliderHeight>
          <randomizable>true</randomizable>
          <valueDisplayEnabled>false</valueDisplayEnabled>
        </bsbObject>
      </bsbObject>
      <bsbObject type='blue.orchestra.blueSynthBuilder.BSBCheckBox'>
        <objectName>EnveloperON</objectName>
        <x>0</x>
        <y>0</y>
        <comment>bypass</comment>
        <automationAllowed>true</automationAllowed>
        <label/>
        <selected>true</selected>
        <randomizable>true</randomizable>
      </bsbObject>
    </bsbObject>
  </graphicInterface>
  <parameterList>
    <parameter uniqueId='582955857' name='Enveloper_speed' label='' min='0.0' max='60.0' bdresolution='0.01' automationEnabled='false' value='36.0'>
      <line name='' version='2' max='60.0' min='0.0' bdresolution='0.01' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='36.0'/>
      </line>
    </parameter>
    <parameter uniqueId='582955859' name='Enveloper_sustain' label='' min='0.0' max='1.0' bdresolution='-1' automationEnabled='false' value='0.0'>
      <line name='' version='2' max='1.0' min='0.0' bdresolution='-1' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='0.0'/>
      </line>
    </parameter>
    <parameter uniqueId='582955861' name='Enveloper_attack' label='' min='0.0' max='1.0' bdresolution='-1' automationEnabled='false' value='0.0'>
      <line name='' version='2' max='1.0' min='0.0' bdresolution='-1' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='0.0'/>
      </line>
    </parameter>
    <parameter uniqueId='582955863' name='Enveloper_release' label='' min='0.0' max='1.0' bdresolution='-1' automationEnabled='false' value='0.0'>
      <line name='' version='2' max='1.0' min='0.0' bdresolution='-1' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='0.0'/>
      </line>
    </parameter>
    <parameter uniqueId='582955865' name='Enveloper_decay' label='' min='0.0' max='1.0' bdresolution='-1' automationEnabled='false' value='0.15000000000000002'>
      <line name='' version='2' max='1.0' min='0.0' bdresolution='-1' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='0.15000000000000002'/>
      </line>
    </parameter>
    <parameter uniqueId='582955867' name='Enveloper_mix' label='' min='0.0' max='1.0' bdresolution='0.01' automationEnabled='false' value='1.0'>
      <line name='' version='2' max='1.0' min='0.0' bdresolution='0.01' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='1.0'/>
      </line>
    </parameter>
    <parameter uniqueId='582955869' name='EnveloperON' label='' min='0.0' max='1.0' bdresolution='1' automationEnabled='false' value='1.0'>
      <line name='' version='2' max='1.0' min='0.0' bdresolution='1' color='-8355712' rightBound='false' endPointsLinked='false'>
        <linePoint x='0.0' y='1.0'/>
      </line>
    </parameter>
  </parameterList>
</effect>