Record and quantize Midi notes


#1

Hi,

I am trying to figure out, if the following is possible:

  • get midi note input for the duration of e. g. 8 or 16 beats
  • replay these beats notes quantized after ‘recording’

I have no real idea how and whether this is possible. My first try is less then a proof of concept and lacks basic features such as rests:

live_loop :get_midi do
  use_real_time
  notes = []
  i = 0
  4.times do |i|
    k, v = sync "/midi/arturia_minilab_mkii_midi_1/1/1/note_on"
    notes.push(k)
    i += 1
    sleep 0.125
  end
  n = notes.ring
  set :my_notes, n
  puts "Array: #{n}"
end

live_loop :play_midi do
  synth :piano, note: get(:my_notes).tick
  sleep 0.25
end

In my imagination I could record midi input for a certain duration with a rather high time resolution (such as 16 possible slots per beat) and replay these notes after the input phase within a time grid e. g. 16th notes.

Something like that:

# Midi Input loop / recording
# time grid based on 0.0625 sleep time
|.  :c .  .  .  .  .  :g .  .  .  .  .  :a .  .  |


# Midi Output loop / replay
# time grid based on 0.25 sleep time
|:c           .           :g           :a           | 

I would appreciate any hints. I am also not sure that my idea as such is well-conceived.

Martin


#2

Hi Martin,

your idea is well-conceived :slight_smile:

In fact, there’s no need to explicitly record anything as Sonic Pi already automatically records the most recent events for you and stores them in the time state system.

However, where Sonic Pi falls short is providing you with simple ways to work with that existing automatic history of events.

Therefore, would it be possible to sketch the kind of code you’d like to be able to write and we can use that as a starting point for a discussion. I think it’s much easier to discuss where the end point would be for you and then figure out how to get there together with you then verifying whether the implementation(s) we come up with actually do help you :slight_smile:


#3

I often think about this use case as well. Not sure how best to indicate a “start” point in the recording though. Maybe just first note? Or could see giving the recording loop a duration that always records/overwrites new events similar to how a GarageBand loop works in recording mode.


#4

@samaaron is there any good precident we could mirror from live audio recording/looping? I still haven’t quite figured out how to work the audio buffer feature.


#5

@samaaron, @matschaffer

Hi Sam, hi Mat,

thanks for the encouraging feedback! At the moment I don’t think, I can flesh this out with more code. Basically I am referring to a similar functionality as in my Live Looper (which at the moment is not more than a proof of concept and could definitely be coded much more elegantly; but it works):

  • you have recording tracks available (currently 4)
  • you can set a loop length for each track (= length of recording buffer)
  • you can arm a track for recoding involving a metronome, which tells you where the loop starts
  • you can then start the recording; the metronome will give an indication about when the recording will start (i. e. after the choosen loop has finished its current run). Right now it counts in advance half the loop length and also tells you when the application stops recording. The touchosc interface also gives visible feedback.
  • the replay of the loop will start immediatelly after the recording

I would like to have the same using midi input.

I do hope that informations is fruitful for some further discussion.


#6

My project Sonic Pi 3 Record/Player using TouchOSC worked along similar lines, without the quantisation. Also I used osc messages to send the note info rather than midi.
The way that I calculated the play times for the notes may be of interest.
I recorded note input in realtime, with an audible metronome to assist timing accuracy. I could then replay it a the same tempo or faster. I could also play a further part at the same time to give some harmony. I also recorded some envelope and volume information as well.

It would be interesting to play around with something similar using external midi input. It would be great to be able to get back time state info since it is already there, rather than having to calculate timings, but this would require some digging around in the SP code to make the info available and usable.


#7

Thanks @robin.newman, I’ll try to have a look at your code. Shouldn’t be so difficult to use midi input (instead of OSC).

Concerning the quantization: I am really interested in this, because it seems quite difficult to play live with a correct timing. (I imagine some sort of recording and looping function beyond what’s already there would make a great SP extension.)

Besides that I found that there is some latency involved in my Live Looper. I recently found out, that it might be due to the controller I used (in conjunction with a softsynth). I had the opportunity to use a proper hardware synth recently and as far as I could tell there was no more or less latency.

I probably will not be able to dive into the Sonic Pi code. I am trying to catch up with you guys to gradually become at least a sufficiently decent coder but I am still more concerned with the musical side so my progress in coding (beyond the Sonic Pi language set) is very slow.