synthio: Finish implementing Math blocks
This commit is contained in:
parent
5de4d197a2
commit
391438102b
|
@ -41,6 +41,7 @@ SRC_BITMAP := \
|
|||
shared-bindings/rainbowio/__init__.c \
|
||||
shared-bindings/struct/__init__.c \
|
||||
shared-bindings/synthio/__init__.c \
|
||||
shared-bindings/synthio/Math.c \
|
||||
shared-bindings/synthio/MidiTrack.c \
|
||||
shared-bindings/synthio/LFO.c \
|
||||
shared-bindings/synthio/Note.c \
|
||||
|
@ -65,6 +66,7 @@ SRC_BITMAP := \
|
|||
shared-module/rainbowio/__init__.c \
|
||||
shared-module/struct/__init__.c \
|
||||
shared-module/synthio/__init__.c \
|
||||
shared-module/synthio/Math.c \
|
||||
shared-module/synthio/MidiTrack.c \
|
||||
shared-module/synthio/LFO.c \
|
||||
shared-module/synthio/Note.c \
|
||||
|
|
|
@ -651,6 +651,7 @@ SRC_SHARED_MODULE_ALL = \
|
|||
supervisor/__init__.c \
|
||||
supervisor/StatusBar.c \
|
||||
synthio/LFO.c \
|
||||
synthio/Math.c \
|
||||
synthio/MidiTrack.c \
|
||||
synthio/Note.c \
|
||||
synthio/Synthesizer.c \
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "shared-module/synthio/LFO.h"
|
||||
|
||||
//| class LFO:
|
||||
//| """A low-frequency oscillator
|
||||
//| """A low-frequency oscillator block
|
||||
//|
|
||||
//| Every `rate` seconds, the output of the LFO cycles through its `waveform`.
|
||||
//| The output at any particular moment is ``waveform[idx] * scale + offset``.
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Artyom Skrobov
|
||||
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/objproperty.h"
|
||||
#include "py/proto.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/util.h"
|
||||
#include "shared-bindings/synthio/Math.h"
|
||||
#include "shared-module/synthio/Math.h"
|
||||
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, SUM, OP_SUM);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, ADD_SUB, OP_ADD_SUB);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, PRODUCT, OP_PRODUCT);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, MUL_DIV, OP_MUL_DIV);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, SCALE_OFFSET, OP_SCALE_OFFSET);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, OFFSET_SCALE, OP_OFFSET_SCALE);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, LERP, OP_LERP);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, CONSTRAINED_LERP, OP_CONSTRAINED_LERP);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, DIV_ADD, OP_DIV_ADD);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, ADD_DIV, OP_ADD_DIV);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, MID, OP_MID);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, MAX, OP_MAX);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, MIN, OP_MIN);
|
||||
MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, ABS, OP_ABS);
|
||||
|
||||
//| class MathOperation:
|
||||
//| """Operation for a Math block"""
|
||||
//|
|
||||
//| SUM: "MathOperation"
|
||||
//| """Computes ``a+b+c``. For 2-input sum, set one argument to ``0.0``. To hold a control value for multiple subscribers, set two arguments to ``0.0``."""
|
||||
//|
|
||||
//| ADD_SUB: "MathOperation"
|
||||
//| """Computes ``a+b-c``. For 2-input subtraction, set ``b`` to ``0.0``."""
|
||||
//|
|
||||
//| PRODUCT: "MathOperation"
|
||||
//| """Computes ``a*b*c``. For 2-input product, set one argument to ``1.0``."""
|
||||
//|
|
||||
//| MUL_DIV: "MathOperation"
|
||||
//| """Computes ``a*b/c``. If ``c`` is zero, the output is ``1.0``."""
|
||||
//|
|
||||
//| SCALE_OFFSET: "MathOperation"
|
||||
//| """Computes ``(a*b)+c``."""
|
||||
//|
|
||||
//| OFFSET_SCALE: "MathOperation"
|
||||
//| """Computes ``(a+b)*c``. For 2-input multiplication, set ``b`` to 0."""
|
||||
//|
|
||||
//| LERP: "MathOperation"
|
||||
//| """Computes ``a * (1-c) + b * c``."""
|
||||
//|
|
||||
//| CONSTRAINED_LERP: "MathOperation"
|
||||
//| """Computes ``a * (1-c') + b * c'``, where ``c'`` is constrained to be between ``0.0`` and ``1.0``."""
|
||||
//|
|
||||
//| DIV_ADD: "MathOperation"
|
||||
//| """Computes ``a/b+c``. If ``b`` is zero, the output is ``c``."""
|
||||
//|
|
||||
//| ADD_DIV: "MathOperation"
|
||||
//| """Computes ``(a+b)/c``. For 2-input product, set ``b`` to ``0.0``."""
|
||||
//|
|
||||
//| MID: "MathOperation"
|
||||
//| """Returns the middle of the 3 input values."""
|
||||
//|
|
||||
//| MAX: "MathOperation"
|
||||
//| """Returns the biggest of the 3 input values."""
|
||||
//|
|
||||
//| MIN: "MathOperation"
|
||||
//| """Returns the smallest of the 3 input values."""
|
||||
//|
|
||||
//| ABS: "MathOperation"
|
||||
//| """Returns the absolute value of ``a``."""
|
||||
//|
|
||||
MAKE_ENUM_MAP(synthio_math_operation) {
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, SUM),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, ADD_SUB),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, PRODUCT),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, MUL_DIV),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, SCALE_OFFSET),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, OFFSET_SCALE),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, LERP),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, CONSTRAINED_LERP),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, DIV_ADD),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, ADD_DIV),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, MID),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, MAX),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, MIN),
|
||||
MAKE_ENUM_MAP_ENTRY(math_op, ABS),
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(synthio_math_operation_locals_dict, synthio_math_operation_locals_table);
|
||||
MAKE_PRINTER(synthio, synthio_math_operation);
|
||||
MAKE_ENUM_TYPE(synthio, MathOperation, synthio_math_operation);
|
||||
|
||||
//| class Math:
|
||||
//| """An arithmetic block
|
||||
//|
|
||||
//| Performs an arithmetic operation on up to 3 inputs. See the
|
||||
//| documentation of ``MathOperation`` for the specific functions available.
|
||||
//|
|
||||
//| The properties can all be changed at run-time.
|
||||
//|
|
||||
//| An Math only updates if it is actually associated with a playing `Synthesizer`,
|
||||
//| including indirectly via a `Note` or another intermediate Math.
|
||||
//|
|
||||
//| Using the same Math as an input to multiple other Maths or Notes is OK, but
|
||||
//| the result if an Math is tied to multiple Synthtesizer objects is undefined.
|
||||
//|
|
||||
//| In the current implementation, Maths are updated every 256 samples. This
|
||||
//| should be considered an implementation detail.
|
||||
//| """
|
||||
//|
|
||||
//| def __init__(
|
||||
//| self,
|
||||
//| operation: MathOperation,
|
||||
//| a: BlockInput,
|
||||
//| b: BlockInput = 0.0,
|
||||
//| c: BlockInput = 1.0,
|
||||
//| ):
|
||||
//| pass
|
||||
static const mp_arg_t math_properties[] = {
|
||||
{ MP_QSTR_operation, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL } },
|
||||
{ MP_QSTR_a, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL } },
|
||||
{ MP_QSTR_b, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } },
|
||||
{ MP_QSTR_c, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(1) } },
|
||||
};
|
||||
|
||||
STATIC mp_obj_t synthio_math_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(math_properties)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(math_properties), math_properties, args);
|
||||
|
||||
synthio_math_obj_t *self = m_new_obj(synthio_math_obj_t);
|
||||
self->base.base.type = &synthio_math_type;
|
||||
|
||||
self->base.last_tick = synthio_global_tick;
|
||||
|
||||
mp_obj_t result = MP_OBJ_FROM_PTR(self);
|
||||
properties_construct_helper(result, math_properties, args, MP_ARRAY_SIZE(math_properties));
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
//| a: BlockInput
|
||||
//| """The first input to the operation"""
|
||||
STATIC mp_obj_t synthio_math_get_a(mp_obj_t self_in) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return common_hal_synthio_math_get_input_obj(self, 0);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(synthio_math_get_a_obj, synthio_math_get_a);
|
||||
|
||||
STATIC mp_obj_t synthio_math_set_a(mp_obj_t self_in, mp_obj_t arg) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
common_hal_synthio_math_set_input_obj(self, 0, arg, MP_QSTR_a);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(synthio_math_set_a_obj, synthio_math_set_a);
|
||||
MP_PROPERTY_GETSET(synthio_math_a_obj,
|
||||
(mp_obj_t)&synthio_math_get_a_obj,
|
||||
(mp_obj_t)&synthio_math_set_a_obj);
|
||||
|
||||
|
||||
//| b: BlockInput
|
||||
//| """The second input to the operation"""
|
||||
STATIC mp_obj_t synthio_math_get_b(mp_obj_t self_in) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return common_hal_synthio_math_get_input_obj(self, 1);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(synthio_math_get_b_obj, synthio_math_get_b);
|
||||
|
||||
STATIC mp_obj_t synthio_math_set_b(mp_obj_t self_in, mp_obj_t arg) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
common_hal_synthio_math_set_input_obj(self, 1, arg, MP_QSTR_b);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(synthio_math_set_b_obj, synthio_math_set_b);
|
||||
MP_PROPERTY_GETSET(synthio_math_b_obj,
|
||||
(mp_obj_t)&synthio_math_get_b_obj,
|
||||
(mp_obj_t)&synthio_math_set_b_obj);
|
||||
|
||||
|
||||
//| c: BlockInput
|
||||
//| """The third input to the operation"""
|
||||
STATIC mp_obj_t synthio_math_get_c(mp_obj_t self_in) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return common_hal_synthio_math_get_input_obj(self, 2);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(synthio_math_get_c_obj, synthio_math_get_c);
|
||||
|
||||
STATIC mp_obj_t synthio_math_set_c(mp_obj_t self_in, mp_obj_t arg) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
common_hal_synthio_math_set_input_obj(self, 2, arg, MP_QSTR_c);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(synthio_math_set_c_obj, synthio_math_set_c);
|
||||
MP_PROPERTY_GETSET(synthio_math_c_obj,
|
||||
(mp_obj_t)&synthio_math_get_c_obj,
|
||||
(mp_obj_t)&synthio_math_set_c_obj);
|
||||
|
||||
|
||||
//| operation: MathOperation
|
||||
//| """The function to compute"""
|
||||
STATIC mp_obj_t synthio_math_get_operation(mp_obj_t self_in) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return cp_enum_find(&synthio_math_operation_type, common_hal_synthio_math_get_operation(self));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(synthio_math_get_operation_obj, synthio_math_get_operation);
|
||||
|
||||
STATIC mp_obj_t synthio_math_set_operation(mp_obj_t self_in, mp_obj_t arg) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
common_hal_synthio_math_set_operation(self, cp_enum_value(&synthio_math_operation_type, arg, MP_QSTR_operation));
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(synthio_math_set_operation_obj, synthio_math_set_operation);
|
||||
MP_PROPERTY_GETSET(synthio_math_operation_obj,
|
||||
(mp_obj_t)&synthio_math_get_operation_obj,
|
||||
(mp_obj_t)&synthio_math_set_operation_obj);
|
||||
|
||||
|
||||
|
||||
//|
|
||||
//| value: float
|
||||
//| """The value of the oscillator (read-only)"""
|
||||
//|
|
||||
STATIC mp_obj_t synthio_math_get_value(mp_obj_t self_in) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return mp_obj_new_float(common_hal_synthio_math_get_value(self));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(synthio_math_get_value_obj, synthio_math_get_value);
|
||||
|
||||
MP_PROPERTY_GETTER(synthio_math_value_obj,
|
||||
(mp_obj_t)&synthio_math_get_value_obj);
|
||||
|
||||
|
||||
static void math_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
(void)kind;
|
||||
properties_print_helper(print, self_in, math_properties, MP_ARRAY_SIZE(math_properties));
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t synthio_math_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_a), MP_ROM_PTR(&synthio_math_a_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_b), MP_ROM_PTR(&synthio_math_b_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_c), MP_ROM_PTR(&synthio_math_c_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_operation), MP_ROM_PTR(&synthio_math_operation_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&synthio_math_value_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(synthio_math_locals_dict, synthio_math_locals_dict_table);
|
||||
|
||||
|
||||
STATIC const synthio_block_proto_t math_proto = {
|
||||
MP_PROTO_IMPLEMENT(MP_QSTR_synthio_block)
|
||||
.tick = common_hal_synthio_math_tick,
|
||||
};
|
||||
|
||||
const mp_obj_type_t synthio_math_type = {
|
||||
{ &mp_type_type },
|
||||
.flags = MP_TYPE_FLAG_EXTENDED,
|
||||
.name = MP_QSTR_Math,
|
||||
.make_new = synthio_math_make_new,
|
||||
.locals_dict = (mp_obj_dict_t *)&synthio_math_locals_dict,
|
||||
.print = math_print,
|
||||
MP_TYPE_EXTENDED_FIELDS(
|
||||
.protocol = &math_proto,
|
||||
),
|
||||
};
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef enum {
|
||||
OP_SUM,
|
||||
OP_ADD_SUB,
|
||||
OP_PRODUCT,
|
||||
OP_MUL_DIV,
|
||||
OP_SCALE_OFFSET,
|
||||
OP_OFFSET_SCALE,
|
||||
OP_LERP,
|
||||
OP_CONSTRAINED_LERP,
|
||||
OP_DIV_ADD,
|
||||
OP_ADD_DIV,
|
||||
OP_MID,
|
||||
OP_MIN,
|
||||
OP_MAX,
|
||||
OP_ABS
|
||||
} synthio_math_operation_t;
|
||||
|
||||
typedef struct synthio_math_obj synthio_math_obj_t;
|
||||
extern const mp_obj_type_t synthio_math_type;
|
||||
extern const mp_obj_type_t synthio_math_operation_type;
|
||||
|
||||
mp_obj_t common_hal_synthio_math_get_input_obj(synthio_math_obj_t *self, size_t i);
|
||||
void common_hal_synthio_math_set_input_obj(synthio_math_obj_t *self, size_t i, mp_obj_t arg, qstr argname);
|
||||
|
||||
synthio_math_operation_t common_hal_synthio_math_get_operation(synthio_math_obj_t *self);
|
||||
void common_hal_synthio_math_set_operation(synthio_math_obj_t *self, synthio_math_operation_t arg);
|
||||
|
||||
mp_float_t common_hal_synthio_math_get_value(synthio_math_obj_t *self);
|
||||
|
||||
mp_float_t common_hal_synthio_math_tick(mp_obj_t self_in);
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include "shared-bindings/synthio/__init__.h"
|
||||
#include "shared-bindings/synthio/LFO.h"
|
||||
#include "shared-bindings/synthio/Math.h"
|
||||
#include "shared-bindings/synthio/MidiTrack.h"
|
||||
#include "shared-bindings/synthio/Note.h"
|
||||
#include "shared-bindings/synthio/Synthesizer.h"
|
||||
|
@ -63,8 +64,8 @@ static const mp_arg_t envelope_properties[] = {
|
|||
//| At least 2 simultaneous notes are supported. samd5x, mimxrt10xx and rp2040 platforms support up to 12 notes.
|
||||
//| """
|
||||
//|
|
||||
//| BlockInput = Union["LFO", float]
|
||||
//| """LFOs and Notes can take any of these types as inputs on certain attributes"""
|
||||
//| BlockInput = Union["Math", "LFO", float, None]
|
||||
//| """Blocks and Notes can take any of these types as inputs on certain attributes"""
|
||||
//|
|
||||
//| class Envelope:
|
||||
//| def __init__(
|
||||
|
@ -306,6 +307,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR(synthio_lfo_tick_obj, 1, synthio_lfo_tick);
|
|||
|
||||
STATIC const mp_rom_map_elem_t synthio_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_synthio) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Math), MP_ROM_PTR(&synthio_math_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MathOperation), MP_ROM_PTR(&synthio_math_operation_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MidiTrack), MP_ROM_PTR(&synthio_miditrack_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Note), MP_ROM_PTR(&synthio_note_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_LFO), MP_ROM_PTR(&synthio_lfo_type) },
|
||||
|
|
|
@ -64,58 +64,6 @@ mp_float_t common_hal_synthio_lfo_tick(mp_obj_t self_in) {
|
|||
return value;
|
||||
}
|
||||
|
||||
mp_float_t synthio_block_slot_get(synthio_block_slot_t *slot) {
|
||||
if (slot->obj == mp_const_none) {
|
||||
return MICROPY_FLOAT_CONST(0.);
|
||||
}
|
||||
|
||||
mp_float_t value;
|
||||
if (mp_obj_get_float_maybe(slot->obj, &value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
synthio_block_base_t *block = MP_OBJ_TO_PTR(slot->obj);
|
||||
if (block->last_tick == synthio_global_tick) {
|
||||
return block->value;
|
||||
}
|
||||
|
||||
block->last_tick = synthio_global_tick;
|
||||
// previously verified by call to mp_proto_get
|
||||
const synthio_block_proto_t *p = mp_type_get_protocol_slot(mp_obj_get_type(slot->obj));
|
||||
block->value = value = p->tick(slot);
|
||||
return value;
|
||||
}
|
||||
|
||||
mp_float_t synthio_block_slot_get_limited(synthio_block_slot_t *lfo_slot, mp_float_t lo, mp_float_t hi) {
|
||||
mp_float_t value = synthio_block_slot_get(lfo_slot);
|
||||
if (value < lo) {
|
||||
return lo;
|
||||
}
|
||||
if (value > hi) {
|
||||
return hi;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int32_t synthio_block_slot_get_scaled(synthio_block_slot_t *lfo_slot, mp_float_t lo, mp_float_t hi) {
|
||||
mp_float_t value = synthio_block_slot_get_limited(lfo_slot, lo, hi);
|
||||
return (int32_t)MICROPY_FLOAT_C_FUN(round)(MICROPY_FLOAT_C_FUN(ldexp)(value, 15));
|
||||
}
|
||||
|
||||
void synthio_block_assign_slot(mp_obj_t obj, synthio_block_slot_t *slot, qstr arg_name) {
|
||||
if (mp_proto_get(MP_QSTR_synthio_block, obj)) {
|
||||
slot->obj = obj;
|
||||
return;
|
||||
}
|
||||
|
||||
mp_float_t value;
|
||||
if (obj != mp_const_none && !mp_obj_get_float_maybe(obj, &value)) {
|
||||
mp_raise_TypeError_varg(translate("%q must be of type %q or %q, not %q"), arg_name, MP_QSTR_Lfo, MP_QSTR_float, mp_obj_get_type_qstr(obj));
|
||||
}
|
||||
|
||||
slot->obj = obj;
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_synthio_lfo_get_waveform_obj(synthio_lfo_obj_t *self) {
|
||||
return self->waveform_obj;
|
||||
}
|
||||
|
|
|
@ -26,26 +26,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
#include "shared-module/synthio/__init__.h"
|
||||
#include "shared-bindings/synthio/__init__.h"
|
||||
|
||||
typedef struct synthio_block_base {
|
||||
mp_obj_base_t base;
|
||||
uint8_t last_tick;
|
||||
mp_float_t value;
|
||||
} synthio_block_base_t;
|
||||
|
||||
typedef struct synthio_block_slot {
|
||||
mp_obj_t obj;
|
||||
} synthio_block_slot_t;
|
||||
|
||||
typedef struct {
|
||||
MP_PROTOCOL_HEAD;
|
||||
mp_float_t (*tick)(mp_obj_t obj);
|
||||
} synthio_block_proto_t;
|
||||
#include "shared-module/synthio/block.h"
|
||||
|
||||
typedef struct synthio_lfo_obj {
|
||||
synthio_block_base_t base;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "shared-bindings/synthio/Math.h"
|
||||
#include "shared-module/synthio/Math.h"
|
||||
|
||||
mp_obj_t common_hal_synthio_math_get_input_obj(synthio_math_obj_t *self, size_t i) {
|
||||
return self->inputs[i].obj;
|
||||
}
|
||||
|
||||
void common_hal_synthio_math_set_input_obj(synthio_math_obj_t *self, size_t i, mp_obj_t arg, qstr argname) {
|
||||
assert(i < MP_ARRAY_SIZE(self->inputs));
|
||||
synthio_block_assign_slot(arg, &self->inputs[i], argname);
|
||||
}
|
||||
|
||||
synthio_math_operation_t common_hal_synthio_math_get_operation(synthio_math_obj_t *self) {
|
||||
return self->operation;
|
||||
}
|
||||
|
||||
void common_hal_synthio_math_set_operation(synthio_math_obj_t *self, synthio_math_operation_t arg) {
|
||||
self->operation = arg;
|
||||
}
|
||||
|
||||
#define ZERO (MICROPY_FLOAT_CONST(0.))
|
||||
|
||||
mp_float_t common_hal_synthio_math_get_value(synthio_math_obj_t *self) {
|
||||
return self->base.value;
|
||||
}
|
||||
|
||||
mp_float_t common_hal_synthio_math_tick(mp_obj_t self_in) {
|
||||
synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_float_t a = synthio_block_slot_get(&self->inputs[0]);
|
||||
|
||||
if (self->operation == OP_ABS) {
|
||||
return MICROPY_FLOAT_C_FUN(fabs)(a);
|
||||
}
|
||||
|
||||
mp_float_t b = synthio_block_slot_get(&self->inputs[1]);
|
||||
mp_float_t c = synthio_block_slot_get(&self->inputs[2]);
|
||||
|
||||
switch (self->operation) {
|
||||
case OP_SUM:
|
||||
return a + b + c;
|
||||
case OP_ADD_SUB:
|
||||
return a + b - c;
|
||||
case OP_PRODUCT:
|
||||
return a * b * c;
|
||||
case OP_MUL_DIV:
|
||||
if (fpclassify(c) == FP_ZERO) {
|
||||
return 0;
|
||||
}
|
||||
return a * b / c;
|
||||
case OP_SCALE_OFFSET:
|
||||
return a * b + c;
|
||||
case OP_OFFSET_SCALE:
|
||||
return (a + b) * c;
|
||||
case OP_CONSTRAINED_LERP:
|
||||
c = MIN(1, MAX(0, c));
|
||||
MP_FALLTHROUGH;
|
||||
case OP_LERP:
|
||||
return a * (1 - c) + b * c;
|
||||
case OP_DIV_ADD:
|
||||
if (fpclassify(b) == FP_ZERO) {
|
||||
return ZERO;
|
||||
}
|
||||
return a / b + c;
|
||||
case OP_ADD_DIV:
|
||||
if (fpclassify(c) == FP_ZERO) {
|
||||
return ZERO;
|
||||
}
|
||||
return (a + b) / c;
|
||||
case OP_MID:
|
||||
if (a < b) {
|
||||
if (b < c) {
|
||||
return b;
|
||||
}
|
||||
if (a < c) {
|
||||
return c;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if (a < c) {
|
||||
return a;
|
||||
}
|
||||
if (c < b) {
|
||||
return b;
|
||||
}
|
||||
return c;
|
||||
case OP_MIN:
|
||||
return MIN(a,MIN(b,c));
|
||||
case OP_MAX:
|
||||
return MAX(a,MAX(b,c));
|
||||
case OP_ABS:
|
||||
break;
|
||||
}
|
||||
return ZERO;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "shared-module/synthio/block.h"
|
||||
|
||||
typedef struct synthio_math_obj {
|
||||
synthio_block_base_t base;
|
||||
synthio_block_slot_t inputs[3];
|
||||
synthio_math_operation_t operation;
|
||||
} synthio_math_obj_t;
|
|
@ -547,3 +547,55 @@ void shared_bindings_synthio_lfo_tick(uint32_t sample_rate) {
|
|||
synthio_global_rate_scale = (mp_float_t)SYNTHIO_MAX_DUR / sample_rate;
|
||||
synthio_global_tick++;
|
||||
}
|
||||
|
||||
mp_float_t synthio_block_slot_get(synthio_block_slot_t *slot) {
|
||||
if (slot->obj == mp_const_none) {
|
||||
return MICROPY_FLOAT_CONST(0.);
|
||||
}
|
||||
|
||||
mp_float_t value;
|
||||
if (mp_obj_get_float_maybe(slot->obj, &value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
synthio_block_base_t *block = MP_OBJ_TO_PTR(slot->obj);
|
||||
if (block->last_tick == synthio_global_tick) {
|
||||
return block->value;
|
||||
}
|
||||
|
||||
block->last_tick = synthio_global_tick;
|
||||
// previously verified by call to mp_proto_get
|
||||
const synthio_block_proto_t *p = mp_type_get_protocol_slot(mp_obj_get_type(slot->obj));
|
||||
block->value = value = p->tick(slot->obj);
|
||||
return value;
|
||||
}
|
||||
|
||||
mp_float_t synthio_block_slot_get_limited(synthio_block_slot_t *lfo_slot, mp_float_t lo, mp_float_t hi) {
|
||||
mp_float_t value = synthio_block_slot_get(lfo_slot);
|
||||
if (value < lo) {
|
||||
return lo;
|
||||
}
|
||||
if (value > hi) {
|
||||
return hi;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int32_t synthio_block_slot_get_scaled(synthio_block_slot_t *lfo_slot, mp_float_t lo, mp_float_t hi) {
|
||||
mp_float_t value = synthio_block_slot_get_limited(lfo_slot, lo, hi);
|
||||
return (int32_t)MICROPY_FLOAT_C_FUN(round)(MICROPY_FLOAT_C_FUN(ldexp)(value, 15));
|
||||
}
|
||||
|
||||
void synthio_block_assign_slot(mp_obj_t obj, synthio_block_slot_t *slot, qstr arg_name) {
|
||||
if (mp_proto_get(MP_QSTR_synthio_block, obj)) {
|
||||
slot->obj = obj;
|
||||
return;
|
||||
}
|
||||
|
||||
mp_float_t value;
|
||||
if (obj != mp_const_none && !mp_obj_get_float_maybe(obj, &value)) {
|
||||
mp_raise_TypeError_varg(translate("%q must be of type %q, not %q"), arg_name, MP_QSTR_BlockInput, mp_obj_get_type_qstr(obj));
|
||||
}
|
||||
|
||||
slot->obj = obj;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/proto.h"
|
||||
|
||||
#include "shared-module/synthio/__init__.h"
|
||||
#include "shared-bindings/synthio/__init__.h"
|
||||
|
||||
typedef struct synthio_block_base {
|
||||
mp_obj_base_t base;
|
||||
uint8_t last_tick;
|
||||
mp_float_t value;
|
||||
} synthio_block_base_t;
|
||||
|
||||
typedef struct synthio_block_slot {
|
||||
mp_obj_t obj;
|
||||
} synthio_block_slot_t;
|
||||
|
||||
typedef struct {
|
||||
MP_PROTOCOL_HEAD;
|
||||
mp_float_t (*tick)(mp_obj_t obj);
|
||||
} synthio_block_proto_t;
|
||||
|
||||
// Update the value inside the lfo slot if the value is an LFO, returning the new value
|
||||
mp_float_t synthio_block_slot_get(synthio_block_slot_t *block_slot);
|
||||
// the same, but the output is constrained to be between lo and hi
|
||||
mp_float_t synthio_block_slot_get_limited(synthio_block_slot_t *block_slot, mp_float_t lo, mp_float_t hi);
|
||||
// the same, but the output is constrained to be between lo and hi and converted to an integer with 15 fractional bits
|
||||
int32_t synthio_block_slot_get_scaled(synthio_block_slot_t *block_slot, mp_float_t lo, mp_float_t hi);
|
||||
|
||||
// Assign an object (which may be a float or a synthio_block_obj_t) to an block slot
|
||||
void synthio_block_assign_slot(mp_obj_t obj, synthio_block_slot_t *block_slot, qstr arg_name);
|
|
@ -0,0 +1,8 @@
|
|||
from synthio import *
|
||||
|
||||
for values in ((-1, 4, 9), (4, -1, 9), (9, 4, -1), (0, 0, 0), (3, 2, 1), (2, 1), (1,)):
|
||||
for op in MathOperation.__dict__.values():
|
||||
o = Math(op, *values)
|
||||
print(op, o)
|
||||
print(lfo_tick(o))
|
||||
print()
|
|
@ -0,0 +1,203 @@
|
|||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=-1, b=4, c=9)
|
||||
(12.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=-1, b=4, c=9)
|
||||
(-6.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=-1, b=4, c=9)
|
||||
(-36.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=-1, b=4, c=9)
|
||||
(-0.4444444444444445,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=-1, b=4, c=9)
|
||||
(5.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=-1, b=4, c=9)
|
||||
(27.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=-1, b=4, c=9)
|
||||
(44.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=-1, b=4, c=9)
|
||||
(4.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=-1, b=4, c=9)
|
||||
(8.75,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=-1, b=4, c=9)
|
||||
(0.3333333333333333,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=-1, b=4, c=9)
|
||||
(4.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=-1, b=4, c=9)
|
||||
(9.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=-1, b=4, c=9)
|
||||
(-1.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=-1, b=4, c=9)
|
||||
(1.0,)
|
||||
|
||||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=4, b=-1, c=9)
|
||||
(12.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=4, b=-1, c=9)
|
||||
(-6.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=4, b=-1, c=9)
|
||||
(-36.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=4, b=-1, c=9)
|
||||
(-0.4444444444444445,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=4, b=-1, c=9)
|
||||
(5.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=4, b=-1, c=9)
|
||||
(27.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=4, b=-1, c=9)
|
||||
(-41.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=4, b=-1, c=9)
|
||||
(-1.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=4, b=-1, c=9)
|
||||
(5.0,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=4, b=-1, c=9)
|
||||
(0.3333333333333333,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=4, b=-1, c=9)
|
||||
(4.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=4, b=-1, c=9)
|
||||
(9.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=4, b=-1, c=9)
|
||||
(-1.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=4, b=-1, c=9)
|
||||
(4.0,)
|
||||
|
||||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=9, b=4, c=-1)
|
||||
(12.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=9, b=4, c=-1)
|
||||
(14.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=9, b=4, c=-1)
|
||||
(-36.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=9, b=4, c=-1)
|
||||
(-36.0,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=9, b=4, c=-1)
|
||||
(35.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=9, b=4, c=-1)
|
||||
(-13.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=9, b=4, c=-1)
|
||||
(14.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=9, b=4, c=-1)
|
||||
(9.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=9, b=4, c=-1)
|
||||
(1.25,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=9, b=4, c=-1)
|
||||
(-13.0,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=9, b=4, c=-1)
|
||||
(4.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=9, b=4, c=-1)
|
||||
(9.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=9, b=4, c=-1)
|
||||
(-1.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=9, b=4, c=-1)
|
||||
(9.0,)
|
||||
|
||||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=0, b=0, c=0)
|
||||
(0.0,)
|
||||
|
||||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=3, b=2, c=1)
|
||||
(6.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=3, b=2, c=1)
|
||||
(4.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=3, b=2, c=1)
|
||||
(6.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=3, b=2, c=1)
|
||||
(6.0,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=3, b=2, c=1)
|
||||
(7.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=3, b=2, c=1)
|
||||
(5.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=3, b=2, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=3, b=2, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=3, b=2, c=1)
|
||||
(2.5,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=3, b=2, c=1)
|
||||
(5.0,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=3, b=2, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=3, b=2, c=1)
|
||||
(3.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=3, b=2, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=3, b=2, c=1)
|
||||
(3.0,)
|
||||
|
||||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=2, b=1, c=1)
|
||||
(4.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=2, b=1, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=2, b=1, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=2, b=1, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=2, b=1, c=1)
|
||||
(3.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=2, b=1, c=1)
|
||||
(3.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=2, b=1, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=2, b=1, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=2, b=1, c=1)
|
||||
(3.0,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=2, b=1, c=1)
|
||||
(3.0,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=2, b=1, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=2, b=1, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=2, b=1, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=2, b=1, c=1)
|
||||
(2.0,)
|
||||
|
||||
synthio.MathOperation.SUM Math(operation=synthio.MathOperation.SUM, a=1, b=0, c=1)
|
||||
(2.0,)
|
||||
synthio.MathOperation.ADD_SUB Math(operation=synthio.MathOperation.ADD_SUB, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.PRODUCT Math(operation=synthio.MathOperation.PRODUCT, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.MUL_DIV Math(operation=synthio.MathOperation.MUL_DIV, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.SCALE_OFFSET Math(operation=synthio.MathOperation.SCALE_OFFSET, a=1, b=0, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.OFFSET_SCALE Math(operation=synthio.MathOperation.OFFSET_SCALE, a=1, b=0, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.LERP Math(operation=synthio.MathOperation.LERP, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.CONSTRAINED_LERP Math(operation=synthio.MathOperation.CONSTRAINED_LERP, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.DIV_ADD Math(operation=synthio.MathOperation.DIV_ADD, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.ADD_DIV Math(operation=synthio.MathOperation.ADD_DIV, a=1, b=0, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.MID Math(operation=synthio.MathOperation.MID, a=1, b=0, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.MAX Math(operation=synthio.MathOperation.MAX, a=1, b=0, c=1)
|
||||
(1.0,)
|
||||
synthio.MathOperation.MIN Math(operation=synthio.MathOperation.MIN, a=1, b=0, c=1)
|
||||
(0.0,)
|
||||
synthio.MathOperation.ABS Math(operation=synthio.MathOperation.ABS, a=1, b=0, c=1)
|
||||
(1.0,)
|
||||
|
Loading…
Reference in New Issue