Hi Rory,
It's an interesting issue! It's actually something I've needed to
spend a little time solving myself. There's a number of issues
involved. I wrote a UDO and a test instrument as well as automated the
number of harmonics (CSD below). What I did was set a max number of
harmonics. The UDO will always recurse down the max number of
harmonics and will always call the oscil3 in each level. The reason I
used maxharmonics was so that each UDO would get initialized. The
reason I always call the oscillator was because I wanted each
oscillator to keep incrementing its phase. I used the knh to
determine if the oscillator would get mixed into the signal or not.
Now, the example is a bit harsh in that it will just cut out the
harmonic altogether or not. It would be more ideal to envelope the
harmonic or instead of using an int value for the knh to actually read
fractional part to determine an amplitude for that harmonic. (i.e.
1.5 would mean play 1st harmonic full strength, 2nd harmonic at .5).
Anyways, let me know if this is more along the lines of what you are
looking for!
steven
;
; "Recursive Opcode Example"
; by Steven Yi
;
;
; Generated by blue 0.124.3 (http://csounds.com/stevenyi/blue/index.html)
;
sr=44100
ksmps=1
nchnls=2
ga_bluemix_1_0 init 0
ga_bluemix_1_1 init 0
ga_bluesub_Master_0 init 0
ga_bluesub_Master_1 init 0
gk_blue_auto0 init 10
gk_blue_auto1 init 0
gk_blue_auto2 init 0
opcode recursiveOscil3,a,ikkp
imax, knh, kfreq, icount xin
gi_sine_table chnget "recursiveOscils.table"
if (gi_sine_table == 0) then
gi_sine_table ftgen 0, 0, 65537, 10, 1
endif
aout oscil3 1, kfreq * icount, gi_sine_table
if (icount < imax) then
a2 recursiveOscil3 imax, knh, kfreq, icount + 1
if (icount < knh) then
aout = aout + a2
endif
endif
xout aout
endop
opcode pan_gm2,aa,ak
ain, kspace xin
klast init -2
kleft init 0
kright init 0
;from MIDI GM-2 Default Pan Curve (RP-036)
;Left Channel Gain [dB] = 20*log (cos (Pi/2* max(0,CC#10 ? 1)/126)
;Right Channel Gain [dB] = 20*log (sin (Pi /2* max(0,CC#10 ? 1)/126)
if (kspace != klast) then
kpercent = (kspace + 1) / 2
kleft = ampdb(20 * log(cos($M_PI_2 * kpercent)))
kright = (kpercent == 0) ? 0 : ampdb(20 * log(sin($M_PI_2 * kpercent)))
endif
aleft = ain * kleft
aright = ain * kright
xout aleft, aright
endop
instr 1 ;testInstr
iamp = ampdb(p4)
ifreq = (p5 > 20 ) ? p5 : cpspch(p5)
kspace = p6
kenv adsr .04, .01, .95, .1
aout recursiveOscil3 10, gk_blue_auto0, ifreq
aout = aout * kenv * iamp
aleft, aright pan_gm2 aout, kspace
outs aleft, aright
endin
instr 2 ;Blue Mixer Instrument
ktempdb = ampdb(gk_blue_auto1)
ga_bluemix_1_0 = ga_bluemix_1_0 * ktempdb
ga_bluemix_1_1 = ga_bluemix_1_1 * ktempdb
ga_bluesub_Master_0 sum ga_bluesub_Master_0, ga_bluemix_1_0
ga_bluesub_Master_1 sum ga_bluesub_Master_1, ga_bluemix_1_1
ktempdb = ampdb(gk_blue_auto2)
ga_bluesub_Master_0 = ga_bluesub_Master_0 * ktempdb
ga_bluesub_Master_1 = ga_bluesub_Master_1 * ktempdb
outc ga_bluesub_Master_0, ga_bluesub_Master_1
ga_bluemix_1_0 = 0
ga_bluemix_1_1 = 0
ga_bluesub_Master_0 = 0
ga_bluesub_Master_1 = 0
endin
instr 3 ;Param: numHarmonics
gk_blue_auto0 init p4
turnoff
endin
instr 4 ;Param: Volume
if (p4 == p5) then
gk_blue_auto1 init p4
turnoff
else
gk_blue_auto1 line p4, p3, p5
endif
endin
instr 5 ;Param: Volume
if (p4 == p5) then
gk_blue_auto2 init p4
turnoff
else
gk_blue_auto2 line p4, p3, p5
endif
endin
i1 0.0 2 80 369.99445
i1 2.0 2 80 391.99545
i1 4.0 2 80 369.99445 0
i1 6.0 2 80 391.99545
i2 0 8
i3 0.3836805522 0.0001 9
i3 0.7673611045 0.0001 8
i3 1.1510416269 0.0001 7
i3 1.534722209 0.0001 6
i3 1.918402791 0.0001 5
i3 2.3020832539 0.0001 4
i3 2.6857638359 0.0001 3
i3 3.069444418 0.0001 2
i3 3.453125 0.0001 1
i3 3.859375 0.0001 2
i3 4.265625 0.0001 3
i3 4.671875 0.0001 4
i3 5.078125 0.0001 5
i3 5.484375 0.0001 6
i3 5.890625 0.0001 7
i3 6.296875 0.0001 8
i3 6.703125 0.0001 9
i3 7.109375 0.0001 10
e
On Tue, Nov 25, 2008 at 3:26 AM, Rory Walsh wrote:
> After thinking about this more I can now simplify my question down to this:
>
> Is it possible to build a recursive UDO with a k-rate variable
> determining the level of recursion?
>
> Below I've presented another example. I want to simply sum a series of
> numbers together but I want to specify the range of numbers to be
> summed.
>
> opcode test, k, kp
> krange, icnt xin ;read input parameters
> if (icnt >= krange) goto skip
> k1 test krange, icnt+1
> skip:
> ksum = icnt
> xout k1+icnt ;write output
> endop
>
>
>
> 2008/11/25 Rory Walsh :
>> Thanks Steven, I had forgotten about your article. It's not quite what
>> I'm looking for but now that I think of it I'm not sure what I am
>> doing can be done with a UDO. I need so simplify my example. I'll get
>> back you on it! Thank for taking a look.
>>
>> Rory.
>>
>> 2008/11/25 Steven Yi :
>>> Hi Rory,
>>>
>>> I'm not sure if this is exactly what you're after, but I had done this UDO:
>>>
>>> opcode yi_add_table,a,ikko
>>>
>>> itable, kenv, kpch, i_index xin
>>>
>>> itablesize = ftlen(itable)
>>>
>>> ifreq tablei i_index, itable
>>> iamp tablei i_index + 1, itable
>>>
>>> kfreq = kpch * ifreq
>>>
>>> if (iamp > 0) then
>>> asig oscil3 iamp, kfreq, gi_sine
>>> else
>>> asig = 0
>>> endif
>>>
>>> kcount = 0
>>> kenv_local = kenv
>>>
>>> loopStart:
>>>
>>> kenv_local = kenv_local * kenv
>>>
>>> loop_lt kcount, 2, i_index + 2, loopStart
>>>
>>> asig = asig * kenv_local
>>>
>>> aout = asig
>>>
>>> if (i_index < itablesize - 2) then
>>> anextsig yi_add_table itable, kenv, kpch, i_index + 2
>>> aout = aout + anextsig
>>> endif
>>>
>>> if (i_index == 0) then
>>> aout balance aout, asig
>>> endif
>>>
>>> xout aout
>>>
>>> endop
>>>
>>> in this Csound Journal article:
>>>
>>> http://www.csounds.com/journal/2006summer/controlFlow_part2.html
>>>
>>> Maybe that helps?
>>>
>>> steven
>>>
>>>
>>> On Mon, Nov 24, 2008 at 11:58 AM, Rory Walsh wrote:
>>>> Thanks Steven, changing khrm to an i-rate variable works as one would
>>>> expect. But using a kgoto doesn't work either. I'm assuming that
>>>> something like this can be done?
>>>>
>>>> Rory.
>>>>
>>>>
>>>> 2008/11/24 Steven Yi :
>>>>> Hi Rory,
>>>>>
>>>>> I think there must be an issue when you change your comparison against
>>>>> the 10 (constant) to the khrm (k-rate) that the type of goto must be
>>>>> changing. Could you do a test making khrm as ihrm to see if that
>>>>> works?
>>>>>
>>>>> steven
>>>>>
>>>>> On Mon, Nov 24, 2008 at 8:30 AM, Rory Walsh wrote:
>>>>>> One of my students was asking if there is a version of the the buzz
>>>>>> opcode that has a fade-in for each harmonic so that pops do not occur
>>>>>> in the output. I didn't know if there was and couldn't find on in the
>>>>>> manual so I set about doing a simple UDO for him. Here's what I have,
>>>>>> the problem is explained below:
>>>>>>
>>>>>> opcode testBuzz, a, kikip
>>>>>> kamp, ifreq, khrm, ifn, icnt xin ; read input parameters
>>>>>> if (icnt >= 10) goto skip
>>>>>> kenv linseg 0, 0.1, 1, 1, 1
>>>>>> a1 testBuzz kamp*kenv, ifreq, khrm, ifn, icnt+1
>>>>>> skip:
>>>>>> aout oscil kamp/khrm, ifreq*icnt, ifn
>>>>>> xout (aout+a1) ; write output
>>>>>> endop
>>>>>>
>>>>>> The problem is that if I use khrm instead of 10 in my test against
>>>>>> icnt, csound will baulks out at init-time. Any suggestions as how can
>>>>>> I do this? I'm trying to use that hkrm value toset the number of
>>>>>> harmonics.
>>>>>>
>>>>>> Rory.
>>>>>>
>>>>>>
>>>>>> Send bugs reports to this list.
>>>>>> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"
>>>>>>
>>>>>
>>>>>
>>>>> Send bugs reports to this list.
>>>>> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"
>>>>>
>>>>
>>>>
>>>> Send bugs reports to this list.
>>>> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"
>>>>
>>>
>>>
>>> Send bugs reports to this list.
>>> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"
>>>
>>
>
>
> Send bugs reports to this list.
> To unsubscribe, send email sympa@lists.bath.ac.uk with body "unsubscribe csound"
>