Skip to content

Commit

Permalink
Create psonic.py
Browse files Browse the repository at this point in the history
  • Loading branch information
gkvoelkl committed Jan 31, 2016
1 parent b2b13cf commit 8eacf68
Showing 1 changed file with 187 additions and 0 deletions.
187 changes: 187 additions & 0 deletions psonic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import random
import time

import sys

from pythonosc import osc_message_builder #osc support
from pythonosc import udp_client

__debug = False

## Base Classes ##

class Note:
"""
Note
"""
def __init__(self,name,midi):
self.name = name
self.midi = midi


class Synth:
"""
Synthesizer
"""
def __init__(self,name):
self.name = name

## Notes ##

C5 = Note('C5',72)
Cs5 = Note('CS5',73)
Db5 = Cs5
D5 = Note('D5',74)
Ds5 = Note('Eb5',75)
Eb5 = Ds5
E5 = Note('Eb5',76)
F5 = Note('F5',77)
Fs5 = Note('Fs5',78)
Gb5 = Fs5
G5 = Note('G5',79)
Gs5 = Note('Gs5',80)
Ab5 = Gs5
A5 = Note('A5',81)
As5 = Note('As5',82)
Bb5 = As5
B5 = Note('B5',83)
C6 = Note('C6',84)

R = Note('rest',0)


## Synthezier ##
DSAW = Synth('dsaw')
TB303 = Synth('tb303')
BLADE = Synth('blade')
PROPHET = Synth('prophet')
SAW = Synth('saw')
BEEP = Synth('beep')
TRI = Synth('tri')

## Scale Mode ##
MINOR_PENTATONIC = "minor pentatonic"

## Module attributes ##
_current_synth = BEEP

## Module methodes ##
def use_synth(synth):
global _current_synth
_current_synth = synth


def play(note, attack=0, release=0, cutoff=0, amp=None, pan=None):
parameters = []
parameter = ''
command = ''

if amp is not None: parameters.append('amp: {0}'.format(amp))
if pan is not None: parameters.append('pan: {0}'.format(pan))

if len(parameters)>0: parameter = ',' + ','.join(parameters)

if type(note) == Note :
command = 'play :{0}{1}'.format(note.name,parameter)
else:
command = 'play {0}{1}'.format(note,parameter)

command = 'use_synth :{0}\n'.format(_current_synth.name) + command
_debug('play command={}'.format(command))
synthServer.run(command)


def sleep(duration):
"""
the same as time.sleep
:param duration:
:return:
"""
time.sleep(duration)
_debug('sleep', duration)

## Compount classes ##

class Ring:
"""
ring buffer
"""
def __init__(self,data):
self.data = data
self.index = -1

def __iter__(self): #return Iterator
return self

def __next__(self): #return Iterator next element
self.index +=1
if self.index == len(self.data):
self.index = 0
return self.data[self.index]


class Scale(Ring):
"""
Scale
"""
def __init__(self,basenote,mode):
super(Scale,self).__init__([basenote, G3, A3])

def shuffle(self):
random.shuffle(self.data)
return self

## Connection classes ##

class SonicPi():
"""
Communiction to Sonic Pi
"""

UDP_IP = "127.0.0.1"
UDP_PORT = 4557
GUI_ID = 'SONIC_PI_PYTHON'

RUN_COMMAND = "/run-code"
STOP_COMMAND = "/stop-all-jobs"

def __init__(self):
self.client = udp_client.UDPClient(SonicPi.UDP_IP, SonicPi.UDP_PORT)

def run(self, command):
self.send_command(SonicPi.RUN_COMMAND, command)

def stop(self):
self.send_command(SonicPi.STOP_COMMAND)

def test_connection(self):
#OSC::Server.new(PORT)
#abort("ERROR: Sonic Pi is not listening on #{PORT} - is it running?")
pass

def send_command(self,address,argument=''):
msg = osc_message_builder.OscMessageBuilder(address=address)
msg.add_arg('SONIC_PI_PYTHON')
msg.add_arg(argument)
msg = msg.build()

self.client.send(msg)

synthServer = SonicPi()

## system functions ##

def _debug(*allargs): #simple debug function for working in different environments
if __debug:print(allargs)


def _init_notes(): #ToDo: __init__
notes = [["C"],["Cs","Db"],["D"],["Ds","Eb"],["E"],["F"],["Fs","Gb"],["G"],["Gs","As"],["A"],["As","Bb"],["B"]]
thismodule = sys.modules[__name__]
setattr(thismodule,'C5',Note('C5',72))

def _init_module(): #ToDo: __init__
#_init_notes()
pass

_init_module()

0 comments on commit 8eacf68

Please sign in to comment.