Create functions 'withOctave', 'withDuration', 'random' and 'tuplet'

This commit is contained in:
Bartłomiej Pluta
2019-07-04 14:06:38 +02:00
parent 586cb2591b
commit 76c02922ec
7 changed files with 122 additions and 45 deletions

View File

@@ -1,12 +1,16 @@
from smnp.environment.environment import Environment from smnp.environment.environment import Environment
from smnp.library.function.combine import combine from smnp.library.function.combine import combine
from smnp.library.function.display import display from smnp.library.function.display import display
from smnp.library.function.duration import withDuration
from smnp.library.function.exit import exit from smnp.library.function.exit import exit
from smnp.library.function.flat import flat from smnp.library.function.flat import flat
from smnp.library.function.interval import interval from smnp.library.function.interval import interval
from smnp.library.function.mic import wait from smnp.library.function.mic import wait
from smnp.library.function.octave import withOctave
from smnp.library.function.rand import random
from smnp.library.function.semitones import semitones from smnp.library.function.semitones import semitones
from smnp.library.function.sleep import sleep from smnp.library.function.sleep import sleep
from smnp.library.function.tuplet import tuplet
from smnp.library.function.type import objectType from smnp.library.function.type import objectType
@@ -20,11 +24,14 @@ def createEnvironment():
interval, interval,
combine, combine,
flat, flat,
wait wait,
random,
tuplet
] ]
methods = [ methods = [
withDuration,
withOctave
] ]
# 'exit': Function(base.exit, ONLY_FUNCTION), # 'exit': Function(base.exit, ONLY_FUNCTION),
# 'print': Function(base.display, ONLY_FUNCTION), # 'print': Function(base.display, ONLY_FUNCTION),

View File

@@ -14,3 +14,8 @@ class FunctionNotFoundException(SmnpException):
class MethodNotFoundException(SmnpException): class MethodNotFoundException(SmnpException):
def __init__(self, object, method): def __init__(self, object, method):
self.msg = f"Method '{method}' of type '{object}' not found" self.msg = f"Method '{method}' of type '{object}' not found"
class IllegalArgumentException(SmnpException):
def __init__(self, msg):
self.msg = msg

View File

@@ -0,0 +1,14 @@
from smnp.library.model import Function
from smnp.library.signature import signature, ofTypes
from smnp.type.model import Type
from smnp.type.value import Value
def _withDuration(env, note, duration):
return Value(Type.NOTE, note.value.withDuration(duration.value))
_sign = signature(ofTypes(Type.NOTE), ofTypes(Type.INTEGER))
withDuration = Function(_sign, _withDuration, 'withDuration')

View File

@@ -1,31 +0,0 @@
from smnp.library.tools import returnElementOrList
def changeDuration(args, env):
if len(args) == 2 and isinstance(args[0], Note) and isinstance(args[1], int):
return args[0].withDuration(args[1])
return # invalid signature
def changeOctave(args, env):
if len(args) == 2 and isinstance(args[0], Note) and isinstance(args[1], int):
return args[0].withOctave(args[1])
return # invalid signature
def tupletList(n, m, list):
return [note.withDuration(note.duration * n / m) for note in list]
def tuplet(args, env):
if len(args) > 2 and type(args[0]) == int and type(args[1]) == int and all(type(x) == Note for x in args[2:]):
n = args[0] # how many notes
m = args[1] # instead of number of notes (3-tuplet: 3 instead 2; 5-tuplet: 5 instead 4 etc.)
return returnElementOrList(tupletList(n, m, args[2:]))
elif len(args) == 3 and type(args[0]) == int and type(args[1]) == int and type(args[2]) == list and all(type(x) == Note for x in args[2]):
n = args[0]
m = args[1]
l = args[2]
return returnElementOrList(tupletList(n, m, l))
else:
pass # not valid signature

View File

@@ -0,0 +1,14 @@
from smnp.library.model import Function
from smnp.library.signature import signature, ofTypes
from smnp.type.model import Type
from smnp.type.value import Value
def _withOctave(env, note, octave):
return Value(Type.NOTE, note.value.withOctave(octave.value))
_sign = signature(ofTypes(Type.NOTE), ofTypes(Type.INTEGER))
withOctave = Function(_sign, _withOctave, 'withOctave')

View File

@@ -1,17 +1,41 @@
import random as r import random as r
from smnp.error.function import IllegalArgumentException
from smnp.library.model import Function, CombinedFunction
from smnp.library.signature import varargSignature, listMatches, ofTypes
from smnp.type.model import Type
def random(args, env):
if not all(isinstance(x, list) and len(x) == 2 and isinstance(x[0], float) for x in args):
return # not valid signature
if sum([x[0] for x in args]) != 1.0:
return # not sums to 100%
choice = r.random()
acc = 0
for e in args:
acc += e[0]
if choice <= acc:
return e[1]
def forType(t):
def _random(env, vararg):
choice = r.random()
acc = 0
if sum(arg.value[0].value for arg in vararg) != 1.0:
raise IllegalArgumentException("Sum of all percentage values must be equal 100%")
for arg in vararg:
percent, item = arg.value
acc += percent.value
if choice <= acc:
return item
_sign = varargSignature(listMatches(ofTypes(Type.PERCENT), ofTypes(t)))
return Function(_sign, _random)
random = CombinedFunction('random', *[ forType(t) for t in Type if t != Type.VOID ])
#
# def random(args, env):
# if not all(isinstance(x, list) and len(x) == 2 and isinstance(x[0], float) for x in args):
# return # not valid signature
# if sum([x[0] for x in args]) != 1.0:
# return # not sums to 100%
# choice = r.random()
# acc = 0
# for e in args:
# acc += e[0]
# if choice <= acc:
# return e[1]
#
#TODO: sample #TODO: sample

View File

@@ -0,0 +1,44 @@
from smnp.library.model import CombinedFunction, Function
from smnp.library.signature import signature, listOf, ofTypes, varargSignature
from smnp.type.model import Type
from smnp.type.value import Value
def _tuplet1(env, n, m, vararg):
t = [Value(Type.NOTE, arg.value.withDuration(arg.value.duration * n.value / m.value)) for arg in vararg]
return Value(Type.LIST, t).decompose()
_sign1 = varargSignature(ofTypes(Type.NOTE), ofTypes(Type.INTEGER), ofTypes(Type.INTEGER))
def _tuplet2(env, n, m, notes):
return _tuplet1(env, n, m, notes.value)
_sign2 = signature(ofTypes(Type.INTEGER), ofTypes(Type.INTEGER), listOf(Type.NOTE))
tuplet = CombinedFunction(
'tuplet',
Function(_sign1, _tuplet1),
Function(_sign2, _tuplet2)
)
# def tupletList(n, m, list):
# return [note.withDuration(note.duration * n / m) for note in list]
#
#
# def tuplet(args, env):
# if len(args) > 2 and type(args[0]) == int and type(args[1]) == int and all(type(x) == Note for x in args[2:]):
# n = args[0] # how many notes
# m = args[1] # instead of number of notes (3-tuplet: 3 instead 2; 5-tuplet: 5 instead 4 etc.)
# return returnElementOrList(tupletList(n, m, args[2:]))
# elif len(args) == 3 and type(args[0]) == int and type(args[1]) == int and type(args[2]) == list and all(type(x) == Note for x in args[2]):
# n = args[0]
# m = args[1]
# l = args[2]
# return returnElementOrList(tupletList(n, m, l))
# else:
# pass # not valid signature