Hi all,

I am a bit late to the party. I finally got around studying the new multichannel code changes and wading through this massive sea of e-mails to get up to date on the discussion :-)

First off, I am very excited about this new feature! Here are a few comments from my side. The e-mail is a bit long, but I tried to write as concisely as possible, so please keep reading :-)

---

There are few things in the API that I think could be streamlined a bit.

1) Currently, external authors have to explicitly create the output signals if they want the object to be multi-channel aware. For example, here's the relevant line in plus_dsp():

sp[2] = signal_new(nullsignal->s_length, outchans, nullsignal->s_sr, 0);

Now, most of this information is redundant. I cannot imagine a situation where you would provide a different vector size or samplerate. The only thing we are really interested in is the number of channels.

Instead of creating the signal, I would rather prefer the following:

signal_setchannels(sp[2], outchans);

IMO, this would be much more descriptive and also reduce the chance for mistakes.

---

2) "dsp" methods now have an additional "t_signal *nullsignal" parameter for cases where you cannot get the vector size otherwise (except by going through the owning canvas). Typical example: multi-channel objects with no signal inlets (because the output signals are yet to be created).

Actually, the introduction of signal_setchannels() - see above - would make this obsolete because you would't need to create signals in the first place! The only remaining use case for the "nullsignal" would be an object with no signal outlets and where all signal inlets are "scalars" (= float to signal promotion is turned off). This is quite an edge case, though, and I cannot think of an example in the Pd core...

On the other hand, I kind of like this extra parameter because it provides a /uniform /way to access shared DSP parameters. However, I would suggest to make a proper structure instead of reusingt_signal, e.g.:

typedef struct _dspinfo
{
    d_blocksize; /* number of items per channel */
    t_float d_sr;  /* samples per second per channel */
    int d_overlap;  /* overlap factor */
    int d_nin; /* number of signal inlets */
    int d_nout; /* number of signal outlets */
    /* ... anything else? */
} t_dspinfo;

Note that we can take the chance to pass some extra info that is not part of t_signal, such as the number of signal inlets and signal outlets.

---

3) IMO, class_setdspflags() should be used consequently in the codebase instead of passing the DSP flags to class_new(). It is not strictly necessary, but it would set a good example to external authors.

As Miller explained, the main reason for class_setdspflags() is that externals using these new feature would refuse to load in older Pd version; otherwise they would just crash.

---

4) Whenever an object requires you to set the number of channels explicitly, e.g. in [send~]/[receive~]/[throw~]/[catch~], there should be a way to change the number of channels with a message!

For example, if I have an ambisonics patch, I would like to be able to change the ambisonics order (and hence the channel count) on the fly.

This can be implemented easily, you just need to update the DSP graph after changing the number of channels.

---

5) Regarding the naming of [pack~]/[unpack~]: I don't have a strong opinion. On the one hand it corresponds nicely to what [pack] and [unpack] does, on the other hand it clashes with the zexy library...

[split~] and [join~] are not bad, but I think they would fit better to a different kind of object (see below).

I find [snake~] and [unsnake~] quite funny :-)

---

6) Regarding the [clone] discussion: I very like the idea of creating embedded abstractions or even accepting compiled objects! I often thought about this myself.

I also think it would also be nice to have something like [mc~] as an alias for [clone -x -d] because the latter is not exactly obvious.

---

7) Ideas for new objects:

* [split~] (or [moses~], etc.): take a multi-channel signal and split it into two different multi-channel signals at the specified channel offset.

* [join~] (or [merge~], etc.): take several multi-channel signals and combine them as a single (multi-channel) signal. (Actually, the same functionality could be achieved by a more generalized version of [pack~] that also deals with multi-channel input signals.)

---

8) Ideas for existing objects:

AFAIU, the plan is to make all math objects multi-channel aware, but not touch any "stateful" objects, such as filters or oscillators. Generally, I agree with this!

Some random objects that could be made multi-channel aware:

a) [sig~], i.e. [sig~ 0.1 0.5 0.7 0.8] would output a 4-channel signal.

b) [snapshot~]. If the input is multi-channel, it would sample all channels and output them as a list. This would be quite handy for metering multi-channel signals :-)

c) [print~], with nice formatting!

d) [expr~] and [fexpr~] :-)

---

Thanks for reading :-)

Christof

On 17.01.2023 04:23, Miller Puckette via Pd-dev wrote:
To Pd dev -

I've pushed what I think is working support for multichannel signals.  Many
objects haven't yet been adapted to deal with them, but there are enough to
at least test the concepts: lop~, send~, receive~, and (ugh) clone are
multichannel-aware, and new pack~ and unpack~ objects are provided to
combine and split signal channels.

I've put a couple of example patches on
http://msp.ucsd.edu/tmp/multichannel-tests.tgz
... the interplay between multichannel inlets and outlets and clone
are sometimes amusing.

cheers
Miller



_______________________________________________
Pd-dev mailing list
Pd-dev@lists.iem.at
https://lists.puredata.info/listinfo/pd-dev
_______________________________________________
Pd-dev mailing list
Pd-dev@lists.iem.at
https://lists.puredata.info/listinfo/pd-dev

Reply via email to