[Csnd] Occasional lag in setting global variable
Date | 2018-06-13 19:52 |
From | Zo=?UTF-8?Q?=C3=AB_?=Sparks |
Subject | [Csnd] Occasional lag in setting global variable |
Attachments | =?UTF-8?B?dGhlX3JpdmVyLmNzZA==?= |
Hullo Csounders, The core of the issue I'm running into is that there sometimes seems to be a slight lag in setting a global variable in the orchestra I'm working with. I'm continuously writing to it at k-rate (albeit with ksmps = 1), and after a period of time I stop writing to it and then read from it immediately afterwards, and sometimes the value is a little behind where it should be, if that makes sense. Most of the time it works fine, maybe 90%, but I'd like to find a way of accomplishing what I'm trying to do that works all of the time. To go into more detail, I'm working on a Cabbage instrument, so it's intended to operate in real time (file is attached). The instrument has several envelopes that need to have a release segment, so instead of using the "r" opcodes I'm using xtratim and release. One of these is a pitch envelope with a slider and a semitone range, and the user can set as the endpoint of the release envelope either the center of the slider, the position of the slider, the maximum value of the slider, or the minimum value of the slider. The challenge is that the release envelope (calculated using transeg) needs to start from whatever the current pitch is, so that if the user releases the key in the middle of the pitch's attack phase, it will gracefully move from the current pitch to the destination of the release envelope instead of abruptly jumping to another pitch. transeg's arguments are all i-rate, but of course the current pitch of the instrument as it travels along its pitch envelope can't be known at i-time; instead, it needs to be known at the moment the user releases the key. The best solution I've found to this problem so far is to do the following while the key is pressed: kpitchenv transeg ipitchfloor, ipitchenva, ipitchenvash, ipitchceil, ipitchenvd, ipitchenvdsh, ipitchenvsus gkcurrpitch = kpitchenv kpitch = semitone(kpitchenv) kfrq = ifrq * kpitch and then this for the release segment: reinit calcrenv calcrenv: icurrpitch = i(gkcurrpitch) rireturn kpitchenv transeg icurrpitch, ipitchenvr, ipitchenvrsh, ipitchenvrfloor kpitch = semitone(kpitchenv) kfrq = ifrq * kpitch This mostly works exactly as intended. The only trouble is that gkcurrpitch doesn't perfectly track kpitchenv; sometimes, it's a little behind when the release segment starts, so there's an audible jump to whatever the value of kpitchenv was a fraction of a second ago. However, if I use a local variable kcurrpitch instead, during the reinit its value is set to whatever the pitch was at the beginning of the note. Since using a global variable does work correctly except for the lag, is there a way I can ensure that it keeps up with kpitchenv? Alternately, is there another way of doing this that accomplishes what I want while avoiding this problem? I've tried all sorts of different methods entirely local to the instrument but I haven't found one that works for all cases, although maybe I'm just missing it. Thanks so much, Zoë |
Date | 2018-06-13 20:20 |
From | Zo=?UTF-8?Q?=C3=AB_?=Sparks |
Subject | Re: [Csnd] Occasional lag in setting global variable |
Oh, as a side note, I'm using Csound 6.11.0 commit e4ca0b1, built from git. |
Date | 2018-06-13 20:39 |
From | Victor Lazzarini |
Subject | Re: [Csnd] Occasional lag in setting global variable |
I wonder if the problem is that rireturn should be placed after the transeg line,
because if you don’t do that, its i-time
parameters will not be updated.
If I understand what you want correctly,
the reinit is used to get an updated
value for transeg, but that update only
happens at i-time. So that needs to be
part of the reinit section.
Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland
|
Date | 2018-06-13 22:55 |
From | Zo=?UTF-8?Q?=C3=AB_?=Sparks |
Subject | Re: [Csnd] Occasional lag in setting global variable |
Hmmm. Well, I tried doing that, but if I do, it seems like the transeg variable for the release segment doesn't move forward; it just continuously outputs whatever its starting value is. For instance, in the following code, where krel stores the output from `release`: krelchanged changed krel if (krel == 0) then kpitchenv transeg ipitchfloor, ipitchenva, ipitchenvash, ipitchceil, ipitchenvd, ipitchenvdsh, ipitchenvsus gkcurrpitch = kpitchenv kpitch = semitone(kpitchenv) kfrq = ifrq * kpitch elseif (krelchanged == 1) then reinit calcrenv calcrenv: icurrpitch = i(gkcurrpitch) kpitchenvrel transeg icurrpitch, ipitchenvr, ipitchenvrsh, ipitchenvrfloor kpitch = semitone(kpitchenvrel) kfrq = ifrq * kpitch rireturn endif kpitchenvrel will output whatever the value of icurrpitch is continuously, instead of actually moving along its envelope. I've tried setting icurrpitch to arbitrary values to make sure of this. So, when the instrument enters its release segment, the pitch will jump to whatever icurrpitch is at that moment and stay there. I wonder if there's something I'm missing about how reinit works. The reason I initially put the transeg statement for the release section outside of reinit was because I figured the only thing that needed to be reinitialized was the value of icurrpitch, in order to capture the value of kcurrpitch in the instant the release segment begins. The behavior I'm observing now, with kpitchenvrel staying still, is really strange to me; I'm not sure why that would happen.
|
Date | 2018-06-13 23:04 |
From | Victor Lazzarini |
Subject | Re: [Csnd] Occasional lag in setting global variable |
Would it not be the case that once release happens and you take the branch that has reinit, that you will be calling reinit at every k-cycle? I would expect that, in which case
transeg will not move forward as you constantly reinit it.
You need to make sure reinit only happens once.
Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland
|
Date | 2018-06-13 23:05 |
From | Zo=?UTF-8?Q?=C3=AB_?=Sparks |
Subject | Re: [Csnd] Occasional lag in setting global variable |
That was why I used `changed` to track krel instead of reading from krel directly; I figured that would trigger only once when krel flipped from 0 to 1. Maybe I'm wrong about that?
|
Date | 2018-06-13 23:13 |
From | Victor Lazzarini |
Subject | Re: [Csnd] Occasional lag in setting global variable |
Ok, maybe it does, but then transeg processing is also bypassed when that variable becomes 0.
You should then have a branch that only
has reinit in it, not the body of the
reinit section.
Victor Lazzarini
Dean of Arts, Celtic Studies, and Philosophy
Maynooth University
Ireland
|
Date | 2018-06-13 23:29 |
From | Zo=?UTF-8?Q?=C3=AB_?=Sparks |
Subject | Re: [Csnd] Occasional lag in setting global variable |
Oh goodness, thanks so much, that worked! I didn't realize it would stop processing transeg after it stopped taking that branch; I thought that once the transeg statement was read it would stay "in scope" so to speak and keep being processed unless something else changed it, but now I see that's not exactly the case. It appears that even if it stays "in scope" in the sense that the value of kfrq and so on can be read afterwards without errors, nothing in that branch gets updated once it's not being followed anymore. I imagine that that might even only be true because kfrq had already been declared prior. For the sake of anyone else in the future reading this that has a similar question, here's the working code: krelchanged changed krel if (krel == 0) then kpitchenv transeg ipitchfloor, ipitchenva, ipitchenvash, ipitchceil, ipitchenvd, ipitchenvdsh, ipitchenvsus gkcurrpitch = kpitchenv kpitch = semitone(kpitchenv) kfrq = ifrq * kpitch elseif (krelchanged == 1) then reinit calcrenv elseif (krel == 1) then calcrenv: icurrpitch = i(gkcurrpitch) kpitchenvrel transeg icurrpitch, ipitchenvr, ipitchenvrsh, ipitchenvrfloor kpitch = semitone(kpitchenvrel) kfrq = ifrq * kpitch rireturn endif
|
Date | 2018-06-14 10:06 |
From | Victor Lazzarini |
Subject | Re: [Csnd] Occasional lag in setting global variable |
That’s because the variable is created alright, but the code does not run if you don’t visit the branch (that’s the whole point of having it). ======================== Prof. Victor Lazzarini Dean of Arts, Celtic Studies, and Philosophy, Maynooth University, Maynooth, Co Kildare, Ireland Tel: 00 353 7086936 Fax: 00 353 1 7086952 > On 13 Jun 2018, at 23:29, Zoë Sparks |