Skip to content

Instantly share code, notes, and snippets.

@rbnpi
Last active July 1, 2016 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbnpi/ac18ce771974ca59b4b7 to your computer and use it in GitHub Desktop.
Save rbnpi/ac18ce771974ca59b4b7 to your computer and use it in GitHub Desktop.
Deux Miniatures coded for Sonic Pi, utilising the Sonatina Symphonic Symphony library. Requires SP2.10dev or later. Article at https://rbnrpi.wordpress.com/2016/03/18/deux-miniatures-coded-on-sonic-pi/ Hear it at https://soundcloud.com/rbnman/deuxminiatures-played-by-sonic-pi
#Deux Miniatures by Victor Kalinnikow here arranged for Oboe and strings
#Utilises the Sonatina Symphonic ORchstera library
#written by Robin Newman, March 2016
#Uses three separate buffers linced by cue and sync#run part 3 THEN part 2 THEN part 1
#path variable needs to be adjusted in all three parts
#amended to handle new thread structure in SP2.11dev
use_debug false
#path to library samples folder (including trailing /)
path='~/Sonatina Symphonic Orchestra/Samples/'
#create array of instrument details
voices=[['2nd Violins sus','2nd Violins','2nd-violins-sus-',1,:g3,:b6],\
['Violas sus','Violas','violas-sus-',0,:c3,:c6],\
['Basses piz','Basses','basses-piz-rr1-',0,:c1,:c4],\
['Basses sus','Basses','basses-sus-',0,:c1,:c4],\
['Basses stc','Basses','basses-stc-rr1-',0,:c1,:c4],\
['Oboe','Oboe','oboe-',1,:as3,:c6]]
llist=[0,1,2,3,4,5] #voicenumbers used
killit=0 #flag to kill live_loop :t when all samples laoded
define :load do |i|
trigger=0
live_loop :t do
sleep 0.3 #can be reduced to 0.2 on Mac or PC
if trigger== 1
cue :start
end
stop if killit==1 #kill loop when all samples loaded
end
load_samples path+voices[i][1],voices[i][2]
trigger=1
sync :start
end
llist.each do |i|
load(i)
end
killit=1 #set flag to killl live_loop :t
sleep 2
puts 'The following voices from Sonatina Symphonic Library can be used:-'
voices.each_with_index do |n,i|
puts i.to_s,n[0]
end
puts voices.length.to_s+' voices'
#setup global variables
sampledir=''
sampleprefix=''
offsetclass=''
low=''
high=''
paths=''
#setup data for current inst
define :setup do |inst,path|
sampledir=voices.assoc(inst)[1]
sampleprefix=voices.assoc(inst)[2]
offsetclass=voices.assoc(inst)[3]
low=voices.assoc(inst)[4]
high=voices.assoc(inst)[5]
#amend path for instrument sampledir
paths=path+sampledir+'/'
end
#define routine to play sample
define :pl do |np,d,inst,vol=1,s=0.9,r=0.1,tp=0,pan=0|
setup(inst,path)
#check if note in range of supplied samples
#use lowest/highest sample for out of range
change=0 #used to give rpitch for coverage outside range
frac=0
n=np+tp #note allowing for transposition
if n.is_a?(Numeric) #allow frac tp or np
frac=n-n.to_i
n=n.to_i
end
if note(np)+tp<note(low) #calc adjustment for low note
change=note(np).to_i+tp-note(low)
n=note(low)
end
if note(np).to_i+tp > note(high) #calc adjustment for high note
change = note(np).to_i+tp-note(high)
n=note(high)
end
if change < -5 or change > 5 #set allowable out of range
#if outside print messsage
puts 'inst: '+inst+' note '+np.to_s+' with transpostion '+tp.to_s+' out of sample range'
else #otherwise calc and play it
#calculate base note and octave
base=note(n)%12
oc = note(n) #do in 2 stages because of alignment bug
oc=oc/12 -1
#find first part of sample note
slookup=['c','c#','d','d#','e','f','f#','g','g#','a','a#','b']
#lookup sample to use,and rpitch offset, according to offsetclass
case offsetclass
when 0
oc += 1 if base == 11 #adjust if sample needs next octave
snumber=[0,0,3,3,3,6,6,6,9,9,9,0]
offset=[ 0,1,-1,0,1,-1,0,1,-1,0,1,-1]
when 1
snumber=[1,1,1,4,4,4,7,7,7,10,10,10]
offset=[-1,0,1,-1,0,1,-1,0,1,-1,0,1]
when 2
oc -= 1 if base == 0 #adjust if sample needs previous octave
snumber=[11,2,2,2,5,5,5,8,8,8,11,11]
offset=[1,-1,0,1,-1,0,1,-1,0,1,-1,0]
when 3
snumber=[0,1,2,3,4,5,6,7,8,9,10,11] #this class has sample for every note
offset=[0,0,0,0,0,0,0,0,0,0,0,0]
end
#generate sample name
sname=sampleprefix+(slookup[snumber[base]]).to_s+oc.to_s
#play sample with appropriate rpitch value
sample paths,sname,rpitch: offset[base]+change+frac,sustain: s*d,release: r*d,pan: pan,amp: vol
end
end
#define function to play lists of linked samples/durations
define :plarray do |notes,durations,offsetclass,vol=1,s=0.9,r=0.1,tp=0,pan=0|
puts offsetclass
notes.zip(durations).each do |n,d|
if n.respond_to?(:each)
n.each do |nv|
pl(nv,d,offsetclass,vol,s,r,tp,pan) if ![nil,:r,:rest].include? nv#allow for rests
end
else
pl(n,d,offsetclass,vol,s,r,tp,pan) if ![nil,:r,:rest].include? n#allow for rests
end
sleep d
end
end
cue :part2
sync :part2
#part 2 of Deux Miniatures by Victor Kalinnikow arrange for Oboe and Strings
#written by Robin Newman, March 2016
#path to library samples folder (including trailing /)
path='~/Sonatina Symphonic Orchestra/Samples/'
#create array of instrument details
voices=[['2nd Violins sus','2nd Violins','2nd-violins-sus-',1,:g3,:b6],\
['Violas sus','Violas','violas-sus-',0,:c3,:c6],\
['Basses piz','Basses','basses-piz-rr1-',0,:c1,:c4],\
['Basses sus','Basses','basses-sus-',0,:c1,:c4],\
['Basses stc','Basses','basses-stc-rr1-',0,:c1,:c4],\
['Oboe','Oboe','oboe-',1,:as3,:c6]]
#setup global variables
sampledir=''
sampleprefix=''
offsetclass=''
low=''
high=''
paths=''
sq=0.14
q=2*sq
c=2*q
cd=3*q
m=2*c
md=3*c
b=2*m
bd=3*m
nv1=[:fs5,:e5,:d5,:cs5,:d5,:b4,:fs4,:g4,:a4,:b4,:a4,:g4,:g5,:fs5,:e5,:d5,:cs5,:fs5,:d5,:cs5,:d5,:cs5,:b4,:e5,:es5,:fs5,\
:e5,:d5,:cs5,:d5,:b4,:fs4,:g4,:a4,:b4,:a4,:g4,:b4,:cs5,:d5,:e5,:d5,:fs5,:b4,:cs5,:d5]
dv1=[q]*9+[c,c,cd]+[q]*9+[c,c,c,q,q]+\
[q]*8+[c,c,cd]+[q]*9
nv1rba=[:cs5,:b4,:a4]
dv1rba=[c,c,cd]
nv1rbb=[:cs5,:b4,:a4,:r,:a4]
dv1rbb=[c,c,c,q,q]
nv2=[:r,:fs4,:e4,:g4,:fs4,:a4,:g4,:fs4,:e4,:g4,:fs4]
dv2=[q,bd,m,m,c,c,b,bd,m,m,m]
nv2rba=[:gs4,:e4]
dv2rba=[m,cd]
nv2rbb=[:gs4,:e4,:r]
dv2rbb=[m,c,c]
nvl=[:r,:a3,:as3,:b3,:cs4,:e4,:d4,:fs4,:e4,:d4,:cs4,:b3,:a3,[:a3,:d4],:as3,:b3,[:c4,:ds4],:b3,:as3,:b3]
dvl=[q,c,c,bd,c,c,c,c,c,cd,q,q,q,c,c,m,m,m,m,m]
nvlrba=[:d4,:cs4]
dvlrba=[m,cd]
nvlrbb=[:d4,:cs4,:r]
dvlrbb=[m,c,c]
nc1=[:r,:d3,:d3,:d3,:d3]
dc1=[q,b*2,b*2,b*2,b]
nc1rra=[:e3,:r]
dc1rra=[m,m-q]
nc1rrb=[:e3,:a3,:r]
dc1rrb=[m,c,c]
nc2=[:r,:a3,:r] #single note fill
dc2=[q+b*2,b+md,c+b*3]
nc2rra=[:r,:a3,:e3,:a2] #piz fill
dc2rra=[q+7*b+m,q,q,q]
#letter A
nv1b=[:b4,:e5,:b4,:cs5,:d5,:d5,:e5,:a5,:e5,:fs5,:g5,:g5,:fs5,:a5,:g5,:fs5,:fs5,:e5,:e5,:fs5,:a5,:g5,:fs5,:fs5,:e5,:e5,:fs5,:a5,:fs5,:d5,:g5,:fs5,:e5,:d5,:cs5,:d5,:cs5,:b4,:e5,:a4,:a4]
dv1b=[q,q,q,q,cd,q]*2+[q,q,q,q,q,c,q]*2+[q,q,q,q]*3+[c,q,q]
#letter B
nv1b.concat [:b4,:e5,:b4,:cs5,:d5,:d5,:e5,:a5,:e5,:fs5,:g5,:g5,:b5,:a5,:g5,:fs5,:es5,:fs5,:a5,:g5,:fs5,:e5,:ds5,:e5,:g5,:fs5,:e5,:d5,:cs5,:b4,:a4,:g4,:fs4,:g4,:fs4,:e4,:d4,:fs4,:e4,:d4,:e4,:fs4,:fs5]
dv1b.concat [q,q,q,q,cd,q,q,q,q,q,cd,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,c,q,q]
#letter C
nv1b.concat [:e5,:d5,:cs5,:d5,:b4,:fs4,:g4,:a4,:b4,:a4,:g4,:g5,:fs5,:e5,:d5,:cs5,:fs5,:d5,:cs5,:d5,:cs5,:b4,:e5,:es5,:fs5]
dv1b.concat [q,q,q,q,q,q,q,q,c,c,cd,q,q,q,q,q,q,q,q,q,c,c,c,q,q]
#letter D
nv1b.concat [:e5,:d5,:cs5,:d5,:b4,:fs4,:g4,:a4,:b4,:a4,:g4,:e4,:fs4,:g4,:fs4,:e4,:a4,:fs4,:e4,:g4,:fs4,:e4,:a4,:fs4,:e4,:d4,:cs4,:d4,:fs4,:fs4,:e4,:d4,:cs4,:d,:fs4,:fs4,:e4,:d4,:a3,:r,:d4,:fs4,:a4,:d5,:fs5]
dv1b.concat [q]*8+[c,c,cd,q]+[q,q,q,q,cd,q]*4+[q,q,q,q,c,c,m,m,b]
#letter A
nv2b=[:b4,:bb4,:a4,:e5,:eb5,:d5,:d5,:a4,:b4,:bb4,:a4,:b4,:bb4,:a4,:b4,:bb4,:a4,:e4,:e4]
dv2b=[cd,q,m,cd,q,m,c,c,c,c,m,c,c,m,cd,q,c,c,m]
#letter B
nv2b.concat [:e4,:d4,:a4,:g4,:g4,:b4,:a4,:g4,:fs4,:es4,:fs4,:a4,:g4,:fs4,:e4,:ds4,:e4,:r,:as3,:g4,:fs4,:e4,:d4,:cs4,:b3,:a3,:b3,:a3,:g3,:a3,:d4,:cs4]
dv2b.concat [m,m,m,cd,q]+[q,q,q,q]*6+[m,c,c]
#letter C
nv2b.concat [:fs4,:e4,:g4,:fs4,:a4,:g4]
dv2b.concat [bd,m,m,c,c,b]
#letter D
nv2b.concat [:fs4,:fs4,:e4,:cs4,:e4,:d4,:cs4,:d4,:cs4,:e4,:d4,:cs4,:d4,:bb3,:a3,:d4,:cs4,:b3,:bb3,:a3,:cs4,:b3,:bb3,:a3,:r,:d4,:r,:d5]
dv2b.concat [b,m,m,cd,c,q,q,q,cd,c,q,q,q,m,q,q,q,q,m,q,q,q,q,c,c,m,m,bd]
#letter A
nvlb=[:e4,:d4,:a4,:g4,:a4,:d4,:d4,:cs4,:d4,:d4,:cs4,:d4,:d4,:e4,:e4,:d4,:cs4,:b3,:a3]
dvlb=[m,m,m,m,c,c,cd,q,m,cd,q,m,cd,q,cd,c,q,q,q]
#letter B
nvlb.concat [:b3,:bb3,:a3,:e4,:eb4,:d4,:cs4,[:g3,:d4],:b3,:b3,:g4,:fs4,:as3,:fs3,:e3,:fs3,:g3,:bb3,:a3,:g3]
dvlb.concat [cd,q,m,cd,q,m,m,c,m,c,q,q,c,m,m,m,q,q,q,q]
#letter C
nvlb.concat [:a3,:as3,:b3,:cs4,:e4,:d4,:fs4,:e4,:d4,:cs4,:b3,:a3]
dvlb.concat [c,c,bd,c,c,c,c,c,cd,q,q,q]
#letter D
nvlb.concat [[:a3,:d4],:as3,:b3,[:c4,:ds4],:b3,:bb3,:g3,:fs3,:a3,:bb3,:g3,:fs3,:g3,:fs3,:g3,:fs3,:r,:fs4]
dvlb.concat [c,c,m,m,m,c,c,cd,q,c,c,m,m,m,m,md,m,c+2*b]
nvlb2=[:r,:a4] #extra note last two bars
dvlb2=[q+39*b,2*b]
#letter A
nc3=[:gs3,:g3,:fs3,:es3,:fs3,:cs4,:c4,:b3,:as3,:b3,:a3,:gs3,:g3,:fs3,:a3,:gs3,:g3,:fs3,:e3,:fs3,:g3,:a3,:r]
dc3=[c,cd,q,q,q,c,cd,q,q,q,m,c,c,c,c,c,c,m,q,q,c,md,c]
#letter B
nc3.concat [:gs3,:g3,:fs3,:es3,:fs3,:cs4,:c4,:b3,:as3,:b3,[:a2,:e2],[:d3,:a3],[:g2,:d3],[:cs3,:g3],[:fs2,:cs3],:b2,[:e2,:b2],:a2]
dc3.concat [c,cd,q,q,q,c,cd,q,q,q,m,c,m,c,m,m,m,b]
#letter C
nc3.concat [:d3,:d3,:d3,:d3,:d3,:d3,:d3,:r,:fs3,:e3,:d3,:a2,:fs2,:e2,:d2,:a2,:fs2,:d2]
dc3.concat [b*2,b,b,b*2,b*2,b*2,c,q,q,q,q,q,q,c,c,c,c,b]
puts nc3.length
puts dc3.length
nc4=[:r,:a3]
dc4=[30*b+q,md]
v2="2nd Violins sus"
v1="Oboe"
vl="Violas sus"
vc="Basses sus"
vcp="Basses piz"
with_fx :reverb,room: 0.6 do
in_thread do
plarray(nv1,dv1,v1)
plarray(nv1rba,dv1rba,v1)
plarray(nv1,dv1,v1)
plarray(nv1rbb,dv1rbb,v1)
plarray(nv1b,dv1b,v1)
end
in_thread do
plarray(nv2,dv2,v2,0.3)
plarray(nv2rba,dv2rba,v2,0.3)
plarray(nv2,dv2,v2,0.3)
plarray(nv2rbb,dv2rbb,v2,0.3)
plarray(nv2b,dv2b,v2,0.3)
end
in_thread do
plarray(nvl,dvl,vl,0.3)
plarray(nvlrba,dvlrba,vl,0.3)
plarray(nvl,dvl,vl,0.3)
plarray(nvlrbb,dvlrbb,vl,0.3)
plarray(nvlb,dvlb,vl,0.3)
end
in_thread do
plarray(nvlb2,dvlb2,vl,0.3)
end
in_thread do
plarray(nc1,dc1,vc,0.5)
plarray(nc1rra,dc1rra,vc,0.5)
plarray(nc1,dc1,vc,0.5)
plarray(nc1rrb,dc1rrb,vc,0.5)
plarray(nc3,dc3,vc,0.5)
end
in_thread do
plarray(nc2,dc2,vc,0.5) #single note fill
sleep b-q
plarray(nc2,dc2,vc,0.5) #single note fill
end
in_thread do
plarray(nc4,dc4,vc,0.5) #single note fill
end
in_thread do
plarray(nc2rra,dc2rra,vcp,0.7) #piz note rfill
end
end
sleep 42*b
cue :part3
sync :part3
#part 2 of Deux Miniatures by Victor Kalinnikow arrange for Oboe and Strings
#written by Robin Newman, March 2016
#path to library samples folder (including trailing /)
path='~/Sonatina Symphonic Orchestra/Samples/'
#create array of instrument details
voices=[['2nd Violins sus','2nd Violins','2nd-violins-sus-',1,:g3,:b6],\
['Violas sus','Violas','violas-sus-',0,:c3,:c6],\
['Basses piz','Basses','basses-piz-rr1-',0,:c1,:c4],\
['Basses sus','Basses','basses-sus-',0,:c1,:c4],\
['Basses stc','Basses','basses-stc-rr1-',0,:c1,:c4],\
['Oboe','Oboe','oboe-',1,:as3,:c6]]
#setup global variables
sampledir=''
sampleprefix=''
offsetclass=''
low=''
high=''
paths=''
use_bpm_mul 1.1
sq=0.14
q=2*sq
c=2*q
cd=3*q
m=2*c
md=3*c
b=2*m
bd=3*m
nv1=[:g4,:a4,:bb4,:c5,:d5,:d5,:f5,:d5,:c5,:d5,:c5,:bb4,:c5,:d5,:d5,:g4,:a4,:bb4,:c5,:d5,:d5,:g5,:f5,:eb5,:d5,:c5,:d5,:c5,:bb4,:c5]
dv1=[sq,sq,sq,sq,q,q,q,cd,sq,sq,q,q,q,c,c,sq,sq,sq,sq,q,q,q,sq,sq,c,sq,sq,q,q,q]
nv1rba=[:g4,:g4]
dv1rba=[c,c]
nv1rbb=[:g4,:g4,:d5]
dv1rbb=[c,q,q]
nv1b=[:f5,:d5,:d5,:f5,:d5,:d5,:f5,:d5,:f5,:d5,:f5,:d5,:g4,:a4,:bb4,:c5,:d5,:d5,:g5,:f5,:eb5,:d5,:c5,:d5,:c5,:bb4,:c5]
dv1b=[q,c,q,q,c,q,q,q,q,q,q,cd,sq,sq,sq,sq,q,q,q,sq,sq,c,sq,sq,q,q,q]
nv1brba=[:g4,:g4,:d5]
dv1brba=[c,q,q]
nv1brbb=[:g4,:g4,:bb4]
dv1brbb=[c,q,q]
nv1c=[:g4,:g4,:bb4,:g4,:g4,:bb4,:g4,:a4,:bb4,:c5,:d5,:f5,:d5,:d5,:bb5,:g5,:g5,:bb5,:g5,:g5,:bb4,:g4,:a4,:bb4,:c5,:d5,:d5,:g5,:g5,:r]
dv1c=[c,q,q,c,q,q,sq,sq,sq,sq,q,q,c,q,q,c,q,q,c,q,q,sq,sq,sq,sq,m,q,sq,sq,sq+c]
nv2=[:r,:d4,:d4,:r,:c4,[:a3,:d4],:d4,:d4,[:g3,:eb4],[:bb3,:d4],:c4,:eb4]
dv2=[c,c,m,c,c,m,c,c,c,c,c,c]
nv2rba=[:d4]
dv2rba=[m]
nv2rbb=[:d4,:r]
dv2rbb=[cd,q]
nv2b=[:a4,:bb4,:a4,:bb4,:a4,:bb4,:a4,:bb4,:a4,:d4,:d4,[:g3,:eb4],[:bb3,:d4],:c4,:eb4]
dv2b=[c,c,c,c,q,q,q,q,m,c,c,c,c,c,c]
nv2brba=[:d4,:r]
dv2brba=[cd,q]
nv2brbb=nv2brba
dv2brbb=dv2brba
nv2c=[:eb4,:d4,:r,:d4,:d4,:r,:eb5,:d5,:r,:r,:a4,[:g4,:d5],[:g4,:d5],:r]
dv2c=[m,m,c,c,cd,q,m,cd,q+c,m,q,sq,sq,q+c]
nvl=[:r,:bb3,:a3,:r,:bb3,:a3,:bb3,:a3,:bb3,:f3,:g3,:g3]
dvl=[c,c,m,c,c,m,c,c,c,c,c,c]
nvlrba=[:bb3]
dvlrba=[m]
nvlrbb=[:bb3,:r]
dvlrbb=[cd,q]
nvlb=[:d4,:g4,:d4,:g4,:d4,:g4,:d4,:g4,:d4,:bb3,:a3,:bb3,:f3,:g3,:g3,:bb3,:r]
dvlb=[c,c,c,c,q,q,q,q,m,c,c,c,c,c,c,cd,q]
nvlc=[:c4,:g3,:r,:a3,:bb3,:r,:c5,:g4,:r,:r,[:a3,:d4],[:g3,:d4],[:g3,:d4],:r]
dvlc=[m,m,c,c,cd,q,m,cd,q+c,m,q,sq,sq,q+c]
nc=[:r,:g3,:f3,:r,:eb3,:d3,:g3,:f3,:eb3,:bb2,:eb3,:c3]
dc=[c,c,m,c,c,m,c,c,c,c,c,c,]
ncrba=[:g3]
dcrba=[m]
ncrbb=[:g3,:r]
dcrbb=[cd,q]
ncb=[:r,:g3,:f3,:eb3,:bb2,:eb3,:c3,:g3,:r]
dcb=[4*m,c,c,c,c,c,c,cd,q]
ncc=[:r,:d3,:g3,:r,:r,:d3,[:g2,:d3],[:g2,:d3],:r]
dcc=[2*m+c,c,cd,q+2*m+c,m,q,sq,sq,q+c]
v1="Oboe"
v2="2nd Violins sus"
vl="Violas sus"
vc="Basses stc"
with_fx :reverb,room: 0.6 do
in_thread do
plarray(nv1,dv1,v1)
plarray(nv1rba,dv1rba,v1)
plarray(nv1,dv1,v1)
plarray(nv1rbb,dv1rbb,v1)
plarray(nv1b,dv1b,v1)
plarray(nv1brba,dv1brba,v1)
plarray(nv1b,dv1b,v1)
plarray(nv1brbb,dv1brbb,v1)
plarray(nv1c,dv1c,v1)
end
in_thread do
plarray(nv2,dv2,v2,0.3)
plarray(nv2rba,dv2rba,v2,0.3)
plarray(nv2,dv2,v2,0.3)
plarray(nv2rbb,dv2rbb,v2,0.3)
plarray(nv2b,dv2b,v2,0.3)
plarray(nv2brba,dv2brba,v2,0.3)
plarray(nv2b,dv2b,v2,0.3)
plarray(nv2brbb,dv2brbb,v2,0.3)
plarray(nv2c,dv2c,v2,0.3)
end
in_thread do
plarray(nvl,dvl,vl,0.3)
plarray(nvlrba,dvlrba,vl,0.3)
plarray(nvl,dvl,vl,0.3)
plarray(nvlrbb,dvlrbb,vl,0.3)
plarray(nvlb,dvlb,vl,0.3)
plarray(nvlb,dvlb,vl,0.3)
plarray(nvlc,dvlc,vl,0.3)
end
in_thread do
plarray(nc,dc,vc,0.3)
plarray(ncrba,dcrba,vc,0.3)
plarray(nc,dc,vc,0.3)
plarray(ncrbb,dcrbb,vc,0.3)
plarray(ncb,dcb,vc,0.3)
plarray(ncb,dcb,vc,0.3)
plarray(ncc,dcc,vc,0.3)
end
end
@Enkerli
Copy link

Enkerli commented Mar 20, 2016

Pretty impressive. Will have to carefully dig through this, as there's clearly a wealth of insight into pattern playing. Been trying a few simple things, learning a whole lot along the way (which is a major benefit from working with SPi). But this one piece could probably help me reach a whole new level.
And the result is really remarkable. Maybe the quality of the (CC-licensed!) samples plays a big part but it's surprising how expressive the oboe can get. Almost as though it were played with a wind controller (or as though each phrase had been through a meticulous tweaking). So, will have to check the code very carefully to understand how the magic happens.

Thanks a whole lot for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment