Re: MultiIn MultiOut Ugen

[email protected] Sat, 24 Oct 2020 15:57:36 +0200
Newsgroups gmane.comp.audio.supercollider.devel
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------8F7A5BDCD0A356B422C4B717
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: quoted-printable

Some more comments:

> float a[n]; // prepare an empty array for processing
> // fill the array with the values of each input
> =A0for (int ch =3D 0; ch < n; ch++) {
> =A0 =A0in =3D IN(ch);
> =A0 =A0a[ch] =3D *in;
> =A0}
Also, here you basically just copy the first sample of each input
channel into a temporary array. I'm not sure this is what you want...
But again, I have to see the actual code.

> To process the array I'm calling the function "process) which returns
> an array of the same size:
It's unusual for a function to *return* an array. Where/how did you
allocate the storage for this array? Either you process in place (so the
array input parameter for your "process" function also serves as the
output parameter), or you pass another array where the result should be
written.

It seems like you then want to assign the results to the outputs. But
there is a problem, because you only have a single value per channel,
but the outputs are audio rate.

So either your UGen is really meant to be control rate, or you need to
process the whole audio block (instead of just taking the first sample).

Christof

On 24.10.2020 14:52, [email protected] wrote:
>
> Hi,
>
> can you post some actual code? It's hard to see what you're actually
> trying to do.
>
>> // output loop
>> for(int i=3D0; i<inNumSamples; i++){
>> =A0 =A0 out =3D &result[i];
>> =A0 }
> Here you are consecutively assigning different *pointer* values to a
> single (pointer?) variable, which is a basically a no-op...
>
>> I'm trying to program a MultiOutUgen which is at the same time a sort
>> of "MultiIn" Ugen.
> That's quite common actually. You just have to be aware that signal
> buffers can alias each other, so you must read *all* inputs before
> writing to any output (at the same sample index). This means that
> depending on the actual code you might have to buffer the input.
>
> However, the safest and easiest way is disable buffer aliasing
> alltogether by registering your UGen with the
> "kUnitDef_CantAliasInputsToOutputs" flag (e.g. by using the
> "DefineSimpleCantAliasUnit" macro).
>
> Christof
>
> On 23.10.2020 21:18, [email protected] wrote:
>> Dear List,
>>
>> I can see that you are busy with a lot of meetings and I don't want
>> to bother you, but I'd like to hear your opinion about my project.
>> I'm trying to program a MultiOutUgen which is at the same time a sort
>> of "MultiIn" Ugen.
>> This is the class:
>>
>> NewOne : MultiOutUGen {
>> *ar {
>> arg in, mul =3D 1.0, add =3D 0.0;
>> ^this.multiNewList(['audio']++ in.asArray)
>> }
>> init { arg ... theInputs;
>> inputs =3D theInputs;
>> ^this.initOutputs(inputs.size, rate);
>> }
>> }
>>
>> The number of outputs is always equal to the number of inputs.
>> In C++ the NewOne_next function defines:
>> int n =3D unit->mNumInputs;
>> out =3D OUT(0);
>> float a[n]; // prepare an empty array for processing
>> // fill the array with the values of each input
>> =A0for (int ch =3D 0; ch < n; ch++) {
>> =A0 =A0in =3D IN(ch);
>> =A0 =A0a[ch] =3D *in;
>> =A0}
>>
>> "a" is now an array of length "n" (equals to the number of inputs,
>> and I'm ready to manipulate it).
>> To process the array I'm calling the function "process) which returns
>> an array of the same size:
>>
>> float *result =3D process(a, n); // returns an array of floats
>>
>> the function "process" works perfectly (I mean: it does what I need).
>> Now the only thing that is missing is sending each index of the array
>> to the appropriate output. I'm trying to do it with a classic for loop:
>>
>> // output loop
>> for(int i=3D0; i<inNumSamples; i++){
>> =A0 =A0 out =3D &result[i];
>> =A0 }
>>
>> but unfortunately the order of the elements of the arrays is wrong.
>> Let me give you an example:
>>
>> a =3D [1,0,1,0];
>> result =3D [1,1,0,0];
>>
>> but in SC if I poll the output of the Ugen the result is:
>> UGen Array [0]: 1 // correct
>> UGen Array [1]: 0 // should be 1
>> UGen Array [2]: 1 // should be 0
>> UGen Array [3]: 0 // correct
>>
>> I'm learning cpp through coding so, there might be inconsistencies in
>> what I presented you, but for what I managed to debug, I think that
>> the problem lies in the "output for loop". If I print result[i]
>> inside the "output loop" the order is correct.
>> Could you help me? Do you need more informations, or more code?
>>
>> thank you
>>
>> Davide
>>

--------------8F7A5BDCD0A356B422C4B717
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta http-equiv=3D"Content-Type" content=3D"text/html;
      charset=3Dwindows-1252">
  </head>
  <body>
    <p>Some more comments:<br>
      <blockquote type=3D"cite">
        <div>float a[n]; // prepare an empty array for processing</div>
        <div>// fill the array with the values of each input</div>
        <div>=A0for (int ch =3D 0; ch &lt; n; ch++) {</div>
        <div>=A0 =A0in =3D IN(ch);</div>
        <div>=A0 =A0a[ch] =3D *in;</div>
        <div>=A0}</div>
      </blockquote>
      Also, here you basically just copy the first sample of each input
      channel into a temporary array. I'm not sure this is what you
      want... But again, I have to see the actual code.<br>
    </p>
    <p>
      <blockquote type=3D"cite">To process the array I'm calling the
        function "process) which returns an array of the same size:</block=
quote>
      It's unusual for a function to *return* an array. Where/how did
      you allocate the storage for this array? Either you process in
      place (so the array input parameter for your "process" function
      also serves as the output parameter), or you pass another array
      where the result should be written.</p>
    <p>It seems like you then want to assign the results to the outputs.
      But there is a problem, because you only have a single value per
      channel, but the outputs are audio rate.</p>
    <p>So either your UGen is really meant to be control rate, or you
      need to process the whole audio block (instead of just taking the
      first sample).</p>
    <p>Christof<br>
    </p>
    <div class=3D"moz-cite-prefix">On 24.10.2020 14:52,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:christof.ressi@=
gmx.at">[email protected]</a> wrote:<br>
    </div>
    <blockquote type=3D"cite"
      cite=3D"mid:8c01afa2-81ce-8f96-1832-877aa18335a2-RbZlAiThDcE@public.gmane.org">
      <meta http-equiv=3D"Content-Type" content=3D"text/html;
        charset=3Dwindows-1252">
      <p>Hi, <br>
      </p>
      <p>can you post some actual code? It's hard to see what you're
        actually trying to do.<br>
      </p>
      <p> </p>
      <blockquote type=3D"cite">
        <div style=3D"background-color: rgb(255, 255, 255);">// output
          loop</div>
        <div style=3D"background-color: rgb(255, 255, 255);">for(int i=3D0=
;
          i&lt;inNumSamples; i++){</div>
        <div style=3D"background-color: rgb(255, 255, 255);">
          <div>=A0 =A0 out =3D &amp;result[i];</div>
          <div>=A0 }</div>
        </div>
      </blockquote>
      Here you are consecutively assigning different *pointer* values to
      a single (pointer?) variable, which is a basically a no-op...
      <p> </p>
      <blockquote type=3D"cite">I'm trying to program a MultiOutUgen which
        is at the same time a sort of "MultiIn" Ugen.</blockquote>
      That's quite common actually. You just have to be aware that
      signal buffers can alias each other, so you must read *all* inputs
      before writing to any output (at the same sample index). This
      means that depending on the actual code you might have to buffer
      the input.
      <p>However, the safest and easiest way is disable buffer aliasing
        alltogether by registering your UGen with the
        "kUnitDef_CantAliasInputsToOutputs" flag (e.g. by using the
        "DefineSimpleCantAliasUnit" macro).</p>
      <p>Christof<br>
      </p>
      <div class=3D"moz-cite-prefix">On 23.10.2020 21:18, <a
          class=3D"moz-txt-link-abbreviated"
          href=3D"mailto:[email protected]" moz-do-not-send=3D"true">davi=
[email protected]</a>
        wrote:<br>
      </div>
      <blockquote type=3D"cite" cite=3D"mid:[email protected]=
">
        <meta http-equiv=3D"content-type" content=3D"text/html;
          charset=3Dwindows-1252">
        <div dir=3D"ltr"><span style=3D"background-color: rgb(255, 255,
            255);">Dear List,</span><br>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">I can see
            that you are busy with a lot of meetings and I don't want to
            bother you, but I'd like to hear your opinion about my
            project.</div>
          <div style=3D"background-color: rgb(255, 255, 255);">I'm trying
            to program a MultiOutUgen which is at the same time a sort
            of "MultiIn" Ugen.</div>
          <div style=3D"background-color: rgb(255, 255, 255);">This is the
            class:</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">
            <div>NewOne : MultiOutUGen {</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">	</span>*ar
              {</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">		</span>arg
              in, mul =3D 1.0, add =3D 0.0;</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">		</span>^this.multiNewList(['audio']++
              in.asArray)</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">	</span>}</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">	</span>init
              { arg ... theInputs;</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">		</span>inputs
              =3D theInputs;</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">		</span>^this.initOutputs(inputs.size,
              rate);</div>
            <div><span class=3D"Apple-tab-span" style=3D"white-space: pre;=
">	</span>}</div>
            <div>}</div>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">The number
            of outputs is always equal to the number of inputs.</div>
          <div style=3D"background-color: rgb(255, 255, 255);">In C++ the
            NewOne_next function defines:</div>
          <div style=3D"background-color: rgb(255, 255, 255);">
            <div>int n =3D unit-&gt;mNumInputs;</div>
            <div>out =3D OUT(0);</div>
            <div>float a[n]; // prepare an empty array for processing</div=
>
            <div>// fill the array with the values of each input</div>
            <div>=A0for (int ch =3D 0; ch &lt; n; ch++) {</div>
            <div>=A0 =A0in =3D IN(ch);</div>
            <div>=A0 =A0a[ch] =3D *in;</div>
            <div>=A0}</div>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">"a" is now
            an array of length "n" (equals to the number of inputs, and
            I'm ready to manipulate it).</div>
          <div style=3D"background-color: rgb(255, 255, 255);">To process
            the array I'm calling the function "process) which returns
            an array of the same size:</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">float
            *result =3D process(a, n); // returns an array of floats</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">the
            function "process" works perfectly (I mean: it does what I
            need).</div>
          <div style=3D"background-color: rgb(255, 255, 255);">Now the
            only thing that is missing is sending each index of the
            array to the appropriate output. I'm trying to do it with a
            classic for loop:</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">// output
            loop</div>
          <div style=3D"background-color: rgb(255, 255, 255);">for(int
            i=3D0; i&lt;inNumSamples; i++){</div>
          <div style=3D"background-color: rgb(255, 255, 255);">
            <div>=A0 =A0 out =3D &amp;result[i];</div>
            <div>=A0 }</div>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">but
            unfortunately the order of the elements of the arrays is
            wrong.</div>
          <div style=3D"background-color: rgb(255, 255, 255);">Let me give
            you an example:</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">a =3D
            [1,0,1,0];</div>
          <div style=3D"background-color: rgb(255, 255, 255);">result =3D
            [1,1,0,0];</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">but in SC
            if I poll the output of the Ugen the result is:</div>
          <div style=3D"background-color: rgb(255, 255, 255);">
            <div>UGen Array [0]: 1 // correct</div>
            <div>UGen Array [1]: 0 // should be 1</div>
            <div>UGen Array [2]: 1 // should be 0</div>
            <div>UGen Array [3]: 0 // correct</div>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">I'm
            learning cpp through coding so, there might be
            inconsistencies in what I presented you, but for what I
            managed to debug, I think that the problem lies in the
            "output for loop". If I print result[i] inside the "output
            loop" the order is correct.</div>
          <div style=3D"background-color: rgb(255, 255, 255);">Could you
            help me? Do you need more informations, or more code?=A0</div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">thank you</=
div>
          <div style=3D"background-color: rgb(255, 255, 255);"><br>
          </div>
          <div style=3D"background-color: rgb(255, 255, 255);">Davide</div=
>
          <br>
        </div>
      </blockquote>
    </blockquote>
  </body>
</html>

--------------8F7A5BDCD0A356B422C4B717--

_______________________________________________
sc-dev mailing list

info (subscription, etc.): http://www.birmingham.ac.uk/facilities/ea-studios/research/supercollider/mailinglist.aspx
archive: http://www.listarc.bham.ac.uk/marchives/sc-dev/
search: http://www.listarc.bham.ac.uk/lists/sc-dev/search/