Compare commits
41 Commits
149d1a0b8d
...
directory-
| Author | SHA1 | Date | |
|---|---|---|---|
| 53a88ca374 | |||
| 7f464366af | |||
| 51420cbd5f | |||
| 533de4668a | |||
| b850440287 | |||
| 7ac026f35f | |||
| 7cb4180d97 | |||
| 51767ff058 | |||
|
|
fe68764e7d | ||
|
|
40d0927a0e | ||
|
|
92b7545e90 | ||
|
|
4912b398dd | ||
|
|
02d5c6e914 | ||
| 13f3a18c4c | |||
| f21220e7b2 | |||
| fe165b77e5 | |||
|
|
a7b0de9e66 | ||
| 43d37f215f | |||
|
|
c1a0a4d919 | ||
| e2f33b8ba7 | |||
| a19717a759 | |||
| 64da80b742 | |||
|
|
34549daf67 | ||
|
|
dd47c0b030 | ||
| 0b7dbbb775 | |||
| 290ff73524 | |||
| 9b1a9f2e03 | |||
| 541ab6d459 | |||
| b96f2aa53b | |||
| edcddde844 | |||
| e41567c101 | |||
| 8002ae8bdb | |||
| 286a43b0b2 | |||
| 229ddb9c37 | |||
| bbcfd8faab | |||
| 5d092a607c | |||
| de28fd87fa | |||
|
|
07c4826bd9 | ||
|
|
501fca079e | ||
|
|
3507899eb3 | ||
|
|
dc2daade1b |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.DS_Store
|
||||
1740
ModEnum.maxhelp
Normal file
1740
ModEnum.maxhelp
Normal file
File diff suppressed because it is too large
Load Diff
3345
ModEnum.maxpat
Normal file
3345
ModEnum.maxpat
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
1286
example.maxpat
1286
example.maxpat
File diff suppressed because it is too large
Load Diff
272
lfogui.css
272
lfogui.css
@@ -1,272 +0,0 @@
|
||||
* {
|
||||
--locked-color: #5fadbf;
|
||||
--unlocked-color: #ff5153;
|
||||
}
|
||||
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
border: 0;
|
||||
overflow: hidden; /* Disable scrollbars */
|
||||
display: block; /* No floating content on sides */
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
input[type=number] {
|
||||
width: 50px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 60px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.timeInput {
|
||||
width: 80px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#matrix {
|
||||
background-color: aquamarine;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.numbox-unclicked {
|
||||
user-select: none;
|
||||
border: solid;
|
||||
font-size: 12vw;
|
||||
}
|
||||
|
||||
.numbox-clicked {
|
||||
user-select: none;
|
||||
border : solid;
|
||||
font-size: 12vw;
|
||||
}
|
||||
|
||||
.param-input-label {
|
||||
width: 93%;
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
.lfo-input-label {
|
||||
width: 40%;
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
/* The switch - the box around the slider */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: #ccc;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
.slider:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
height: 13px;
|
||||
width: 13px;
|
||||
left: 2px;
|
||||
bottom: 2px;
|
||||
background-color: white;
|
||||
-webkit-transition: .4s;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
input:checked + .slider {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
input:focus + .slider {
|
||||
box-shadow: 0 0 1px #2196F3;
|
||||
}
|
||||
|
||||
input:checked + .slider:before {
|
||||
-webkit-transform: translateX(13px);
|
||||
-ms-transform: translateX(13px);
|
||||
transform: translateX(13px);
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
.slider.round {
|
||||
border-radius: 17px;
|
||||
}
|
||||
|
||||
.slider.round:before {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.enum-count {
|
||||
background-color: aquamarine;
|
||||
}
|
||||
|
||||
.label {
|
||||
background-color: aliceblue;
|
||||
padding: 0 4px 0 4px;
|
||||
margin: 0 2px 0 2px;
|
||||
border-color: #333333;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.base-val {
|
||||
background-color: lightgray;
|
||||
border-color: #333333;
|
||||
border-width: 1px;
|
||||
width: 50px;
|
||||
margin-left: 2px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.linked {
|
||||
color: red;
|
||||
border-width: 1px;
|
||||
width: 50px;
|
||||
font-size: small;
|
||||
margin-left: 2px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
|
||||
@keyframes pulse-animation {
|
||||
0% {
|
||||
color: black;
|
||||
}
|
||||
100% {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
25
lfogui.html
25
lfogui.html
@@ -1,28 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<!--
|
||||
We start with a basic html 'page' that is the size of the jweb object,
|
||||
but has no scrollbars nor floating content.
|
||||
-->
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="./lfogui.css">
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="./src/lfogui.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="lfo-container"></div>
|
||||
|
||||
<script src="./react.js"></script>
|
||||
<script src="./react-dom.js"></script>
|
||||
<script src="./moment.js"></script>
|
||||
<script src="./common.js"></script>
|
||||
<script src="./enums.js"></script>
|
||||
<script src="./modulators.js"></script>
|
||||
<script src="./lfogui.js">
|
||||
|
||||
|
||||
</script>
|
||||
<script src="./lib/react.js"></script>
|
||||
<script src="./lib/react-dom.js"></script>
|
||||
<script src="./lib/moment.js"></script>
|
||||
<script src="./src/common.js"></script>
|
||||
<script src="./src/enums.js"></script>
|
||||
<script src="./src/modulators.js"></script>
|
||||
<script src="./src/lfogui.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
0
react-dom.js → lib/react-dom.js
vendored
0
react-dom.js → lib/react-dom.js
vendored
0
react.js → lib/react.js
vendored
0
react.js → lib/react.js
vendored
93
myStorage.json
Normal file
93
myStorage.json
Normal file
File diff suppressed because one or more lines are too long
@@ -43,15 +43,19 @@ function Switch(props){
|
||||
e('span', {className: 'slider round'}, null))
|
||||
}
|
||||
|
||||
function SendSaveEvent(){
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(new CustomEvent('saveDict', {'detail' : "localStorage"}));
|
||||
}, 50)
|
||||
}
|
||||
|
||||
function CreateParamChanger(arr, setArr, index, postCB=() => {}, preCB=(val) => val){
|
||||
return (event) => {
|
||||
let newArr = arr.slice();
|
||||
newArr[index] = preCB(event.target.value);
|
||||
setArr(newArr);
|
||||
postCB();
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(new CustomEvent('saveDict', {'detail' : "localStorage"}));
|
||||
}, 50)
|
||||
SendSaveEvent();
|
||||
|
||||
log(`${index} ${event.target.value}`);
|
||||
}
|
||||
@@ -64,9 +68,7 @@ function CreateMatrixParamChanger(matrix, setMatrix, i, j){
|
||||
});
|
||||
newMatrix[i][j] = event.target.value;
|
||||
setMatrix(newMatrix);
|
||||
setTimeout(() => {
|
||||
window.dispatchEvent(new CustomEvent('saveDict', {'detail' : "localStorage"}));
|
||||
}, 50)
|
||||
SendSaveEvent();
|
||||
log(`${i}, ${j} ${event.target.value}`);
|
||||
|
||||
}
|
||||
@@ -4,14 +4,18 @@
|
||||
|
||||
|
||||
|
||||
function DataCell(element) {
|
||||
return e('td', null, element);
|
||||
}
|
||||
|
||||
// NOT A REACT FUNCTIONAL COMPONENT. MERELY RETURNS AN ARRAY WHICH IS UNPACKED
|
||||
function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames, setEnumNames, djParam, locked){
|
||||
let items = [];
|
||||
for (let i = 0; i < MAXENUMPOINTS; i++){
|
||||
|
||||
items.push(ListItem(e(TextBox, {locked, onChange: CreateMatrixParamChanger(enumNames, setEnumNames, index, i), value: enumNames[index][i], id:`text-${djParam}-${enumNames[index][i]}`}, null)));
|
||||
items.push(DataCell(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, {locked, onChange: CreateMatrixParamChanger(enumBreakPoints, setEnumBreakPoints, index, i + 1), value:enumBreakPoints[index][i + 1]}, null)));
|
||||
items.push(DataCell(e(NumberBox, {locked, onChange: CreateMatrixParamChanger(enumBreakPoints, setEnumBreakPoints, index, i + 1), value:enumBreakPoints[index][i + 1]}, null)));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
@@ -19,15 +23,15 @@ function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames,
|
||||
function EnumeratorRow(props){
|
||||
let linkedText = props.linked ? "<- mods" : "";
|
||||
|
||||
let content = e('ul', {className: 'lfo-item', id: `${props.djParam}-enum-row`},
|
||||
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)),
|
||||
let content = e('tr', {className: 'lfo-item', id: `${props.djParam}-enum-row`},
|
||||
DataCell(DropDown({locked:props.locked, onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
|
||||
DataCell(DropDown({locked:props.locked, onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
|
||||
DataCell(e(NumberBox, {locked:props.locked, onChange: props.setEnumItemCounts, step:1, value:props.enumItems, className: 'enum-count'}, null)),
|
||||
DataCell(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))
|
||||
DataCell(e(Button, {locked:props.locked, text:'+', onClick: props.addEnum}, null)),
|
||||
DataCell(e(Button, {locked:props.locked, text:'-', onClick: props.removeEnum}, null)),
|
||||
DataCell(e("div", {className:"linked"}, linkedText))
|
||||
);
|
||||
if (props.visible){
|
||||
return content;
|
||||
378
src/lfogui.css
Normal file
378
src/lfogui.css
Normal file
@@ -0,0 +1,378 @@
|
||||
* {
|
||||
--locked-color: #5fadbf;
|
||||
--unlocked-color: #ff5153;
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: white;
|
||||
--active: royalblue;
|
||||
--nonactive: rgb(205, 205, 205);
|
||||
--alert: red;
|
||||
--textcolor: black;
|
||||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
|
||||
|
||||
html {
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Poppins", sans-serif;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
border: 0;
|
||||
overflow-x: scroll;
|
||||
overflow-y: scroll;
|
||||
display: block;
|
||||
/* No floating content on sides */
|
||||
}
|
||||
|
||||
/*navigation*/
|
||||
.header {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 1em;
|
||||
border-bottom: 1px solid var(--active);
|
||||
}
|
||||
|
||||
.header button {
|
||||
border: 1px solid var(--active);
|
||||
color: var(--active);
|
||||
background-color: white;
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
padding: 0.5em;
|
||||
margin: 4px;
|
||||
font-size: 0.9em;
|
||||
min-width: 4.5em;
|
||||
}
|
||||
|
||||
td button {
|
||||
background-color: white;
|
||||
color: var(--active);
|
||||
border: 1px solid var(--active);
|
||||
}
|
||||
|
||||
/* :::::::::::::: SELECTING MODULATORS/ENUMERATORS */
|
||||
|
||||
.header button.highlighted-button {
|
||||
color: var(--active);
|
||||
border: 1px solid var(--active);
|
||||
}
|
||||
|
||||
.header button.unhighlighted-button {
|
||||
color: var(--nonactive);
|
||||
border: 1px solid var(--nonactive);
|
||||
}
|
||||
|
||||
/* table */
|
||||
table {
|
||||
margin: 1em;
|
||||
padding: 0em;
|
||||
border-collapse: collapse;
|
||||
background-color: lightsteelblue;
|
||||
}
|
||||
|
||||
/* points datacells should have a min-width*/
|
||||
.enum-count {
|
||||
min-width: 5.6em;
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0.4em 0.3em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
thead {
|
||||
color: white;
|
||||
background-color: var(--active);
|
||||
}
|
||||
|
||||
tr,
|
||||
td {
|
||||
margin: 0em;
|
||||
}
|
||||
|
||||
td:last-child {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* input types */
|
||||
/* dropdown list */
|
||||
select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
option, select>* {
|
||||
font-size: 0.8em !important;
|
||||
padding: 0em !important;
|
||||
margin: 0em !important;
|
||||
min-height: 0em !important;
|
||||
}
|
||||
*/
|
||||
option {
|
||||
background-color: var(--active);
|
||||
}
|
||||
|
||||
option:not(:checked) {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
/* input */
|
||||
input,
|
||||
select {
|
||||
border: 1px solid var(--active);
|
||||
color: var(--active);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
line-height: 1.5em;
|
||||
height: 1.5em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input {
|
||||
padding-left: 5px;
|
||||
/*slight padding on left*/
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 60px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.timeInput {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#matrix {
|
||||
background-color: aquamarine;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.numbox-unclicked {
|
||||
user-select: none;
|
||||
border: solid;
|
||||
font-size: 12vw;
|
||||
}
|
||||
|
||||
.numbox-clicked {
|
||||
user-select: none;
|
||||
border: solid;
|
||||
font-size: 12vw;
|
||||
}
|
||||
|
||||
.param-input-label {
|
||||
width: 93%;
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
.lfo-input-label {
|
||||
width: 40%;
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
/* The switch - the box around the slider */
|
||||
.switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
.switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
input[type="range"] {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
height: 8px;
|
||||
border-radius: 6px;
|
||||
background-color: white;
|
||||
outline: none;
|
||||
opacity: 0.7;
|
||||
-webkit-transition: .2s;
|
||||
transition: opacity .2s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/*slider knob*/
|
||||
input[type="range"]::-webkit-slider-runnable-track {
|
||||
-webkit-appearance: none;
|
||||
color: var(--active);
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background: var(--active);
|
||||
box-shadow: -80px 0 0 80px var(--active);
|
||||
}
|
||||
|
||||
input[type="range"]::-moz-range-progress {
|
||||
background-color: var(--active);
|
||||
}
|
||||
|
||||
h5 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
background-color: aliceblue;
|
||||
padding: 0 4px 0 4px;
|
||||
margin: 0 2px 0 2px;
|
||||
border-color: #333333;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
.base-val {
|
||||
border: none;
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: 0.9em;
|
||||
width: 50px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.linked {
|
||||
color: red;
|
||||
border-width: 1px;
|
||||
width: 50px;
|
||||
font-size: small;
|
||||
margin-left: 2px;
|
||||
margin-top: 5px;
|
||||
display: none;
|
||||
/*hide*/
|
||||
}
|
||||
|
||||
|
||||
@keyframes pulse-animation {
|
||||
0% {
|
||||
color: black;
|
||||
}
|
||||
|
||||
100% {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
|
||||
#pulse {
|
||||
animation: pulse-animation 0.2s normal;
|
||||
}
|
||||
|
||||
/* :::::::::::::: LOCK CSS */
|
||||
|
||||
.locked-component {
|
||||
pointer-events: none;
|
||||
background-color: #333333;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
@@ -9,9 +9,10 @@ else
|
||||
const e = React.createElement;
|
||||
|
||||
let lfos = [];
|
||||
const MAXLFOS = 20;
|
||||
const MAXENUMS = 20;
|
||||
const MAXLFOS = 200;
|
||||
const MAXENUMS = 200;
|
||||
const MAXENUMPOINTS = 10;
|
||||
const MAXUSERDEFINED = 4;
|
||||
|
||||
|
||||
|
||||
@@ -29,8 +30,8 @@ const LockModes = Object.freeze({
|
||||
var modPhases = Array(MAXLFOS).fill(0);
|
||||
var firstUpdateTime = Date.now();
|
||||
|
||||
const MODULATORLABELS = ["inst", "-type-", "---shape---", "-------param-------", "--timebase--", "-min-", "-max", "-phase-", "center"];
|
||||
const ENUMERATORLABELS = ["inst", "---parameter---", "-# points-"];
|
||||
const MODULATORLABELS = ["inst", "type", "shape", "param", "timebase", "min", "max", "phase", "center", "result", "", ""];
|
||||
const ENUMERATORLABELS = ["inst", "parameter", "# points"];
|
||||
|
||||
|
||||
function parseLfoTimeNonMusical(lfoTime) {
|
||||
@@ -64,14 +65,8 @@ function MasterLfoHandler(){
|
||||
initVisArr[0] = true;
|
||||
|
||||
const [viewMode, setViewMode] = React.useState(ViewModes.MOD);
|
||||
const toggleViewMode = () => {
|
||||
if (viewMode === ViewModes.MOD)
|
||||
setViewMode(ViewModes.ENUM);
|
||||
else
|
||||
setViewMode(ViewModes.MOD);
|
||||
};
|
||||
|
||||
const [lockMode, setLockMode] = React.useState(LockModes.LOCK);
|
||||
const [lockMode, setLockMode] = React.useState(LockModes.UNLOCK);
|
||||
const toggleLockMode = () => {
|
||||
if (lockMode === LockModes.UNLOCK)
|
||||
setLockMode(LockModes.LOCK);
|
||||
@@ -79,18 +74,35 @@ function MasterLfoHandler(){
|
||||
setLockMode(LockModes.UNLOCK);
|
||||
};
|
||||
|
||||
const [enabled, setEnabled] = React.useState(false);
|
||||
const toggleEnabled = () => {
|
||||
setEnabled(!enabled);
|
||||
};
|
||||
|
||||
const displayIfEnabled = (content) => {
|
||||
if (enabled)
|
||||
return content
|
||||
}
|
||||
|
||||
let toggleEnabledText = enabled ? `Hide \u{25BE}` : `Show \u{25B8}`;
|
||||
|
||||
/// MODULATOR ARRAYS
|
||||
let userDefinedWavesBase = [];
|
||||
let userDefinedFunctionsBase = [];
|
||||
let userDefinedTypesBase = [0, 0, 0, 0]; //0 = wave, 1 = function
|
||||
|
||||
for (let i=0; i<4; i++){
|
||||
for (let i = 0; i < MAXUSERDEFINED; i++) {
|
||||
userDefinedWavesBase.push(Array(50).fill(0));
|
||||
userDefinedFunctionsBase.push(Array(101).fill(0));
|
||||
}
|
||||
const [userDefinedWaves, setUserDefinedWaves] = React.useState(userDefinedWavesBase);
|
||||
const [userDefinedFunctions, setUserDefinedFunctions] = React.useState(userDefinedFunctionsBase);
|
||||
const [userDefinedTypes, setUserDefinedTypes] = React.useState(userDefinedTypesBase);
|
||||
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 [modCenterVals, setModCenterVals] = React.useState({ '1': {}, '2': {}, '3': {}, '4': {}, '5': {}, '6': {}});
|
||||
|
||||
const [ticks, setTicks] = React.useState(0);
|
||||
const [beatsInMeasure, setBeatsInMeasure] = React.useState(4);
|
||||
@@ -244,7 +256,7 @@ function MasterLfoHandler(){
|
||||
function handleTick(event) {
|
||||
let time = (Date.now() - firstUpdateTime) / 1000;
|
||||
let noiseData = { lastPhaseArr, setLastPhaseArr, cachedNoiseValueArr1, setCachedNoiseValueArr1, cachedNoiseValueArr2, setCachedNoiseValueArr2, noiseTypeArr };
|
||||
operateModulators(modVisibleArr, modTypeArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, initPhaseArr, noiseData, userDefinedWaves, time, beatsInMeasure, ticks);
|
||||
operateModulators(modVisibleArr, modTypeArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, initPhaseArr, noiseData, userDefinedWaves, userDefinedFunctions, userDefinedTypes, time, beatsInMeasure, ticks);
|
||||
}
|
||||
|
||||
function handleTimeSig(event) {
|
||||
@@ -256,10 +268,25 @@ function MasterLfoHandler(){
|
||||
setUserDefinedWaves(userDefinedWaves);
|
||||
}
|
||||
|
||||
function handleChangeUserFunction(event) {
|
||||
userDefinedFunctions[event.detail.index] = event.detail.points;
|
||||
setUserDefinedFunctions(userDefinedFunctions);
|
||||
}
|
||||
|
||||
function handleChangeUserDefinedType(event) {
|
||||
userDefinedTypes[event.detail.index - 1] = event.detail.type;
|
||||
setUserDefinedTypes(userDefinedTypes);
|
||||
}
|
||||
|
||||
function handleMaxTicks(event) {
|
||||
setTicks(event.detail);
|
||||
}
|
||||
|
||||
function handleChangeViewMode(event){
|
||||
setEnabled(true);
|
||||
setViewMode(event.detail);
|
||||
}
|
||||
|
||||
function setNN(event) {
|
||||
|
||||
for (let i = 0; i < MAXLFOS; i++) {
|
||||
@@ -327,7 +354,10 @@ function MasterLfoHandler(){
|
||||
window.addEventListener('enum', handleEnum);
|
||||
window.addEventListener('timesig', handleTimeSig);
|
||||
window.addEventListener('userWave', handleChangeUserWave);
|
||||
window.addEventListener('userFunction', handleChangeUserFunction);
|
||||
window.addEventListener('userDefinedType', handleChangeUserDefinedType);
|
||||
window.addEventListener('maxTicks', handleMaxTicks);
|
||||
window.addEventListener('viewMode', handleChangeViewMode);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('loadDict', handleLoad);
|
||||
@@ -339,9 +369,12 @@ function MasterLfoHandler(){
|
||||
window.removeEventListener('enum', handleEnum);
|
||||
window.removeEventListener('timesig', handleTimeSig);
|
||||
window.removeEventListener('userWave', handleChangeUserWave);
|
||||
window.removeEventListener('userFunction', handleChangeUserFunction);
|
||||
window.removeEventListener('userDefinedType', handleChangeUserDefinedType);
|
||||
window.removeEventListener('maxTicks', handleMaxTicks);
|
||||
window.removeEventListener('viewMode', handleChangeViewMode);
|
||||
};
|
||||
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, userDefinedWaves, modCenterVals, render, beatsInMeasure, ticks]);
|
||||
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, userDefinedWaves, userDefinedFunctions, userDefinedTypes, modCenterVals, render, beatsInMeasure, ticks]);
|
||||
|
||||
|
||||
function CheckLinked(inst, param, checkInstArr, checkParamArr) {
|
||||
@@ -419,6 +452,7 @@ function MasterLfoHandler(){
|
||||
allModSetters[j](array);
|
||||
}
|
||||
}
|
||||
SendSaveEvent();
|
||||
rerender(!render);
|
||||
|
||||
}
|
||||
@@ -428,6 +462,7 @@ function MasterLfoHandler(){
|
||||
let newArr = modVisibleArr.slice();
|
||||
newArr[id] = false;
|
||||
setModVisibleArr(newArr);
|
||||
SendSaveEvent();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -451,9 +486,15 @@ function MasterLfoHandler(){
|
||||
enumItems: enumItemCounts[i],
|
||||
setEnumItemCounts: CreateParamChanger(enumItemCounts, setEnumItemCounts, i),
|
||||
enumBreakPoints: enumBreakPoints,
|
||||
setEnumBreakPoints: setEnumBreakPoints,
|
||||
setEnumBreakPoints: (val) => {
|
||||
setEnumBreakPoints(val);
|
||||
SendSaveEvent
|
||||
},
|
||||
enumNames: enumNames,
|
||||
setEnumNames: setEnumNames,
|
||||
setEnumNames: (val) => {
|
||||
setEnumNames(val);
|
||||
SendSaveEvent
|
||||
},
|
||||
visible: enumVisibleArr[i],
|
||||
djParam: enumDjParamArr[i],
|
||||
setDjParam: CreateParamChanger(enumDjParamArr, setEnumDjParamArr, i),
|
||||
@@ -499,6 +540,7 @@ function MasterLfoHandler(){
|
||||
}
|
||||
}
|
||||
rerender(!render);
|
||||
SendSaveEvent();
|
||||
}
|
||||
},
|
||||
removeEnum: () => {
|
||||
@@ -506,6 +548,7 @@ function MasterLfoHandler(){
|
||||
let newArr = enumVisibleArr.slice();
|
||||
newArr[id] = false;
|
||||
setEnumVisibleArr(newArr);
|
||||
SendSaveEvent();
|
||||
}
|
||||
}
|
||||
}, null)
|
||||
@@ -514,16 +557,19 @@ function MasterLfoHandler(){
|
||||
|
||||
|
||||
var grid;
|
||||
var title;
|
||||
var modButtonClass;
|
||||
var enumButtonClass;
|
||||
var labels;
|
||||
if (viewMode === ViewModes.MOD) {
|
||||
grid = modContents;
|
||||
title = "MODULATORS";
|
||||
modButtonClass = "highlighted-button";
|
||||
enumButtonClass = "unhighlighted-button";
|
||||
labels = MODULATORLABELS;
|
||||
}
|
||||
else {
|
||||
grid = enumContents;
|
||||
title = "ENUMERATORS";
|
||||
modButtonClass = "unhighlighted-button";
|
||||
enumButtonClass = "highlighted-button";
|
||||
labels = ENUMERATORLABELS;
|
||||
}
|
||||
|
||||
@@ -536,13 +582,22 @@ function MasterLfoHandler(){
|
||||
}
|
||||
|
||||
return e('div', null,
|
||||
e('div', {className: 'container'},
|
||||
e(Switch, {ontoggle: toggleViewMode}, null),
|
||||
e('span', {className: lockClass, onClick: toggleLockMode}, null)),
|
||||
e('div', { className: 'header' },
|
||||
e('div', {className: 'nav'},
|
||||
displayIfEnabled(e('button', { onClick: () => setViewMode(ViewModes.MOD), className: modButtonClass}, 'Modulators')),
|
||||
displayIfEnabled(e('button', { onClick: () => setViewMode(ViewModes.ENUM), className: enumButtonClass }, 'Enumerators'))
|
||||
),
|
||||
e('button', { onClick: toggleEnabled, id: 'hide-button'}, toggleEnabledText),
|
||||
|
||||
e('h5', null, title),
|
||||
e('ul', null, ...labels.map(x => ListItem(Label(x)))),
|
||||
e('div', {id: 'grid'}, ...grid)
|
||||
//allows lock mode
|
||||
//e('span', { className: lockClass, onClick: toggleLockMode }, null)
|
||||
),
|
||||
|
||||
displayIfEnabled(
|
||||
e('table', { id: 'table' },
|
||||
e('thead', null, e('tr', { id: 'headers' }, ...labels.map(x => e('th', {id: x == '# points' ? 'points' : x}, x)))),
|
||||
e('tbody', null, ...grid)
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -564,7 +619,6 @@ if (!DEBUG){
|
||||
});
|
||||
|
||||
window.max.bindInlet("param", (inst, paramName, val) => {
|
||||
|
||||
window.dispatchEvent(new CustomEvent('param', { 'detail': [inst, paramName, val] }));
|
||||
});
|
||||
|
||||
@@ -581,6 +635,21 @@ if (!DEBUG){
|
||||
window.dispatchEvent(new CustomEvent('userWave', { 'detail': data }));
|
||||
});
|
||||
|
||||
window.max.bindInlet("viewMode", (mode) => {
|
||||
window.dispatchEvent(new CustomEvent('viewMode', { 'detail': parseInt(mode) }));
|
||||
});
|
||||
|
||||
window.max.bindInlet("userFunction", (index, ...points) => {
|
||||
//list of 101 points between 0-100
|
||||
let data = { points, index };
|
||||
window.dispatchEvent(new CustomEvent('userFunction', { 'detail': data }));
|
||||
});
|
||||
|
||||
window.max.bindInlet("userDefinedType", (index, type) => {
|
||||
let data = { index, type };
|
||||
window.dispatchEvent(new CustomEvent('userDefinedType', { 'detail': data }));
|
||||
})
|
||||
|
||||
setInterval(() => {
|
||||
window.dispatchEvent(new CustomEvent('tick'));
|
||||
}, 200);
|
||||
@@ -7,7 +7,7 @@ var TYPEOPTIONS = ["LFO", "Noise"];
|
||||
var SHAPETYPES = ["Sine", "SawUp", "SawDown", "Tri", "Square", "Custom_1", "Custom_2", "Custom_3", "Custom_4"];
|
||||
var NOISETYPES = ["Rand", "Line Int.", "Sine Int."]
|
||||
|
||||
var INSTANCEOPTIONS = ["1", "2", "3", "4"];
|
||||
var INSTANCEOPTIONS = ["1", "2", "3", "4", "5", "6"];
|
||||
|
||||
const MODPARAMOPTIONS = ["NONE", "stream", "pulse_length", "eventfulness", "event_length", "metriclarity",
|
||||
"harmoniclarity", "melodic_cohesion", "melody_scope", "tonic_pitch", "pitch_center", "pitch_range", "dynamics",
|
||||
@@ -22,7 +22,9 @@ function ControlType(){
|
||||
return e('select', {className: 'control-type'}, Option("LFO"));
|
||||
}
|
||||
|
||||
|
||||
function DataCell(element) {
|
||||
return e('td', null, element);
|
||||
}
|
||||
|
||||
function LfoRow(props){
|
||||
|
||||
@@ -34,38 +36,42 @@ function LfoRow(props){
|
||||
let typeOption = null;
|
||||
|
||||
if (props.type == "LFO"){
|
||||
typeOption = ListItem(DropDown({locked:props.locked, onChange: props.setShape, value:props.shape, options: SHAPETYPES}));
|
||||
typeOption = DataCell(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}));
|
||||
typeOption = DataCell(DropDown({locked:props.locked, onChange: props.setNoise, value:props.noise, options: NOISETYPES}));
|
||||
}
|
||||
|
||||
let content = e('ul', {className: 'lfo-item'},
|
||||
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})),
|
||||
let content = e('tr', {className: 'lfo-item'},
|
||||
DataCell(DropDown({locked:props.locked, onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
|
||||
DataCell(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)),
|
||||
//ListItem(e(NumberBox, {onChange:props.setAmp, value:props.amp, step:0.1}, null)),
|
||||
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, locked: props.locked}, null)),
|
||||
ListItem(e(Button, {text:'-', onClick: props.removeLfo, locked: props.locked}, null)),
|
||||
ListItem(e("div", {className:"linked"}, linkedText)),
|
||||
DataCell(DropDown({locked:props.locked, onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
|
||||
DataCell(e("input", {onChange:props.setFreq, value:props.freq, className:"timeInput"}, null)),
|
||||
DataCell(e(NumberBox, {onChange:props.setMin, value:props.min, step:0.1}, null)),
|
||||
DataCell(e(NumberBox, {onChange:props.setMax, value:props.max, step:0.1}, null)),
|
||||
//DataCell(e(NumberBox, {onChange:props.setAmp, value:props.amp, step:0.1}, null)),
|
||||
DataCell(e(NumberBox, {onChange:props.setPhase, value:props.phase, step:0.1}, null)),
|
||||
DataCell(e("div", {className:"base-val"}, center.toString())),
|
||||
DataCell(e("input", {type: 'range', min: 0, max: 1, step: 0.01, readonly: true, id: `slider-${props.instanceNum}-${props.djParam}`})),
|
||||
DataCell(e(Button, {text:'+', onClick: props.addLfo, locked: props.locked}, null)),
|
||||
DataCell(e(Button, {text:'-', onClick: props.removeLfo, locked: props.locked}, null)),
|
||||
DataCell(e("div", {className:"linked"}, linkedText)),
|
||||
);
|
||||
if (props.visible){
|
||||
return content
|
||||
return content;
|
||||
};
|
||||
}
|
||||
|
||||
function indexUserWave(phase, index, userDefinedWaves){
|
||||
return parseFloat(userDefinedWaves[index][Math.floor(phase * 50)]) / 127
|
||||
return parseFloat(userDefinedWaves[index][Math.floor(phase * 50)]) / 127;
|
||||
}
|
||||
|
||||
function indexWave(type, phase, userDefinedWaves){
|
||||
function indexUserFunction(phase, index, userDefinedFunctions){
|
||||
return parseFloat(userDefinedFunctions[index][Math.floor(phase * 101)]) / 127;
|
||||
}
|
||||
|
||||
function indexWave(type, phase, userDefinedWaves, userDefinedFunctions, userDefinedTypes){
|
||||
switch (type){
|
||||
case "Sine":
|
||||
return (Math.sin(phase * Math.PI * 2) / 2) + 0.5;
|
||||
@@ -78,17 +84,17 @@ function indexWave(type, phase, userDefinedWaves){
|
||||
case "Square":
|
||||
return +(phase > 0.5);
|
||||
case "Custom_1":
|
||||
return indexUserWave(phase, 1, userDefinedWaves);
|
||||
return userDefinedTypes[0] == 0 ? indexUserWave(phase, 1, userDefinedWaves) : indexUserFunction(phase, 1, userDefinedFunctions);
|
||||
case "Custom_2":
|
||||
return indexUserWave(phase, 2, userDefinedWaves);
|
||||
return userDefinedTypes[1] == 0 ? indexUserWave(phase, 2, userDefinedWaves) : indexUserFunction(phase, 2, userDefinedFunctions);
|
||||
case "Custom_3":
|
||||
return indexUserWave(phase, 3, userDefinedWaves);
|
||||
return userDefinedTypes[2] == 0 ? indexUserWave(phase, 3, userDefinedWaves) : indexUserFunction(phase, 3, userDefinedFunctions);
|
||||
case "Custom_4":
|
||||
return indexUserWave(phase, 4, userDefinedWaves);
|
||||
return userDefinedTypes[3] == 0 ? indexUserWave(phase, 4, userDefinedWaves) : indexUserFunction(phase, 4, userDefinedFunctions);
|
||||
}
|
||||
}
|
||||
|
||||
function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, centers, freqs, mins, maxs, waveTypes, phaseArr, noiseData, userDefinedWaves, currTime, beatsInMeasure, ticks){
|
||||
function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, centers, freqs, mins, maxs, waveTypes, phaseArr, noiseData, userDefinedWaves, userDefinedFunctions, userDefinedTypes, currTime, beatsInMeasure, ticks){
|
||||
for (let i=0; i<paramNames.length; i++){
|
||||
if (visibleArr[i]){
|
||||
|
||||
@@ -102,7 +108,7 @@ function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, cent
|
||||
let output = 0;
|
||||
|
||||
if (typeArr[i] == "LFO")
|
||||
output = operateLFO(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWaves, name, currTime, beatsInMeasure, ticks);
|
||||
output = operateLFO(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWaves, userDefinedFunctions, userDefinedTypes, 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")
|
||||
@@ -111,7 +117,7 @@ function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, cent
|
||||
}
|
||||
}
|
||||
|
||||
function operateLFO(center, inst, timeBaseStr, min, max, waveType, phaseArr, phaseIndex, userDefinedWaves, name, currTime, beatsInMeasure, maxTicks){
|
||||
function operateLFO(center, inst, timeBaseStr, min, max, waveType, phaseArr, phaseIndex, userDefinedWaves, userDefinedFunctions, userDefinedTypes, name, currTime, beatsInMeasure, maxTicks){
|
||||
let amp = parseFloat(max) - parseFloat(min);
|
||||
let phaseType;
|
||||
let timeBase;
|
||||
@@ -123,7 +129,7 @@ function operateLFO(center, inst, timeBaseStr, min, max, waveType, phaseArr, pha
|
||||
phase = (currTime * timeBase + parseFloat(phaseArr[phaseIndex])) % 1.00;
|
||||
else if (phaseType === PhaseTypes.MUSICAL)
|
||||
phase = (maxTicks % timeBase) / timeBase;
|
||||
let unscaled = indexWave(waveType, phase, userDefinedWaves);
|
||||
let unscaled = indexWave(waveType, phase, userDefinedWaves, userDefinedFunctions, userDefinedTypes);
|
||||
syncDisplay(inst, name, unscaled);
|
||||
|
||||
return unscaled * amp + center + parseFloat(min);
|
||||
@@ -152,9 +158,6 @@ function operateNoise(center, inst, timeBaseStr, min, max, waveType, phaseArr, i
|
||||
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];
|
||||
@@ -168,13 +171,11 @@ function operateNoise(center, inst, timeBaseStr, min, max, waveType, phaseArr, i
|
||||
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){
|
||||
Reference in New Issue
Block a user