[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 |