Way to invoke an FX without using with_fx

Hi, I’m just wondering is there a way to initialise an effect without using with_fx. Where I’m coming from is, I guess, Python where ‘with’ is kinda just syntactic sugar

with open('file') as f:
    do_stuff

is equivalent to something like

f = file('file')
f.open()
do_stuff
f.close()

So I’m wondering if I can do something similar … gurgle →

fx1 = invoke(:reverb)
play 60
fx1.stop()

I went looking at source code and the best thing I found was sonicpiapis.cpp. My C++ is too dang weak but I’m keen to hack at it.

Hello @horza :slightly_smiling_face:

The sonicpiapis.cpp file is used to provide autocompletion lists to select from when starting to type certain commands in the editor.

There is currently no way to trigger an fx with any kind of alternate built-in syntax.
Sonic Pi currently relies on calling an fx by using a Ruby ‘block’, so that it can explicitly wrap a section of code within the block. This makes it much easier to reason about what the fx is having an effect on.
See here for the definition of with_fx:

Updating the system so that fx (or synths, samples etc) could be operated on in a more object-oriented manner (if that is what we’d call it?), while theoretically possible, would require significant changes to the underlying codebase. @samaaron may have more to say about it but IMO it’s unlikely that we ourselves would be interested in changing the paradigm that is used to invoke fx anyway, as the current method seems to be much simpler and friendlier for say a 10 year old child to understand (one of our core principles).

if you know what type of effect you want, you could set it up “as normal” and set the mix = 0
then, tweak the mix level when you want it to affect the sound in the with_fx container?

I don’t know why you would want to do something like that, but one way to control what effects are in use are by using blocks in ruby. For example if you want to use random set of effects you could do something like this:

def with_effects(x,&block)
  x = x.dup
  if x.length>0 then
    n = x.shift
    if n[:with_fx] then
      with_fx n[:with_fx], n do
        with_effects(x,&block)
      end
    end
  else
    yield
  end
end

live_loop :random_effects do
  
  random_fx = [ # Modify effects and parameters here
    {with_fx: :echo, phase: 0.5 },
    {with_fx: :whammy, grainsize: 2.0},
    {with_fx: :ixi_techno},
    {with_fx: :flanger, feedback: 0.5},
    {with_fx: :tremolo, phase: 0.1},
    {with_fx: :bitcrusher, bits: 6}
  ].shuffle.pick(3)
  
  with_effects random_fx do
    play (scale :C, :kurdili_hicazkar).pick
  end
  
  sleep [0.25,0.5].choose
end

… and then you could just manipulate the effects in the array as you wish.

4 Likes

This sounds rather cool!

1 Like

Thanks for the suggestion amiika. I ended up with something quite similar and it seems to work well enough for my needs.

1 Like