I’m working through some code on Sam’s MagPi resource. Here’s the code:
live_loop :moon_rise do
with_fx :echo, mix: 1, mix_slide: 8 do |fx|
control fx, mix: 1
notes = (scale :e3, :minor_pentatonic, num_octaves: 2).shuffle
sn = synth :prophet, sustain: 8, note: :e1, cutoff: 70, cutoff_slide: 8
control sn, cutoff: 130
sleep 2
32.times do
control sn, note: notes.tick, pan: rrand(-1,1)
sleep 0.125
end
end
end
I’m confused about the |fx| at the end of the second line, and how it’s used in line 3. Specifically, what does setting the |fx| like that mean? Does it always have to be on the same line as the with_fx, and at the end? Is this a way to declare a variable and then use it in line 3?
I think it is just a reference pointer to the running with_fx :echo
It needn’t be called fx but any valid variable name you like. I tried it with do |rbn| and it was fine.
You then use it in conjunction with control to reference the running fx wrapper and alter one of its parameters.
Its exactly the same mechanism used further down the live loop to control the cutoff of the synth that is playing. Create a reference to it (in this case using sn = synth…
and then use control sn. This slightly diffent way of creating the reference needs to be used with a fx wrapper. You can’t do x=with_fx :echo…
but hace to use with_fx :echo… do |foo|
control foo…
Actually, that helps a lot. I was trying to do that x = with_fx: echo thing. It made sense to me, perhaps I was thinking Pythonese? Clearly, this isn’t Python.
So “control” then takes that variable/reference and allows you to make changes, right?
I suppose learning any new language works best when you have other languages learned. Then you can say, “this is how Ruby does it”, and the analogy makes sense. It’s the teacher in me!
To be technical - while Sonic Pi’s functions can use the |…| to define parameters, as seen in the first of the two links above, and you can do the same to define a variable that captures an fx node to later control, the latter case is not so much parameterised functions, in the sense that if you did make your own function, you can then go ahead and call the function and pass values in as the parameter(s), but the with_fx ... do |x| only sets x for you, letting you use it inside the with_fx.
…and of course, if you want to get super technical, the || are used for defining parameters to use in Ruby’s versions of closures (blocks, procs and lambdas) but luckily we don’t really need to know that just to use Sonic Pi!
I have made several attempts to grasp, what this (‘a closure’) is (recently in JavaScript). I guess it will take several more attempts until I will have succeeded but I will keep trying. Having said that, that is the reason I always appreciate such technical side notes.