has anyone got any ideas on how to make a “structured song” ? I’ve been working on trying to make a useable / “easy to follow” tick counter that can define were you are in a song (intro, break, bridge, chorus, verse, outro, end (etc))… I was also playing with making beats with a string (instead of an array) so that’s sprinkled in here too… any use?
use_cue_logging false
use_debug false
use_bpm 100
intro = false
# arrays that hold references to samples
bds = [0, :drum_bass_hard, :bd_boom]
sns = [0, :sn_dolf, :sn_generic]
hts = [0, :drum_cymbal_pedal, :drum_cymbal_closed, :drum_cymbal_open]
# strings that represent beat patterns (numbers refer to sample positions in sample arrays (above)
bd0 = "20000000"
sn0 = "0"
ht0 = "00100001"
bd1 = "10020000"
sn1 = "00001000"
ht1 = "0010"
bd2 = "1002000011020000"
sn2 = "0000010000100000"
ht2 = "0010001000100100"
bd3 = "01"
sn3 = "10"
ht3 = "0001"
# set up 2 variables to keep track of current & old "section"
@sec = :intro
@oldSec = :intro
# function to change the "global" state of playing
define :setPlay do | tf |
@playing = tf
end
#set playing = true (could put it into a defonce call if you want)
@playing = true
# hash to keep track of "sections" where times & specific beats for that section are kept.
sections = {
:intro => {:time => [0,1], :bp => bd0, :sp => sn0, :hp => ht0},
:break => {:time => [5,13], :bp => bd2, :sp => sn2, :hp => ht2},
:main => {:time => (2..16).to_a, :bp => bd1, :sp => sn1, :hp => ht1},
:end => {:time => [17], :bp => bd3, :sp => sn3, :hp => ht3},
}
# function that takes a list & a number so it can play a beat from a sample in that list (l) at position (x)
define :beatX do | l, x |
# l = list of samples | x = beat
# if x isn't 0, we play the sample from the list passed
if x!=0 and l
sample l[x]
end
end
# live loop to control what section we're in
live_loop :sectionCheck do
t = tick
# find the section based on the Tick position in "sections" ranges
@sec = sections.select{|k,v| v[:time].include? t}.keys()[0]
if sections.keys().include? @sec
puts "tick = #{t}"
if @sec != @oldSec
puts "section change to #{@sec}"
@oldSec = @sec
end
else
setPlay(false)
stop
end
sleep 4 # 4 beats per bar
end
# live loop that calculates what beat to play from the tick position
live_loop :beats do
if @playing == true
t = tick
#bassdrums
beatX(bds, sections[@sec][:bp].chars().ring[t].to_i)
#snaredrums
beatX(sns, sections[@sec][:sp].chars().ring[t].to_i)
#hi hats
with_fx :level, amp: 0.4 do
beatX(hts, sections[@sec][:hp].chars().ring[t].to_i)
end
sleep 0.25 # standard 1/4 beat sleep
else
stop
end
end