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