[Csnd-dev] UDO compilation seclects i- instead of k-rate

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[Csnd-dev] UDO compilation seclects i- instead of k-rate

joachim-3
hi -

if i have something like
        kVal OPCODE iVal1, iVal2
the k-version of OPCODE is chosen.

but if i define UDO both at i and k, then in
        kVal UDO iVal1, iVal2
the i-version of UDO is chosen.

i think this is not correct, and should be in the same way as it works
for OPCODE.

below is an example which should explain everything.

thanks for having a look -

        joachim




<CsoundSynthesizer>
<CsOptions>
</CsOptions>
<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

   opcode RndInt, i, ii
iMin, iMax xin
iRnd random iMin, iMax+.999999
xout int(iRnd)
   endop

   opcode RndInt, k, kk
kMin, kMax xin
kRnd random kMin, kMax+.999999
xout int(kRnd)
   endop

instr 1

  kBla init 10
  printk2 kBla
  ;the following line does not affect the
  ;init of kBla as it is only valid at perf time
  kBla random 1, 2
  turnoff

endin
schedule 1, 0, 1

instr 2 ;wrong in my opinion

  kBla init 10
  printk2 kBla
  ;the following line resets the initialization
  ;of kBla as the i-time version of the UDO RndInt
  ;is selected (rather than the k-version)
  kBla RndInt 1, 2
  turnoff

endin
schedule 2, 0, 1

instr 3

  kBla init 10
  printk2 kBla
  ;forcing to select the k-rate version of the
  ;UDO works again
  kBla = RndInt:k(1, 2)
  turnoff

endin
schedule 3, 0, 1

</CsInstruments>
<CsScore>

</CsScore>
</CsoundSynthesizer>


output:
  i1    10.00000
  i2     0.00000
  i3    10.00000
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

Dave Seidel
This touches on an issue that's been confounding me lately. In the Csound manual, in the "opcode" entry, it's stated:

These opcodes actually run only at i-time. Performance time copying is done by the user opcode call. This means that skipping xin or xout with kgoto has no effect, while skipping with igoto affects both init and performance time operation.

However, in the FLOSS manual chapter on UDOs, in the second paragraph, it is stated: "They run at i-time or at k-time."

Which one is correct? Is the manual out of date?

The issue for me has been that I have a rather complex script (Implication Organ). The initial version uses MIDI controls (as in knobs & sliders), but I've been rewriting it to use OSC for those functions. In the process of rewriting, I had to shift a lot of things from running at i-time to running at k-time. When I did this, my UDOs stopped working as expected. It took a while before I realized that what was happening was that the UDO were only firing at i-time -- even for opcodes where all inputs and outputs were defined as k-variables. Is it possible that there's a bug? Unless the manual is correct and they only run at i-time.

This seems related to what Joachim is asking above.

I am working with the latest code in the develop branch.

Thanks,
Dave
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

joachim-3
hi dave -

if you look at instr 3 of my example, i think it is clear that a UDO can
work only at k-rate (as any k-rate build-in opcode).

the point is that a k-rate output variable should force the UDO to
choose the k-rate version (if there is one in the definition), and this
is not the case, as far as i see.

best -

        joachim



On 16/08/18 13:49, Dave Seidel wrote:

> This touches on an issue that's been confounding me lately. In the
> Csound manual, in the "opcode" entry, it's stated:
>
>     These opcodes actually run only at i-time. Performance time copying
>     is done by the user opcode call. This means that skipping /xin/ or
>     /xout/ with /kgoto/ has no effect, while skipping with /igoto/
>     affects both init and performance time operation.
>
>
> However, in the FLOSS manual chapter on UDOs, in the second paragraph,
> it is stated: "They run at i-time or at k-time."
>
> Which one is correct? Is the manual out of date?
>
> The issue for me has been that I have a rather complex script
> (Implication Organ). The initial version uses MIDI controls (as in knobs
> & sliders), but I've been rewriting it to use OSC for those functions.
> In the process of rewriting, I had to shift a lot of things from running
> at i-time to running at k-time. When I did this, my UDOs stopped working
> as expected. It took a while before I realized that what was happening
> was that the UDO were only firing at i-time -- even for opcodes where
> all inputs and outputs were defined as k-variables. Is it possible that
> there's a bug? Unless the manual is correct and they only run at i-time.
>
> This seems related to what Joachim is asking above.
>
> I am working with the latest code in the develop branch.
>
> Thanks,
> Dave
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

Dave Seidel
Joachim, thanks for the reminder of the ":k()" override -- I seem to always forget that these exist.

On Thu, Aug 16, 2018 at 8:51 AM joachim heintz <[hidden email]> wrote:
hi dave -

if you look at instr 3 of my example, i think it is clear that a UDO can
work only at k-rate (as any k-rate build-in opcode).

the point is that a k-rate output variable should force the UDO to
choose the k-rate version (if there is one in the definition), and this
is not the case, as far as i see.

best -

        joachim



On 16/08/18 13:49, Dave Seidel wrote:
> This touches on an issue that's been confounding me lately. In the
> Csound manual, in the "opcode" entry, it's stated:
>
>     These opcodes actually run only at i-time. Performance time copying
>     is done by the user opcode call. This means that skipping /xin/ or
>     /xout/ with /kgoto/ has no effect, while skipping with /igoto/
>     affects both init and performance time operation.
>
>
> However, in the FLOSS manual chapter on UDOs, in the second paragraph,
> it is stated: "They run at i-time or at k-time."
>
> Which one is correct? Is the manual out of date?
>
> The issue for me has been that I have a rather complex script
> (Implication Organ). The initial version uses MIDI controls (as in knobs
> & sliders), but I've been rewriting it to use OSC for those functions.
> In the process of rewriting, I had to shift a lot of things from running
> at i-time to running at k-time. When I did this, my UDOs stopped working
> as expected. It took a while before I realized that what was happening
> was that the UDO were only firing at i-time -- even for opcodes where
> all inputs and outputs were defined as k-variables. Is it possible that
> there's a bug? Unless the manual is correct and they only run at i-time.
>
> This seems related to what Joachim is asking above.
>
> I am working with the latest code in the develop branch.
>
> Thanks,
> Dave


--
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

Mauro Giubileo
In reply to this post by joachim-3
Hi, I think I understood why there is the strange behaviour you noticed.
First of all, it is independent from the polymorphism, because the problem arises when you use just a single UDO too.

The problem is in the way Csound manages the UDOs execution that is different from that of native opcodes.
For example, let's take a native opcode with k-time output:

  kSomething NATIVE_OPCODE ...params...

the above code will run ONLY at k-time because that native opcode returns a k-value. This is the expected behaviour and it works correctly.
Now, let's take an UDO opcode witk k-time output:

  kSomething UDO ...params...

In this case, Csound will run the UDO at i-time too, because inside the UDO definition there could be i-values to initialize. Of course, the k-rate native instructions inside the UDO will be skipped... All except two: "xin" and "xout". These statements are executed at init-time, and this is written in the Csound reference docs (https://csound.com/docs/manual/xout.html):

  "[...]These opcodes actually run only at i-time. Performance time copying is done by the user opcode call.[...]"

In your example, the problem is not in the presence of two "RndInt" UDOs, but in the fact that Csound will run the i-time part of your UDO code at i-time, regardless of the type of its output variable types... And, in doing this, your RndInt UDO will not be completely skipped at init-time (as it would be if it was a native opcode with k-value output):

instr 2 (at init-time:)
  EXECUTED: kBla init 10
  *SKIPPED* printk2 kBla
  EXECUTED: kBla RndInt 1, 2  <--- it will be executed the i-time part and kBla will be overwritten by a 0 value
  *SKIPPED* turnoff
endin

instr 2 (at performance-time:)
  *SKIPPED* kBla init 10
  EXECUTED: printk2 kBla
  EXECUTED: kBla RndInt 1, 2  <--- it will be executed the k-time part
  EXECUTED: turnoff
endin

Of course, at init-time, the instruction "kRnd random kMin, kMax+.999999" inside the RndInt UDO will be skipped because "random" is a native opcode and works, as expected, only at k-time.

So, when RndInt returns from its init-pass, the kBla variable will be set to RndInt->kRnd, that is 0, because during init-time the central line with the 'random' statement ("kRnd random kMin, kMax+.999999") was skipped (being that "random" is a native opcode and works, as expected, only at k-time), therefore RndInt->kRnd wasn't valued yet and Csound considers it as 0...

The result is that, at performance-time, the printed value of kBla, for the second instrument, will be 0, not 10.

This also explains why, in the case of the functional syntax, it works as you expected:

instr 3
  kBla init 10
  printk2 kBla
  ;forcing to select the k-rate version of the
  ;UDO works again
  kBla = RndInt:k(1, 2)
  turnoff
endin

This works not because you forced the ':k' (in fact you could skip the ':k' and it should work anyway), but because the '=' is like a native opcode to Csound, so its behaviour is to skip its execution at init-time... And the result is that, in "instr 3", kBla will not be touched at init-time, as you expect.

Anyway, altough this explains why there is this strange behaviour, I think it's not the "right" behaviour and it should be corrected in some way, because it is very confusing for the user.

All the problems arise from this:

 kBla RndInt 1, 2  <--- at init-time Csound will run the i-time part of the UDO

At init-time it's ok to execute the i-time part of RndInt, I understand... but why you have to return its (undefined at init-time) value too, being that the return value in this case is a k-type variable?
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

Mauro Giubileo

I want to add, regarding whether or not this is a bug, that in the Csound reference docs for "init" opcode (https://csound.com/docs/manual/init.html) you can read:

Note that init provides the only case of an init-time statement being permitted to write into a perf-time (k- or a-rate) result cell; the statement has no effect at perf-time.

Actually, this is not true, because in the example of joachim, the k-rate UDO "RndInt" write a 0 in the k-rate kBla variable at init-time! So, or the above note is false, or we have a bug! :-)

Regards,
Mauro


Il 2018-08-18 19:00 Mauro G. ha scritto:

Hi, I think I understood why there is the strange behaviour you noticed.
First of all, it is independent from the polymorphism, because the problem arises when you use just a single UDO too.

The problem is in the way Csound manages the UDOs execution that is different from that of native opcodes.
For example, let's take a native opcode with k-time output:

  kSomething NATIVE_OPCODE ...params...

the above code will run ONLY at k-time because that native opcode returns a k-value. This is the expected behaviour and it works correctly.
Now, let's take an UDO opcode witk k-time output:

  kSomething UDO ...params...

In this case, Csound will run the UDO at i-time too, because inside the UDO definition there could be i-values to initialize. Of course, the k-rate native instructions inside the UDO will be skipped... All except two: "xin" and "xout". These statements are executed at init-time, and this is written in the Csound reference docs (https://csound.com/docs/manual/xout.html):

  "[...]These opcodes actually run only at i-time. Performance time copying is done by the user opcode call.[...]"

In your example, the problem is not in the presence of two "RndInt" UDOs, but in the fact that Csound will run the i-time part of your UDO code at i-time, regardless of the type of its output variable types... And, in doing this, your RndInt UDO will not be completely skipped at init-time (as it would be if it was a native opcode with k-value output):

instr 2 (at init-time:)
  EXECUTED: kBla init 10
  *SKIPPED* printk2 kBla
  EXECUTED: kBla RndInt 1, 2  <--- it will be executed the i-time part and kBla will be overwritten by a 0 value
  *SKIPPED* turnoff
endin

instr 2 (at performance-time:)
  *SKIPPED* kBla init 10
  EXECUTED: printk2 kBla
  EXECUTED: kBla RndInt 1, 2  <--- it will be executed the k-time part
  EXECUTED: turnoff
endin

Of course, at init-time, the instruction "kRnd random kMin, kMax+.999999" inside the RndInt UDO will be skipped because "random" is a native opcode and works, as expected, only at k-time.

So, when RndInt returns from its init-pass, the kBla variable will be set to RndInt->kRnd, that is 0, because during init-time the central line with the 'random' statement ("kRnd random kMin, kMax+.999999") was skipped (being that "random" is a native opcode and works, as expected, only at k-time), therefore RndInt->kRnd wasn't valued yet and Csound considers it as 0...

The result is that, at performance-time, the printed value of kBla, for the second instrument, will be 0, not 10.

This also explains why, in the case of the functional syntax, it works as you expected:

instr 3
  kBla init 10
  printk2 kBla
  ;forcing to select the k-rate version of the
  ;UDO works again
  kBla = RndInt:k(1, 2)
  turnoff
endin

This works not because you forced the ':k' (in fact you could skip the ':k' and it should work anyway), but because the '=' is like a native opcode to Csound, so its behaviour is to skip its execution at init-time... And the result is that, in "instr 3", kBla will not be touched at init-time, as you expect.

Anyway, altough this explains why there is this strange behaviour, I think it's not the "right" behaviour and it should be corrected in some way, because it is very confusing for the user.

All the problems arise from this:

 kBla RndInt 1, 2  <--- at init-time Csound will run the i-time part of the UDO

At init-time it's ok to execute the i-time part of RndInt, I understand... but why you have to return its (undefined at init-time) value too, being that the return value in this case is a k-type variable?
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

joachim-3
In reply to this post by Mauro Giubileo
thanks, mauro, for these illuminating explanations.

i am curious whether others think it should be changed, too.  i agree
with you that it is confusing for users.

        joachim



On 18/08/18 19:00, Mauro G. wrote:

> Hi, I think I understood why there is the strange behaviour you noticed.
> First of all, it is independent from the polymorphism, because the problem arises when you use just a single UDO too.
>
> The problem is in the way Csound manages the UDOs execution that is different from that of native opcodes.
> For example, let's take a native opcode with k-time output:
>
>   kSomething NATIVE_OPCODE ...params...
>
> the above code will run ONLY at k-time because that native opcode returns a k-value. This is the expected behaviour and it works correctly.
> Now, let's take an UDO opcode witk k-time output:
>
>   kSomething UDO ...params...
>
> In this case, Csound will run the UDO at i-time too, because inside the UDO definition there could be i-values to initialize. Of course, the k-rate native instructions inside the UDO will be skipped... All except two: "xin" and "xout". These statements are executed at init-time, and this is written in the Csound reference docs (https://csound.com/docs/manual/xout.html):
>
>   "[...]These opcodes actually run only at i-time. Performance time copying is done by the user opcode call.[...]"
>
> In your example, the problem is not in the presence of two "RndInt" UDOs, but in the fact that Csound will run the i-time part of your UDO code at i-time, regardless of the type of its output variable types... And, in doing this, your RndInt UDO will not be completely skipped at init-time (as it would be if it was a native opcode with k-value output):
>
> instr 2 (at init-time:)
>   EXECUTED: kBla init 10
>   *SKIPPED* printk2 kBla
>   EXECUTED: kBla RndInt 1, 2  <--- it will be executed the i-time part and kBla will be overwritten by a 0 value
>   *SKIPPED* turnoff
> endin
>
> instr 2 (at performance-time:)
>   *SKIPPED* kBla init 10
>   EXECUTED: printk2 kBla
>   EXECUTED: kBla RndInt 1, 2  <--- it will be executed the k-time part
>   EXECUTED: turnoff
> endin
>
> Of course, at init-time, the instruction "kRnd random kMin, kMax+.999999" inside the RndInt UDO will be skipped because "random" is a native opcode and works, as expected, only at k-time.
>
> So, when RndInt returns from its init-pass, the kBla variable will be set to RndInt->kRnd, that is 0, because during init-time the central line with the 'random' statement ("kRnd random kMin, kMax+.999999") was skipped (being that "random" is a native opcode and works, as expected, only at k-time), therefore RndInt->kRnd wasn't valued yet and Csound considers it as 0...
>
> The result is that, at performance-time, the printed value of kBla, for the second instrument, will be 0, not 10.
>
> This also explains why, in the case of the functional syntax, it works as you expected:
>
> instr 3
>   kBla init 10
>   printk2 kBla
>   ;forcing to select the k-rate version of the
>   ;UDO works again
>   kBla = RndInt:k(1, 2)
>   turnoff
> endin
>
> This works not because you forced the ':k' (in fact you could skip the ':k' and it should work anyway), but because the '=' is like a native opcode to Csound, so its behaviour is to skip its execution at init-time... And the result is that, in "instr 3", kBla will not be touched at init-time, as you expect.
>
> Anyway, altough this explains why there is this strange behaviour, I think it's not the "right" behaviour and it should be corrected in some way, because it is very confusing for the user.
>
> All the problems arise from this:
>
>  kBla RndInt 1, 2  <--- at init-time Csound will run the i-time part of the UDO
>
> At init-time it's ok to execute the i-time part of RndInt, I understand... but why you have to return its (undefined at init-time) value too, being that the return value in this case is a k-type variable?
>
Reply | Threaded
Open this post in threaded view
|

Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate

Mauro Giubileo

I'm glad I could be of help. :-)

I'm learning Csound myself so I thank you for giving me the opportunity to deepen these aspects of the language. It is useful to know these little and misleading quirks that otherwise can cause you a lot of headaches. :-D

Regards,
Mauro


Il 2018-08-18 21:25 joachim heintz ha scritto:

thanks, mauro, for these illuminating explanations.

i am curious whether others think it should be changed, too.  i agree with you that it is confusing for users.

    joachim



On 18/08/18 19:00, Mauro G. wrote:
Hi, I think I understood why there is the strange behaviour you noticed.
First of all, it is independent from the polymorphism, because the problem arises when you use just a single UDO too.

The problem is in the way Csound manages the UDOs execution that is different from that of native opcodes.
For example, let's take a native opcode with k-time output:

  kSomething NATIVE_OPCODE ...params...

the above code will run ONLY at k-time because that native opcode returns a k-value. This is the expected behaviour and it works correctly.
Now, let's take an UDO opcode witk k-time output:

  kSomething UDO ...params...

In this case, Csound will run the UDO at i-time too, because inside the UDO definition there could be i-values to initialize. Of course, the k-rate native instructions inside the UDO will be skipped... All except two: "xin" and "xout". These statements are executed at init-time, and this is written in the Csound reference docs (https://csound.com/docs/manual/xout.html):

  "[...]These opcodes actually run only at i-time. Performance time copying is done by the user opcode call.[...]"

In your example, the problem is not in the presence of two "RndInt" UDOs, but in the fact that Csound will run the i-time part of your UDO code at i-time, regardless of the type of its output variable types... And, in doing this, your RndInt UDO will not be completely skipped at init-time (as it would be if it was a native opcode with k-value output):

instr 2 (at init-time:)
  EXECUTED: kBla init 10
  *SKIPPED* printk2 kBla
  EXECUTED: kBla RndInt 1, 2  <--- it will be executed the i-time part and kBla will be overwritten by a 0 value
  *SKIPPED* turnoff
endin

instr 2 (at performance-time:)
  *SKIPPED* kBla init 10
  EXECUTED: printk2 kBla
  EXECUTED: kBla RndInt 1, 2  <--- it will be executed the k-time part
  EXECUTED: turnoff
endin

Of course, at init-time, the instruction "kRnd random kMin, kMax+.999999" inside the RndInt UDO will be skipped because "random" is a native opcode and works, as expected, only at k-time.

So, when RndInt returns from its init-pass, the kBla variable will be set to RndInt->kRnd, that is 0, because during init-time the central line with the 'random' statement ("kRnd random kMin, kMax+.999999") was skipped (being that "random" is a native opcode and works, as expected, only at k-time), therefore RndInt->kRnd wasn't valued yet and Csound considers it as 0...

The result is that, at performance-time, the printed value of kBla, for the second instrument, will be 0, not 10.

This also explains why, in the case of the functional syntax, it works as you expected:

instr 3
  kBla init 10
  printk2 kBla
  ;forcing to select the k-rate version of the
  ;UDO works again
  kBla = RndInt:k(1, 2)
  turnoff
endin

This works not because you forced the ':k' (in fact you could skip the ':k' and it should work anyway), but because the '=' is like a native opcode to Csound, so its behaviour is to skip its execution at init-time... And the result is that, in "instr 3", kBla will not be touched at init-time, as you expect.

Anyway, altough this explains why there is this strange behaviour, I think it's not the "right" behaviour and it should be corrected in some way, because it is very confusing for the user.

All the problems arise from this:

 kBla RndInt 1, 2  <--- at init-time Csound will run the i-time part of the UDO

At init-time it's ok to execute the i-time part of RndInt, I understand... but why you have to return its (undefined at init-time) value too, being that the return value in this case is a k-type variable?