First time here? Check out the FAQ!
x

Is there a way to interpolate only in Capytalk without upsampling?

+1 vote
256 views

I realise we ask this question many times in different ways... but I still haven't found a way to do it and occasionally for efficiency reasons, it crops up.

For example, I have a bunch of constants all generating a Capytalk created signal (random walks so on...)  - the L represents a pasted sound in this post

| strategies |

strategies := #(
{ s1 L}
{ s2 L}
{ s3 L}
{ s4 L}
).

"selector"

(!Strategies * strategies size) of: strategies

When I select this way, the elements can only snap to the new signal source.

If I arranged all the constants as inputs into an InterpolateN then I could smoothly morph  (interpolate) over any duration. The pay off is that the signals seem to get upsampled to audiorate. In my Sound I want to have maybe 16 of these sources and each one replicated 16 times. This overloads the DSP on my Pacarana when its done using interpolateN - but when done in Capytalk there is barely any DSP used at all.

So I want to keep the efficiency, but get something like the morphing effect - I don't need it to be upsampled, they are only Capytalk to begin with.

 

Any ideas?

asked Feb 23, 2016 in Capytalk & Smalltalk by cristian-vogel (Master) (8,370 points)

1 Answer

+1 vote

Let evExps be an Array of n EventExpressions.

Let !M be an EventValue that ranges from 0 to n - 1 (your "morph" control).

Then the following can be used as a generalized interpolation function on an array of EventExpressions:

| fractM |

fractM := !M - !M truncated.

((1 - fractM) * (!M of: evExps)) + (fractM * (!M + 1 of: evExps))

answered Feb 23, 2016 by ssc (Savant) (120,590 points)
that works brilliantly and is easy to remember!

One thing I noticed is that !M needs to be multiplied by the number of events in evExps

so

((1 - fractM) * ((!M * evExps size) of: evExps)) + (fractM * ((!M * evExpts size) + 1 of: evExps))
Hey cristian,

I think ssc changed the range of !M in the vcs to make it work. Otherwise
!M - !M truncated is always !M. However if you multiply !M by evExps size in the equation for fractM as well it would work. I guess that's what you wanted to show anyway :)

@ssc: what about a capytalk shortcut message for this? something like !M interpolateN: anArray possibly?
Right, the example was assuming that you would change the range of !M in the VCS to (0, n-1).  I've also added a new expression to the Expressions Library:arrays.txt called Interpolate or morph between EventExpressions in an Array.  In that example it shows how to do the scaling of !M:

--
| n evExps fractM scaledM |

n := 3.
evExps := 0 to: n collect: [ :i | !Fader suffix2: i ].

scaledM := !M * n.

fractM := scaledM - scaledM truncated.

((1 - fractM) * (scaledM of: evExps)) + (fractM * (scaledM + 1 of: evExps))
...