Bach Air on a G String

Been doing some Bach today. Here is his Air on a G string arranged for Piano.
I’ve taken the piano part and split it into three parts (two in the right and and one in the left hand).
I’ve tweaked the piano synth defaults to give a mellower sound, and also added extensive dynamic variation, utilising two lists, one giving the start time of each change and the other holding pairs of target amplitude and slide time to get there. The whole is controlled using the at command, and I control the fx :level to get the required amplitude. A separate fx :level sets the relative amplitude of the left hand bass part to balance it and a third amplifies the resultant whole to give a louder overall volume.
I haven’t added comments in the code, as it just fits a normal Sonic Pi buffer on my Mac without objecting. Comments take it over the limit! So here’s a couple of further notes.
the line t=t.collect { |n| n * bl } is a ruby method of multiplying every element in a list in this case by bl, the number of beats in a bar.
Each part is played in a thread so that they play together. I loop round the list of notes an durations and use tick and look to get each corresponding pair in turn for each part. (the ticks, and looks are local to each thread). The commented out line #play 96,release: 0.1 #to debug lets you hear with a high beep that the level changes are initiated at the correct times. Useful for debugging them.

So therr we are. It makes a nice classical piece to chill out to.

#Air_on_a_G_string.rb
use_synth :piano
use_bpm 66
use_debug false
use_synth_defaults attack: 0.01,vel: 0.6,hard: 0.45,stereo_width: 0.3
ff=0.9;f=0.7;mf=0.4;p=0.3;pp=0.2
bl=4

with_fx :reverb,room: 0.8,mix: 0.6 do
  with_fx :level,amp: 4 do
    with_fx :level,amp: mf do |vr|
      set :vr,vr
      
      t=[0,3.5,4,6,7,11,12,15.5,16,18,19,23,24,27,28,31,32,35,36,40,45.5,48,51,52,55,56,59,60,64,69.5]
      
      t=t.collect { |n| n * bl }
      
      l=[[f,2*bl],[mf,0.5*bl],[f,2*bl],[mf,1*bl],[f,1*bl],[mf,1*bl],
         [f,2*bl],[mf,0.5*bl],[f,2*bl],[mf,1*bl],[f,1*bl],[mf,1*bl],
         [f,1*bl],[mf,1*bl],[f,2*bl],[mf,1*bl],[f,1*bl],[mf,1*bl],[f,4*bl],[ff,3*bl],[mf,1.5*bl],
         [f,1*bl],[mf,1*bl],[f,2*bl],[mf,1*bl],[f,1*bl],[mf,1*bl],[f,4*bl],[ff,3*bl],[p,1.5*bl]]
      
      at t,l   do |v|
        #play 96,release: 0.1 #to debug
        puts v[0],v[1]
        control get(:vr),amp:v[0], amp_slide: v[1] #change dynamic level using control
      end
      
      #part 1
      a1=[:B4,:B4,:E5,:C5,:B4,:A4,:G4,:Fs4,:G4,:Fs4,:E4,:D4,:D5,:B4,:F4,:E4,:A4,:Gs4,:D5,:C5,:C5,:A4,:E4,:D4,:G4,:Fs4,:C5,:B4,:B4,:Cs5,:D5,:G4,:G4,:A4,:B4,:B4,:A4,:A4,:G4,:Fs4,:E4,:E4,:Fs4,:G4,:G4,:Fs4,:E4,:D4,:B4,:B4,:E5,:C5,:B4,:A4,:G4,:Fs4,:G4,:Fs4,:E4,:D4,:D5,:B4,:F4,:E4,:A4,:Gs4,:D5,:C5,:C5,:A4,:E4,:D4,:G4,:Fs4,:C5,:B4,:B4,:Cs5,:D5,:G4,:G4,:A4,:B4,:B4,:A4,:A4,:G4,:Fs4,:E4,:E4,:Fs4,:G4,:G4,:Fs4,:E4,:D4,:Fs4,:r,:G4,:Fs4,:E4,:Fs4,:D4,:D5,:F4,:E4,:E5,:D5,:C5,:B4,:C5,:B4,:A4,:G4,:Fs4,:E4,:Ds4,:E4,:Fs4,:G4,:A4,:B4,:C5,:B4,:A4,:G4,:Fs4,:E4,:Fs4,:G4,:A4,:G4,:E4,:G4,:r,:B4,:A4,:G4,:E5,:D5,:Cs5,:B4,:A4,:D5,:D4,:E4,:Fs4,:G4,:Fs4,:E4,:D4,:G4,:B4,:A4,:A4,:C5,:B4,:B4,:D5,:C5,:C5,:D4,:r,:Fs4,:A4,:C5,:C5,:A4,:B4,:B4,:C5,:D5,:G4,:r,:B4,:D5,:F5,:E5,:G4,:Fs4,:A4,:C5,:E4,:D4,:A4,:B4,:C5,:C5,:B4,:A4,:G4,:Fs4,:E4,:Fs4,:G4,:Fs4,:G4,:G4,:Fs4,:r,:G4,:Fs4,:E4,:Fs4,:D4,:D5,:F4,:E4,:E5,:D5,:C5,:B4,:C5,:B4,:A4,:G4,:Fs4,:E4,:Ds4,:E4,:Fs4,:G4,:A4,:B4,:C5,:B4,:A4,:G4,:Fs4,:E4,:Fs4,:G4,:A4,:G4,:E4,:G4,:r,:B4,:A4,:G4,:E5,:D5,:Cs5,:B4,:A4,:D5,:D4,:E4,:Fs4,:G4,:Fs4,:E4,:D4,:G4,:B4,:A4,:A4,:C5,:B4,:B4,:D5,:C5,:C5,:D4,:r,:Fs4,:A4,:C5,:C5,:A4,:B4,:B4,:C5,:D5,:G4,:r,:B4,:D5,:F5,:E5,:G4,:Fs4,:A4,:C5,:E4,:D4,:A4,:B4,:C5,:C5,:B4,:A4,:G4,:Fs4,:E4,:Fs4,:G4,:Fs4,:G4,:G4]
      b1=[4.0,5.0,0.5,0.5,0.083333336,0.4166667,0.5,0.5,0.5,2.0,0.5,1.5,4.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,4.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,3.0,0.5,0.5,1.0,0.5,0.25,0.25,0.5,0.5,0.5,0.5,0.5,0.5,0.25,0.25,0.5,1.0,0.5,0.5,4.0,4.0,5.0,0.5,0.5,0.083333336,0.4166667,0.5,0.5,0.5,2.0,0.5,1.5,4.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,4.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,3.0,0.5,0.5,1.0,0.5,0.25,0.25,0.5,0.5,0.5,0.5,0.5,0.5,0.25,0.25,0.5,1.0,0.5,0.5,4.0,2.25,0.25,0.25,0.25,0.25,0.25,0.5,3.0,1.0,1.0,1.5,0.5,0.5,0.5,2.25,0.25,0.25,0.25,0.5,0.5,0.5,0.5,1.5,0.5,1.5,0.5,2.0,1.0,0.5,0.5,0.5,0.5,0.5,0.25,0.25,1.0,4.0,2.25,0.25,0.5,0.5,0.5,3.0,0.5,0.5,0.25,0.25,0.5,1.0,1.5,0.25,0.25,1.5,0.5,2.0,3.0,0.5,0.5,3.0,0.5,0.5,3.0,0.5,0.5,4.0,2.25,0.25,0.5,0.5,0.5,0.5,0.5,2.0,0.5,0.25,0.25,2.25,0.25,0.5,0.5,0.5,3.0,1.0,0.5,0.5,2.0,1.0,1.0,0.5,0.25,0.25,0.5,1.0,0.5,0.25,0.25,1.0,0.5,1.0,0.5,0.5,4.0,2.25,0.25,0.25,0.25,0.25,0.25,0.5,3.0,1.0,1.0,1.5,0.5,0.5,0.5,2.25,0.25,0.25,0.25,0.5,0.5,0.5,0.5,1.5,0.5,1.5,0.5,2.0,1.0,0.5,0.5,0.5,0.5,0.5,0.25,0.25,1.0,4.0,2.25,0.25,0.5,0.5,0.5,3.0,0.5,0.5,0.25,0.25,0.5,1.0,1.5,0.25,0.25,1.5,0.5,2.0,3.0,0.5,0.5,3.0,0.5,0.5,3.0,0.5,0.5,4.0,2.25,0.25,0.5,0.5,0.5,0.5,0.5,2.0,0.5,0.25,0.25,2.25,0.25,0.5,0.5,0.5,3.0,1.0,0.5,0.5,2.0,1.0,1.0,0.5,0.25,0.25,0.5,1.0,0.5,0.25,0.25,1.0,0.5,1.0,0.5,0.5,4.0]
      in_thread do        
        a1.length.times do
          play a1.tick,sustain: b1.look
          sleep b1.look
        end
      end
      #part 2
      a2=[[:D4,:G4],[:E4,:G4],[:E4,:G4],:E4,[:A3,:D4],:D4,:F4,:E4,:F4,:r,:r,:r,:E4,:D4,:E4,:r,:r,[:D4,:G4],[:D4,:A4],[:B3,:E4],:Cs4,:E4,[:Cs4,:E4],[:A3,:D4],[:B3,:D4],[:A3,:D4],[:A3,:Cs4],[:Fs3,:A3],[:D4,:G4],[:E4,:G4],[:E4,:G4],:E4,[:A3,:D4],:D4,:F4,:E4,:F4,:r,:r,:r,:E4,:D4,:E4,:r,:r,[:D4,:G4],[:D4,:A4],[:B3,:E4],:Cs4,:E4,[:Cs4,:E4],[:A3,:D4],[:B3,:D4],[:A3,:D4],[:A3,:Cs4],[:Fs3,:A3],[:A3,:D4],:r,[:F4,:B4],:r,:r,[:E4,:A4],:r,:r,:r,:r,:A3,:B3,:Fs4,:E4,:Ds4,:E4,:Fs4,[:B3,:E4],:C4,:C4,:Ds4,[:G3,:B3],[:A3,:E4],:D4,[:E4,:A4,:Cs5],[:E4,:A4],:D4,:A3,:B3,:Cs4,[:A3,:D4],[:Fs3,:A3],:D4,:E4,:F4,:E4,:r,:Fs4,:E4,:Fs4,:r,:Gs4,:Fs4,:Gs4,[:E4,:B4],[:E4,:A4],[:A3,:C4],:D4,[:D4,:G4],[:D4,:G4],[:D4,:G4],:D4,:C4,[:B3,:F4],[:E4,:G4,:C5],:D4,:C4,[:E4,:G4],:C4,:A3,[:D4,:Fs4],[:D4,:G4],[:C4,:E4],[:B3,:D4],:C4,[:A3,:D4],[:C4,:D4],[:B3,:D4],[:A3,:D4],:r,[:F4,:B4],:r,:r,[:E4,:A4],:r,:r,:r,:r,:A3,:B3,:Fs4,:E4,:Ds4,:E4,:Fs4,[:B3,:E4],:C4,:C4,:Ds4,[:G3,:B3],[:A3,:E4],:D4,[:E4,:A4,:Cs5],[:E4,:A4],:D4,:A3,:B3,:Cs4,[:A3,:D4],[:Fs3,:A3],:D4,:E4,:F4,:E4,:r,:Fs4,:E4,:Fs4,:r,:Gs4,:Fs4,:Gs4,[:E4,:B4],[:E4,:A4],[:A3,:C4],:D4,[:D4,:G4],[:D4,:G4],[:D4,:G4],:D4,:C4,[:B3,:F4],[:E4,:G4,:C5],:D4,:C4,[:E4,:G4],:C4,:A3,[:D4,:Fs4],[:D4,:G4],[:C4,:E4],[:B3,:D4],:C4,[:A3,:D4],[:C4,:D4],[:B3,:D4]]
      b2=[4.0,4.0,2.0,2.0,4.0,1.0,0.5,0.5,3.0,1.0,2.0,1.0,0.5,0.5,3.0,1.0,2.0,3.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0,4.0,4.0,2.0,2.0,4.0,1.0,0.5,0.5,3.0,1.0,2.0,1.0,0.5,0.5,3.0,1.0,2.0,3.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0,3.0,1.0,3.0,1.0,4.0,3.0,1.0,2.0,1.0,0.5,0.5,1.0,0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,1.0,4.0,3.0,1.0,3.0,1.0,1.0,1.0,1.0,1.0,2.0,2.0,1.0,0.5,0.5,2.0,1.0,0.5,0.5,2.0,1.0,0.5,0.5,1.0,1.0,4.0,3.0,1.0,1.0,2.0,1.0,1.0,1.0,2.0,3.0,1.0,1.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0,3.0,1.0,3.0,1.0,4.0,3.0,1.0,2.0,1.0,0.5,0.5,1.0,0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,1.0,4.0,3.0,1.0,3.0,1.0,1.0,1.0,1.0,1.0,2.0,2.0,1.0,0.5,0.5,2.0,1.0,0.5,0.5,2.0,1.0,0.5,0.5,1.0,1.0,4.0,3.0,1.0,1.0,2.0,1.0,1.0,1.0,2.0,3.0,1.0,1.0,2.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0]
      in_thread do
        a2.length.times do
          play a2.tick,sustain: b2.look
          sleep b2.look
        end
      end
    end
    
    with_fx :level,amp: pp do
      #part 3
      a3=[:G2,:G3,:Fs3,:Fs2,:E2,:E3,:D3,:D2,:C2,:C3,:Cs3,:Cs2,:D2,:D3,:C3,:C2,:B2,[:Gs3,:D4],[:A3,:D4],:A2,:Gs2,[:B3,:D4],:E3,[:Gs3,:E4],:A2,[:A3,:C4],[:G3,:C4],:G2,:Fs2,[:A3,:C4],:D3,[:Fs3,:D4],:G2,:G3,:Fs3,:Fs2,:E2,:E3,:Cs3,:A2,:D3,:B2,:A2,:A2,:D2,:E2,:Fs2,:G2,:A2,:C3,:B2,:A2,:G2,:G3,:Fs3,:Fs2,:E2,:E3,:D3,:D2,:C2,:C3,:Cs3,:Cs2,:D2,:D3,:C3,:C2,:B2,[:Gs3,:D4],[:A3,:D4],:A2,:Gs2,[:B3,:D4],:E3,[:Gs3,:E4],:A2,[:A3,:C4],[:G3,:C4],:G2,:Fs2,[:A3,:C4],:D3,[:Fs3,:D4],:G2,:G3,:Fs3,:Fs2,:E2,:E3,:Cs3,:A2,:D3,:B2,:A2,:A2,:D2,:D2,:D3,:C3,:C2,:B1,[:Gs3,:D4],:E4,[:A3,:D4,:F4],:A2,:Gs2,[:B3,:D4],:E3,[:Gs3,:E4],:A2,:A3,:G3,:G2,:Fs2,[:Fs3,:A3],:B3,[:E3,:A3,:C4],:E2,:Ds2,:E2,:Fs2,:Ds2,:E2,[:C3,:G3],[:A2,:A3],[:B2,:A3],:E2,:E3,:D3,:D2,:Cs2,:Cs3,:B2,:B1,:A1,:A3,:G3,:G2,:Fs2,:Fs3,:G2,:A2,:D2,:D3,:C3,:C2,:B1,[:B2,:G3],[:C3,:G3],:C2,:Cs2,[:Cs3,:A3],[:D3,:A3],:D2,:Ds2,[:Ds3,:B3],[:E3,:B3],:Gs2,:A2,:A3,:G3,:G2,:Fs2,:Fs3,:D3,:Fs3,:G3,:G2,:F2,:F3,:E3,:E2,:D2,:D3,:C3,:C2,:B1,:B2,:A2,:A3,:G3,:G2,:Fs2,:D2,:G2,:C3,:D3,:C3,:D3,:D2,[:G2,:D3],:D2,:D3,:C3,:C2,:B1,[:Gs3,:D4],:E4,[:A3,:D4,:F4],:A2,:Gs2,[:B3,:D4],:E3,[:Gs3,:E4],:A2,:A3,:G3,:G2,:Fs2,[:Fs3,:A3],:B3,[:E3,:A3,:C4],:E2,:Ds2,:E2,:Fs2,:Ds2,:E2,[:C3,:G3],[:A2,:A3],[:B2,:A3],:E2,:E3,:D3,:D2,:Cs2,:Cs3,:B2,:B1,:A1,:A3,:G3,:G2,:Fs2,:Fs3,:G2,:A2,:D2,:D3,:C3,:C2,:B1,[:B2,:G3],[:C3,:G3],:C2,:Cs2,[:Cs3,:A3],[:D3,:A3],:D2,:Ds2,[:Ds3,:B3],[:E3,:B3],:Gs2,:A2,:A3,:G3,:G2,:Fs2,:Fs3,:D3,:Fs3,:G3,:G2,:F2,:F3,:E3,:E2,:D2,:D3,:C3,:C2,:B1,:B2,:A2,:A3,:G3,:G2,:Fs2,:D2,:G2,:C3,:D3,:C3,:D3,:D2,[:G2,:D3]]
      b3=[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,0.5,0.5,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,4.0]
      in_thread do
        a3.length.times do
          play a3.tick,sustain: b3.look*0.95
          sleep b3.look
        end
      end
    end
  end
end
4 Likes

Sounds nice with :tri too.

Eli…

Yes, although I would want to adjust level settings and add release times to balance this.
I might do a strings version (using external samples) which is what it was played by originally of course.

Very nice @robin.newman,

if you prefer an organ sound also quite convincing with:

use_synth_defaults attack: 0.075, depth: 2, divisor: 1

1 Like