Smoothly fading samples and synths

#10

@Martin no apologies… no problem!!! but thank u for your time :heart_eyes:
this is gonna be a hard problem for me :disappointed_relieved:
but thanks to @Eli too for the suggestions
now i want to make some experiments and then i will write to u too again
i hope to discover some new things useful for everyone :sunglasses:

thanks again and see u soon

1 Like
#11

@MarieRose,

also, on your experimental journey, if you come across any ideas you wish “just worked” and had a bit of code you’d love to be able to write and it do what you expected it to, please let me know.

I always love hearing ideas which include:

  • context (what kind of thing you’re trying to do)
  • a code sketch (what kind of code you’d like to be able to write)
  • behaviour (what the code should do)

:slight_smile:

1 Like
#12

Hi @MarieRose,

building on @Eli suggestion to use set_volume! I coded a short example which might help. Usually I do not use in_thread but I guess, that is what you might have had in mind. I am also not sure I did the counting right (did not check twice) but I hope the comments are correct; anyway, I guess the overall principle is sketched out (surely there are other ways to achieve similar results):

# beats and bars: 
# 1 bar = 4 beats = 16 * 0.25 beats
# if you count all the sleeps, the tune is 16 bars or 64 beats long
use_bpm 120
set_volume! 0


# volume fade = 4 bars (64 x 0.25 or 16 full beats)
in_thread do
  64.times do
    set_volume! (line 0,1, steps: 64, inclusive: true).ramp.tick
    sleep 0.25
  end
end

# one loop = one bar
# let the drums play for 16 bars, 4 bars fade in
in_thread do
  16.times do
    sample :loop_amen, beat_stretch: 4
    sleep 4
  end
end

# after the 4-bar-fade start the the bassline
sleep 16

# bassline is 2 bars long (8 beats)
# let it play along the drums which will last for
# 12 bars from here on ...
in_thread do
  with_synth :fm do
    with_synth_defaults release: 0.5, cutoff: 60, depth: 2, amp: 1.5 do
      6.times do
      play :c2
      sleep 0.5
      play :c2
      sleep 4
      play :g2
      sleep 3
      play :bb2
      sleep 0.5
    end
   end
  end
end

# start the keyboard after the bass phrase has played 2 times
# = 16 beats
sleep 16

in_thread do
  with_fx :reverb, room: 0.75, mix: 0.5 do
    with_synth :dsaw do
      with_synth_defaults cutoff: 80, amp: 1.5 do
        4.times do
          play (chord :c4, :minor7), release: 0.25
          sleep 1.5
          play (chord :c4, :minor7), release: 1.25
          sleep 1.5
          play (chord :d4, :minor7), release: 0.25
          sleep 3.5
          play (chord :d4, :minor7), release: 0.25
          sleep 1.5
        end
      end
    end
  end
end

# remaining beats/beats for the track is 32 beats / 8 bars
# let 4 bars play and then fade out for 4 bars
sleep 16

# volume fade takes 64 x 0.25 = 4 bars
in_thread do
  64.times do
    set_volume! (line 1,0, steps: 64, inclusive: true).ramp.tick
    sleep 0.25
  end
end

stop
2 Likes
#13

thank u so much @Martin
it seems working
i just need to elaborate on the language :sweat_smile:
u will probably hate me :disappointed_relieved: but i tried to do the same thing with the fx
i am trying to make a fade in and a fade out with the fx
a sort of automation…

do u know how to make it?
cause i investigate in the manual but i did not find anything about it
now i would like to study ruby"…

thank u so much,

marie r.

#14

Hi MarieRose…

I got here before Martin, but I’m pretty sure he would say
much the same thing… use the ‘with_fx :level’ command,
and a line fade… example below:

Eli…

use_bpm 120
set_volume! 3
fade_out = (line 3,0, steps: 6, inclusive: true)


in_thread do
  with_synth :fm do
    with_synth_defaults release: 0.5, cutoff: 60, depth: 2, amp: 1 do
      6.times do
        with_fx :level, amp: fade_out.tick do
          play :c4
          sleep 0.5
          play :c4
          sleep 2
          play :g4
          sleep 1.5
          play :bb4
          sleep 0.5
        end
      end
    end
  end
end
1 Like
#15

hi @Eli thank u so much
this evening is dedicated to coding :upside_down_face: cause i am working at the tracks for my school (conservatory)
i hope that this occasion can be good to learn coding and with your company this can happen :sunny:

thank u again

#16

Hi @Eli,

yes, you’re right, I would have :wink: . The only downside is, that you do not get a continious fadeout because every loop cycle you have just one value (of fade_out); surely this can be an effect you want… but …

… amusingly, we’re now back to the beginning of the thread: If you toss in a control for :level, apply a double tick and tweak some values, you’ll have it:

use_bpm 120
set_volume! 3
fade_out = (line 1,0, steps: 20, inclusive: true).ramp


in_thread do
  with_synth :fm do
    with_synth_defaults release: 0.5, cutoff: 60, depth: 2, amp: 1 do
      12.times do
        with_fx :level, amp: fade_out.tick do |lev|
          control lev, amp: fade_out.tick, amp_slide: 6
          play :c4
          sleep 0.5
          play :c4
          sleep 2
          play :g4
          sleep 1.5
          play :bb4
          sleep 0.5
        end
      end
    end
  end
end
1 Like
#17

wooow
thanks @Martin :ok_hand: :pray:

#18

I much prefer your version. :slight_smile:

Out of interest… I’ve been trying to code a ‘drop’, like
they use in a lot of hip-hop / house…

They double then triple the drums / snare / volume over
about 10 seconds, then cut it off dead… and ‘drop’
(for example), a female vocal into the quiet spot, before
restarting the drums etc…

Any ideas? I’ve tried depth and density, but it just doesn’t
seem to be right somehow…

Eli…

1 Like
#19

:persevere:
sorry
but it does not seem to work
first I had forgotten a command and it seemed to work :disappointed_relieved:
sorry if I insist, probably I did not understand the code
i understand what’s “ramp”, what’s “tick” and the other commands but i don’t understand the reason why the code seems not to function.

sorry again

#20

Looking at @josephwilk’s post (Making a ‘drop’) this even becomes much simpler with set_mixer_control!. Sam has taken care of that already.

But as the saying goes: detours increase the local knowledge.

# beats and bars: 
# 1 bar = 4 beats = 16 * 0.25 beats
# if you count all the sleeps, the tune is 16 bars or 64 beats long
use_bpm 120
set_mixer_control! amp: 1, amp_slide: 8

# one loop = one bar
# let the drums play for 16 bars, 4 bars fade in
in_thread do
  16.times do
    sample :loop_amen, beat_stretch: 4
    sleep 4
  end
end

# after the 4-bar-fade start the the bassline
sleep 16

# bassline is 2 bars long (8 beats)
# let it play along the drums which will last for
# 12 bars from here on ...
in_thread do
  with_synth :fm do
    with_synth_defaults release: 0.5, cutoff: 60, depth: 2, amp: 1.5 do
      6.times do
      play :c2
      sleep 0.5
      play :c2
      sleep 4
      play :g2
      sleep 3
      play :bb2
      sleep 0.5
    end
   end
  end
end

# start the keyboard after the bass phrase has played 2 times
# = 16 beats
sleep 16

in_thread do
  with_fx :reverb, room: 0.75, mix: 0.5 do
    with_synth :dsaw do
      with_synth_defaults cutoff: 80, amp: 1.5 do
        4.times do
          play (chord :c4, :minor7), release: 0.25
          sleep 1.5
          play (chord :c4, :minor7), release: 1.25
          sleep 1.5
          play (chord :d4, :minor7), release: 0.25
          sleep 3.5
          play (chord :d4, :minor7), release: 0.25
          sleep 1.5
        end
      end
    end
  end
end

# remaining beats/beats for the track is 32 beats / 8 bars
# let 4 bars play and then fade out for 4 bars
sleep 16
set_mixer_control! amp: 0, amp_slide: 8
stop
#21

Great technique, Martin.
Can use it for rate, pan, amp, release, … Opens up a whole new load of barely-music experiments :rofl:

#dueling blips

live_loop :panner do
  pann = (line -1, 1, inclusive: true, steps: 64).mirror
  vol = (line 0.1, 1, inclusive: true, steps: 32).mirror
  rat = (line 2, 4, inclusive: true, steps: 64).mirror
  
  2.times do
    if one_in(2) then
      sample :elec_blip, rate: rat.tick, pan: pann.tick, amp: 1 - vol.tick
    else
      sample :elec_blip2, rate: 6 - rat.tick, pan: pann.tick * -1, amp: vol.tick
    end
    sleep 0.2
  end
  
  with_fx :reverb, room: rrand(0.2, 0.75) do
    sample :bd_klub, amp: vol.look - 0.1 if one_in(4)
  end
  sample :bd_ada, amp: 0.2
end
#22

Be careful about using tick in multiple places. tick is local to the thread not the ring. Rings do not have state and therefore don’t have any notion of the current index.

#23

Hi,

I’d appreciate very much if someone could run my first to code examples (see top of this thread) and check if it does what I said it would (fade in/out smoothly). I did use this several times in other context and it worked (otherwise I would not have posted it :wink: ). Since a few weeks it doesn’t anymore and I wonder if there is something wrong with my installation (SP 3.1).

Cheers
Martin

Smooth Parameter Automation
#24

A while ago, I found a way to fade individual tracks(live_loops) in and out.
I use a ramped line, with minimal maths involved:

I usually use individual live_loops for ‘tracks’, so I can just use the local tick.

PS:
@Martin Both code snippets work as expected.
I run SP 3.1 on Windows.

#25

Hi @Davids-Fiddle,

thanks very much for testing!

And yes, I also do use line or range (using the syntax (range 0,1,0.1).ramp). The thing is: I was looking for a solution which is not dependant on the time a live_loop runs: So in case I have a loop which has a sleep of 4 (see the :loop_amen example) I wanted a smooth fading and not a fade where the volume increases stepwise only every four beats. That’s why I choose this approach. So now I will have to find out why my SP doesn’t do it anymore … :frowning:

Nevertheless I will check out your tutorial (which I have not yet). So thanks for sharing!

#26

So many great ideas here for fading! Thanks!

Has anyone experimented with something akin to fade groups? Particularly in a live-code context for quicker modifications of loops in progress. One thing I’d like to do is be able to target a given live_loop and apply a fade (or perhaps toggle a mute?) to it. For example:


# Apply a fade to only loops a and b, letting c play at full volume
apply_fade([:a, :b])

# Or alternately - only c and a are fading in and b is full volume.
# apply_fade([:c, :a])

live_loop :a do
  # play stuff
end

live_loop :b do
  # play stuff
end

live_loop :c do
  # play stuff
end
#27

Here is a sample progarm which can control three separate loops in this way.
The code is almost identical for each loop section.
The function apply_fade lets you control each loop with one command. setting data to 1 fades loop on
setting data to 0 fades loop off.
You could put more than one loop inside each fx :level and they would be controlled together.
Fade time can be changed by changing amp_slide times
I used sample loops for teh loops but you can put anything you want in them. You could also use a metronome loop to sync them if required.

#Program controls fade up/down of three live_loops
#fade time 1 beat, but can be adjusted using slide times
#can be different for each loop if required

define :apply_fade do |flist,fvalue|
  flist.zip(fvalue).each do |f,v| # allows lists to be linked and corresponding values to be processed
    set f,v
  end
end

apply_fade([:La,:Lb,:Lc],[0,1,0]) #set fade values 1 on, 0 off

with_fx :level,amp: 1 do |va|
  in_thread do
    loop do
      control va,amp: get(:La),amp_slide: 1
      sleep 1
    end
  end
  
  live_loop :a do
    sample :loop_amen,beat_stretch:2
    sleep 2
  end
end

with_fx :level,amp: 1 do |vb|
  in_thread do
    loop do
      control vb,amp: get(:Lb),amp_slide: 1
      sleep 1
    end
  end
  
  live_loop :b do
    sample :loop_tabla,beat_stretch:8
    sleep 8
  end
end

with_fx :level,amp: 1 do |vc|
  in_thread do
    loop do
      control vc,amp: get(:Lc),amp_slide: 1
      sleep 1
    end
  end
  
  live_loop :c do
    sample  :loop_garzul,beat_stretch:8
    sleep 8
  end
end
#28

Hi Martin,

Wow, this threads covered a lot of ground… So, heres a little
drum beat, with 2 different ‘backgrounds’, fading into each other
and providing a composite background…

Initially you only get the beat… If you take the stop out of either
background, you will hear it fade in and out.

If you take out both stop 's you get the mixed background

This isn’t really meant to teach anything to anyone… I
was just pottering around and it sort of wrote itself… :slight_smile:

Eli…

#Spiralysis
#by Eli...

use_bpm 120

bg1 = (ring 0.0,0.1,0.2,0.3,0.4,0.5,0.0,0.0).mirror
bg2 = (ring 0.5,0.4,0.3,0.2,0.1,0.0,0.0,0.0).mirror

melody_1 = [:c4,:r,:ds4,:ds4,:g4,:c4,:r,:gs4,:r,:r,:gs3,:r,:g3,:r,:r,:r].ring

live_loop :beats do
  sleep 1
end

live_loop :bar do
  sleep 4
end

live_loop :mixer do
  tick
  set :bvol1, bg1.look
  set :bvol2, bg2.look
  sync :bar
end

live_loop :kick, sync: :beats  do
  sample :bd_haus
  sleep 1.5
  sample :bd_haus
  sleep 1
  sample :bd_haus
  sample :drum_cymbal_closed
  sleep 1
  sample :bd_haus
  sample :drum_cymbal_closed
  sleep 0.5
end

live_loop :kick1, sync: :bar do
  sample :bd_ada
  sleep 1
  sample :bd_ada
  sample :sn_dolf, sustain: 0, release: 0.08, hpf: 80
  sleep 1
end

live_loop :tom, sync: :beats  do
  sample :drum_tom_lo_soft
  sleep 0.5
end

live_loop :snap, sync: :beats  do
  sleep 1
  if rand(1) < 0.75 then
    sample :perc_snap, amp: 0.5
  else
    sample :perc_snap2, amp: 0.5
  end
  sleep 1
end

with_fx :reverb, mix: 0.5, room: 0.9 do
  with_fx :ixi_techno, mix: 0.75, room: 0.9 do
    
    live_loop :background1, sync: :beats do
      
      stop
      
      this_vol = get :bvol1
      use_synth_defaults amp: this_vol * 4
      use_synth (ring :supersaw, :prophet, :prophet, :tech_saws).tick
      3.times do
        play :C4, cutoff: rrand(60,80)
        sleep 0.5
        play :G3, cutoff: rrand(60,90)
        sleep 0.5
        play :C4, cutoff: rrand(60,70)
        sleep 0.5
        play :Gs3, cutoff: rrand(60,80)
        sleep 0.25
        play :Gs3, cutoff: rrand(70,100)
        sleep 0.25
      end
      1.times do
        play :c4, cutoff: rrand(60,80), release: 1
        sleep 0.5
        play :g4, cutoff: rrand(60,90), release: 1
        sleep 0.5
        play :c4, cutoff: rrand(60,70), release: 1
        sleep 0.5
        play :gs3 + 7, cutoff: rrand(80,100), release: 1
        sleep 0.5
      end
    end
    
    live_loop :background2 do
      
      stop
      
      sync :beats if rand(1) < 0.5
      this_vol = get :bvol2
      
      use_synth_defaults cutoff: 70, release: 1.2, amp: this_vol * 4, pulse_width: rrand(0,1)
      use_synth [:subpulse, :pulse].choose
      if rand(1) < 0.75 then
        with_fx :ixi_techno, mix: 0.55, room: 0.85, damp: 0.8 do
          16.times do
            play melody_1.look - 12
            sleep 0.25
            tick
          end
        end
      else
        use_synth :prophet
        16.times do
          play melody_1.look - 12
          sleep 0.25
          tick
        end
      end
    end
  end
end
#29

Hi @Eli,

yes, that’s an interesting idea to use a live_loop to set amp-values. The only thing which keeps me from doing that, is, that, to be applied, you depend on the runtime (the added sleeps) of the live_loop which calls these values. That is why I quite like the idea of amp_slide: It gives you more freedom to control your volume manipulation (or any other option) somehow independant from the time your life_loop needs to set another amp value:

Just imagine: you could have a synth melody changing every 0.25 compared to one with a release of 8. Actually you probably will not be able to fade the second one with ticking. It just takes to long. The other thing is, that using a ring and ticking through the values in most cases actually creates a stepwise fading. If you want to have it smoothly, you will need to apply amp_slide (either within the live_loops or by using set_mixer_control! for a whole buffer).

I updated my Sonic Pi Resources and tried to collect and comment different examples for fading (1,2).