Sonic-pi-cli for Sonic Pi3.2dev

One piece of code which I have used quite a bit with Sonic Pi is Nick Johnstone’s excellent sonic-pi-cli command line tool, which enables you to send commands to Sonic Pi as if they were coming from the GUI. Thus you can emulate the stop-all-jobs command or run code remotely from a terminal (on the local host).

However, recent changes to the port allocations in Sonic Pi 3.2dev break the present version (and similar tools). Over the last couple of days I have been working on a solution to this, initially adding a -p parameter to allow the port to be specified, but this was kludgy and needed the user to determine the port, which is now dynamically allocated. Then I realised that the Listen port for the server is actually posted to the server-output.log and so I hit on the idea of reading the log file and extracting the port value and then incorporating the correct value in the sonic-pi-cli tool. To start with I used a ruby system command and ‘grep’ to extract the required data, but then I realised that this would have problems for Windows users, so instead I used Ruby file handling commands to open the file and read the port value. I also added an override so that it would work with earlier values of Sonic Pi which did not include the Listen port data, but for all of which the server port was the known static value 4557.

I have posted the code on a fork of the sonic-pi-cli code here if you want to try it out, and I have tested it on Raspberry Pi, Mac and Windows. I haven’t tested a Linux box directly, but it should perform as does the Raspberry Pi, if someone would like to check it out.
You can build the gem by downloading the sonic-pi-cli folder, then from within the folder using gem build sonic-pi-cli-gemspec
followed by gem install sonic-pi-cli-0.1.3.gem
After a bit more testing I will do a PR back to Nick’s original version.

The code is also useful directly within Sonic Pi to set up a programmatic stop-all-jobs command as if you had pushed the stop button, as shown below:

#This program lets you find the current server Listen port,
#where the Sonic Pi server listens to command from the GUI front end
#It also demonstrates how to setup a Stop All command
#and how to send code to run on Sonic Pi
#developed by Robin Newman, August 2019

#WARNING this uses undocumented features in Sonic Pi which MAY CHANGE
#and it is not guaranteed to work with future versions of Sonic Pi
#The program was developed because of upcoming changes introduced in SP3.2dev

define :pvalue do #get current listen port for Sonic Pi from log file
  value= 4557 #pre new logfile format port was always 4557
  File.open(ENV['HOME']+'/.sonic-pi/log/server-output.log','r') do |f1|
    while l = f1.gets
      if l.include?"Listen port:"
        value = l.split(" ").last.to_i
        break
      end
    end
    f1.close
  end
  return value
end
puts "Server Listen port is: #{pvalue}"

define :stop_all do #this command simulates pusshing the stop button
  osc_send "localhost",pvalue, "/stop-all-jobs"
end

define :command do |s| #this command lets you send code to be executed
  #the guid-rbn can be any value you like eg foo, but IS necessary
  osc_send "localhost",pvalue, "/run-code","guid-rbn",s
end

#send some sonic Pi commands to be played
command 'use_debug false;live_loop :pl do; play rrand_i(48,84),release: 0.2; sleep 0.2; end'
sleep 5
#now stop anything playing on Sonic Pi
stop_all