First time here? Check out the FAQ!

How do I iterate over an arbitrary number of inputs to a script?

0 votes

I'm making a Sound that takes an arbitrary number of inputs, a bit like a Mixer. 

My Sound has a Script that I want to iterate over the inputs and do stuff to them. 

As a placeholder for the arbitrary number of inputs my Script ("MAIN") has a SoundCollectionVariable in its input. 

To build and test this Sound I've put another Script (the "DEV" script) at the end that creates an OrderedCollection of Sounds and passes it to the MAIN Script.

For instance the DEV script would have something like this in it:

| sndCol |

sndCol := OrderedCollection new.

sndCol add: (osc freq: 256 hz).
sndCol add: (osc freq: 2017 hz).

    start: 0
    mixerInputs: sndCol.



"(Where osc is the name of an Oscillator Sound and mixerInputs is the name of main's SoundCollectionVariable)"


It doesn't work. I get errors that say:

"osc is redeclared. You may have declared it both as a temporary and as a block variable". 


But if I replace the "main" Script with a Mixer containing the same SoundCollectionVariable it works fine, I can hear two oscillators purring away.


I'm using the SoundCollectionVariable because ultimately I want to encapsulate my Sound and I want it to have an "Inputs" parameter that can take an arbitrary number of input Sounds. 


How do I write a Script that can go through each of its inputs and how can I pass a collection of Sounds to that Script?




asked Nov 12, 2019 in Capytalk & Smalltalk by alan-jackson (Virtuoso) (15,680 points)
"I'm making a Sound that takes an arbitrary number of inputs, a bit like a Mixer.
My Sound has a Script that I want to iterate over the inputs and do stuff to them."
This sounds a lot like what a Replicator can do (especially since your example is all Oscillators, each with a different Frequency). Could you say a bit more about what it is you would like to do to each Sound in the mix? (Replicator may be an even more compact way to represent the sound than an encapsulation would be).

1 Answer

0 votes

You can refer to Sounds in the Script's inputs without knowing their names using

orchestra at: <anIndex>

So if you use SoundCollectionVariable and give it the name Inputs, you can first set a Collection to be the default collection (so you can click the Collection button when it asks for the value of ?inputs). Then set its parameter type to soundCollection and its type to soundCollection. Here's an example.

But there may be other ways of accomplishing what you want to do (depending on what it is exactly).

answered Nov 12, 2019 by ssc (Savant) (118,510 points)
If I put a SoundCollectionVariable into the Inputs parameter of a Script it deletes any other Sound that's in there. The SCV seems to "become" the inputs field, not be a member of it.

What I want to do is construct a complex Sound where I put some Sounds on the end of each of the Sounds in the Inputs field.

The problem I have now is that the SCV gets rid of the other Sounds in the Script's Inputs field so I lose the Sounds I wanted to combine the inputs with. I've tried putting the SCV in a Mixer and putting the Mixer in the Inputs field, but I can't work out how to then access any of the members of the SCV.

(also I tried replacing "orchestra at:" with "inputs at:" and your example continues to work, so can I assume inputs is equivalent to orchestra?)
This seems related to a question Cristian asked a while ago:

It seems the answer is to put the SCV in a mixer that is parallel to the Script. I'll try that. I don't understand why the Script would be able to "see" the name of the SCV in the parallel mixer. I would have thought it would have been out of scope.