Recording phrases from the keyboard

I’m enjoying use arpeggios and step sequences, but I’d like to spice them up a bit with some actual played phrases, complete with slight timing variations. That’s bread and butter in DAW but not really SPi’s thing. Although I’ve seen some amazing compositions using arrays and sleeps to be fair. I guess if it’s transcribing a written music that’s one thing.

Up to now, I’ve been playing the phrase, recording the audio then playing that as sample from SPi. I thought it would be nice to do it live.

Here’s my lofi script I’ve written for this. The first loop records the midi keystrokes by pushing the pitch and virtual time to an array. On each key press, it writes out the arrays to the log. Second loop is the metronome.

Then I simple copy the text for both arrays from the log and paste them in the second loop, uncomment the stop to test them. Then in a composition I can copy that loop in as-is and make it play whatever synth or midi out is needed.

Here’s the recording loop

EDIT: for simplications and corrections for bpm. I found at and time_warp both helpfully take array arguments. Very helpful.

#Midi keyboard phrase recorder
use_bpm 100
notes=[]
times=[]
t0=0.0
live_loop :rec do
  #stop
  use_real_time
  n,v=sync mhs_cue="/midi:mpk_mini_midi_1:*:*/"+"note_on"
  if tick==0
    t0=rt(vt)
  end
  notes.push n
  times.push (rt(vt)-t0)
  puts "x="+notes.to_s
  puts "y="+times.to_s
  play n, amp: 0.1
end

live_loop :beat do
  sample :perc_snap, amp: 0.1
  sleep 1
end

Heres’ the playback loop

live_loop :play, sync: :beat do
  #stop
  
  x=[72, 76, 79, 82, 84, 72, 75, 76, 67, 70, 72, 60]
  y=[0.0, 0.926166666666667, 1.4659683333333335, 1.9814483333333337, 2.485541666666667, 3.464901666666666, 3.9442516666666663, 4.444533333333334, 5.396926666666667, 5.876469999999999, 6.420806666666667, 6.9414533333333335]
  
  time_warp y, x do |n|
    play n, sustain: 0.2, amp: 0.1
  end
  
  sleep 8
end
1 Like

Just to add that it’s easy to use this code to record step sequences too, by ignoring time array. It’s all about mixing it up, machine and human, repetition and variation

Updates and refinements. Now this script writes the output to a file every so often, which is easier to handle than the log output. Also writes out an optional quantised version of the times.

#Midi Keyboard Recorder V3
#Record a phrase from midi keyboard into an array
#Notes are written to notes.txt file every n beats.
use_bpm 80
notes=[]
times=[]
t0=0.0
first=true
live_loop :mrc_midi_input do
  #To start a new run, uncomment stop Alt-R, press a few midi keys to clear, then re-comment the stop, Alt-R again.
  #stop
  use_real_time
  n,v=sync "/midi:mpk_mini_midi_1:*:*/"+"note_on"
  if first
    t0=rt(vt)
    first=false
    puts "New Run"
  end
  notes.push n
  times.push (rt(vt)-t0).round(3)
  #set :notes, notes; set :times, times
  play n, amp: 0.1
end

live_loop :mrc_metronome do
  sample :perc_snap, amp: 0.1
  sleep 1
end

live_loop :mrc_writefile do
  #Quantise
  h=0.25
  q=[]
  for i in 0..times.length-1
    t=times[i]
    q.push(h*(((t+h/2.0)/h).floor))
  end

  puts "x="+notes.to_s
  puts "y="+times.to_s
  File.write("notes.txt", "x="+notes.to_s + "\n" "y="+times.to_s + "\n" + "q="+q.to_s, mode: "w")

  sleep 4
end

live_loop :play, sync: :mrc_metronome do
  #stop

x=[60, 62, 64, 65, 67, 72, 71, 69, 67, 65, 72, 71, 69, 67, 65, 64, 62, 60]
y=[0.0, 0.233, 0.47, 0.706, 1.003, 1.932, 2.213, 2.447, 2.669, 2.946, 3.897, 4.191, 4.417, 4.635, 4.914, 5.403, 5.915, 6.48]
q=[0.0, 0.25, 0.5, 0.75, 1.0, 2.0, 2.25, 2.5, 2.75, 3.0, 4.0, 4.25, 4.5, 4.75, 5.0, 5.5, 6.0, 6.5]

  time_warp q, x do |n|
    play n, sustain: 0.1, releae: 0.1, amp: 0.1
    #midi4x4 n,100,0.2,1,2
  end

  sleep 8
end