Skip to content

Commit

Permalink
Fixed to ADSR Analog Mode
Browse files Browse the repository at this point in the history
ADSR analog mode had two bugs

1. It misused _mm_and_ps so was incorrectly rounding decay time
2. It didn't allow for swells in sustain once the sustain stage
   was underway

This fixes both those problems. In some cases the fix to surge-synthesizer#1 will
change the sound of patches by making the decay time slower (but
more correct).

Closes surge-synthesizer#1439
Closes surge-synthesizer#825
  • Loading branch information
baconpaul committed Jan 8, 2020
1 parent 5b678cc commit eaafe5b
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 75 deletions.
18 changes: 17 additions & 1 deletion scripts/patch-tool/patch-grep.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,22 @@ def sceneFun(xml):
return False


def hasAnalogEnv(xml):
try:
pt = xml.getElementsByTagName("patch")[0]
aem = 0
aem = aem + int(pt.getElementsByTagName("a_env1_mode")[0].attributes["value"].nodeValue)
aem = aem + int(pt.getElementsByTagName("a_env2_mode")[0].attributes["value"].nodeValue)
aem = aem + int(pt.getElementsByTagName("b_env1_mode")[0].attributes["value"].nodeValue)
aem = aem + int(pt.getElementsByTagName("b_env2_mode")[0].attributes["value"].nodeValue)

if aem > 0:
return True
return False
except:
return False


def containsFX(xml):
try:
pt = xml.getElementsByTagName("patch")[0]
Expand All @@ -46,7 +62,7 @@ def containsFX(xml):


def target(xml):
return containsFX(xml)
return hasAnalogEnv(xml)


def patchToDom(patch):
Expand Down
16 changes: 14 additions & 2 deletions src/common/dsp/AdsrEnvelope.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,13 @@ class AdsrEnvelope : public ModulationSource

bool gate = (envstate == s_attack) || (envstate == s_decay);
__m128 v_gate = gate ? _mm_set_ss(v_cc) : _mm_set_ss(0.f);
__m128 v_is_gate = _mm_cmpgt_ss( v_gate, _mm_set_ss( 0.0 ) );

discharge = _mm_and_ps(_mm_or_ps(_mm_cmpgt_ss(v_c1_delayed, one), discharge), v_gate);
// The original code here was
// _mm_and_ps(_mm_or_ps(_mm_cmpgt_ss(v_c1_delayed, one), discharge), v_gate);
// which ored in the v_gate value as opposed to the boolean
discharge = _mm_and_ps( _mm_or_ps(_mm_cmpgt_ss(v_c1_delayed, one), discharge), v_is_gate );

v_c1_delayed = v_c1;

__m128 S = _mm_load_ss(&lc[s].f);
Expand All @@ -174,7 +179,14 @@ class AdsrEnvelope : public ModulationSource
__m128 v_release = v_gate;

__m128 diff_v_a = _mm_max_ss(_mm_setzero_ps(), _mm_sub_ss(v_attack, v_c1));
__m128 diff_v_d = _mm_min_ss(_mm_setzero_ps(), _mm_sub_ss(v_decay, v_c1));

// This change from a straight min allows sustain swells
__m128 diff_vd_kernel = _mm_sub_ss(v_decay, v_c1);
__m128 diff_vd_kernel_min = _mm_min_ss(_mm_setzero_ps(), diff_vd_kernel );
__m128 dis_and_gate = _mm_and_ps(discharge, v_is_gate );
__m128 diff_v_d = _mm_or_ps(_mm_and_ps(dis_and_gate, diff_vd_kernel),
_mm_andnot_ps(dis_and_gate, diff_vd_kernel_min));

__m128 diff_v_r = _mm_min_ss(_mm_setzero_ps(), _mm_sub_ss(v_release, v_c1));

// calculate coefficients for envelope
Expand Down
Loading

0 comments on commit eaafe5b

Please sign in to comment.