Generate code externally, then use Sonic Pi at command line to render to audio in bulk?

If I had a file containing Sonic Pi code, would it be possible to cause Sonic Pi to run it, render it out to a WAV, and then quit?
I’m working on a project that will generate a number of code files, and I would like to be able to bulk-generate the audio from the command line. Is that possible?

2 Likes

Hi muteboy
I had a play with this and came up with the following. Basically I used the command sent to the Sonic Pi server from the gui which cause it to record a file. These are OSC cmmands sent to port 4557 rather than port 4559 which is used for cues.
I took a source list of sonic pi files (with complete pathnames) and then fed correpsonding pairs into the function playsave which used the run_file command to play each file in sonic pi, but also inserted commands to start and stop recording and then to save the resulting file. YOu can do this with the audo volume of your external amp turned right down, so you don;t need to listen while the files are playing/recording.

The only change I had to make was to add a cue :finish command at the end of each sonic pi file when it had finished (within the file), to hold up the next run_file command until the cue was received triggering the sync command in the function.

I tred it with three files and each got a separate recording. I set a lead in and out time of 0.5 seconds around each recording.
This was all done on a Mac running Sonic Pi 3.0.1 but I see no reason why it won’t work on a Pi as well, although you may need to allow a longer pause than 1 second between each run to allow the saving to complete as it will be slower onto an SD card.

Note the ‘rbnguid’ in each of the osc commands is like a key identifier that has to be there for the command to work and should be the same for all three osc commands.

#demo program to automatically play a series of Sonic Pi files
#and save a wav recording of each one
#written by Robin Newman, October 2018

source_list=["/Users/rbn/Documents/SPfromXML/rhythmAutoWav.rb",
             
             "/Users/rbn/Documents/SPfromXML/FurEliseAutoWav.rb",
             
             "/Users/rbn/Documents/SPfromXML/notewanderAutoWav.rb"]
save_list=["/Users/rbn/Documents/SPfromXML/rhythmAutoWav.wav",
           
           "/Users/rbn/Documents/SPfromXML/FurEliseAutoWav.wav",
           
           "/Users/rbn/Documents/SPfromXML/notewanderAutoWav.wav"]


define :playsave do |source_file,save_file|
  osc_send "localhost",4557,"/start-recording",'rbnguid'
  sleep 0.5 #lead in time
  run_file source_file #add line cue :finish at end of each source file
  sync :finish
  sleep 0.5  #lead_out time
  osc_send "localhost",4557,"/stop-recording",'rbnguid'
  sleep 0.5
  osc_send "localhost",4557,"/save-recording",'rbnguid',save_file
  sleep 1 #allow time for the file to be saved to media
end

source_list.length.times do |i|
  
  puts "processing file #{source_list[i]}"
  playsave source_list[i],save_list[i]
  puts "saved file #{save_list[i]}"
end

Edit removed extraneous string that had attached to the end of line
source_list.length.times do |i|"/Users/rbn/Documents/SPfromXML/RubberDub.rb"
should read source_list.length.times do |i|

1 Like