Tuesday, February 26, 2019

ex6. csound GEN10 routine

The GEN10 routine is used to generate sine tables.


Depending on the number of parameters, we can have harmonic partials.


We use a helper file, table.py, to create the string for the f statement for the table.


We use amps of [1,0.5]. That means we have fundamental (f) and first partial (at frequency 2f) with relative amp of 0.5. The actual amps will be adjusted by csound normalization.


This program uses the sine with two components in the oscillator.


# ex6.py
# GEN 10 sine table

from csd import CSD
import table
from opcodes import envelope, output, source

csd = CSD(__file__)

csd.begin()

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

csd.middle()

csd.add('i 1 0 40')

csd.add_tables([table.sine(
                    num=1,
                    amps=[1,0.5]
                    )
                ])

csd.end()

We use table.py file:


# table.py
# ver 0

import sys

#1. sine
def sine(**dic):
    ''' GEN10 — Generate composite waveforms made up of weighted sums of
    .. simple sinusoids.
    num, time(0),
    size(2**14), 2 to power or 2 to power + 1
    norm(True), whether signal should be normalized
    amps, [str1, str2, ...] where str1, str2, are relative strengths of
    .. the fixed harmonic partial numbers 1,2,3, etc., beginning in p5.
    .. Partials not required should be given a strength of zero. If only
    .. 1 component, we can write it as 1 and not [1] for simple sine '''
    num = dic.get('num', 0)
    if num == 0:
        print('We need a table number.')
        sys.exit(-1)
    time = dic.get('time', 0)
    norm = dic.get('norm', True)
    if norm: gen = 1
    else: gen = -1
    amps = dic.get('amps', [])
    size = dic.get('size', 2**14)
    if type(amps) == type(0):
        amps = [amps]
    if len(amps) == 0:
        print('amps must be a list of numbers or a number')
        sys.exit(-1)
    amps = [str(amp) for amp in amps]
    string = 'f %d %d %d %d %s' % (num, time, size, gen*10, ' '.join(amps))
    return string

We use output.py from opcodes folder:


# output.py
# ver 0

import sys

#1. out
def out(**dic):
    ''' Writes mono audio data to an external device or stream.
    sig_in '''
    sig_in = dic.get('sig_in', '')
    if len(sig_in) == '':
        print('We need sig_in for out')
        sys.exit(-1)
    return 'out %s' % sig_in

#2. outs
def outs(**dic):
    ''' Writes stereo audio data to an external device or stream.
    sig_in (2-len) '''
    sig_in = dic.get('sig_in', [])
    if len(sig_in) != 2:
        print('We need sig_in (2-len) for outs')
        sys.exit(-1)
    return 'outs %s,%s' % (sig_in[0],sig_in[1])

We also use source.py from opcodes folder:


# source.py
# ver 0

import sys

#1. lfo
def lfo(**dic):
    ''' A low frequency oscillator of various shapes.
    itype = 0 - sine, itype = 1 - triangles,
    itype = 2 - square (bipolar), itype = 3 - square (unipolar),
    itype = 4 - saw-tooth, itype = 5 - saw-tooth(down)
    sig_out, amp, freq, type '''
    sig_out = dic.get('sig_out','')
    if sig_out=='':
        print('We need sig_out for lfo')
        sys.exit(-1)
    amp = dic.get('amp', 1)
    freq = dic.get('freq', 440)
    itype = dic.get('itype', 0)
    return '%s lfo %s, %s, %s' % (sig_out,amp,freq,itype)

#2. poscil
def poscil(**dic):
    ''' High precision oscillator
    sig_out, amp, freq, and table '''
    sig_out = dic.get('sig_out','')
    if sig_out == '':
        print('We need sig_out for poscil')
        return
    amp = dic.get('amp', 1)
    freq = dic.get('freq', 440)
    table = dic.get('table', 1)
    return '%s poscil %s, %s, %d' % (sig_out,amp,freq,table)

The audio for the output file is here.

No comments:

Post a Comment