First time here? Check out the FAQ!
x

How do I construct a variable length array of EventValues in the ExtraValues parameter field of a StepSequencer sound?

0 votes
283 views

Why does the following expression work in the ExtraValues field of a StepSequencer:

    { Array with: #(!PBends) , (1 to: 16 collect: [:i | !Bends_ suffix: i ]) }

But the expression below gives a stack trace?

    { Array with: #(!PBends) , (1 to: ?Steps collect: [:i | !Bends_ suffix: i ]) }

 

Initially I created an array of EventValues in a script and tried to concatenate that array with #(!PBends) in the ExtraValues paramater but couldn't get that to work either:

Script:

orchestra first
start: 0 s
seqVoiceNumber: ?VoiceNumber
gates: {1 to: ?Steps collect: [:i | !On_ suffix: i]}
pitches: {1 to: ?Steps collect: [:i | (!Pitch_ suffix: i) + (!Octave * 12) + 60]}
velocities: {1 to: ?Steps collect: [:i | !Vel_ suffix: i]}
bends: {1 to: ?Steps collect: [:i | !Bends_ suffix: i]}
controller: {1 to: ?Steps collect: [:i | !Control_ suffix: i]}

ExtraValues parameter:

{ Array with: #(!Index) , ?bends }

 

 

 

asked May 8, 2017 in Capytalk & Smalltalk by alan-jackson (Virtuoso) (15,840 points)
edited May 8, 2017 by alan-jackson

1 Answer

+1 vote
 
Best answer

In the Script, use the following expression:

orchestra first
  start: 0 s
  seqVoiceNumber: ?VoiceNumber
  gates: {1 to: ?Steps collect: [ :i | !On_ suffix: i]}
  pitches: {1 to: ?Steps collect: [ :i | (!Pitch_ suffix: i) + (!Octave * 12) + 60]}
  velocities: {1 to: ?Steps collect: [ :i | !Vel_ suffix: i]}
  extraValue: ({1 to: ?Steps collect: [ :i | !Bends_ suffix: i]} copyWithFirst: !Index)
  controller: {1 to: ?Steps collect: [ :i | !Control_ suffix: i]}

and in the ExtraValues parameter:

?extraValue

When Kyma asks, indicate that ?extraValue is an element.

The value of the ExtraValues parameter should be an Array. Each element of that Array is an Array where the first element is the name of an EventValue and the remaining elements are the values that the EventValue should take on for each stage of the sequence. In this case, we have told the Sound editor that the variable ?extraValue is an element of the Array that makes up the ExtraValues parameter value.

The expression for the extra value is slightly convoluted because of the nature of the ExtraValues parameter in the StepSequencer and because of the mixture of EventValues and LazyVariables.

Let's look at the expression from the inside out:

{1 to: ?Steps collect: [ :i | !Bends_ suffix: i]}

This expression makes an Array of EventValues as soon as ?Steps is given a value. Before ?Steps has a value, the expression is a LazyEvaluator object that is waiting to be given a value for its variables. (You can think of the LazyEvaluator as a kind of "Smalltalk message recorder" that can play back the Smalltalk messages once all of the variables have concrete values.)

At the next level, we have:

(EXPR copyWithFirst: !Index)

where EXPR is the previous expression. It asks the Array created by EXPR to copy itself with the element !Index prepended to the Array.

Using copyWithFirst: causes the LazyEvaluator object to add that message to its saved recording. When ?Steps is finally provided, it will play back all of the messages it has recorded and returns the result.

This new expression is essentially the same as what you had before:

(#(!Index), EXPR)

which is asking the Array with the single element !Index in it to make a copy with the EXPR Array concatenated to the end. This expression is asking the Array to concatenate the LazyEvaluator object to the end of it, which the Array does not know how to do (which is why we used copyWithFirst: instead).

 

answered May 10, 2017 by ssc (Savant) (126,620 points)
selected May 11, 2017 by alan-jackson
...