# Hexadecimal/binary rhythmic scheme

## Note that

### “spread” example 3 in documentation

live_loop :euclid_beat do
sample :elec_bong, amp: 1.5 if (spread 3, 8).tick
sample :perc_snap, amp: 0.8 if (spread 7, 11).look
sample :bd_haus, amp: 2 if (spread 1, 4).look
sleep 0.125
end

## Binary rhythmic scheme

# Binary rhythmic scheme
def schr(num)
num.split(//).collect  { |n| n == "1" }
end

live_loop :euclid_beat do
sample :elec_bong, amp: 1.5 if schr('10010010').ring.tick
sample :perc_snap, amp: 0.8 if schr('10101101101').ring.look
sample :bd_haus, amp: 2 if schr('1000').ring.look
sleep 0.125
end

## Hexadecimal/binary rhythmic scheme

More efficient but less flexible because I made the choice to keep 4 bits for 1 hexadecimal.

0=0000, 1=0001, 2=0010, 3=0011
4=0100, 5=0101, 6=0110, 7=0111
8=1000, 9=1001, a=1010, b=1011
c=1100, d=1101, e=1110, f=1111

# Binary rhythmic scheme
def schr(num)
num.split(//).collect  { |n| n == "1" }
end

# hexadecimal/binary rhythmic scheme
# 0=0000, 1=0001, 2=0010, 3=0011
# 4=0100, 5=0101, 6=0110, 7=0111
# 8=1000, 9=1001, a=1010, b=1011
# c=1100, d=1101, e=1110, f=1111
def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }
end

live_loop :euclid_beat do
sample :elec_bong, amp: 1.5 if schr2('92').ring.tick
sample :perc_snap, amp: 0.8 if schr('10101101101').ring.look # 11 bits, not possible in hex because I made the choice to keep 4 bits for 1 hexadecimal
sample :bd_haus, amp: 2 if schr2('8').ring.look
sleep 0.125
end
1 Like

You may already be aware of it, but at least in regards to binary notation there’s also the built in alternative, bools - eg:

sample :elec_bong, amp: 1.5 if (bools 1, 0, 0, 1, 0, 0, 1, 0).look

Your function is definitely more compact to use though!

1 Like

No, I did not know that but hexadecimal is more efficient.

The binary was a necessary step (the “to_s (2)”) and so we understand better perhaps.

I put the “.ring” in the function, it’s better.

I also want to manage synth with different chord sequences.

Is my code correct?

use_bpm 50
# hexadecimal/binary rhythmic scheme
def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }.ring
end
# 0=0000, 1=0001, 2=0010, 3=0011
# 4=0100, 5=0101, 6=0110, 7=0111
# 8=1000, 9=1001, a=1010, b=1011
# c=1100, d=1101, e=1110, f=1111

live_loop :foo do
p1 = [chord(:a3,"major7"), chord(:fs3,"minor7"), chord(:b3,"minor7"), chord(:E3,"7")]
p2 = [chord(:d4,"minor7"), chord(:e4,"7"), chord(:fs3,"minor7"), chord(:b3,"minor7")]
6.times do |y| # sequences
4.times do |x| # chords
16.times do # samples/notes
if y < 4
abc=p1[x]
else
abc=p2[x]
end
sample :drum_snare_soft, amp: 1.5 if schr2('1210').tick ^ (one_in 24)   # drum
sample :drum_cymbal_closed, amp: 0.8 if (spread 7, 11).look             # drum
sample :bd_haus, amp: 1.5 if schr2('80').look ^ (one_in 32)             # drum
play abc, amp: 1.5,release: 0.1 if schr2('2').look ^ (one_in 30)        # chord
play abc.choose+12, amp: 0.7,release: 0.3 if (one_in 3)                 # solo
play abc[0]-12, amp: 1.2,release: 0.4 if schr2('92').look ^ (one_in 12) # bass
sleep 0.125
end
end
end
end
5 Likes

That is absolutely brilliant, And with a little tweaking, it sounds
even more realistic…

Eli…

use_bpm 50
# hexadecimal/binary rhythmic scheme
def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }.ring
end

live_loop :foo do
p1 = [chord(:a3,"major7"), chord(:fs3,"minor7"), chord(:b3,"minor7"), chord(:E3,"7")]
p2 = [chord(:d4,"minor7"), chord(:e4,"7"), chord(:fs3,"minor7"), chord(:b3,"minor7")]
6.times do |y| # sequences
4.times do |x| # chords
16.times do # samples/notes
if y < 4
abc=p1[x]
else
abc=p2[x]
end
sample :drum_snare_soft, amp: 1.5 if schr2('1210').tick ^ (one_in 24)   # drum
sample :drum_cymbal_closed, amp: 0.8 if (spread 7, 11).look             # drum
sample :bd_haus, amp: 1.5 if schr2('80').look ^ (one_in 32)             # drum
use_synth :pluck
play abc, amp: 3,release: 0.3 if schr2('2').look ^ (one_in 30)        # chord
use_synth :piano
play abc.choose+12, amp: 0.7,release: 0.3 if (one_in 3)                 # solo
use_synth :fm
play abc[0]-12, amp: 1,release: 0.4 if schr2('92').look ^ (one_in 12) # bass
sleep 0.125
end
end
end
end
1 Like

I agree with @Eli This is brilliant.

I have converted it for three channel midi output, and am playing it to a three manual virtual pipe organ which sounds great.
I used

define :mplay do |n,*args|
n.to_a.each do |x|
midi x,*args
end
end

for the first play abc command i.e. mplay abc… and added channel: and port: settings. Otherwise the same. The other two play abc commands just play single notes so you can use straight midi here.

use_bpm 50
# hexadecimal/binary rhythmic scheme
def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }.ring
end
# 0=0000, 1=0001, 2=0010, 3=0011
# 4=0100, 5=0101, 6=0110, 7=0111
# 8=1000, 9=1001, a=1010, b=1011
# c=1100, d=1101, e=1110, f=1111
use_midi_defaults port: "rbnphone bluetooth"
live_loop :foo do
p1 = [chord(:a3,"major7"), chord(:fs3,"minor7"), chord(:b3,"minor7"), chord(:E3,"7")]
p2 = [chord(:d4,"minor7"), chord(:e4,"7"), chord(:fs3,"minor7"), chord(:b3,"minor7")]
6.times do |y| # sequences
4.times do |x| # chords
16.times do # samples/notes
if y < 4
abc=p1[x]
else
abc=p2[x]
end
puts abc

sample :drum_snare_soft, amp: 1.5 if schr2('1210').tick ^ (one_in 24)   # drum
sample :drum_cymbal_closed, amp: 0.8 if (spread 7, 11).look             # drum
sample :bd_haus, amp: 1.5 if schr2('80').look ^ (one_in 32)             # drum
mplay abc, channel: 2,sustain: 0.1 #if schr2('2').look ^ (one_in 30)        # chord
midi abc.choose+12, channel: 1,sustain: 0.3 if (one_in 3)                 # solo
midi abc[0]-12, channel: 3,sustain: 0.4 if schr2('92').look ^ (one_in 12) # bass
sleep 0.125
end
end
end
end

Eli’s mods for Sonic Pi also sound very very cool!

Thank you but the problem is that you have to wait for an entire cycle to see code changes.
It’s not live coding anymore

Granted its not live coding, but then live coding is only one
aspect of using Sonic Pi. I like writing stuff that has a fixed
format. Songs that have a beginning middle and end. I
tend towards hip-hop and edm type music, and if I can
figure out the

schr2('xxxx')

required for that type of beat, this is very compact and
mutable code that will save me hours of writing live loops.

Eli…

I found a solution maybe.

Also, I tested something else in ternary, like 6/8 ^^.

use_bpm 47

# hexadecimal/binary rhythmic scheme
def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }.ring
end
# 0=0000, 1=0001, 2=0010, 3=0011
# 4=0100, 5=0101, 6=0110, 7=0111
# 8=1000, 9=1001, a=1010, b=1011
# c=1100, d=1101, e=1110, f=1111

live_loop :a do #sequences
6.times do
X = tick; sleep 12
end
tick_reset
end

live_loop :b do #chords
4.times do
I = tick; sleep 3
end
tick_reset
end

live_loop :foo do #samples/notes
chords = (ring 1, 2, 5, 1)
if X<4
abc=(chord_degree chords[I], :c3,:major,4)
else
abc=(chord_degree chords[I], :b2,:major,4)
end
sample :drum_snare_soft, amp: 1.5 if schr2('924').tick ^ (one_in 12)     # drum
sample :drum_cymbal_closed, amp: 0.8 if schr2('b6d').look ^ (one_in 31)  # drum
sample :bd_haus, amp: 1.5 if schr2('888').look ^ (one_in 32)             # drum
use_synth :pluck
play abc, amp: 2,release: 0.3 if schr2('8cb').look ^ (one_in 30)       # chord
use_synth :piano
play abc.choose+12, amp: 0.7,release: 0.3 if (one_in 3)                  # solo
use_synth :fm
play abc.butlast.reflect.look-12, amp: 1,release: 0.4 if schr2('924').look ^ (one_in 12) # bass
sleep 0.125
end

I wanted to test the command “with_swing” (“heeey” ^^)

with_swing -0.1, pulse: 3 do

It’s fine but I have an error after more than 3 minutes

Runtime Error:[buffer 7, line 35] - SonicPi::Lang::Core::TimeTravelError
Thread death +--> :live_loop_foo
Time travel error - a jump back of -0.1 is too far.
Sorry, although it would be amizing, you can't go back in time beyond the sched_ahead time of 0.5
use_bpm 65

# hexadecimal/binary rhythmic scheme
# 0=0000, 1=0001, 2=0010, 3=0011
# 4=0100, 5=0101, 6=0110, 7=0111
# 8=1000, 9=1001, a=1010, b=1011
# c=1100, d=1101, e=1110, f=1111
def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }.ring
end

live_loop :a do #sequences
6.times do
X = tick; sleep 12
end
tick_reset
end

live_loop :b do #chords
4.times do
I = tick; sleep 3
end
tick_reset
end

live_loop :foo do #samples/notes
chords = (ring 1, 2, 5, 1)
if X<4
abc=(chord_degree chords[I], :c3,:major,4)
else
abc=(chord_degree chords[I], :b2,:major,4)
end
puts X
puts I
with_swing -0.1, pulse: 3 do
sample :drum_snare_soft, amp: 1.5 if schr2('924').tick ^ (one_in 12)     # drum
sample :drum_cymbal_closed, amp: 1 if schr2('aaa').look ^ (one_in 24)  # drum
sample :bd_haus, amp: 2 if schr2('888').look ^ (one_in 32)    # drum
with_fx :bitcrusher do
sample :bd_tek, amp: 3.5 if schr2('800').look ^ (one_in 31)    # drum
sample :elec_hi_snare, amp: 1.5 if schr2('020').look ^ (one_in 30)    # drum
end
play abc, amp: 1,release: 0.2 if schr2('8cb').look ^ (one_in 32)       # chord
use_synth :dpulse
play abc.choose+12, amp: 0.5,release: 0.3 if (one_in 3)                  # solo
use_synth :fm
play abc.butlast.reflect.look-12, amp: 1.2,release: 0.4 if schr2('924').look ^ (one_in 12) # bass
end
sleep 0.125
end

Apparently, to use “with_swing”, you have to increase the “sched_ahead_time” but after a while, it always ends up shifting and crashing anyway.

See for yourself ^^

use_random_seed 4
use_bpm 50

def schr2(num)
num.hex.to_s(2).rjust(num.size*4, '0').split(//).collect  { |n| n == "1" }.ring
end

live_loop :a do #sequences

6.times do; X = tick; sleep 15; end
tick_reset
end

live_loop :b do #chords
5.times do; I = tick; sleep 3; end
tick_reset
end

live_loop :foo do #samples/notes
if X<4
chords = (ring 1, 7, 6, 2, 5)
abc=(chord_degree chords[I], :a2,:major,4)
else
chords = (ring 4, 4, 5, 6, 2)
abc=(chord_degree chords[I], :a2,:major,4)
end
puts I
with_fx :slicer, phase: [0.5,0.25,0.75,0.125,0.25][I] do
play abc+12, amp: 1.7,attack: 0.2,release: 3 if schr2('800').look      # chord
end
use_synth :saw
play abc+12, amp: 0.4,attack: 0.2,release: 3 if schr2('800').look      # chord
with_fx :echo, phase: [0.5,0.25,0.75,0.25,0.5][I]  do
play abc, amp: 1.2 ,release: 0.2 if schr2('8cb').look ^ (one_in 32)       # chord
end
with_fx :reverb do
use_synth :hollow
play abc.reflect.look+36, amp: 2,release: 1, attack: 0, cutoff: rrand(90,110) if schr2('800').look ^ (one_in 9)                  # solo
use_synth :pulse
play abc[0]-12,attack: 0.05, amp: 0.7,release: 0.35, cutoff: rrand(110,120) if schr2('a22').look ^ (one_in 24) # bass
end
with_swing -0.125,pulse: 3 do
sample :drum_snare_soft, amp: 1.5 if schr2('924').tick ^ (one_in 12)     # drum
sample :drum_cymbal_closed, amp: 1 if schr2('aaa').look ^ (one_in 24)  # drum
sample :bd_haus, amp: 2 if schr2('888').look ^ (one_in 32)    # drum
with_fx :bitcrusher,amp: 1.3,cutoff: rrand(110,130) do
sample :bd_tek, amp: 2 if schr2('800').look ^ (one_in 31)    # drum
sample :elec_hi_snare, amp: 1 if schr2('020').look ^ (one_in 30)    # drum
end
end
sleep 0.125
end

S’funny… I played your code for about 30 mins straight, with no error…
(Win 10, 16G mem, early i7 processor, SP 3.1)

Try running it again, from a fresh start of SP. I’ve found in the past that
running other code beforehand can ‘influence’ how a track behaves.

Eli…

1 Like