Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADSR Envelope #2

Open
JosephHinz opened this issue Feb 15, 2022 · 2 comments
Open

ADSR Envelope #2

JosephHinz opened this issue Feb 15, 2022 · 2 comments

Comments

@JosephHinz
Copy link
Collaborator

Hi James,

While working with the ADSR envelope code, I was getting no release at the end. Plotting the envelope generated the plot:
image
(For a sound length of 1 second)

I've applied a fix and extension to the envelope code in mine to overcome this problem, but thought you would like to know the fix applied:

`nlen=params['note_length']
edict=params[f'{etype}_envelope']

    # read envelope params from dictionary
    a = edict['A']
    d = edict['D']
    s = edict['S'] #s now defines the time length of the sustain
    r = edict['R']
    a_k = edict['Ac']
    d_k = edict['Dc']
    s_k = edict['Sc'] #s_k defines the value the envelope sustains at
    r_k = edict['Rc']
    lvl = edict['level']
    
    # effective input sample times, clipped to ensure always defined
    sampt = samp/self.samprate
    
    # handy time values
    t1 = a 
    t2 = a+d
    t3 = a+d+s
    t4 = a+d+s+r #added this to separate the envelope length from the sound length (allows for a time period of silence at the end)

    # determine segments and envelope value when note turns off
    #fixed envelope segments to accommodate new variables
    a_seg = lambda t: 1-env_segment_curve(t, a, 1, -a_k)
    d_seg = lambda t: s_k+env_segment_curve(t-t1, d, 1-s, d_k)
    s_seg = lambda t: s_k
    o_seg = lambda t: 0.

    if nlen < t1:
        env_off = a_seg(nlen)
    elif nlen < t2:
        env_off = d_seg(nlen)
    else:
        env_off = s_k

    r_seg = lambda t: env_segment_curve(t-t4+r, r, env_off, r_k) #fixed the release section to accommodate new variables

    # conditionals to determine which segment a sample is in
    # fixed conditionals to accommodate new variables
    a_cond = sampt < t1
    d_cond = np.logical_and(sampt<min(t2,nlen), sampt>=t1)
    s_cond = np.logical_and(sampt<min(t3,nlen), sampt>=min(t2,nlen))
    r_cond = np.logical_and(sampt<t4, sampt>=min(t3,nlen))
    o_cond = sampt >= t4

    # compute envelope for each sample 
    env =  np.piecewise(sampt,
                        [a_cond, d_cond, s_cond, r_cond, o_cond],
                        [a_seg, d_seg, s_seg, r_seg, o_seg])
    return lvl*env`

This new code gives the following plot:
image

@james-trayford
Copy link
Owner

james-trayford commented Feb 21, 2022

@JosephHinz great catch on a relatively untested part of the code, I will look into this. If possible, you can make a merge request on this file and we can incorporate your changes directly into the main code to give you proper attribution on any fix. Let me know if you have any questions about this.

@james-trayford
Copy link
Owner

NB it seems like in your example with the old version of the code the envelope was shooting past zero at 1.3s, so you get a signal with an inverted phase, but approaching an absolute volume level of ~ 0.1, explaining why the sound was not dying off

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants