24 Commits

Author SHA1 Message Date
081e33dd07 modulator noise function previous val bug 2024-11-29 14:20:29 +01:00
eb02657b4a center vals included in NN data 2024-10-22 13:27:07 +02:00
d670aefcbd enums start with NONE 2024-10-22 12:32:42 +02:00
a35fecafae NN data receiving 2024-10-22 10:58:46 +02:00
b3ba9b0f2d cachedNoise no longer an array 2024-10-18 15:34:53 +02:00
102a88b242 bugfix - modulators not properly initializing 2024-10-15 14:54:37 +02:00
aebfbe5277 Merge pull request 'main' (#6) from main into nn-communication
Reviewed-on: #6
2024-10-15 12:27:53 +02:00
2d81a832af Merge branch 'nn-communication' into main 2024-10-15 12:27:08 +02:00
cdbcf24dfc Merge pull request 'fixed userwave update' (#5) from lock into main
Reviewed-on: #5
2024-10-15 12:21:08 +02:00
64f1455f69 fixed userwave update 2024-10-14 09:16:05 +02:00
trian-gles
a855d254cd non musical timing to ms value for input from neural net 2024-10-11 15:34:37 +02:00
09a1b5f20f Merge pull request 'lock mode' (#4) from lock into main
Reviewed-on: #4
2024-10-11 13:36:54 +02:00
34e99f09fd lock mode 2024-10-11 12:52:54 +02:00
86a994546e Merge pull request 'noise-functions' (#3) from noise-functions into main
Reviewed-on: #3
2024-10-10 12:25:22 +02:00
d22cdc8401 basic random value noise functions 2024-10-10 12:23:50 +02:00
trian-gles
43e517cc4e added new init values 2024-09-26 12:40:47 +02:00
a608b083f3 working sine interpolation 2024-09-25 15:59:27 +02:00
83cf801ec3 merge conflict 2024-09-24 14:35:37 +02:00
trian-gles
45e168ba11 UI changes 2024-09-24 14:35:01 +02:00
37a65058bc Merge pull request 'musical-timing-phase' (#2) from musical-timing-phase into main
Reviewed-on: #2
2024-09-03 11:37:51 +02:00
trian-gles
45847fbae4 phase calculated from ticks 2024-09-03 11:34:32 +02:00
trian-gles
c794b5bc2f separated phase handling into two options 2024-09-02 16:58:18 +02:00
trian-gles
c8c410a38f UI changes 2024-08-08 15:31:57 +02:00
985b6c832f Merge pull request 'user defined wavetable shape' (#1) from user-defined-table into main
Reviewed-on: #1
2024-08-08 14:32:34 +02:00
6 changed files with 901 additions and 370 deletions

View File

@@ -5,7 +5,8 @@ function isNumeric(str) {
}
function DropDown(props) {
return e('select', {type: "number", onChange: props.onChange, value: props.value},
let className = props.locked ? 'locked-component' : '';
return e('select', {className, type: "number", onChange: props.onChange, value: props.value},
...props.options.map((item) => Option(item)));
}
@@ -18,11 +19,13 @@ function Label(text){
}
function NumberBox(props){
return e('input', {type: "number", onChange: props.onChange, step: props.step, value: props.value, className: props.className}, null);
let extraClassName = props.locked ? ' locked-component' : '';
return e('input', {type: "number", onChange: props.onChange, step: props.step, value: props.value, className: props.className + extraClassName}, null);
}
function TextBox(props){
return e('input', {type: "text", value: props.value, onChange: props.onChange, id: props.id});
let className = props.locked ? 'locked-component' : '';
return e('input', {className, type: "text", value: props.value, onChange: props.onChange, id: props.id});
}
function Option(str, value){
@@ -30,7 +33,8 @@ function Option(str, value){
}
function Button(props){
return e('button', {onClick: props.onClick}, props.text);
let className = props.locked ? 'locked-component' : '';
return e('button', {onClick: props.onClick, className}, props.text);
}
function Switch(props){

View File

@@ -5,13 +5,13 @@
// NOT A REACT FUNCTIONAL COMPONENT. MERELY RETURNS AN ARRAY WHICH IS UNPACKED
function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames, setEnumNames, djParam){
function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames, setEnumNames, djParam, locked){
let items = [];
for (let i = 0; i < MAXENUMPOINTS; i++){
items.push(ListItem(e(TextBox, {onChange: CreateMatrixParamChanger(enumNames, setEnumNames, index, i), value: enumNames[index][i], id:`text-${djParam}-${enumNames[index][i]}`}, null)));
items.push(ListItem(e(TextBox, {locked, onChange: CreateMatrixParamChanger(enumNames, setEnumNames, index, i), value: enumNames[index][i], id:`text-${djParam}-${enumNames[index][i]}`}, null)));
// Add 1 to make up for the lower enum bound
items.push(ListItem(e(NumberBox, {onChange: CreateMatrixParamChanger(enumBreakPoints, setEnumBreakPoints, index, i + 1), value:enumBreakPoints[index][i + 1]}, null)));
items.push(ListItem(e(NumberBox, {locked, onChange: CreateMatrixParamChanger(enumBreakPoints, setEnumBreakPoints, index, i + 1), value:enumBreakPoints[index][i + 1]}, null)));
}
return items;
}
@@ -20,13 +20,13 @@ function EnumeratorRow(props){
let linkedText = props.linked ? "<- mods" : "";
let content = e('ul', {className: 'lfo-item', id: `${props.djParam}-enum-row`},
ListItem(DropDown({onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
ListItem(e(NumberBox, {onChange: props.setEnumItemCounts, step:1, value:props.enumItems, className: 'enum-count'}, null)),
ListItem(e(NumberBox, {onChange: CreateMatrixParamChanger(props.enumBreakPoints, props.setEnumBreakPoints, props.index, 0), value:props.enumBreakPoints[props.index][0], step:0.1}, null)),
...(EnumeratorItems(props.index, props.enumBreakPoints, props.setEnumBreakPoints, props.enumNames, props.setEnumNames, props.djParam).slice(0, props.enumItems * 2)),
ListItem(e(Button, {text:'+', onClick: props.addEnum}, null)),
ListItem(e(Button, {text:'-', onClick: props.removeEnum}, null)),
ListItem(DropDown({locked:props.locked, onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
ListItem(DropDown({locked:props.locked, onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
ListItem(e(NumberBox, {locked:props.locked, onChange: props.setEnumItemCounts, step:1, value:props.enumItems, className: 'enum-count'}, null)),
ListItem(e(NumberBox, {locked:props.locked, onChange: CreateMatrixParamChanger(props.enumBreakPoints, props.setEnumBreakPoints, props.index, 0), value:props.enumBreakPoints[props.index][0], step:0.1}, null)),
...(EnumeratorItems(props.index, props.enumBreakPoints, props.setEnumBreakPoints, props.enumNames, props.setEnumNames, props.djParam, props.locked).slice(0, props.enumItems * 2)),
ListItem(e(Button, {locked:props.locked, text:'+', onClick: props.addEnum}, null)),
ListItem(e(Button, {locked:props.locked, text:'-', onClick: props.removeEnum}, null)),
ListItem(e("div", {className:"linked"}, linkedText))
);
if (props.visible){

View File

@@ -4,13 +4,13 @@
"appversion" : {
"major" : 8,
"minor" : 6,
"revision" : 2,
"revision" : 4,
"architecture" : "x64",
"modernui" : 1
}
,
"classnamespace" : "box",
"rect" : [ 34.0, 76.0, 981.0, 763.0 ],
"rect" : [ -1510.0, 147.0, 1170.0, 725.0 ],
"bglocked" : 0,
"openinpresentation" : 0,
"default_fontsize" : 12.0,
@@ -39,6 +39,252 @@
"subpatcher_template" : "",
"assistshowspatchername" : 0,
"boxes" : [ {
"box" : {
"id" : "obj-7",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 643.0, 631.0, 50.0, 22.0 ]
}
}
, {
"box" : {
"id" : "obj-51",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patcher" : {
"fileversion" : 1,
"appversion" : {
"major" : 8,
"minor" : 6,
"revision" : 4,
"architecture" : "x64",
"modernui" : 1
}
,
"classnamespace" : "box",
"rect" : [ 59.0, 119.0, 640.0, 480.0 ],
"bglocked" : 0,
"openinpresentation" : 0,
"default_fontsize" : 12.0,
"default_fontface" : 0,
"default_fontname" : "Arial",
"gridonopen" : 1,
"gridsize" : [ 15.0, 15.0 ],
"gridsnaponopen" : 1,
"objectsnaponopen" : 1,
"statusbarvisible" : 2,
"toolbarvisible" : 1,
"lefttoolbarpinned" : 0,
"toptoolbarpinned" : 0,
"righttoolbarpinned" : 0,
"bottomtoolbarpinned" : 0,
"toolbars_unpinned_last_save" : 0,
"tallnewobj" : 0,
"boxanimatetime" : 200,
"enablehscroll" : 1,
"enablevscroll" : 1,
"devicewidth" : 0.0,
"description" : "",
"digest" : "",
"tags" : "",
"style" : "",
"subpatcher_template" : "",
"assistshowspatchername" : 0,
"boxes" : [ {
"box" : {
"id" : "obj-43",
"linecount" : 2,
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 163.0, 100.0, 609.0, 35.0 ],
"text" : "4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
}
}
, {
"box" : {
"comment" : "",
"id" : "obj-46",
"index" : 1,
"maxclass" : "inlet",
"numinlets" : 0,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 753.0, 40.0, 30.0, 30.0 ]
}
}
, {
"box" : {
"comment" : "",
"id" : "obj-49",
"index" : 1,
"maxclass" : "outlet",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 163.0, 200.5, 30.0, 30.0 ]
}
}
],
"lines" : [ {
"patchline" : {
"destination" : [ "obj-49", 0 ],
"source" : [ "obj-43", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-43", 1 ],
"source" : [ "obj-46", 0 ]
}
}
]
}
,
"patching_rect" : [ 754.0, 606.5, 59.0, 22.0 ],
"saved_object_attributes" : {
"description" : "",
"digest" : "",
"globalpatchername" : "",
"tags" : ""
}
,
"text" : "p NNdata"
}
}
, {
"box" : {
"id" : "obj-44",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 754.0, 635.5, 89.0, 22.0 ],
"text" : "prepend setNN"
}
}
, {
"box" : {
"id" : "obj-42",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 529.0, 843.0, 99.0, 22.0 ],
"saved_object_attributes" : {
"client_rect" : [ 903, 252, 1512, 568 ],
"parameter_enable" : 0,
"parameter_mappable" : 0,
"storage_rect" : [ 780, 524, 1380, 824 ]
}
,
"text" : "pattrstorage asdf",
"varname" : "asdf"
}
}
, {
"box" : {
"id" : "obj-26",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 3,
"outlettype" : [ "", "", "" ],
"patching_rect" : [ 659.0, 856.0, 40.0, 22.0 ],
"restore" : [ {
"data" : {
"enumArrays" : [ [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "1", "1", "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "2", "2", "2", "2", "2", "2", "2", "2", "2", "2" ], [ "attenuation", "attenuation", "meter", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation" ] ],
"enumMats" : [ [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ "0", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ], [ [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "4 4", "3 4", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ] ] ],
"modArrays" : [ [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "Noise", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO" ], [ "1", "3", "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "SawDown", "Custom", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine" ], [ "Sine Int.", "Rand", "Rand", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int." ], [ "metriclarity", "attenuation", "meter", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE" ], [ "2s", "0.3hz", "1.3.0", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz" ], [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ], [ "3", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ], [ 0.298999999999978, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0.492543640556194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]
}
}
],
"saved_object_attributes" : {
"parameter_enable" : 0,
"parameter_mappable" : 0
}
,
"text" : "pattr",
"varname" : "u671001838"
}
}
, {
"box" : {
"id" : "obj-31",
"maxclass" : "newobj",
"numinlets" : 2,
"numoutlets" : 2,
"outlettype" : [ "", "" ],
"patching_rect" : [ 432.0, 628.0, 80.0, 22.0 ],
"text" : "route NNdata"
}
}
, {
"box" : {
"id" : "obj-13",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 363.0, 124.0, 56.0, 22.0 ],
"text" : "dumpNN"
}
}
, {
"box" : {
"fontname" : "Arial",
"fontsize" : 13.0,
"id" : "obj-29",
"maxclass" : "newobj",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"patching_rect" : [ 465.0, 141.0, 210.0, 23.0 ],
"text" : "metro @interval 40 ticks @active 1"
}
}
, {
"box" : {
"id" : "obj-28",
"maxclass" : "button",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"parameter_enable" : 0,
"patching_rect" : [ 826.0, 79.0, 24.0, 24.0 ]
}
}
, {
"box" : {
"id" : "obj-3",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 817.0, 147.0, 80.0, 22.0 ],
"text" : "prepend ticks"
}
}
, {
"box" : {
"id" : "obj-54",
"maxclass" : "newobj",
@@ -104,22 +350,10 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 28.0, 473.0, 115.0, 22.0 ],
"patching_rect" : [ 27.0, 410.0, 115.0, 22.0 ],
"text" : "param 4 meter \"3 4\""
}
}
, {
"box" : {
"id" : "obj-85",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 28.0, 361.5, 139.0, 22.0 ],
"text" : "param 3 attenuation 100"
}
}
, {
"box" : {
@@ -129,8 +363,8 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 586.0, 713.0, 89.0, 36.0 ],
"text" : "harmoniclarity 40.156651"
"patching_rect" : [ 546.0, 735.0, 89.0, 35.0 ],
"text" : "harmoniclarity 0.512565"
}
}
@@ -142,8 +376,8 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 491.0, 713.0, 85.0, 36.0 ],
"text" : "event_length 29.843349"
"patching_rect" : [ 451.0, 735.0, 85.0, 35.0 ],
"text" : "event_length 0.791345"
}
}
@@ -155,8 +389,8 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 385.0, 715.0, 84.0, 36.0 ],
"text" : "metriclarity 22.176645"
"patching_rect" : [ 345.0, 737.0, 84.0, 35.0 ],
"text" : "metriclarity 2.770749"
}
}
@@ -167,7 +401,7 @@
"numinlets" : 4,
"numoutlets" : 4,
"outlettype" : [ "", "", "", "" ],
"patching_rect" : [ 410.0, 671.0, 273.0, 22.0 ],
"patching_rect" : [ 370.0, 693.0, 273.0, 22.0 ],
"text" : "routepass metriclarity event_length harmoniclarity"
}
@@ -179,7 +413,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 1066.052632331848145, 53.0, 99.894735336303711, 89.0 ],
"patching_rect" : [ 1066.052632331848145, 53.0, 99.894735336303711, 87.0 ],
"text" : "You can use Hz, seconds, ms, hh:mm:ss, or bars.beats.ticks for the period/frequency"
}
@@ -191,7 +425,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 1181.315790414810181, 40.0, 81.0, 117.0 ],
"patching_rect" : [ 1181.315790414810181, 40.0, 81.0, 114.0 ],
"text" : "Min and max must be ADDED to the center value to determine the true bounds. "
}
@@ -199,23 +433,12 @@
, {
"box" : {
"id" : "obj-72",
"linecount" : 4,
"linecount" : 5,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 913.0, 107.0, 150.0, 62.0 ],
"text" : "center values are read only, they must be configured by an upstream value"
}
}
, {
"box" : {
"id" : "obj-66",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 480.5, 613.0, 32.0, 22.0 ],
"text" : "print"
"patching_rect" : [ 913.0, 107.0, 150.0, 74.0 ],
"text" : "center values are read only, they must be configured by an upstream value OR loaded from the dictionary"
}
}
@@ -228,7 +451,7 @@
"numinlets" : 5,
"numoutlets" : 5,
"outlettype" : [ "", "", "", "", "" ],
"patching_rect" : [ 626.0, 613.0, 81.0, 23.0 ],
"patching_rect" : [ 558.0, 661.0, 81.0, 23.0 ],
"text" : "route 1 2 3 4"
}
@@ -244,18 +467,6 @@
"text" : "prepend timesig"
}
}
, {
"box" : {
"id" : "obj-52",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 545.0, 135.0, 89.0, 22.0 ],
"text" : "prepend tempo"
}
}
, {
"box" : {
@@ -264,7 +475,7 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"patching_rect" : [ 325.0, 17.0, 55.0, 22.0 ],
"patching_rect" : [ 333.0, 40.0, 55.0, 22.0 ],
"text" : "del 1000"
}
@@ -300,7 +511,7 @@
"numoutlets" : 5,
"outlettype" : [ "preset", "int", "preset", "int", "" ],
"patching_rect" : [ 934.0, 27.0, 100.0, 40.0 ],
"pattrstorage" : "storage"
"pattrstorage" : "asdf"
}
}
@@ -308,9 +519,9 @@
"box" : {
"data" : {
"data" : {
"enumArrays" : [ [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "2", "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "2", "4", 2, "2", "2", "2", "2", "2", "2", "2" ], [ "scale", "meter", "NONE", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation" ] ],
"enumMats" : [ [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ], [ [ "major", "minor", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "4 4", "3 4", "7 8", "2 4", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ] ] ],
"modArrays" : [ [ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "1", "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "Sine", "Tri", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine" ], [ "metriclarity", "meter", "event_length", "harmoniclarity", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE" ], [ "1hz", "0.4.0", "3s", "00:00:03", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz" ], [ "20", "0", "20", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ], [ "80", "2", "70", "50", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "0", "0", "0", "0.5", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ] ]
"enumArrays" : [ [ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "1", "1", "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "2", "2", "2", "2", "2", "2", "2", "2", "2", "2" ], [ "attenuation", "attenuation", "meter", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation" ] ],
"enumMats" : [ [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ "0", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ], [ [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "4 4", "3 4", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ] ] ],
"modArrays" : [ [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "Noise", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO", "LFO" ], [ "1", "3", "4", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "SawDown", "Custom", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine" ], [ "Sine Int.", "Rand", "Rand", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int.", "Sine Int." ], [ "metriclarity", "attenuation", "meter", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE", "NONE" ], [ "2s", "0.3hz", "1.3.0", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz", "1hz" ], [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ], [ "3", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ], [ 0.298999999999978, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 0.492543640556194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] ]
}
}
@@ -320,7 +531,7 @@
"numinlets" : 2,
"numoutlets" : 5,
"outlettype" : [ "dictionary", "", "", "", "" ],
"patching_rect" : [ 773.0, 808.0, 166.0, 22.0 ],
"patching_rect" : [ 778.0, 923.0, 166.0, 22.0 ],
"saved_object_attributes" : {
"embed" : 1,
"legacy" : 1,
@@ -352,7 +563,7 @@
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"patching_rect" : [ 980.368419170379639, 702.0, 22.0, 22.0 ],
"patching_rect" : [ 989.0, 831.0, 22.0, 22.0 ],
"text" : "t b"
}
@@ -375,7 +586,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 137.5, 440.0, 246.0, 66.0 ],
"patching_rect" : [ 137.0, 377.0, 246.0, 64.0 ],
"text" : "this param is sent in its already enumerated form, so it will first be turned into a number halfway between the enumeration boundaries"
}
@@ -387,7 +598,7 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 22.0, 444.0, 115.0, 22.0 ],
"patching_rect" : [ 21.0, 381.0, 115.0, 22.0 ],
"text" : "param 4 meter \"4 4\""
}
@@ -399,8 +610,8 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 949.0, 647.0, 156.0, 22.0 ],
"text" : "meter 3 4"
"patching_rect" : [ 924.0, 748.0, 156.0, 22.0 ],
"text" : "meter 4 4"
}
}
@@ -411,8 +622,8 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 824.0, 647.0, 101.0, 22.0 ],
"text" : "attenuation 200"
"patching_rect" : [ 799.0, 748.0, 101.0, 22.0 ],
"text" : "attenuation 1"
}
}
@@ -423,8 +634,8 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 662.0, 647.0, 157.0, 22.0 ],
"text" : "scale minor"
"patching_rect" : [ 627.0, 754.0, 157.0, 22.0 ],
"text" : "attenuation 0.783634"
}
}
@@ -432,11 +643,11 @@
"box" : {
"id" : "obj-27",
"maxclass" : "newobj",
"numinlets" : 3,
"numoutlets" : 3,
"outlettype" : [ "", "", "" ],
"patching_rect" : [ 423.5, 588.0, 133.0, 22.0 ],
"text" : "routepass saved debug"
"numinlets" : 4,
"numoutlets" : 4,
"outlettype" : [ "", "", "", "" ],
"patching_rect" : [ 432.0, 594.0, 177.0, 22.0 ],
"text" : "routepass saved NNdata debug"
}
}
@@ -447,7 +658,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 504.0, 546.5, 268.0, 34.0 ],
"patching_rect" : [ 504.0, 546.5, 268.0, 33.0 ],
"text" : "we can only output symbols from jweb, so this turns them into lists"
}
@@ -471,7 +682,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 548.52631402015686, 80.0, 150.0, 34.0 ],
"patching_rect" : [ 548.52631402015686, 80.0, 150.0, 33.0 ],
"text" : "see below for why we use separate names..."
}
@@ -483,7 +694,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 781.0, 17.0, 150.0, 48.0 ],
"patching_rect" : [ 707.0, 15.0, 150.0, 47.0 ],
"text" : "self explanatory. Warning-will overwrite whatever is saved."
}
@@ -495,35 +706,10 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 1261.315790414810181, 47.0, 78.0, 103.0 ],
"patching_rect" : [ 1261.315790414810181, 47.0, 78.0, 100.0 ],
"text" : "You can use the `phase` control to phase offset two LFOs of the same frequency"
}
}
, {
"box" : {
"bubble" : 1,
"id" : "obj-7",
"linecount" : 5,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 161.5, 261.0, 197.0, 79.0 ],
"text" : "This parameter is defined in the enumerators but not the modulators. It will be enumerated and immediately output"
}
}
, {
"box" : {
"id" : "obj-5",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 59.0, 256.0, 104.0, 22.0 ],
"text" : "param 2 scale 1.6"
}
}
, {
"box" : {
@@ -533,7 +719,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 159.0, 347.0, 254.0, 52.0 ],
"patching_rect" : [ 114.0, 279.0, 254.0, 51.0 ],
"text" : "This parameter is not defined by either the Modulators or Enumerators, so it will be passed directly to the output"
}
@@ -546,7 +732,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 159.0, 190.0, 197.0, 66.0 ],
"patching_rect" : [ 167.0, 180.0, 197.0, 64.0 ],
"text" : "This parameter is defined in the modulators, and when sent will act as the center value for that LFO"
}
@@ -558,7 +744,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 59.0, 634.0, 254.0, 158.0 ],
"patching_rect" : [ 59.0, 634.0, 254.0, 154.0 ],
"text" : "The operation runs\n\nInput > Denumeration > Modulators > Enumerators > Output\n\nA parameter from the input not established by a Modulator will be passed directly to the Enumerators\n\nLikewise, the Enumerators will pass not established parameters"
}
@@ -582,7 +768,7 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 28.0, 331.0, 139.0, 22.0 ],
"patching_rect" : [ 37.0, 253.0, 139.0, 22.0 ],
"text" : "param 3 attenuation 200"
}
@@ -606,7 +792,7 @@
"numinlets" : 2,
"numoutlets" : 5,
"outlettype" : [ "dictionary", "", "", "", "" ],
"patching_rect" : [ 980.368419170379639, 726.0, 97.0, 22.0 ],
"patching_rect" : [ 989.0, 855.0, 97.0, 22.0 ],
"saved_object_attributes" : {
"embed" : 0,
"legacy" : 1,
@@ -625,7 +811,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 504.0, 6.0, 150.0, 34.0 ],
"patching_rect" : [ 309.0, 6.0, 150.0, 33.0 ],
"text" : "required due to the asynchronous operation"
}
@@ -637,7 +823,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 773.0, 692.0, 150.0, 117.0 ],
"patching_rect" : [ 786.0, 797.0, 150.0, 114.0 ],
"text" : "Storage for the matrix. Unfortunately, jsweb dictionary handling isn't great, so we can't use it like a native dict object and need to do this wild hack for usage with pattrstorage"
}
@@ -685,7 +871,7 @@
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 402.0, 173.0, 838.631580829620361, 368.0 ],
"patching_rect" : [ 397.0, 180.0, 838.631580829620361, 368.0 ],
"rendermode" : 0,
"url" : "file://lfogui.html"
}
@@ -712,6 +898,13 @@
"source" : [ "obj-12", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-13", 0 ]
}
}
, {
"patchline" : {
@@ -763,6 +956,20 @@
"source" : [ "obj-22", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-25", 0 ],
"source" : [ "obj-26", 1 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-31", 0 ],
"source" : [ "obj-27", 1 ]
}
}
, {
"patchline" : {
@@ -774,14 +981,42 @@
, {
"patchline" : {
"destination" : [ "obj-63", 0 ],
"source" : [ "obj-27", 3 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-7", 1 ],
"source" : [ "obj-27", 2 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-66", 0 ],
"source" : [ "obj-27", 1 ]
"destination" : [ "obj-47", 0 ],
"source" : [ "obj-28", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-47", 0 ],
"source" : [ "obj-29", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-3", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-51", 0 ],
"source" : [ "obj-31", 0 ]
}
}
@@ -809,7 +1044,7 @@
, {
"patchline" : {
"destination" : [ "obj-15", 0 ],
"order" : 3,
"order" : 2,
"source" : [ "obj-37", 0 ]
}
@@ -825,7 +1060,7 @@
, {
"patchline" : {
"destination" : [ "obj-22", 0 ],
"order" : 5,
"order" : 4,
"source" : [ "obj-37", 0 ]
}
@@ -837,19 +1072,11 @@
"source" : [ "obj-37", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-5", 0 ],
"order" : 2,
"source" : [ "obj-37", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-8", 0 ],
"order" : 4,
"order" : 3,
"source" : [ "obj-37", 0 ]
}
@@ -876,6 +1103,13 @@
"source" : [ "obj-40", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-44", 0 ]
}
}
, {
"patchline" : {
@@ -886,8 +1120,8 @@
}
, {
"patchline" : {
"destination" : [ "obj-52", 0 ],
"source" : [ "obj-47", 4 ]
"destination" : [ "obj-3", 0 ],
"source" : [ "obj-47", 7 ]
}
}
@@ -900,15 +1134,8 @@
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-5", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-52", 0 ]
"destination" : [ "obj-44", 0 ],
"source" : [ "obj-51", 0 ]
}
}
@@ -974,13 +1201,6 @@
"source" : [ "obj-8", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-85", 0 ]
}
}
, {
"patchline" : {

View File

@@ -1,5 +1,9 @@
html,
body {
* {
--locked-color: #5fadbf;
--unlocked-color: #ff5153;
}
html, body {
width: 100%;
height: 100%;
margin: 0px;
@@ -179,3 +183,90 @@ html,
#pulse {
animation: pulse-animation 0.2s normal;
}
/* :::::::::::::: LOCK CSS */
.locked-component {
pointer-events: none;
background-color: #333333;
color : white;
}
.container {
display: flex;
width: 100%;
justify-content: space-between;
}
/* Locked */
.lock {
margin-top: 14px;
width: 24px;
height: 21px;
border: 3px solid var(--locked-color);
border-radius: 5px;
position: relative;
cursor: pointer;
-webkit-transition: all 0.1s ease-in-out;
transition: all 0.1s ease-in-out;
}
.lock:after {
content: "";
display: block;
background: var(--locked-color);
width: 3px;
height: 7px;
position: absolute;
top: 50%;
left: 50%;
margin: -3.5px 0 0 -2px;
-webkit-transition: all 0.1s ease-in-out;
transition: all 0.1s ease-in-out;
}
.lock:before {
content: "";
display: block;
width: 10px;
height: 10px;
bottom: 100%;
position: absolute;
left: 50%;
margin-left: -8px;
border: 3px solid var(--locked-color);
border-top-right-radius: 50%;
border-top-left-radius: 50%;
border-bottom: 0;
-webkit-transition: all 0.1s ease-in-out;
transition: all 0.1s ease-in-out;
}
/* Locked Hover */
.lock:hover:before {
height: 12px;
}
/* Unlocked */
.unlocked {
transform: rotate(10deg);
}
.unlocked:before {
bottom: 130%;
left: 31%;
margin-left: -11.5px;
transform: rotate(-45deg);
}
.unlocked,
.unlocked:before {
border-color: var(--unlocked-color);
}
.unlocked:after {
background: var(--unlocked-color);
}
/* Unlocked Hover */
.unlocked:hover {
transform: rotate(3deg);
}
.unlocked:hover:before {
height: 10px;
left: 40%;
bottom: 124%;
transform: rotate(-30deg);
}

193
lfogui.js
View File

@@ -20,6 +20,11 @@ const ViewModes = Object.freeze({
ENUM: 1
});
const LockModes = Object.freeze({
UNLOCK: 0,
LOCK: 1
});
var modPhases = Array(MAXLFOS).fill(0);
var firstUpdateTime = Date.now();
@@ -28,6 +33,30 @@ const MODULATORLABELS = ["inst", "-type-", "---shape---", "-------param-------",
const ENUMERATORLABELS = ["inst", "---parameter---", "-# points-"];
function parseLfoTimeNonMusical(lfoTime){
if (lfoTime.slice(-2) == "hz"){
return parseFloat(lfoTime.slice(0, -2));
}
else if (lfoTime.slice(-2) == "ms"){
return 1000 / parseFloat(lfoTime.slice(0, -2));
}
else if (lfoTime.slice(-1) == "s"){
return 1 / parseFloat(lfoTime.slice(0, -1));
}
else if ((lfoTime.match(/:/g) || []).length == 2){
return 1 / moment.duration(lfoTime).asSeconds();
}
else if ((lfoTime.match(/\./g) || []).length == 2){
return 0; // ignore musical timings
}
else {
return 0;
}
}
function nnFreqToHzString(num){
return `${num}hz`;
}
function MasterLfoHandler(){
@@ -43,18 +72,28 @@ function MasterLfoHandler(){
setViewMode(ViewModes.MOD);
};
const [lockMode, setLockMode] = React.useState(LockModes.LOCK);
const toggleLockMode = () => {
if (lockMode === LockModes.UNLOCK)
setLockMode(LockModes.LOCK);
else
setLockMode(LockModes.UNLOCK);
};
/// MODULATOR ARRAYS
const [userDefinedWave, setUserDefinedWave] = React.useState(Array(50).fill(0));
const [modVisibleArr, setModVisibleArr] = React.useState(initVisArr);
const [modTypeArr, setModTypeArr] = React.useState(Array(MAXLFOS).fill('LFO'));
const [modInstanceNumArr, setModInstanceNumArr] = React.useState(Array(MAXLFOS).fill('1'));
const [modCenterVals, setModCenterVals] = React.useState({'1':{}, '2':{}, '3':{}, '4':{}});
const [bpm, setBpm] = React.useState(100);
const [ticks, setTicks] = React.useState(0);
const [beatsInMeasure, setBeatsInMeasure] = React.useState(4);
const [noiseTypeArr, setNoiseTypeArr] = React.useState(Array(MAXLFOS).fill('Sine Int.'));
const [shapeArr, setShapeArr] = React.useState(Array(MAXLFOS).fill('Sine'));
const [djParamArr, setDjParamArr] = React.useState(Array(MAXLFOS).fill('NONE'));
@@ -64,23 +103,28 @@ function MasterLfoHandler(){
const [minArr, setMinArr] = React.useState(Array(MAXLFOS).fill('0'));
const [maxArr, setMaxArr] = React.useState(Array(MAXLFOS).fill('1'));
const [phaseArr, setPhaseArr] = React.useState(Array(MAXLFOS).fill('0'));
const [initPhaseArr, setInitPhaseArr] = React.useState(Array(MAXLFOS).fill('0'));
const [lastPhaseArr, setLastPhaseArr] = React.useState(Array(MAXLFOS).fill(0));
const [cachedNoiseValueArr1, setCachedNoiseValueArr1] = React.useState(Array(MAXLFOS).fill(0));
const [cachedNoiseValueArr2, setCachedNoiseValueArr2] = React.useState(Array(MAXLFOS).fill(0));
const allModArrays = [modVisibleArr, modInstanceNumArr, shapeArr, djParamArr, freqArr, minArr, maxArr, phaseArr];
const allModSetters = [setModVisibleArr, setModInstanceNumArr, setShapeArr, setDjParamArr, setFreqArr, setMinArr, setMaxArr, setPhaseArr];
const modBlankVals = [true, '1', SHAPETYPES[0], MODPARAMOPTIONS[0], '1hz', '0', '1', '0'];
const allModArrays = [modVisibleArr, modTypeArr, modInstanceNumArr, shapeArr, noiseTypeArr, djParamArr, freqArr, minArr, maxArr, initPhaseArr, lastPhaseArr, cachedNoiseValueArr1, cachedNoiseValueArr2];
const allModSetters = [setModVisibleArr, setModTypeArr, setModInstanceNumArr, setShapeArr, setNoiseTypeArr, setDjParamArr, setFreqArr, setMinArr, setMaxArr, setInitPhaseArr, setLastPhaseArr, setCachedNoiseValueArr1, setCachedNoiseValueArr2];
const modBlankVals = [true, 'LFO', '1', SHAPETYPES[0], NOISETYPES[0], MODPARAMOPTIONS[0], '1hz', '0', '1', '0', 0, 0, 0];
/// ENUMERATOR ARRAYS
const [enumVisibleArr, setEnumVisibleArr] = React.useState(initVisArr);
const [enumInstanceNumArr, setEnumInstanceNumArr] = React.useState(Array(MAXLFOS).fill('1'));
const [enumItemCounts, setEnumItemCounts] = React.useState(Array(MAXENUMPOINTS).fill('2'));
const [enumDjParamArr, setEnumDjParamArr] = React.useState(Array(MAXENUMPOINTS).fill('attenuation'));
const [enumDjParamArr, setEnumDjParamArr] = React.useState(Array(MAXENUMPOINTS).fill('NONE'));
let baseEnumBreakpoints = Array(MAXENUMS).fill(0).map(x => Array(MAXENUMPOINTS+ 1).fill(0));
for (let i = 0; i < MAXENUMS; i++){
for (let j=0; j < MAXENUMPOINTS + 1; j++){
baseEnumBreakpoints[i][j] = j;
baseEnumBreakpoints[i][j] = j - 0.5;
}
}
const [enumBreakPoints, setEnumBreakPoints] = React.useState(baseEnumBreakpoints);
@@ -88,7 +132,7 @@ function MasterLfoHandler(){
const getBlankEnumBreakPointRow = () => {
let arr = []
for (let i=0; i< MAXENUMPOINTS + 1; i++)
arr.push(i)
arr.push(i - 0.5)
return arr;
}
@@ -112,17 +156,14 @@ function MasterLfoHandler(){
React.useEffect(() => {
function handleLoad(event) {
window.max.getDict(event.detail, (dict) => {
for (let i = 0; i<allModArrays.length; i++) {
for (let i = 0; i<dict.data.modArrays.length; i++) {
allModSetters[i](dict.data.modArrays[i]);
}
for (let i = 0; i<allEnumArrays.length; i++) {
allEnumArrSetters[i](dict.data.enumArrays[i]);
}
for (let i = 0; i<allEnumMats.length; i++) {
allEnumMatSetters[i](dict.data.enumMats[i]);
}
@@ -200,11 +241,8 @@ function MasterLfoHandler(){
function handleTick(event) {
let time = (Date.now() - firstUpdateTime) / 1000;
operateModulators(modVisibleArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, phaseArr, userDefinedWave, time, bpm, beatsInMeasure);
}
function handleBpm(event) {
setBpm(event.detail);
let noiseData = {lastPhaseArr, setLastPhaseArr, cachedNoiseValueArr1, setCachedNoiseValueArr1, cachedNoiseValueArr2, setCachedNoiseValueArr2, noiseTypeArr};
operateModulators(modVisibleArr, modTypeArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, initPhaseArr, noiseData, userDefinedWave, time, beatsInMeasure, ticks);
}
function handleTimeSig(event) {
@@ -215,27 +253,92 @@ function MasterLfoHandler(){
setUserDefinedWave(event.detail);
}
function handleMaxTicks(event){
setTicks(event.detail);
}
function setNN(event){
for (let i=0; i<MAXLFOS; i++){
freqArr[i] = nnFreqToHzString(event.detail[i]);
}
setFreqArr(freqArr)
for (let i=MAXLFOS; i<MAXLFOS * 2; i++){
minArr[i - MAXLFOS] = event.detail[i];
}
setMinArr(minArr);
for (let i=MAXLFOS*2; i<MAXLFOS * 3; i++){
maxArr[i - MAXLFOS*2] = event.detail[i];
}
setMaxArr(maxArr);
for (let i=MAXLFOS*3; i<MAXLFOS * 4; i++){
initPhaseArr[i - MAXLFOS*3] = parseFloat(event.detail[i]);
}
setInitPhaseArr(initPhaseArr);
for (let i=MAXLFOS*4; i<MAXLFOS * 5; i++){
let index = i - MAXLFOS*4;
let inst = modInstanceNumArr[index];
let param = djParamArr[index];
modCenterVals[inst][param] = parseFloat(event.detail[i]);
}
setModCenterVals(modCenterVals);
rerender(!render); // BAD! SHOULD NOT BE DOING THIS!
}
function dumpNN(event){
let allNNData = [];
freqArr.forEach(element => {
allNNData.push(parseLfoTimeNonMusical(element));
});
allNNData = allNNData.concat(minArr);
allNNData = allNNData.concat(maxArr);
allNNData = allNNData.concat(initPhaseArr);
let lfoMatchedCenterVals = [];
for (let i=0; i<MAXLFOS; i++){
let inst = modInstanceNumArr[i];
let param = djParamArr[i];
lfoMatchedCenterVals.push(modCenterVals[inst][param]);
if (!lfoMatchedCenterVals[i])
lfoMatchedCenterVals[i] = 0
}
allNNData = allNNData.concat(lfoMatchedCenterVals);
window.max.outlet("NNdata " + allNNData.join(" "));
}
window.addEventListener('loadDict', handleLoad);
window.addEventListener('saveDict', handleSave);
window.addEventListener('dumpNN', dumpNN);
window.addEventListener('setNN', setNN);
window.addEventListener('tick', handleTick);
window.addEventListener('param', handleParam);
window.addEventListener('enum', handleEnum);
window.addEventListener('tempo', handleBpm);
window.addEventListener('timesig', handleTimeSig);
window.addEventListener('userWave', handleChangeUserWave);
window.addEventListener('maxTicks', handleMaxTicks);
return () => {
window.removeEventListener('loadDict', handleLoad);
window.removeEventListener('saveDict', handleSave);
window.removeEventListener('dumpNN', dumpNN);
window.removeEventListener('setNN', setNN);
window.removeEventListener('tick', handleTick);
window.removeEventListener('param', handleParam);
window.removeEventListener('enum', handleEnum);
window.removeEventListener('tempo', handleBpm);
window.removeEventListener('timesig', handleTimeSig);
window.removeEventListener('userWave', handleChangeUserWave);
window.removeEventListener('maxTicks', handleMaxTicks);
};
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, modCenterVals, render, bpm, beatsInMeasure]);
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, userDefinedWave, modCenterVals, render, beatsInMeasure, ticks]);
function CheckLinked(inst, param, checkInstArr, checkParamArr){
@@ -256,10 +359,17 @@ function MasterLfoHandler(){
modContents.push(
e(LfoRow, {
locked : lockMode,
instanceNum : modInstanceNumArr[i],
setInstanceNum: CreateParamChanger(modInstanceNumArr, setModInstanceNumArr, i),
type: modTypeArr[i],
setType: CreateParamChanger(modTypeArr, setModTypeArr, i),
shape: shapeArr[i],
setShape: CreateParamChanger(shapeArr, setShapeArr, i),
noise: noiseTypeArr[i],
setNoise: CreateParamChanger(noiseTypeArr, setNoiseTypeArr, i),
djParam: djParamArr[i],
setDjParam: CreateParamChanger(djParamArr, setDjParamArr, i),
centerVals: modCenterVals,
@@ -275,13 +385,15 @@ function MasterLfoHandler(){
max: maxArr[i],
setMax: CreateParamChanger(maxArr, setMaxArr, i),
phase: phaseArr[i],
setPhase: CreateParamChanger(phaseArr, setPhaseArr, i),
phase: initPhaseArr[i],
setPhase: CreateParamChanger(initPhaseArr, setInitPhaseArr, i),
visible: modVisibleArr[i],
linked: CheckLinked(modInstanceNumArr[i], djParamArr[i], enumInstanceNumArr, enumDjParamArr),
addLfo: () => {
if (id < MAXLFOS - 1){
if (modVisibleArr[id + 1]){
let emptyIndex = modVisibleArr.findIndex((item) => !item);
@@ -297,6 +409,7 @@ function MasterLfoHandler(){
}
}
else {
for (var j = 0; j < allModArrays.length; j++){ // no space below, easy.
let array = allModArrays[j];
array[id + 1] = modBlankVals[j];
@@ -304,6 +417,7 @@ function MasterLfoHandler(){
}
}
rerender(!render);
}
},
removeLfo: () => {
@@ -328,7 +442,7 @@ function MasterLfoHandler(){
enumContents.push(
e(EnumeratorRow, {
index: i,
locked : lockMode,
instanceNum : enumInstanceNumArr[i],
setInstanceNum: CreateParamChanger(enumInstanceNumArr, setEnumInstanceNumArr, i),
enumItems: enumItemCounts[i],
@@ -410,8 +524,19 @@ function MasterLfoHandler(){
labels = ENUMERATORLABELS;
}
let lockClass;
if (lockMode == LockModes.LOCK){
lockClass = 'lock';
}
else {
lockClass = 'lock unlocked';
}
return e('div', null,
e('div', {className: 'container'},
e(Switch, {ontoggle: toggleViewMode}, null),
e('span', {className: lockClass, onClick: toggleLockMode}, null)),
e('h5', null, title),
e('ul', null, ...labels.map(x => ListItem(Label(x)))),
e('div', {id: 'grid'}, ...grid)
@@ -427,29 +552,31 @@ if (!DEBUG){
window.dispatchEvent(new CustomEvent('saveDict', {'detail' : dictId}));
});
window.max.bindInlet("dumpNN", () => {
window.dispatchEvent(new CustomEvent('dumpNN'));
});
window.max.bindInlet("setNN", (...data) => {
window.dispatchEvent(new CustomEvent('setNN', {'detail' : data}));
});
window.max.bindInlet("param", (inst, paramName, val) => {
window.dispatchEvent(new CustomEvent('param', {'detail' : [inst, paramName, val]}));
});
window.max.bindInlet("tempo", (val) => {
window.dispatchEvent(new CustomEvent('tempo', {'detail' : val}));
});
window.max.bindInlet("timesig", (top, bottom) => {
window.dispatchEvent(new CustomEvent('timesig', {'detail' : [top, bottom]}));
});
window.max.bindInlet("ticks", (val) => {
window.dispatchEvent(new CustomEvent('maxTicks', {'detail' : val}));
});
window.max.bindInlet("userWave", (...points) => {
window.dispatchEvent(new CustomEvent('userWave', {'detail' : points}));
});
/* window.max.binInlet("userWave", (...points) => {
window.dispatchEvent(new CustomEvent('userWave', {'detail' : [points]}));
log("received user points");
}); */
setInterval(() => {
window.dispatchEvent(new CustomEvent('tick'));
}, 200);

View File

@@ -2,7 +2,10 @@
// MODULATORS
/////////////////////////
var TYPEOPTIONS = ["LFO", "Noise"];
var SHAPETYPES = ["Sine", "SawUp", "SawDown", "Tri", "Square", "Custom"];
var NOISETYPES = ["Rand", "Line Int.", "Sine Int."]
var INSTANCEOPTIONS = ["1", "2", "3", "4"];
@@ -10,6 +13,11 @@ const MODPARAMOPTIONS = ["NONE", "stream", "pulse_length", "eventfulness", "even
"harmoniclarity", "melodic_cohesion", "melody_scope", "tonic_pitch", "pitch_center", "pitch_range", "dynamics",
"attenuation", "chordal_weight", "tonality-profile", "ostinato-buffer", "ostinato", "meter", "scale"];
const PhaseTypes = Object.freeze({
MUSICAL: Symbol("musical"),
TIME: Symbol("time")
});
function ControlType(){
return e('select', {className: 'control-type'}, Option("LFO"));
}
@@ -23,11 +31,20 @@ function LfoRow(props){
if (!center)
center = 0;
let typeOption = null;
if (props.type == "LFO"){
typeOption = ListItem(DropDown({locked:props.locked, onChange: props.setShape, value:props.shape, options: SHAPETYPES}));
}
else if (props.type == "Noise"){
typeOption = ListItem(DropDown({locked:props.locked, onChange: props.setNoise, value:props.noise, options: NOISETYPES}));
}
let content = e('ul', {className: 'lfo-item'},
ListItem(DropDown({onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
ListItem(ControlType()),
ListItem(DropDown({onChange: props.setShape, value:props.shape, options: SHAPETYPES})),
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
ListItem(DropDown({locked:props.locked, onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
ListItem(DropDown({locked:props.locked, options: TYPEOPTIONS, onChange: props.setType, value:props.type})),
typeOption,
ListItem(DropDown({locked:props.locked, onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
ListItem(e("input", {onChange:props.setFreq, value:props.freq, className:"timeInput"}, null)),
ListItem(e(NumberBox, {onChange:props.setMin, value:props.min, step:0.1}, null)),
ListItem(e(NumberBox, {onChange:props.setMax, value:props.max, step:0.1}, null)),
@@ -35,8 +52,8 @@ function LfoRow(props){
ListItem(e(NumberBox, {onChange:props.setPhase, value:props.phase, step:0.1}, null)),
ListItem(e("div", {className:"base-val"}, center.toString())),
ListItem(e("input", {type: 'range', min: 0, max: 1, step: 0.01, readonly: true, id: `slider-${props.instanceNum}-${props.djParam}`})),
ListItem(e(Button, {text:'+', onClick: props.addLfo}, null)),
ListItem(e(Button, {text:'-', onClick: props.removeLfo}, null)),
ListItem(e(Button, {text:'+', onClick: props.addLfo, locked: props.locked}, null)),
ListItem(e(Button, {text:'-', onClick: props.removeLfo, locked: props.locked}, null)),
ListItem(e("div", {className:"linked"}, linkedText)),
);
if (props.visible){
@@ -61,7 +78,7 @@ function indexWave(type, phase, userDefinedWave){
}
}
function operateModulators(visibleArr, instanceNumArr, paramNames, centers, freqs, mins, maxs, waveTypes, phaseArr, userDefinedWave, currTime, bpm, beatsInMeasure){
function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, centers, freqs, mins, maxs, waveTypes, phaseArr, noiseData, userDefinedWave, currTime, beatsInMeasure, ticks){
for (let i=0; i<paramNames.length; i++){
if (visibleArr[i]){
@@ -71,54 +88,126 @@ function operateModulators(visibleArr, instanceNumArr, paramNames, centers, freq
if (centers[inst].hasOwnProperty(name)){
center = centers[inst][name];
}
let output = operateModulator(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWave, name, currTime, bpm, beatsInMeasure);
let output = 0;
if (typeArr[i] == "LFO")
output = operateLFO(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWave, name, currTime, beatsInMeasure, ticks);
else
output = operateNoise(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, name, noiseData, currTime, beatsInMeasure, ticks);
if (name !== "NONE")
window.dispatchEvent(new CustomEvent('enum', {'detail' : [inst, name, output]}));
}
}
}
function operateModulator(center, inst, freq, min, max, waveType, phaseArr, phaseI, userDefinedWave, name, currTime, bpm, beatsInMeasure){
function operateLFO(center, inst, timeBaseStr, min, max, waveType, phaseArr, phaseIndex, userDefinedWave, name, currTime, beatsInMeasure, maxTicks){
let amp = parseFloat(max) - parseFloat(min);
let phaseType;
let timeBase;
freq = parseLfoTime(freq, bpm, beatsInMeasure);
let phase = (currTime * freq + parseFloat(phaseArr[phaseI])) % 1.00;
[timeBase, phaseType] = parseLfoTime(timeBaseStr, beatsInMeasure);
let phase;
if (phaseType === PhaseTypes.TIME)
phase = (currTime * timeBase + parseFloat(phaseArr[phaseIndex])) % 1.00;
else if (phaseType === PhaseTypes.MUSICAL)
phase = (maxTicks % timeBase) / timeBase;
let unscaled = indexWave(waveType, phase, userDefinedWave);
let el = document.getElementById(`slider-${inst}-${name}`);
if (el)
el.value = unscaled;
syncDisplay(inst, name, unscaled);
return unscaled * amp + center + parseFloat(min);
}
function syncDisplay(inst, name, val) {
let el = document.getElementById(`slider-${inst}-${name}`);
function parseLfoTime(lfoTime, bpm, beatsInMeasure){
if (el)
el.value = val;
}
// For now, we're only using sine interpolation
function operateNoise(center, inst, timeBaseStr, min, max, waveType, phaseArr, index, name, noiseData, currTime, beatsInMeasure, maxTicks){
let amp = parseFloat(max) - parseFloat(min);
let phaseType;
let timeBase;
let noiseType = noiseData.noiseTypeArr[index];
[timeBase, phaseType] = parseLfoTime(timeBaseStr, beatsInMeasure);
let phase;
if (phaseType === PhaseTypes.TIME)
phase = (currTime * timeBase + parseFloat(phaseArr[index])) % 1.00;
else if (phaseType === PhaseTypes.MUSICAL)
phase = (maxTicks % timeBase) / timeBase;
if (noiseData.cachedNoiseValueArr1[index] == 0 || noiseData.lastPhaseArr[index] > phase){ // occurs if the phase reset to 0 or at the very start
noiseData.cachedNoiseValueArr2[index] = noiseData.cachedNoiseValueArr1[index];
if (noiseData.cachedNoiseValueArr1[index] == 0)
noiseData.cachedNoiseValueArr2[index] = center;
noiseData.cachedNoiseValueArr1[index] = Math.random();
noiseData.setCachedNoiseValueArr1(noiseData.cachedNoiseValueArr1);
noiseData.setCachedNoiseValueArr2(noiseData.cachedNoiseValueArr2);
}
noiseData.lastPhaseArr[index] = phase;
noiseData.setLastPhaseArr(noiseData.lastPhaseArr);
//let unscaled = (noiseData.cachedNoiseValueArr[index][1] - noiseData.cachedNoiseValueArr[index][0]) * sinePhase + noiseData.cachedNoiseValueArr[index][0];
let unscaled = interpolateNoise(noiseType, noiseData.cachedNoiseValueArr1[index], noiseData.cachedNoiseValueArr2[index], phase);
syncDisplay(inst, name, unscaled);
return unscaled * amp + center + parseFloat(min);
}
function interpolateNoise(type, cachedVal1, cachedVal2, phase){
let interpVal;
switch (type){
case "Sine Int.":
interpVal = (Math.sin(Math.PI + Math.PI * phase) + 1) / 2;
break;
case "Rand":
interpVal = 0;
break;
case "Line Int.":
interpVal = phase;
break;
}
return (cachedVal2 - cachedVal1) * interpVal + cachedVal1;
}
// actual returns the period for musical timing, to avoid floating point errors
function parseLfoTime(lfoTime, beatsInMeasure){
if (lfoTime.slice(-2) == "hz"){
return parseFloat(lfoTime.slice(0, -2));
return [parseFloat(lfoTime.slice(0, -2)), PhaseTypes.TIME];
}
else if (lfoTime.slice(-2) == "ms"){
return 1000 / parseFloat(lfoTime.slice(0, -2));
return [1000 / parseFloat(lfoTime.slice(0, -2)), PhaseTypes.TIME];
}
else if (lfoTime.slice(-1) == "s"){
return 1 / parseFloat(lfoTime.slice(0, -1));
return [1 / parseFloat(lfoTime.slice(0, -1)), PhaseTypes.TIME];
}
else if ((lfoTime.match(/:/g) || []).length == 2){
return 1 / moment.duration(lfoTime).asSeconds();
return [1 / moment.duration(lfoTime).asSeconds(), PhaseTypes.TIME];
}
else if ((lfoTime.match(/\./g) || []).length == 2){
return musicalTimingToFreq(...lfoTime.split('.'), bpm, beatsInMeasure)
return [musicalTimingToFreq(...lfoTime.split('.'), beatsInMeasure), PhaseTypes.MUSICAL];
}
else {
return 0;
return [0, PhaseTypes.TIME];
}
}
function musicalTimingToFreq(bars, beats, ticks, bpm, beatsInMeasure){
let totalTicks = (parseFloat(bars) * parseFloat(beatsInMeasure) + beats) * 480 + parseFloat(ticks);
let tpm = bpm * 480;
let cyclesPerMinute = tpm / totalTicks;
let hz = cyclesPerMinute / 60;
return hz;
function musicalTimingToFreq(bars, beats, ticks, beatsInMeasure){
let totalTicks = (parseFloat(bars) * parseFloat(beatsInMeasure) + parseFloat(beats)) * 480 + parseFloat(ticks);
return totalTicks;
}