[CM] Simple oscillator?
peiman
peimankhosravi at gmail.com
Thu Nov 18 14:55:08 PST 2010
Thanks!
So after studying your example I came up with the code below. Ideally I
wanted the oscilator's speed to be controlable independatly from the event
density. So I am creating two processes one for LFO control (put into a
global variable) and the other as the event generator. It works (sounds OK)
but is probably not very efficient. There must be a better way :-)
Best,
Peiman
;;;;;;;;;;;;;
variable a = 0
process sine (time, rate)
with i = 0
for r = 2 * pi * (fit (i, 0, 1000, 1) / 1000)
until elapsed() >= time
set a = sin(r)
set i += 1
wait interp( elapsed(), rate)
end
process test (time, low)
until elapsed() >= time
send("osc:message", "/test/osc", rescale(a, -1, 1, interp( elapsed(),
low), 125))
wait .01
end
sprout( list (sine(25, {0 0.0005 20 .00005}), test(25, {0 80 19 120 20 70 25
124})) )
Heinrich Taube wrote:
>
> here is a chunk of a lesson on mapping (from my algocomp1 class) that
> talks about sin
> and demonstrates its use in processes, hopefully it will answer some
> of your questions.
>
> ive pasted the contents here in case the attached file (sin.sal2) gets
> rejected by the listserv.
>
>
>
> ;;; -*- syntax: Sal2; font-size: 18; theme: "Emacs"; -*-
>
> ;
> ;; 'Sin'ful composition
> ;
>
> ; Lots of math functions also perform mapping. For example 'sin'
> ; (sine) maps radians values into amplitudes between -1 and 1.
> ; Recall that radians are simply another way to measure angles:
> ; degrees chop the unit circle up int 360 equal parts and radians chop
> ; the circle up into 2pi parts. In other words 360 degrees equals 2pi
> ; radians. Let's use rescale to show this:
>
> loop for deg from 0 to 360 by 45
> for rad = rescale(deg, 0, 360, 0, 2 * pi)
> print(deg, " degrees = ", rad, " radians.")
> end
>
> ; Now forget about degrees, lets just move 2pi radians in 8 steps from
> ; 0 to 1 see what sine gives us:
>
> loop for x from 0 to 1 by 1/8
> for rad = rescale(x, 0, 1, 0, 2 * pi)
> for amp = sin(rad)
> print("x=", x, " radians=", rad, " sin=", amp)
> end
>
> ; so as x goes from 0 to 1, radians goes from 0 to 2pi and sin returns
> ; the amplitude. if we plot these values of sine left to right we get
> ; a perfectly symmetrical 'wave figure' (called the sine wave) with a
> ; shape that looks something like this:
>
> ; +1 | * *
> ; | * *
> ; 0 |*--------*--------*----->
> ; | * *
> ; -1 | * *
>
> ;X : 0 1/4 1/2 3/4 1
> ;Rad: 0 pi/2 pi 3pi/2 2pi
>
>
> ; Since sin values range from -1 to 1 all we have to do is use the
> ; 'rescale' function to map sin values to appropriate ranges for
> ; musical parameters. For example, this loop maps sin values to key
> ; numbers between 60 and 84:
>
> loop for x from 0 to 1 by 1/8
> for rad = rescale(x, 0, 1, 0, 2 * pi)
> for amp = sin(rad)
> for key = rescale(amp, -1, 1, 60, 84)
> print("x=", x, " radians=", rad, " keynum=", key)
> end
>
> ; So we've mapped x from 0:1 to a sine wave shape of key numbers
> ; between 60 and 84! What would this sound like?
>
> ;
> ;; Using sin in a musical process
> ;
>
> ; How can we use sin to control the evolution of a musical process?
> ; The loop example above hints at how we can solve at least one
> ; approach to the problem. Imagine that we want to control the key
> ; numbers of a process that runs for 100 iterations of a counter
> ; variable i. On each iteration we want to calculate the current value
> ; of sin and output a corresponding keynum. Calculating the keynum
> ; from the output value of sin is easy (we use rescale), but how do we
> ; convert the process iteration variable 'i' into a radian value 'r'
> ; that we can pass into sin? A moments reflection will tell that
> ; something like this will work:
>
> ; [1] r = 2 * pi * (i / 100))
>
> ; formula [1] says that as counter i moves from 0 to 100 the radians r
> ; moves from 0 to 2pi. For example:
> ; when i=0 then i/100=0 so r=2pi*0 and r=0;
> ; when i=50 then i/100=.5 so r=2pi*.5 and r=pi
> ; when i=100 then i/100=1 so r=2pi*1 and r=2pi and so on.
>
> ; lets implement the 100 event test process:
>
> process sine1 ()
> for i below 100
> for r = 2 * pi * (i / 100)
> for a = sin(r)
> send("mp:midi", key: rescale(a, -1, 1, 21, 21 + 88))
> wait .1
> end
>
> sprout( sine1() )
>
> ; TODO: This example can be generalized! Copy/paste the definition
> ; to create a new process called sine2 that accept four arguments:
> ; reps, rate, low and high. The process should run for reps
> ; iterations, output keynums between low and high, and wait rate
> ; seconds between iterations. For example here are two calls to the
> ; function you will create:
>
> sprout( sine2(100, .1, 0, 127) )
>
> sprout( sine2(100, .1, 30, 90) )
>
> ; How can we make the process generate more than one cycle of the wave
> ; as i goes from 0 to num? Perhaps we can see if we compare formula
> ; [1] with a second version:
>
> ; [1] r = 2 * pi * (i / 100))
> ; [2] r = 2 * pi * 10 * (i / 100)
>
> ; As i goes from 1 to 100, formula [1] goes 1 trip around 2pi radians
> ; and formula [2] goes 10 trips around 2 pi radians. Since [2] make
> ; ten trips from 0-pi in the same time [1] makes 1 trip, the frequency
> ; of [2] is ten times that of [1]
>
> ; Lets generalize this by adding a new parameter 'cycs' just after the
> ; 'num' parameter use that parameter as a "frequency" for radian
> ; calculation.
>
> process sine3 (len, cycs, low, hi, rhy, dur, amp)
> with 2pi = 2 * pi
> for i below len
> for a = sin ( (2pi * cycs * (i / len)) )
> send("mp:midi", key: rescale(a ,-1, 1, low, hi),
> amp: amp, dur: dur)
> wait rhy
> end
>
> ;; we test it out by specify 4 cycles in 100 notes:
>
> sprout( sine3(100, 4, 20, 100, .1, .1, .6) )
>
> ; lastly, we can "dirty up" the deterministic motion of sin by adding a
> ; random component to its values:
>
> process sine4 (len, cycs, low, hi, dirty, rhy, dur, amp)
> with 2pi = 2 * pi
> for i below len
> for a = sin ( (2pi * cycs * (i / len)) )
> for r = between(- dirty, dirty)
> send("mp:midi", key: rescale( a + r ,-1 - dirty, 1 + dirty, low, hi),
> amp: amp, dur: dur)
> wait rhy
> end
>
> sprout (sine4(100, 4, 20, 100, .2, .1, .1, .6))
>
> ; and lastly, here is a process that uses sin to generate
> ; "oscillating" rhythmic patterns, ie moving faster and slower around
> ; a central rhythmic value.
>
> process sinrhy (num, cycs, fast, slow, lb, ub)
> for x to num
> for s = sin( 2 * pi * cycs * (x / num))
> for k = between(lb, ub)
> send( "mp:midi", key: k, dur: .1 )
> wait rescale( s, -1, 1, slow, fast)
> end
>
> sprout( sinrhy(40, 3, .05, .6, 60, 80) )
>
> ;; the discrete function is like rescale but it maps floating point
> ;; values onto integers, or lists of values.
>
> loop repeat 20
> for x = ran(1.0)
> for d = discrete(x, 0.0, 1.0, 48, 90)
> print( "x=", x, " d=", d )
> end
>
> ;; you can also map onto lists of discrete values
>
> process sine5 (len, cycs, scal, rhy, dur, amp)
> with 2pi = 2 * pi
> for i below len
> for a = sin ( (2pi * cycs * (i / len)) )
> send("mp:midi", key: discrete(a ,-1, 1, scal),
> amp: amp, dur: dur)
> wait rhy
> end
>
> begin
> with scal = scale(50, 20, 1, 2)
> sprout( sine5(100, 4, scal, .1, .1, .6) )
> end
>
>
>
>
> _______________________________________________
> Cmdist mailing list
> Cmdist at ccrma.stanford.edu
> http://ccrma-mail.stanford.edu/mailman/listinfo/cmdist
>
>
--
View this message in context: http://old.nabble.com/Simple-oscillator--tp28565858p30253068.html
Sent from the CCRMA - CMdist mailing list archive at Nabble.com.
More information about the Cmdist
mailing list