Re: Delay zak variables
Date | 2007-09-19 11:12 |
From | Alex Weiss |
Subject | Re: Delay zak variables |
Dear Steven, thanks a lot for your help. Don't worry, I know a bit about programming and recursion, so your explanations made perfectly sense. Your UDO worked as expected. I am really relieved that there is a way to tackle my problem. Also, I knew of your articles, but it seems like I didn't read the second part. There's just one thing I don't unterstand: Why do izakstart and izakend have to be i-rate? Oh, and I stumbled across another problem: Let's say I want to output the last nchnls a-rate signals of my zak array (i.e. the last two for nchnls=2). Obviously, I could simply get all the signals needed (using zar) and output them. However, this would require changing the code everytime nchnls changes. Is there a way simplify the process, so that no code changes are required? At first, I thought that outz would do what I want, but apparently it doesn't (I have yet to find out what _exactly_ it does, since the manual remains _very_ unspecific). Alex Hi Alex, You are correct and you can not use a loop to do what you want. This being able to delay x number of signals isn't a straightforward thing to do in csound. When you call an opcode, you can imagine it being like an object and that you are calling something like vdelay.process(x). If you think of it this way, it means each time you call it, you are advancing its internal state by one step in the processing. Normally this is the expected behavior that you call it once per k- count, but if you call it multiple times the behavior won't be what you're expecting. For Csound, any time you want to process x number of signals (process a variable amount of signals) you'll need to use a recursive User Defined Opcode (UDO). It's the only way to setup things correctly and can be tricky if you are not experienced with recursive algorithms (I don't know your background). Your example does not vary the delay times so I can't really suggest a complete solution, but something like: opcode recurseVdelay 0, kii kdelay, izakstart, izakend xin azak zar izakstart adelay vdelay azak, kdelay, 5000 zaw adelay, izakstart if (izakstart <= izakend) then recurseVdelay kdelay, izakstart + 1, izakend endif endop then call it in instr code like: recurseVdelay kdelay, 0, izakspace I haven't tried the above code but I think it'll work. steven p.s. - If you haven't checked them out already, I wrote two articles for the Csound Journal on control flow which describes loops and recursive UDO's: http://www.csounds.com/journal/2006spring/controlFlow.html http://www.csounds.com/journal/2006summer/controlFlow_part2.html The whole thing about loops and why you can't call most opcodes in loops is explained in part2 in discussing when to use recursion. |
Date | 2007-09-26 17:32 |
From | "Steven Yi" |
Subject | Re: Delay zak variables |
Attachments | None |
Date | 2007-09-26 18:50 |
From | Anthony Kozar |
Subject | Re: Delay zak variables |
Will outch work here ? Anthony Steven Yi wrote on 9/26/07 12:32 PM: > I'm not really sure what outz does either! As for outputting x number > of signals to x nchnls, I'm looking and I don't happen to see any > "out" style opcode that allows writing a particular channel num. It'd > be nice to find something like: > > outnum kchannelNum, asig > > but I'm not seeing anything like that. I'm not sure there's going to > be a simple way to do this unfortunately. > > steven |
Date | 2007-09-26 19:24 |
From | "Steven Yi" |
Subject | Re: Delay zak variables |
Attachments | None |
Date | 2007-09-27 13:38 |
From | Lou Cohen |
Subject | Re: Delay zak variables |
I have written a loop to tap a delay line a variable number of times. Each tapped signal then gets added to a final output signal. I use this loop as part of an extended orchestra for live improvisation, and I confess I have not examined the code in quite awhile. But I use it every day and it works. There are some limitations: If I change the length of the delay line or the delay values of the tap time intervals, I'll hear clicks. Therefore I use a gui/knob to reduce the output level of the delay line to zero whenever I want to change those values during a performance. I then bring the level back up to an audible level. This routine makes use of table access (providing me with data I can loop upon) as well as deltap, delayw and delayr and global variables -- no zak opcodes. I hope it's commented enough to be useful. Here it is: ------------------------------------------------------ instr 900 ;delay realtime input as per user-knob ;Perform only once: get an instrument start-time in k-cycles, ; capture number of seconds in a k-cycle. iDelayLineLength init giMaxDelay kLeftRight init 1 ;if 1, delay tap goes to right channel, else left. ktapLength init 0 ;giTapTable ;number of table which stores number of taps and tap times ;gktapTableSize ;size of table giTapTable, stores number of taps and tap times ;gktapCountIndex ;location in table giTapTable of count of number of active delay taps ;gktapcountknob ;variable that receives value of tap count knob ;gktapcount ;variable containing user-designated value of number of desired delay taps ;merge all generated sounds with realtime input. ;modulate incoming signal according to knob. gaEchoSignal = gkechoInLevel * (galeft/2 + garight/2 + garealtime) ;Assign the delay line to "adel". Tap the line ; at "adel1Tap" etc. Write gaEchoSignal into the delay line. atemp init 0 ktapCount tab gktapCountIndex, giTapTable ;get tap count from tap table if(ktapCount <= 0) then adel delayr iDelayLineLength atemp = 0 atempR = 0 atempL = 0 atemp deltap gkrealtimedelay ;maximum user-specified delay ;send to both channels galeft = galeft + gkdelaylevel * (atemp) + garealtime garight = garight + gkdelaylevel * (atemp) + garealtime delayw gaEchoSignal endif if(gkrealtimedelay>0.0 && gktapcount>0) then adel delayr iDelayLineLength kIndex = 1 ;table entries are 1-based kLeftRight = 1 loopstart: if (kIndex>ktapCount) kgoto loopend ktapLength tab kIndex, giTapTable ;get next tap time if(kLeftRight==-1) then atempR deltap ktapLength * gkrealtimedelay galeft = galeft + gkdelaylevel * (atempR) + garealtime endif if(kLeftRight==1) then atempL deltap ktapLength * gkrealtimedelay garight = garight + gkdelaylevel * (atempL) + garealtime endif kLeftRight = -kLeftRight kIndex = kIndex + 1 kgoto loopstart loopend: delayw gaEchoSignal endif if(gkdelaylevel==0) then ;grand echo check box has just been de-selected. ;Time to randomize the echo tap constants. event "i", 899, 0, 0.01 ;randomize the delay tap times gkdelaylevelknob = gkdelaylevelknob + 0.01 outvalue "delaylevelknob", gkdelaylevelknob ;gkechoSave = gkecho endif endin ---------------------------------------------------------------- On 9/26/07 13:50, " Anthony Kozar" |