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)
)