Git Product home page Git Product logo

sonic-pi-tool's Introduction

Sonic Pi Tool (Python)

sonic-pi-tool.py is a rewrite of the Rust sonic-pi-tool in Python. It is a handy command line utility for playing with the Sonic Pi server. It can be used instead of the Sonic Pi GUI for all your music making needs :)

It's ideal for use with sonicpi.vim

Installation

Sonic Pi Tool doesn't currently have a proper installer. However it is just a simple Python script with a couple of dependencies, so it's not hard to install manually:

# Install dependencies:
pip install click oscpy psutil

# Download script:
curl -O https://raw.githubusercontent.com/emlyn/sonic-pi-tool/master/sonic-pi-tool.py

# Make it executable:
chmod +x sonic-pi-tool.py

# Copy it somewhere on the PATH:
sudo cp sonic-pi-tool.py /usr/local/bin/

sonic-pi-tool.py should be compatible with Python 3.6+. There is also a python2 branch that maintains compatibility with Python 2.7, but might not have all the latest features of the master branch.

Usage

Options

Options common to most or all commands:

  • --host: The host name or IP address to use when communicating with the Sonic Pi server.
  • --cmd-port: The port number on which the Sonic Pi server listens for incoming commands. If this is negative, try to find the port number in the Sonic Pi server-log file, and fall back to the absolute value specified if it can't be found in the log file.
  • --osc-port: The port number on which the Sonic Pi server listens for incoming OSC cues.
  • --preamble / --no-preamble: Some versions of Sonic Pi, when started without the GUI, fail to initialise the OSC server. This adds a bit of code at the start of any evaluated code to initialise the OSC server if it has not already been initialised.
  • --verbose / --no-verbose: Print out more information to help with debugging.
  • --help (or -h): Display help information.

Commands

The available commands are:

  • check: Check if Sonic Pi is running.
  • start-server: Start Sonic Pi server process.
  • logs: Follow logs from Sonic Pi server process.
  • eval: Evaluate Sonic Pi code from command line.
  • eval-file: Evaluate Sonic Pi code from a file.
  • eval-stdin: Evaluate Sonic Pi code from stdin.
  • run-file: Run a file in Sonic Pi without sending contents.
  • osc: Send an OSC message to Sonic Pi (or other OSC server).
  • record: Record Sonic Pi sound to a wav file.
  • stop: Stop any running Sonic Pi code.
  • shutdown: Shut down any running Sonic Pi processes.

check

Used to check if the Sonic Pi server is running. If the server isn't running many of the tool's commands (such as eval) will not work.

This command returns an exit code of zero if the server is running, one if it is not running, or two if it cannot determine whether it is running.

sonic-pi-tool.py check
# Sonic Pi is running, and listening on port 4557 for commands and 4560 for OSC

start-server

Attempts start the Sonic Pi server, if the executable can be found. Searches a few standard locations, first in the current directory, then the users home directory and finally some standard install locations.

If it is unable to find your installation, you can pass the location in the --path option. Please also consider raising an issue including the path to your install, and I will add it to the list of search paths.

Not currently supported on Windows.

sonic-pi-tool.py start-server
# Sonic Pi server booting...
# Using protocol: udp
# Detecting port numbers...
# ...

logs

Prints out log messages emitted by the Sonic Pi server.

This command won't succeed if the Sonic Pi GUI is running as that will already be consuming the logs itself.

sonic-pi-tool.py logs
#
# [Run 2, Time 32.7]
#  โ”” synth :beep, {note: 65.0, release: 0.1, amp: 0.9741}
#
# [Run 2, Time 32.8]
#  โ”” synth :beep, {note: 39.0, release: 0.1, amp: 0.9727}

eval

Take a string of Sonic Pi code and send it to the Sonic Pi server to be played.

sonic-pi-tool.py eval "use_real_time; play :C4"
# *ding*

eval-file

Read Sonic Pi code from a file and send it to the Sonic Pi server to be played. If the file is too big, consider using run-file instead.

sonic-pi-tool.py eval-file path/to/code.rb
# *music*

eval-stdin

Read Sonic Pi code from standard in and send it to the Sonic Pi server to be played.

echo "play :C4" | sonic-pi-tool.py eval-stdin
# *ding*

run-file

Send a command to the Sonic Pi server to load and play the specified file. This avoids problems with files being too long since the entire content no longer needs to fit in a single OSC message.

sonic-pi-tool.py run-file path/to/code.rb
# *music*

osc

Send an OSC cue to Sonic Pi. Allows a running Sonic Pi script to receive data from or synchronise to an external system.

sonic-pi-tool.py osc /trigger/foo 123
# Triggers `sync "/osc*/trigger/foo"` command running in Sonic Pi

record

Record the audio output of a Sonic Pi session to a local file. Stop and save the recording when the Enter key is pressed.

sonic-pi-tool.py record /tmp/output.wav
# Recording started, saving to /tmp/output.wav.
# Press Enter to stop the recording...

stop

Stop all jobs running on the Sonic Pi server, stopping the music.

sonic-pi-tool.py stop
# *silence*

shutdown

Shut down any Sonic Pi processes (started either with the GUI or the start-server command). Can be used to shut down any stray processes left if Sonic Pi fails to shut down correctly, as these can sometimes prevent Sonic Pi from starting up again.

sonic-pi-tool.py shutdown
# Sonic Pi has been shut down

MPL 2.0 Licence

sonic-pi-tool's People

Contributors

emlyn avatar lilyinstarlight avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

sonic-pi-tool's Issues

Installation class lacks log function

Log is called in the run method, but it doesn't exist in the Installation class. Getting this traceback:

Traceback (most recent call last): File "/usr/local/bin/sonic-pi-tool.py", line 427, in <module> cli(obj=None) File "/usr/lib/python2.7/dist-packages/click/core.py", line 764, in __call__ return self.main(*args, **kwargs) File "/usr/lib/python2.7/dist-packages/click/core.py", line 717, in main rv = self.invoke(ctx) File "/usr/lib/python2.7/dist-packages/click/core.py", line 1137, in invoke return _process_result(sub_ctx.command.invoke(sub_ctx)) File "/usr/lib/python2.7/dist-packages/click/core.py", line 956, in invoke return ctx.invoke(self.callback, **ctx.params) File "/usr/lib/python2.7/dist-packages/click/core.py", line 555, in invoke return callback(*args, **kwargs) File "/usr/local/bin/sonic-pi-tool.py", line 392, in start_server inst.run() File "/usr/local/bin/sonic-pi-tool.py", line 300, in run self.log("Running: {}".format(' '.join(args))) AttributeError: Installation instance has no attribute 'log'

Background mode

Add a --background flag to start-server that starts the server, then leaves it running in the background and returns to the shell.

We'd probably also want a shutdown-server command to shut it down later.

OSC does not work even with the preamble

Hi,
I like the tool very much. My next step was to use the OSC function of SP. I am running Sonic Pi without GUI. When I tried running the following code nothing happened:

live_loop :listen do
  use_real_time
  n = sync "/osc*/play_this"
  synth :saw, note: n
end

Even with the --premble paramter, this was the logs output:


=> Starting run 3

Runtime Error: [eval] - Errno::EADDRINUSE
Thread death!
 Address already in use - bind(2) for "127.0.0.1" port 4557
/opt/sonic-pi/app/server/ruby/lib/sonicpi/osc/udp_server.rb:31:in `bind'
/opt/sonic-pi/app/server/ruby/lib/sonicpi/osc/udp_server.rb:31:in `initialize'
eval:in `new'
eval:in `block (2 levels) in __spider_eval'
/opt/sonic-pi/app/server/ruby/lib/sonicpi/runtime.rb:781:in `eval'
/opt/sonic-pi/app/server/ruby/lib/sonicpi/runtime.rb:781:in `block (2 levels) in __spider_eval'
/opt/sonic-pi/app/server/ruby/lib/sonicpi/runtime.rb:1042:in `block (2 levels) in __in_thread'

=> Completed run 3

=> All runs completed

=> Pausing SuperCollider Audio Server

Can you help me please? The cue server does not seem to work.

fails to start server (Raspbian/Buster)

Stock install fails to start-server. Error/output pasted below:

jeff@phonotropic:~ $ sonic-pi-tool.py start-server
Found installation at: /usr/lib/sonic-pi
Running: ruby /usr/lib/sonic-pi/server/bin/sonic-pi-server.rb
Failed to load the fast_osc c-extension, falling back to pure Ruby version
Overriding fast_osc c-extension FastOsc::decode_single_message, falling back to pure Ruby version
Sonic Pi server booting...
Using protocol: udp
Detecting port numbers...
Send port: 4558
Listen port: 4557
  - OK
Scsynth port: 4556
  - OK
Scsynth send port: 4556
  - OK
OSC cues port: 4559
  - OK
Erlang port: 4560
  - OK
OSC MIDI out port: 4561
  - OK
OSC MIDI in port: 4562
  - OK
Booting server...


Booting Sonic Pi
----------------

Booting on Raspberry Pi
Jackd not running on system. Starting...
jackdmp 1.9.12
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2016 Grame.
Copyright 2016-2017 Filipe Coelho.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in realtime mode with priority 10
self-connect-mode is "Don't restrict self connect requests"
Failed to connect to session bus for device reservation: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11

To bypass device reservation via session bus, set JACK_NO_AUDIO_RESERVATION=1 prior to starting jackd.

Audio device hw:0 cannot be acquired...
Cannot initialize driver
JackServer::Open failed with -1
Failed to open server
Traceback (most recent call last):
ruby: No such file or directory -- /usr/app/server/ruby/bin/task-register.rb (LoadError)
Traceback (most recent call last):
ruby: No such file or directory -- /usr/app/server/ruby/bin/task-register.rb (LoadError)
Boot - Starting the SuperCollider server...
Boot - scsynth -u 4556 -m 131072 -a 1024 -D 0 -R 0 -l 1 -i 2 -o 2 -z 128 -c 128 -U /usr/lib/SuperCollider/plugins:/usr/app/server/native/extra-ugens/ -b 4096 -B 127.0.0.1
Traceback (most recent call last):
ruby: No such file or directory -- /usr/app/server/ruby/bin/task-register.rb (LoadError)
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
Failed to connect to session bus for device reservation: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11

Audio device hw:0 cannot be acquired...
Cannot initialize driver
JackServer::Open failed with -1
Failed to open server
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
terminate called without an active exception
Traceback (most recent call last):
ruby: No such file or directory -- /usr/app/server/ruby/bin/task-clear.rb (LoadError)
Boot - Unable to boot SuperCollider - boot server log did not report server ready
Failed to start server: Boot - Unable to boot SuperCollider - boot server log did not report server ready
/usr/lib/sonic-pi/server/lib/sonicpi/scsynthexternal.rb:228:in `rescue in boot_and_wait'
/usr/lib/sonic-pi/server/lib/sonicpi/scsynthexternal.rb:221:in `boot_and_wait'
/usr/lib/sonic-pi/server/lib/sonicpi/scsynthexternal.rb:381:in `boot_server_raspberry_pi'
/usr/lib/sonic-pi/server/lib/sonicpi/scsynthexternal.rb:149:in `boot'
/usr/lib/sonic-pi/server/lib/sonicpi/scsynthexternal.rb:37:in `initialize'
/usr/lib/sonic-pi/server/lib/sonicpi/server.rb:78:in `new'
/usr/lib/sonic-pi/server/lib/sonicpi/server.rb:78:in `initialize'
/usr/lib/sonic-pi/server/lib/sonicpi/studio.rb:183:in `new'
/usr/lib/sonic-pi/server/lib/sonicpi/studio.rb:183:in `init_scsynth'
/usr/lib/sonic-pi/server/lib/sonicpi/studio.rb:56:in `initialize'
/usr/lib/sonic-pi/server/lib/sonicpi/lang/sound.rb:125:in `new'
/usr/lib/sonic-pi/server/lib/sonicpi/lang/sound.rb:125:in `block (2 levels) in included'
/usr/lib/sonic-pi/server/bin/sonic-pi-server.rb:177:in `new'
/usr/lib/sonic-pi/server/bin/sonic-pi-server.rb:177:in `<main>'
Server is exiting.
Shutting down GUI...
Traceback (most recent call last):
        2: from /usr/lib/sonic-pi/server/bin/sonic-pi-server.rb:142:in `block in <main>'
        1: from /usr/lib/sonic-pi/server/lib/sonicpi/osc/udp_client.rb:30:in `send'
/usr/lib/sonic-pi/server/lib/sonicpi/osc/udp_client.rb:30:in `send': Connection refused - send(2) (Errno::ECONNREFUSED)

Tool doesn't work with 3.2.2 on Raspi

For 3.2.2, I changed some paths, lines 189 and 289, which might not be perfect, but it then worked.
around line 188:-
ruby_paths = ['server/native/ruby/bin/ruby'] server_paths = ['server/ruby/bin/sonic-pi-server.rb', 'server/bin/sonic-pi-server.rb', 'server/ruby/bin/sonic-pi-server.rb']
around line 289:-
default_paths = ('./Sonic Pi.app', # Check current dir first './app', '~/Applications/Sonic Pi.app', # Then home dir '/Applications/Sonic Pi.app', # Finally standard dirs '/opt/sonic-pi-3.2.2/app', '/usr/lib/sonic-pi')

I also changed port to osc_port on line 100 (might be wrong there !!??)

p.s. The ports may also be wrong as per the previous post. It works ok until you run the gui - this kills the server. (I may have caused this problem by not cloning the original - investigating... it might be any of the ports - trying websocket port - just the same as before.)

Also you need a symlink : sudo ln -s /usr/bin/sonic-pi-3-2-2 /usr/bin/sonic-pi

Deal with random command port

This now looks in the logs for the command port, but the logs are only written when the full app is started, not when just the server is started by sonic-pi-tool.
It should probably write to the same log file, so that the port-determining logic works in all cases.

More commands

The server supports some more commands that could be useful:

  • /reload reload ruby lib files(?)
  • /mixer-* control overall mixer (mono/stereo, hpf, lpf, amp)
  • midi-* start/stop/reset midi system
  • others? see here

Attribute error when executing check

There is an Attribute Error when executing the tool:

File "d:/OneDrive - Universitat de Barcelona/OP-Pi/software/sonic-pi-tool.py", line 100, in server_port_in_use
    sock.bind(('127.0.0.1', self.port))
AttributeError: 'Server' object has no attribute 'port'

Changing the line to
sock.bind(('127.0.0.1', self.osc_port))
fixes the error but I don't know if in this line you meant to use osc_port or cmd_port

Tool doesn't work in Sonic Pi 3.2

The tool doesn't work in the new Sonic Pi update as the port has been changed from 4559 to 4560 and other OSC changes have been added.

Binary distribution

Use something like PyInstaller to generate binaries with Python+dependencies bundled into a single executable for easier distribution to end users.
Should ideally produce binaries for Windows, macOS, Linux & Raspberry Pi.

Windows support

This almost certainly doesn't work on Windows - fix that.

Home directory detection

Should look at the SONIC_PI_HOME environment variable, and use it if set to determine directory for logs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.