Add 'plot' function and remove deprecated 'percent' type

This commit is contained in:
Bartłomiej Pluta
2019-07-30 13:59:18 +02:00
parent 8abae7c2ff
commit 7e55fe4c1a
5 changed files with 145 additions and 8 deletions

View File

@@ -0,0 +1,106 @@
from smnp.error.runtime import RuntimeException
from smnp.function.model import CombinedFunction, Function
from smnp.function.signature import signature
from smnp.module.synth.lib.wave import plot
from smnp.type.model import Type
from smnp.type.signature.matcher.type import ofType
DEFAULT_BPM = 120
DEFAULT_OVERTONES = [0.4, 0.3, 0.1, 0.1, 0.1]
DEFAULT_DECAY = 4
DEFAULT_ATTACK = 100
# TODO: this code is shared with synth.py module, remove repetition
def getBpm(config):
key = Type.string("bpm")
if key in config.value:
bpm = config.value[key]
if bpm.type != Type.INTEGER or bpm.value <= 0:
raise RuntimeException("The 'bpm' property must be positive integer", None)
return bpm.value
return DEFAULT_BPM
def getOvertones(config):
key = Type.string("overtones")
if key in config.value:
overtones = config.value[key]
rawOvertones = [overtone.value for overtone in overtones.value]
if overtones.type != Type.LIST or not all(overtone.type in [Type.FLOAT, Type.INTEGER] for overtone in overtones.value):
raise RuntimeException("The 'overtones' property must be list of floats", None)
if len(rawOvertones) < 1:
raise RuntimeException("The 'overtones' property must contain one overtone at least", None)
if any(overtone < 0 for overtone in rawOvertones):
raise RuntimeException("The 'overtones' property mustn't contain negative values", None)
if sum(rawOvertones) > 1.0:
raise RuntimeException("The 'overtones' property must contain overtones which sum is not greater than 1.0", None)
return rawOvertones
return DEFAULT_OVERTONES
def getDecay(config):
key = Type.string("decay")
if key in config.value:
decay = config.value[key]
if not decay.type in [Type.INTEGER, Type.FLOAT] or decay.value < 0:
raise RuntimeException("The 'decay' property must be non-negative integer or float", None)
return decay.value
return DEFAULT_DECAY
def getAttack(config):
key = Type.string("attack")
if key in config.value:
attack = config.value[key]
if not attack.type in [Type.INTEGER, Type.FLOAT] or attack.value < 0:
raise RuntimeException("The 'attack' property must be non-negative integer or float", None)
return attack.value
return DEFAULT_ATTACK
class Config:
def __init__(self, bpm, overtones, decay, attack):
self.bpm = bpm
self.overtones = overtones
self.decay = decay
self.attack = attack
@staticmethod
def default():
return Config(DEFAULT_BPM, DEFAULT_OVERTONES, DEFAULT_DECAY, DEFAULT_ATTACK)
_signature1 = signature(ofType(Type.NOTE))
def _function1(env, note):
config = Config.default()
plot(note.value, config)
_signature2 = signature(ofType(Type.MAP), ofType(Type.NOTE))
def _function2(env, config, note):
bpm = getBpm(config)
overtones = getOvertones(config)
decay = getDecay(config)
attack = getAttack(config)
plot(note.value, Config(bpm, overtones, decay, attack))
function = CombinedFunction(
'plot',
Function(_signature1, _function1),
Function(_signature2, _function2)
)

View File

@@ -11,6 +11,7 @@ from smnp.type.signature.matcher.type import ofTypes, ofType
DEFAULT_BPM = 120
DEFAULT_OVERTONES = [0.4, 0.3, 0.1, 0.1, 0.1]
DEFAULT_DECAY = 4
DEFAULT_ATTACK = 100
def getBpm(config):
@@ -59,15 +60,28 @@ def getDecay(config):
return DEFAULT_DECAY
def getAttack(config):
key = Type.string("attack")
if key in config.value:
attack = config.value[key]
if not attack.type in [Type.INTEGER, Type.FLOAT] or attack.value < 0:
raise RuntimeException("The 'attack' property must be non-negative integer or float", None)
return attack.value
return DEFAULT_ATTACK
class Config:
def __init__(self, bpm, overtones, decay):
def __init__(self, bpm, overtones, decay, attack):
self.bpm = bpm
self.overtones = overtones
self.decay = decay
self.attack = attack
@staticmethod
def default():
return Config(DEFAULT_BPM, DEFAULT_OVERTONES, DEFAULT_DECAY)
return Config(DEFAULT_BPM, DEFAULT_OVERTONES, DEFAULT_DECAY, DEFAULT_ATTACK)
_signature1 = varargSignature(listOf(Type.NOTE, Type.INTEGER))
@@ -87,8 +101,9 @@ def _function3(env, config, notes):
bpm = getBpm(config)
overtones = getOvertones(config)
decay = getDecay(config)
attack = getAttack(config)
play(rawNotes, Config(bpm, overtones, decay))
play(rawNotes, Config(bpm, overtones, decay, attack))
_signature4 = varargSignature(ofTypes(Type.NOTE, Type.INTEGER), ofType(Type.MAP))
@@ -96,8 +111,9 @@ def _function4(env, config, notes):
bpm = getBpm(config)
overtones = getOvertones(config)
decay = getDecay(config)
attack = getAttack(config)
play([ notes ], Config(bpm, overtones, decay))
play([ notes ], Config(bpm, overtones, decay, attack))
function = CombinedFunction(