Curious how to sample live instruments and play them back/manipulate them in real time in sonic pi.
I do lots of sessions with live instrumentalists and would love to also be able to incorporate something like this into live performances.
<3
Curious how to sample live instruments and play them back/manipulate them in real time in sonic pi.
I do lots of sessions with live instrumentalists and would love to also be able to incorporate something like this into live performances.
<3
Hey @dj_dave I love the concept of using Sonic Pi as a âloop pedalâ! Opens up a lot of possibilities.
So from what I can tell, there are two parts to making this happen: Getting a live_audio stream into Sonic Pi and then use the :record fx to store an audio file that you can access and manipulate in your code.
To get the audio going into Sonic PI, you first need to select the Enable Audio Inputs
in the preferences window under the âaudioâ tab
Sonic PI will most likely ask you to restart at that point as it canât switch audio sources while running.
When starting up Sonic Pi again, you might get this error window:
I got one like this because I was using Looppack as an audio output which was a 6 channel out but when I switched to headphones, it worked fine. If it comes up, you may just have to fiddle with what you are using for I/O sources.
If you are trying to record live instruments, you should also have some type of USB audio interface that the instruments can plug into. I use a Sterling Harmony H224 which you can see listed as the in in the preferences window under âAudio Hardware Informationâ
With that set up, you can get an audio stream up and running pretty quick with the live_audio
function. You just give it a specific name and you should hear the instrument coming through Sonic Pi
live_audio :guitar
Once you have that, you can wrap that function inside a with_fx :record
block. You will need to provide a buffer name where there recorded audio will be stored
with_fx :record, buffer: :take1 do
live_audio :guitar
end
When you run that code, it will create an 8 beat .wav file of whatever audio was coming through the live_audio stream at that time. 8 beats is the default amount. According to the docs, the actual amount of time will depend of the bpm. You can specify a specific amount of beats for the buffer this way
with_fx :record, buffer: [:take1, 16] do #this makes a 16 beat .wav file
live_audio :guitar
end
When going to play this back, you will need to write the buffer name along with the amount you gave it. Otherwise, you will override the buffer you made with another one. More on this in a bitâŚ
To play it back, you can just use the sample function along with the command buffer
and the name you gave the buffer in the :record fx
sample buffer[:take1]
If you made a specific size buffer, you would need to put that when you call the sample function
with_fx :record, buffer: [:take1, 16] do #this makes a 16 beat .wav file
live_audio :guitar
end
sample buffer[:take1, 16] #plays the 16 beat buffer you recorded
However, from experimenting with this, you canât just play this sample without making some changes to the code you used to record it, otherwise you will just record over the buffer you just made with a new one.
For instance, in the code below
with_fx :record, buffer: :take1 do
live_audio :guitar
end
sample buffer[:take1]
if you run the code, even if you add the sample code after running the first block of code, the first block of code will override the initial :take1
buffer that you recoded with a new one and so by the time you get to the sample line playing that buffer, you wonât hear what you originally recorded.
There are a few ways you can work around this.
with_fx :record
linewith_fx :record, buffer: :take2 do #changed to:take2 after recording :take1
live_audio :guitar
end
sample buffer[:take1] #plays audio from original run when buffer was named :take1
:stop
as an option to the live_audio
functionwith_fx :record, buffer: :take1 do
live_audio :guitar, :stop #stops audio input from being recorded
end
sample buffer[:take1]
From here, you can put the sample buffer into a live loop and do whatever you want with it. You can also record multiple different audio files as you go. Just make sure to change the buffer name each time you record something new and then remember to use one of the methods to make sure you donât override it when you go to play it back.
Another thing I noticed playing around with this, from the instrumentalist perspective, was knowing exactly when to come in so that whatever I played would loop up correctly. One method that worked ok was to add a block of code as a count off before the record block ran:
#gives a 4 beat countoff to set the tempo for the instrumentalist to play to
4.times do
sample :elec_blip
sleep 1
end
#Starts recording after the 4 beat countoff
with_fx :record, buffer: :take1 do
live_audio :guitar
end
Again, when it came time to play it back, I had to comment out that countoff clock of code and add the :stop to the live_audio and then write in the sample line of code to play it, but it did work.
I was also able to get things working in a more dynamic setting with live loops and adding more recorded audio as I went. I started by recording a starting riff with the countoff to set the tempo using the code above. Once I had that, I played the recorded audio in a live loop. From there, I created a countoff live loop that would sync up with the original riff I had going:
live_loop :a do
sample buffer[:take1]
sleep 4
end
live_loop :countoff, sync: :a do
##| stop #Uncomment this when I want to run the buffer I just recorded
4.times do
sample :elec_blip
sleep 1
end
with_fx :record, buffer: :take2 do
with_fx :reverb, room: 1 do
live_audio :guitar
sleep 4
end
end
stop #stops loop so it doesn't go back and re-record over the audio buffer
end
From there, each time I want to add another buffer, I just change the buffer name and rerun the code. I get the 4 beat countoff which now syncs up with the original loop I made and then play another piece of audio. The stop at the bottom keeps the loop from going back and overriding what I just did and then I add the stop at the top once Iâm ready to play the new buffer in a different live loop:
live_loop :a do
sample buffer[:take1]
sleep 4
end
live_loop :countoff, sync: :a do
stop
4.times do
sample :elec_blip
sleep 1
end
with_fx :record, buffer: :take2 do
with_fx :reverb, room: 1 do
live_audio :guitar
sleep 4
end
end
stop
end
live_loop :b, sync: :a do
sample buffer[:take2]
sleep 4
end
The one issue I ran into was that for some reason after running it the countoff loop a second time and then using the stop commands, it wouldnât run again even if I commented out the stops. A quick workaround was to just change the name of the countoff live loop each time I ran it, just to something like countoff2 which worked but it wasnât ideal. If anyone is still reading who might know why, I got this message in the log
=> Thread :live_loop_countoff exists: skipping creation
But other then that, it seemed to work pretty well!
Hope that is helpful. I know it was somewhat longwinded, but I really got into playing around with it and I imagine there are others who will find this useful. I 'm gonna try to put all of this into a tutorial soon.
Lemme know if it works for you (or anyone else)
This is sooooo helpful thanks so much!!!