Sequencer based on short fragments - controlling parameters via midi?

Hi,
I made up a sequencer based on the repetition of little melodic fragments within a euklidean rhythmic framework.
Works fine, but would be much better if I was able to alter the diverse parameters via a midi controller. Unfortunately, I was not able to work that out by myself, so any help is highly appreciated!

Also, have fun with the sequencer! I hope it is self explanatory - if not, don´t hesitate to ask :slight_smile:

#PatternTriggerSequencer euklidian

use_bpm 120

define :untergrenze do
  untergrenze = 60
end

define :obergrenze do
  obergrenze = 72
end

in_thread(name: :pitches) do
  use_random_seed 3
  A = rrand(untergrenze, obergrenze)
  B = rrand(untergrenze, obergrenze)
  C = rrand(untergrenze, obergrenze)
  D = rrand(untergrenze, obergrenze)
  E = rrand(untergrenze, obergrenze)
end

define :n do
  n = 16
end

live_loop :patterncues1 do
  cue :zammm if (spread 6, n).tick
  sleep 0.5
end

live_loop :patterncues2 do
  cue :pammm if (spread 5, n).tick
  sleep 0.5
end

#choosing pitches
in_thread(name: :chose1) do
  use_random_seed 2
  set :pitch1a, [A, B, C, D, E].pick(1)
  set :pitch2a, [A, B, C, D, E].pick(1)
  set :pitch3a, [A, B, C, D, E].pick(1)
end

#choosing pitches
in_thread(name: :chose2) do
  use_random_seed 3
  set :pitch1b, [A, B, C, D, E].pick(1)
  set :pitch2b, [A, B, C, D, E].pick(1)
end

#choosing interonset intervalls
in_thread(name: :chose_interonset1) do
  use_random_seed 3
  X_a = rrand(0.2, 0.75)
  X_aq = quantise(X_a, 0.25)
  Y_a = rrand(0.5, 0.75)
  Y_aq = quantise(Y_a, 0.25)
end

in_thread(name: :chose_interonset2) do
  use_random_seed 1
  X_b = rrand(0.2, 0.75)
  X_bq = quantise(X_b, 0.25)
  Y_b = rrand(0.5, 0.75)
  Y_bq = quantise(Y_b, 0.25)
end

live_loop :pattern_one do
  sync :zammm
  play get[:pitch1a], sustain: 0, release: 0.2, pan: 0.3
  sleep   X_aq
  play get[:pitch2a], sustain: 0, release: 0.2, pan: 0.3
  sleep Y_aq
end

live_loop :pattern_two do
  sync :pammm
  play get[:pitch1b], sustain: 0, release: 0.2, pan: -0.3
  sleep  X_bq
  play get[:pitch2b], sustain: 0, release: 0.2, pan: -0.3
  sleep Y_bq
end
1 Like

My last thread contains some simple code to control an fx via a midi device (such as a keyboard with knobs). Maybe you want to have a look at the code, and if you don’t get it to run, I’m happy to further assist.

1 Like

Hey Benjamin,
thanks! I´ll have a look!

I managed to adapt your example to control the frequency of a repeated note:

live_loop :controller do
  use_real_time
  control_num,val = sync "/midi/arturia_beatstep_pro_arturia_beatsteppro/2/1/control_change"
  set :pitch, (val)
end

live_loop :play do
  play get(:pitch), sustain: 0, decay: 0.1, release: 0.09
  sleep 0.25
end

:slightly_smiling_face:

However, how to distinguish between different controllers?
Would be great to also control the sleep time, for example. Sonic Pi assigns different numbers to the different controllers of the Beatstep, but I don´t know how to practically make this work out in code.

Example for controlling sleep time:

live_loop :controller do
  use_real_time
  control_num,val = sync "/midi/arturia_beatstep_pro_arturia_beatsteppro/2/1/control_change"
  set :slp, (val)
end

live_loop :play do
  play rrand(60, 72), sustain: 0, decay: 0.01, release: 0.09
  sleep ((get(:slp)*0.01) + 0.01)
end

How to combine both? How to include the first number in the square brackets which indicates the specific controller knob that is used for a single parameter?

The midi messages sends the control number and then the value. The control_num holds the number of the triggering controller. You should be able to follow this by a series of if statements to adjust different parameters.
e.g. something like

live_loop :controller do
  use_real_time
  control_num,val = sync "/midi/arturia_beatstep_pro_arturia_beatsteppro/2/1/control_change"

set :pitch, val  if control_num==23 #actual num depends on your controller
set :sleep_time, val if control_num==24 #num depends on controller
end

live_loop :play do
  play get(:pitch), sustain: 0, decay: 0.1, release: 0.09
  sleep get(:sleep_time)*<scalefactor>#scale to get suitable range
end

NB you should set default values for :pitch and :sleep_time as they will not be set initially until you change a control
set :pitch,80
set :sleep_time,0.25 at start of program

1 Like

Hey Robin,
thanks a lot! Now this basic example works :slight_smile:

set :pitch,60
set :sleep_time,0.5

live_loop :controller do
  use_real_time
  control_num,val = sync "/midi/arturia_beatstep_pro_arturia_beatsteppro/2/1/control_change"
  
  set :pitch, val  if control_num==16
  set :sleep_time, val if control_num==17
end

live_loop :play do
  play get(:pitch), sustain: 0, decay: 0.1, release: 0.09
  sleep get(:sleep_time)*0.01 + 0.1#+0.1 added to prevent 0 sleep time when controler value is zero
end