Using pynput to control sonic pi

Hi, I’m working on a project that aims to control sonic pi with an external keyboard.
I am new to the coding world, and I was hoping for someone to help me understand how can I use pynput to control the keyboard and give allocated input to precise instruments on Sonic pi.

Thanks.

PS. I’ve tried to use the following code but is not working because it says that it has to be run as an administrator.

import keyboard
from pythonosc import osc_message_builder
from pythonosc import udp_client
sendto = udp_client.SimpleUDPClient(‘127.0.0.1’, 4560)
sendto.send_message(‘/osc/test’, [19])

print (“hello”)
while (1):

# making a loop
try:  # used try so that if user pressed other than the given key error will not be shown
  if keyboard.is_pressed('q'):  # if key 'q' is pressed 
        sendto.send_message('/osc/exit')
        print('You Pressed q to quit Key!')
        break  # finishing the loop
  if keyboard.is_pressed('up'):  # if key 'up' is pressed 
        print('You Pressed UP')
        sendto.send_message('/osc/play', [0])
  if keyboard.is_pressed('down'):  # if key 'up' is pressed 
        print('You Pressed Down')
        sendto.send_message('/osc/play', [1])
  
except:
    break  # if user pressed a key other than the given key the loop will break

I’m just throwing this in as I don’t have time to test now but putting something like this as your first line:

#!/usr/bin/env python3

can solve a Permission denied error or needing to run as administrator on some system configurations. You might need to alter the path to point to your Python install, I’m on Linux.

This is code from when I was playing around with osc. This bit sends some random value to /filter over osc:

#!/usr/bin/env python3

#python-osc only works with python 3 so make sure to set your environment!

#official python-osc website: https://pypi.org/project/python-osc/
#code taken from the example code there

"""Small example OSC client

This program sends 10 random values between 0.0 and 1.0 to the /filter address,
waiting for 1 seconds between each value.
"""
import argparse
import random
import time

from pythonosc import osc_message_builder
from pythonosc import udp_client

#from the Sonic Pi github:
#sender = udp_client.SimpleUDPClient('127.0.0.1', 4559)
#sender.send_message('/trigger/prophet', [70, 100, 8])

if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument("--ip", default="127.0.0.1",
      help="The ip of the OSC server")
  parser.add_argument("--port", type=int, default=4559, #4559 is the port where Sonic Pi listens
      help="The port the OSC server is listening on")
  args = parser.parse_args()

  client = udp_client.SimpleUDPClient(args.ip, args.port)

  for x in range(10):
    client.send_message("/filter", random.random())
    time.sleep(1)

And in Sonic Pi you need something like this to listen for it:

live_loop :testOSC do
  use_real_time
  n = (sync "/osc:127.0.0.1:**/filter")[0] #sync gets an array of values, take the first one
  print n
  play toMidiRange(n)
  sleep 1
end

define :toMidiRange do |input|
  midiRangeValue = 127 * input
  return midiRangeValue
end