Tuesday, February 26, 2019

ex5. adsr opcode

The adsr opcode is used to create an envelope with attack, decay, release time as well as sustain level.


This program uses an adsr envelope on the right channel as we can see by opening in program like Audacity.


# ex5.py
# adsr envelope function

from csd import CSD
from opcodes import envelope

csd = CSD(__file__)

csd.begin()

csd.add('giSine ftgen 0, 0, 2^10, 10, 1')

csd.add_instrument(
    num = 1,
    opcodes = [envelope.line(
                   sig_out = 'kfreq',
                   end_pts = [2,8]
                   ),
               'kres lfo 220,2',
               envelope.linen(
                   sig_out = 'kenv',
                   rise = 'idur/40',
                   decay = 'idur/40'
                   ),
               envelope.adsr(
                   sig_out = 'kadsr',
                   ),
               'aOsc poscil 0.5, kfreq+kres, giSine',
               'outs kenv*aOsc, kadsr*aOsc' ])

csd.middle()

csd.add('i 1 0 40')

csd.end()

We use envelope.py from opcodes folder.


# envelope.py
# ver 0

import sys

#1. adsr
def adsr(**dic):
    ''' Calculates the classical ADSR envelope using linear segments.
    sig_out
    attack, duration of attack phase
    decay, duration of decay
    sustain_level, level for sustain phase
    release, duration of release phase
    delay, period of zero before the envelope starts '''
    sig_out = dic.get('sig_out', '')
    if sig_out == '':
        print('We need sig_out for adsr')
        sys.exit(-1)
    attack = dic.get('attack','0.1*idur')
    decay = dic.get('decay', '0.1*idur')
    sustain_level = dic.get('sustain_level', 0.5)
    release = dic.get('release', '0.1*idur')
    delay = dic.get('delay', 0)
    t = sig_out,attack,decay,sustain_level,release,delay
    return '%s adsr %s,%s,%s,%s,%s' % t


#2. line
def line(**dic):
    ''' Trace a straight line between specified points.
    sig_out
    end_pts, [ia, ib] where ia is start value and ib is value after dur
    dur, duration in seconds of segment '''
    sig_out = dic.get('sig_out', '')
    if sig_out == '':
        print('We need sig_out for line')
        sys.exit(-1)
    end_pts = dic.get('end_pts', [])
    if len(end_pts) != 2:
        print('We need end_pts (2-len) for line')
        sys.exit(-1)
    dur = dic.get('dur', 1)
    return '%s line %s,%s,%s' % (sig_out,end_pts[0],dur,end_pts[1])

#3. linen
def linen(**dic):
    ''' Applies a straight line rise and decay pattern to an input amp signal
    sig_out, amp
    rise, rise time in seconds. None, if <= 0.
    dur, overall duration in seconds.
    decay, decay time in seconds. Zero means no decay. '''
    sig_out = dic.get('sig_out','')
    if sig_out == '':
        print('We need sig_out for linen')
        sys.exit(-1)
    amp = dic.get('amp', 1)
    rise = dic.get('rise', '0.1*idur')
    dur = dic.get('dur', 'idur')
    decay = dic.get('decay', '0.1*idur')
    return '%s linen %s,%s,%s,%s' % (sig_out,amp,rise,dur,decay)

The video with the sound is here.

No comments:

Post a Comment