First time here? Check out the FAQ!
x

how to create envelopes by using arrays?

0 votes
1,261 views

hello,

i need some help with arrays. my aim is to build an array with 16 values that are all y-values of an envelope (env). since i only want to use 3 points to define the shape of env (controlled via hotvalues), all values inbetween should be interpolated. for example a v-shaped env, where the first value in the array is 2, the 8th is 0 and the 16th 2. so the resulting values in the array should be something like :  2 1.75 1.5 1.25 1 0.75 0.5 0.25 0 0.25 0.5 0.75 1 1.25 1.5 1.75 2

is it possible to build env directly while creating the array via "collect:"? my first thought was to increment/ decrement over the 16 values … any ideas?

 

–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

EDIT: here you find the example sound that illustrates my problem:

http://kyma.symbolicsound.com/qa/?qa=blob&qa_blobid=11405502956699543066

 

 

 

 

 

asked Aug 28, 2017 in Capytalk & Smalltalk by x (Practitioner) (620 points)
edited Sep 1, 2017 by x
here is the sketch that i had in mind: doing the v-shaped envelope. the whole script is a bit complicated and its only working with constants for now. any improvements/feedback is very welcome.

{0 to: 15 collect: [:i | |pointY1 pointY2 pointY3 pointX1
pointX2 pointX3 Ydist1 Xdist1 Ydist2 Xdist2 YMin1 YMin2|

pointY1 := 1.
pointY2 := 0.
pointY3 := 1.
pointX1 := 1 .
pointX2 := 8 .
pointX3 := 16.

Ydist1 := (pointY2 - pointY1) abs.
Ydist2 := (pointY3 - pointY2) abs.
Xdist1 := (pointX2 - pointX1).
Xdist2 := (pointX3 - pointX2).
YMin1 := pointY1 vmin: pointY2.
YMin2 := pointY2 vmin: pointY3.

(i le: Xdist1)
true:
((pointY1 gt: pointY2)
            true: ((Xdist1 - i) * (Ydist1 / Xdist1)) + YMin1
            false: i * (Ydist1/ Xdist1) + YMin1)
false:  ((pointY2 gt: pointY3)
            true: ((Xdist2 - (i - Xdist1)) * (Ydist2 / Xdist2)) + YMin2
            false: (i - Xdist1) * (Ydist2/ Xdist2) + YMin2)
]}

2 Answers

0 votes
Another, related, approach: you could use an InputOutputCharacteristic to define your mapping from X to Y.  Then use a FunctionGenerator on a Ramp waveform as the input.  That way you could trigger the FunctionGenerator whenever you want to trigger the envelope, and you could change the duration by changing the duration of the FunctionGenerator.
answered Aug 28, 2017 by ssc (Savant) (128,200 points)
changing the duration would be a nice feature. also your version might be more flexible than mine. adding more control points in my script would be a hassle.
could you please elaborate how we would get the env-data – from InputOutputCharacteristic – into an array. thanks.
Could you put split your code example in two parts? Then the code for generating the X values would go into the InValues field and the code for generating the Y values would go into the OutValues field of the InputOutputCharacteristic.
sorry, i can't follow. what would be the result.

and still i need an array with 16 vaues and i am not sure how to get it from IOC´s output signal.
The output of the IOC would be the envelope. The X and Y values would be EventValues (faders in the VCS). The input to the IOC would function as a time index.
If you look at the Prototype called "OscillatorWithTimeIndex w/ InputOutputCharacteristic Quantized to Steps" you can see an example of using Smalltalk to create the InValues and OutValues. (This one is not an envelope generator; it's just an example of creating arrays in the parameter fields of the InputOutputCharacteristic).
thanks for the hint.
now, how do i store the successive values form the IOC signal-output into an array?
Why do you need to store the values in an Array? How are you going to use that Array (other than to generate an envelope)?
i like to use it in sciphy´s FrequencyRatio parameter, wich expect an array (in my case with 16 values). just like SyntheticSpectrumFromArrays Amplitude and Frequencies parameter.
Ah ok, I was responding to your original question: How to create an envelope using Arrays.
Are you asking how to create an Array?
sorry if i was not clear enough about. as a very capytalk beginner, i had the feeling that my script is not efficient so i was looking for improvement or alternative ways to get the array done. not sure if i could use IOC output for that…

my capyscript already goes in to the right direction. But guess what, i  just made some tests again and i realised that it is buggy.
i uploaded an example sound that illustrates the problem (you can find it at the top of this thread). to make it more clear i put the array-code into the amplitudes parameter of the  syntheticSpectrumFromArray module. so you will instantly hear the result of the array. to get an idea of the problem, just increase the PX1 slider. it should increase the amplitudes of the higher partials, right? but instead it decreases them…any idea why this is happening?
This is one thing that I'm missing in Kyma (especially since I started coding in C/C++) - we could really need dynamic arrays: that would definitely open up some doors, and also it would make this problem here pretty simple: first of all you could add as many points as you like on the fly, and second they would stay ordered so you you easily implement a search function to find the adjacent points and calculate an interpolated value. just my two cents, I know it's not really helpful at the moment ;)
+1 vote
answered Sep 1, 2017 by ssc (Savant) (128,200 points)
There's a related example already in the Sound Library. Look in SpectralProcessing-Live*.kym at the example:
 "Random Surf by FFT Spectral Shaping"
i am away from my paca for a week now. looking forward to see and understand your sound than. thanks for taking the time.
...