[Csnd] python language proxy
| Date | 2008-01-17 22:07 |
| From | Eduardo Moguillansky |
| Subject | [Csnd] python language proxy |
Hi. I am new to this list and quite new to csound.
For a project involving code generation in python using the api I have been
designing a language proxy in python, quite similar to what sclang is in
supercollider. I have already implemented many of the opcodes but was having
doubts about how to approach if/goto. So my questions are:
- how efficient are these constructs?
- Supercollider does not have such constructs, uses always signals to
control flow. Is there a similar way in csound?
And one last question: is there any way to add instrs/opcodes on the fly?
thanks!
The general approach is quite similar to the approach in supercollider, in
the sense that not every python expression is valid in an instrument or a
user defined opcode: only opcodes, mathematical expressions and other ad hoc
constructs.
Here is how an instrument looks, based on an example of the manual:
from cslang import *
orc = Orchestra(sr=44100, kr=4410, nchnls=1)
@instr
def example_phaser1(amp, order, freq, feedback):
amp *= 0.05
harms = orc.sr * .4 / 100
envelope = LinSeg.kr(0, 0.2, amp, self.dur - .2, amp, .2, 0)
signal = GBuzz.ar(amp=1, cps=100, num_harmonics=harms,
lowest_harmonic=1, mul=0.95)
kfreq = Oscili.kr(5500, freq) + 5600
out = Phaser1.ar(source=signal, freq=kfreq, order=order,
feedback=feedback)
Out((signal + out) * envelope)
The same, but with an alternative syntax based on pipes and partial
evaluation:
@instr
def example_phaser1_bis(amp, order, freq, feedback):
amp *= 0.05
harms = orc.sr * .4 / 100
signal = GBuzz.ar(amp=1, cps=100, num_harmonics=harms,
lowest_harmonic=1, mul=0.95)
envelope = LinSeg.kr(0, 0.2, amp, self.dur - .2, amp, .2, 0)
(signal
|
Phaser1.ar(source=_,
freq=Oscili.kr(5500, freq) + 5600,
order=order,
feedback=feedback)
|
(_ + signal ) * envelope
|
Out)
A still simpler instrument, played for 10 secs:
@instr
def simple(freq=440, amp=0.5):
envelope = LinSeg.kr(0, dur * .2, amp, dur * .8, amp, dur, 0)
(SinOsc.kr(20)
|
SinOsc.ar(freq + _)
|
(_ * envelope)
|
Out)
sco = Score()
sco.play(Event(simple(freq=1000), t=now, dur=10))
A simple opcode (you do not need to say what the opcode returns, it is
inferred):
@opcode
def freq_upshift(ain, freq):
"""
a variation of the freqShift UDO
"""
real, imag = Hilbert.ar(ain)
asin = SinOsc.ar(freq)
acos = SinOsc.ar(freq, phase=0.25)
mod1 = real * acos
mod2 = imag * asin
return (mod1 + mod2) * 0.7
--
View this message in context: http://www.nabble.com/python-language-proxy-tp14923098p14923098.html
Sent from the Csound - General mailing list archive at Nabble.com.
|
| Date | 2008-01-18 10:53 |
| From | Cesare Marilungo |
| Subject | [Csnd] Re: python language proxy |
Interesting project! -c. Eduardo Moguillansky wrote: > Hi. I am new to this list and quite new to csound. > For a project involving code generation in python using the api I have been > designing a language proxy in python, quite similar to what sclang is in > supercollider. I have already implemented many of the opcodes but was having > doubts about how to approach if/goto. So my questions are: > - how efficient are these constructs? > - Supercollider does not have such constructs, uses always signals to > control flow. Is there a similar way in csound? > > And one last question: is there any way to add instrs/opcodes on the fly? > > thanks! > > The general approach is quite similar to the approach in supercollider, in > the sense that not every python expression is valid in an instrument or a > user defined opcode: only opcodes, mathematical expressions and other ad hoc > constructs. > > Here is how an instrument looks, based on an example of the manual: > > from cslang import * > > orc = Orchestra(sr=44100, kr=4410, nchnls=1) > > @instr > def example_phaser1(amp, order, freq, feedback): > amp *= 0.05 > harms = orc.sr * .4 / 100 > envelope = LinSeg.kr(0, 0.2, amp, self.dur - .2, amp, .2, 0) > signal = GBuzz.ar(amp=1, cps=100, num_harmonics=harms, > lowest_harmonic=1, mul=0.95) > kfreq = Oscili.kr(5500, freq) + 5600 > out = Phaser1.ar(source=signal, freq=kfreq, order=order, > feedback=feedback) > Out((signal + out) * envelope) > > The same, but with an alternative syntax based on pipes and partial > evaluation: > > @instr > def example_phaser1_bis(amp, order, freq, feedback): > amp *= 0.05 > harms = orc.sr * .4 / 100 > signal = GBuzz.ar(amp=1, cps=100, num_harmonics=harms, > lowest_harmonic=1, mul=0.95) > envelope = LinSeg.kr(0, 0.2, amp, self.dur - .2, amp, .2, 0) > > (signal > | > Phaser1.ar(source=_, > freq=Oscili.kr(5500, freq) + 5600, > order=order, > feedback=feedback) > | > (_ + signal ) * envelope > | > Out) > > A still simpler instrument, played for 10 secs: > > @instr > def simple(freq=440, amp=0.5): > envelope = LinSeg.kr(0, dur * .2, amp, dur * .8, amp, dur, 0) > > (SinOsc.kr(20) > | > SinOsc.ar(freq + _) > | > (_ * envelope) > | > Out) > > sco = Score() > sco.play(Event(simple(freq=1000), t=now, dur=10)) > > A simple opcode (you do not need to say what the opcode returns, it is > inferred): > > @opcode > def freq_upshift(ain, freq): > """ > a variation of the freqShift UDO > """ > real, imag = Hilbert.ar(ain) > asin = SinOsc.ar(freq) > acos = SinOsc.ar(freq, phase=0.25) > mod1 = real * acos > mod2 = imag * asin > return (mod1 + mod2) * 0.7 > > > -- www.cesaremarilungo.com |