Compare commits
59 Commits
noise-func
...
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 | ||
| 149d1a0b8d | |||
| 4ee8a93791 | |||
| c706461443 | |||
| 081e33dd07 | |||
| eb02657b4a | |||
| d670aefcbd | |||
| 68baa3c8de | |||
| a35fecafae | |||
| b3ba9b0f2d | |||
| 102a88b242 | |||
| aebfbe5277 | |||
| 2d81a832af | |||
| cdbcf24dfc | |||
| 64f1455f69 | |||
|
|
a855d254cd | ||
| 09a1b5f20f | |||
| 34e99f09fd | |||
| 86a994546e |
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
1036
example.maxpat
1036
example.maxpat
File diff suppressed because it is too large
Load Diff
181
lfogui.css
181
lfogui.css
@@ -1,181 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
25
lfogui.html
25
lfogui.html
@@ -1,28 +1,21 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<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>
|
<head>
|
||||||
<link rel="stylesheet" href="./lfogui.css">
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="./src/lfogui.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="lfo-container"></div>
|
<div id="lfo-container"></div>
|
||||||
|
|
||||||
<script src="./react.js"></script>
|
<script src="./lib/react.js"></script>
|
||||||
<script src="./react-dom.js"></script>
|
<script src="./lib/react-dom.js"></script>
|
||||||
<script src="./moment.js"></script>
|
<script src="./lib/moment.js"></script>
|
||||||
<script src="./common.js"></script>
|
<script src="./src/common.js"></script>
|
||||||
<script src="./enums.js"></script>
|
<script src="./src/enums.js"></script>
|
||||||
<script src="./modulators.js"></script>
|
<script src="./src/modulators.js"></script>
|
||||||
<script src="./lfogui.js">
|
<script src="./src/lfogui.js"></script>
|
||||||
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
</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
@@ -5,7 +5,8 @@ function isNumeric(str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function DropDown(props) {
|
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)));
|
...props.options.map((item) => Option(item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,11 +19,13 @@ function Label(text){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function NumberBox(props){
|
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){
|
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){
|
function Option(str, value){
|
||||||
@@ -30,7 +33,8 @@ function Option(str, value){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Button(props){
|
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){
|
function Switch(props){
|
||||||
@@ -39,12 +43,20 @@ function Switch(props){
|
|||||||
e('span', {className: 'slider round'}, null))
|
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){
|
function CreateParamChanger(arr, setArr, index, postCB=() => {}, preCB=(val) => val){
|
||||||
return (event) => {
|
return (event) => {
|
||||||
let newArr = arr.slice();
|
let newArr = arr.slice();
|
||||||
newArr[index] = preCB(event.target.value);
|
newArr[index] = preCB(event.target.value);
|
||||||
setArr(newArr);
|
setArr(newArr);
|
||||||
postCB();
|
postCB();
|
||||||
|
SendSaveEvent();
|
||||||
|
|
||||||
log(`${index} ${event.target.value}`);
|
log(`${index} ${event.target.value}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -56,6 +68,7 @@ function CreateMatrixParamChanger(matrix, setMatrix, i, j){
|
|||||||
});
|
});
|
||||||
newMatrix[i][j] = event.target.value;
|
newMatrix[i][j] = event.target.value;
|
||||||
setMatrix(newMatrix);
|
setMatrix(newMatrix);
|
||||||
|
SendSaveEvent();
|
||||||
log(`${i}, ${j} ${event.target.value}`);
|
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
|
// 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 = [];
|
let items = [];
|
||||||
for (let i = 0; i < MAXENUMPOINTS; i++){
|
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(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
|
// 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(DataCell(e(NumberBox, {locked, onChange: CreateMatrixParamChanger(enumBreakPoints, setEnumBreakPoints, index, i + 1), value:enumBreakPoints[index][i + 1]}, null)));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
@@ -19,15 +23,15 @@ function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames,
|
|||||||
function EnumeratorRow(props){
|
function EnumeratorRow(props){
|
||||||
let linkedText = props.linked ? "<- mods" : "";
|
let linkedText = props.linked ? "<- mods" : "";
|
||||||
|
|
||||||
let content = e('ul', {className: 'lfo-item', id: `${props.djParam}-enum-row`},
|
let content = e('tr', {className: 'lfo-item', id: `${props.djParam}-enum-row`},
|
||||||
ListItem(DropDown({onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
|
DataCell(DropDown({locked:props.locked, onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
|
||||||
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
|
DataCell(DropDown({locked:props.locked, onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
|
||||||
ListItem(e(NumberBox, {onChange: props.setEnumItemCounts, step:1, value:props.enumItems, className: 'enum-count'}, null)),
|
DataCell(e(NumberBox, {locked:props.locked, 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)),
|
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).slice(0, props.enumItems * 2)),
|
...(EnumeratorItems(props.index, props.enumBreakPoints, props.setEnumBreakPoints, props.enumNames, props.setEnumNames, props.djParam, props.locked).slice(0, props.enumItems * 2)),
|
||||||
ListItem(e(Button, {text:'+', onClick: props.addEnum}, null)),
|
DataCell(e(Button, {locked:props.locked, text:'+', onClick: props.addEnum}, null)),
|
||||||
ListItem(e(Button, {text:'-', onClick: props.removeEnum}, null)),
|
DataCell(e(Button, {locked:props.locked, text:'-', onClick: props.removeEnum}, null)),
|
||||||
ListItem(e("div", {className:"linked"}, linkedText))
|
DataCell(e("div", {className:"linked"}, linkedText))
|
||||||
);
|
);
|
||||||
if (props.visible){
|
if (props.visible){
|
||||||
return content;
|
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;
|
const e = React.createElement;
|
||||||
|
|
||||||
let lfos = [];
|
let lfos = [];
|
||||||
const MAXLFOS = 20;
|
const MAXLFOS = 200;
|
||||||
const MAXENUMS = 20;
|
const MAXENUMS = 200;
|
||||||
const MAXENUMPOINTS = 10;
|
const MAXENUMPOINTS = 10;
|
||||||
|
const MAXUSERDEFINED = 4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -20,38 +21,88 @@ const ViewModes = Object.freeze({
|
|||||||
ENUM: 1
|
ENUM: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const LockModes = Object.freeze({
|
||||||
|
UNLOCK: 0,
|
||||||
|
LOCK: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var modPhases = Array(MAXLFOS).fill(0);
|
var modPhases = Array(MAXLFOS).fill(0);
|
||||||
var firstUpdateTime = Date.now();
|
var firstUpdateTime = Date.now();
|
||||||
|
|
||||||
const MODULATORLABELS = ["inst", "-type-", "---shape---", "-------param-------", "--timebase--", "-min-", "-max", "-phase-", "center"];
|
const MODULATORLABELS = ["inst", "type", "shape", "param", "timebase", "min", "max", "phase", "center", "result", "", ""];
|
||||||
const ENUMERATORLABELS = ["inst", "---parameter---", "-# points-"];
|
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() {
|
function MasterLfoHandler() {
|
||||||
|
|
||||||
let initVisArr = Array(MAXLFOS).fill(false);
|
let initVisArr = Array(MAXLFOS).fill(false);
|
||||||
initVisArr[0] = true;
|
initVisArr[0] = true;
|
||||||
|
|
||||||
const [viewMode, setViewMode] = React.useState(ViewModes.MOD);
|
const [viewMode, setViewMode] = React.useState(ViewModes.MOD);
|
||||||
const toggleViewMode = () => {
|
|
||||||
if (viewMode === ViewModes.MOD)
|
const [lockMode, setLockMode] = React.useState(LockModes.UNLOCK);
|
||||||
setViewMode(ViewModes.ENUM);
|
const toggleLockMode = () => {
|
||||||
|
if (lockMode === LockModes.UNLOCK)
|
||||||
|
setLockMode(LockModes.LOCK);
|
||||||
else
|
else
|
||||||
setViewMode(ViewModes.MOD);
|
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
|
/// MODULATOR ARRAYS
|
||||||
|
let userDefinedWavesBase = [];
|
||||||
|
let userDefinedFunctionsBase = [];
|
||||||
|
let userDefinedTypesBase = [0, 0, 0, 0]; //0 = wave, 1 = function
|
||||||
|
|
||||||
const [userDefinedWave, setUserDefinedWave] = React.useState(Array(50).fill(0));
|
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 [modVisibleArr, setModVisibleArr] = React.useState(initVisArr);
|
||||||
const [modTypeArr, setModTypeArr] = React.useState(Array(MAXLFOS).fill('LFO'));
|
const [modTypeArr, setModTypeArr] = React.useState(Array(MAXLFOS).fill('LFO'));
|
||||||
const [modInstanceNumArr, setModInstanceNumArr] = React.useState(Array(MAXLFOS).fill('1'));
|
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 [ticks, setTicks] = React.useState(0);
|
||||||
const [beatsInMeasure, setBeatsInMeasure] = React.useState(4);
|
const [beatsInMeasure, setBeatsInMeasure] = React.useState(4);
|
||||||
@@ -68,25 +119,26 @@ function MasterLfoHandler(){
|
|||||||
|
|
||||||
const [initPhaseArr, setInitPhaseArr] = 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 [lastPhaseArr, setLastPhaseArr] = React.useState(Array(MAXLFOS).fill(0));
|
||||||
const [cachedNoiseValueArr, setCachedNoiseValueArr] = React.useState(Array(MAXLFOS).fill([0, 0]));
|
const [cachedNoiseValueArr1, setCachedNoiseValueArr1] = React.useState(Array(MAXLFOS).fill(0));
|
||||||
|
const [cachedNoiseValueArr2, setCachedNoiseValueArr2] = React.useState(Array(MAXLFOS).fill(0));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const allModArrays = [modVisibleArr, modTypeArr, modInstanceNumArr, shapeArr, noiseTypeArr, djParamArr, freqArr, minArr, maxArr, initPhaseArr, lastPhaseArr, cachedNoiseValueArr];
|
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, lastPhaseArr, cachedNoiseValueArr];
|
const allModSetters = [setModVisibleArr, setModTypeArr, setModInstanceNumArr, setShapeArr, setNoiseTypeArr, setDjParamArr, setFreqArr, setMinArr, setMaxArr, setInitPhaseArr, setLastPhaseArr, setCachedNoiseValueArr1, setCachedNoiseValueArr2];
|
||||||
const modBlankVals = [true, 'LFO', '1', SHAPETYPES[0], MODPARAMOPTIONS[0], "Sine Int.", '1hz', '0', '1', '0', 0, [0, 0]];
|
const modBlankVals = [true, 'LFO', '1', SHAPETYPES[0], NOISETYPES[0], MODPARAMOPTIONS[0], '1hz', '0', '1', '0', 0, 0, 0];
|
||||||
|
|
||||||
|
|
||||||
/// ENUMERATOR ARRAYS
|
/// ENUMERATOR ARRAYS
|
||||||
const [enumVisibleArr, setEnumVisibleArr] = React.useState(initVisArr);
|
const [enumVisibleArr, setEnumVisibleArr] = React.useState(initVisArr);
|
||||||
const [enumInstanceNumArr, setEnumInstanceNumArr] = React.useState(Array(MAXLFOS).fill('1'));
|
const [enumInstanceNumArr, setEnumInstanceNumArr] = React.useState(Array(MAXLFOS).fill('1'));
|
||||||
const [enumItemCounts, setEnumItemCounts] = React.useState(Array(MAXENUMPOINTS).fill('2'));
|
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));
|
let baseEnumBreakpoints = Array(MAXENUMS).fill(0).map(x => Array(MAXENUMPOINTS + 1).fill(0));
|
||||||
for (let i = 0; i < MAXENUMS; i++) {
|
for (let i = 0; i < MAXENUMS; i++) {
|
||||||
for (let j = 0; j < MAXENUMPOINTS + 1; j++) {
|
for (let j = 0; j < MAXENUMPOINTS + 1; j++) {
|
||||||
baseEnumBreakpoints[i][j] = j;
|
baseEnumBreakpoints[i][j] = j - 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const [enumBreakPoints, setEnumBreakPoints] = React.useState(baseEnumBreakpoints);
|
const [enumBreakPoints, setEnumBreakPoints] = React.useState(baseEnumBreakpoints);
|
||||||
@@ -94,7 +146,7 @@ function MasterLfoHandler(){
|
|||||||
const getBlankEnumBreakPointRow = () => {
|
const getBlankEnumBreakPointRow = () => {
|
||||||
let arr = []
|
let arr = []
|
||||||
for (let i = 0; i < MAXENUMPOINTS + 1; i++)
|
for (let i = 0; i < MAXENUMPOINTS + 1; i++)
|
||||||
arr.push(i)
|
arr.push(i - 0.5)
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,14 +172,12 @@ function MasterLfoHandler(){
|
|||||||
function handleLoad(event) {
|
function handleLoad(event) {
|
||||||
window.max.getDict(event.detail, (dict) => {
|
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]);
|
allModSetters[i](dict.data.modArrays[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < allEnumArrays.length; i++) {
|
for (let i = 0; i < allEnumArrays.length; i++) {
|
||||||
allEnumArrSetters[i](dict.data.enumArrays[i]);
|
allEnumArrSetters[i](dict.data.enumArrays[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < allEnumMats.length; i++) {
|
for (let i = 0; i < allEnumMats.length; i++) {
|
||||||
allEnumMatSetters[i](dict.data.enumMats[i]);
|
allEnumMatSetters[i](dict.data.enumMats[i]);
|
||||||
}
|
}
|
||||||
@@ -205,8 +255,8 @@ function MasterLfoHandler(){
|
|||||||
|
|
||||||
function handleTick(event) {
|
function handleTick(event) {
|
||||||
let time = (Date.now() - firstUpdateTime) / 1000;
|
let time = (Date.now() - firstUpdateTime) / 1000;
|
||||||
let noiseData = {lastPhaseArr, setLastPhaseArr, cachedNoiseValueArr, setCachedNoiseValueArr, noiseTypeArr};
|
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);
|
operateModulators(modVisibleArr, modTypeArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, initPhaseArr, noiseData, userDefinedWaves, userDefinedFunctions, userDefinedTypes, time, beatsInMeasure, ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTimeSig(event) {
|
function handleTimeSig(event) {
|
||||||
@@ -214,34 +264,117 @@ function MasterLfoHandler(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleChangeUserWave(event) {
|
function handleChangeUserWave(event) {
|
||||||
setUserDefinedWave(event.detail);
|
userDefinedWaves[event.detail.index] = event.detail.points;
|
||||||
|
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) {
|
function handleMaxTicks(event) {
|
||||||
setTicks(event.detail);
|
setTicks(event.detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleChangeViewMode(event){
|
||||||
|
setEnabled(true);
|
||||||
|
setViewMode(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('loadDict', handleLoad);
|
||||||
window.addEventListener('saveDict', handleSave);
|
window.addEventListener('saveDict', handleSave);
|
||||||
|
window.addEventListener('dumpNN', dumpNN);
|
||||||
|
window.addEventListener('setNN', setNN);
|
||||||
window.addEventListener('tick', handleTick);
|
window.addEventListener('tick', handleTick);
|
||||||
window.addEventListener('param', handleParam);
|
window.addEventListener('param', handleParam);
|
||||||
window.addEventListener('enum', handleEnum);
|
window.addEventListener('enum', handleEnum);
|
||||||
window.addEventListener('timesig', handleTimeSig);
|
window.addEventListener('timesig', handleTimeSig);
|
||||||
window.addEventListener('userWave', handleChangeUserWave);
|
window.addEventListener('userWave', handleChangeUserWave);
|
||||||
|
window.addEventListener('userFunction', handleChangeUserFunction);
|
||||||
|
window.addEventListener('userDefinedType', handleChangeUserDefinedType);
|
||||||
window.addEventListener('maxTicks', handleMaxTicks);
|
window.addEventListener('maxTicks', handleMaxTicks);
|
||||||
|
window.addEventListener('viewMode', handleChangeViewMode);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('loadDict', handleLoad);
|
window.removeEventListener('loadDict', handleLoad);
|
||||||
window.removeEventListener('saveDict', handleSave);
|
window.removeEventListener('saveDict', handleSave);
|
||||||
|
window.removeEventListener('dumpNN', dumpNN);
|
||||||
|
window.removeEventListener('setNN', setNN);
|
||||||
window.removeEventListener('tick', handleTick);
|
window.removeEventListener('tick', handleTick);
|
||||||
window.removeEventListener('param', handleParam);
|
window.removeEventListener('param', handleParam);
|
||||||
window.removeEventListener('enum', handleEnum);
|
window.removeEventListener('enum', handleEnum);
|
||||||
window.removeEventListener('timesig', handleTimeSig);
|
window.removeEventListener('timesig', handleTimeSig);
|
||||||
window.removeEventListener('userWave', handleChangeUserWave);
|
window.removeEventListener('userWave', handleChangeUserWave);
|
||||||
|
window.removeEventListener('userFunction', handleChangeUserFunction);
|
||||||
|
window.removeEventListener('userDefinedType', handleChangeUserDefinedType);
|
||||||
window.removeEventListener('maxTicks', handleMaxTicks);
|
window.removeEventListener('maxTicks', handleMaxTicks);
|
||||||
|
window.removeEventListener('viewMode', handleChangeViewMode);
|
||||||
};
|
};
|
||||||
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, modCenterVals, render, beatsInMeasure, ticks]);
|
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, userDefinedWaves, userDefinedFunctions, userDefinedTypes, modCenterVals, render, beatsInMeasure, ticks]);
|
||||||
|
|
||||||
|
|
||||||
function CheckLinked(inst, param, checkInstArr, checkParamArr) {
|
function CheckLinked(inst, param, checkInstArr, checkParamArr) {
|
||||||
@@ -262,6 +395,7 @@ function MasterLfoHandler(){
|
|||||||
modContents.push(
|
modContents.push(
|
||||||
|
|
||||||
e(LfoRow, {
|
e(LfoRow, {
|
||||||
|
locked: lockMode,
|
||||||
instanceNum: modInstanceNumArr[i],
|
instanceNum: modInstanceNumArr[i],
|
||||||
setInstanceNum: CreateParamChanger(modInstanceNumArr, setModInstanceNumArr, i),
|
setInstanceNum: CreateParamChanger(modInstanceNumArr, setModInstanceNumArr, i),
|
||||||
|
|
||||||
@@ -311,14 +445,16 @@ function MasterLfoHandler(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log("adding lfo");
|
|
||||||
for (var j = 0; j < allModArrays.length; j++) { // no space below, easy.
|
for (var j = 0; j < allModArrays.length; j++) { // no space below, easy.
|
||||||
let array = allModArrays[j];
|
let array = allModArrays[j];
|
||||||
array[id + 1] = modBlankVals[j];
|
array[id + 1] = modBlankVals[j];
|
||||||
allModSetters[j](array);
|
allModSetters[j](array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SendSaveEvent();
|
||||||
rerender(!render);
|
rerender(!render);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeLfo: () => {
|
removeLfo: () => {
|
||||||
@@ -326,6 +462,7 @@ function MasterLfoHandler(){
|
|||||||
let newArr = modVisibleArr.slice();
|
let newArr = modVisibleArr.slice();
|
||||||
newArr[id] = false;
|
newArr[id] = false;
|
||||||
setModVisibleArr(newArr);
|
setModVisibleArr(newArr);
|
||||||
|
SendSaveEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -343,15 +480,21 @@ function MasterLfoHandler(){
|
|||||||
enumContents.push(
|
enumContents.push(
|
||||||
e(EnumeratorRow, {
|
e(EnumeratorRow, {
|
||||||
index: i,
|
index: i,
|
||||||
|
locked: lockMode,
|
||||||
instanceNum: enumInstanceNumArr[i],
|
instanceNum: enumInstanceNumArr[i],
|
||||||
setInstanceNum: CreateParamChanger(enumInstanceNumArr, setEnumInstanceNumArr, i),
|
setInstanceNum: CreateParamChanger(enumInstanceNumArr, setEnumInstanceNumArr, i),
|
||||||
enumItems: enumItemCounts[i],
|
enumItems: enumItemCounts[i],
|
||||||
setEnumItemCounts: CreateParamChanger(enumItemCounts, setEnumItemCounts, i),
|
setEnumItemCounts: CreateParamChanger(enumItemCounts, setEnumItemCounts, i),
|
||||||
enumBreakPoints: enumBreakPoints,
|
enumBreakPoints: enumBreakPoints,
|
||||||
setEnumBreakPoints: setEnumBreakPoints,
|
setEnumBreakPoints: (val) => {
|
||||||
|
setEnumBreakPoints(val);
|
||||||
|
SendSaveEvent
|
||||||
|
},
|
||||||
enumNames: enumNames,
|
enumNames: enumNames,
|
||||||
setEnumNames: setEnumNames,
|
setEnumNames: (val) => {
|
||||||
|
setEnumNames(val);
|
||||||
|
SendSaveEvent
|
||||||
|
},
|
||||||
visible: enumVisibleArr[i],
|
visible: enumVisibleArr[i],
|
||||||
djParam: enumDjParamArr[i],
|
djParam: enumDjParamArr[i],
|
||||||
setDjParam: CreateParamChanger(enumDjParamArr, setEnumDjParamArr, i),
|
setDjParam: CreateParamChanger(enumDjParamArr, setEnumDjParamArr, i),
|
||||||
@@ -397,6 +540,7 @@ function MasterLfoHandler(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rerender(!render);
|
rerender(!render);
|
||||||
|
SendSaveEvent();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeEnum: () => {
|
removeEnum: () => {
|
||||||
@@ -404,6 +548,7 @@ function MasterLfoHandler(){
|
|||||||
let newArr = enumVisibleArr.slice();
|
let newArr = enumVisibleArr.slice();
|
||||||
newArr[id] = false;
|
newArr[id] = false;
|
||||||
setEnumVisibleArr(newArr);
|
setEnumVisibleArr(newArr);
|
||||||
|
SendSaveEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, null)
|
}, null)
|
||||||
@@ -412,24 +557,47 @@ function MasterLfoHandler(){
|
|||||||
|
|
||||||
|
|
||||||
var grid;
|
var grid;
|
||||||
var title;
|
var modButtonClass;
|
||||||
|
var enumButtonClass;
|
||||||
var labels;
|
var labels;
|
||||||
if (viewMode === ViewModes.MOD) {
|
if (viewMode === ViewModes.MOD) {
|
||||||
grid = modContents;
|
grid = modContents;
|
||||||
title = "MODULATORS";
|
modButtonClass = "highlighted-button";
|
||||||
|
enumButtonClass = "unhighlighted-button";
|
||||||
labels = MODULATORLABELS;
|
labels = MODULATORLABELS;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
grid = enumContents;
|
grid = enumContents;
|
||||||
title = "ENUMERATORS";
|
modButtonClass = "unhighlighted-button";
|
||||||
|
enumButtonClass = "highlighted-button";
|
||||||
labels = ENUMERATORLABELS;
|
labels = ENUMERATORLABELS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lockClass;
|
||||||
|
if (lockMode == LockModes.LOCK) {
|
||||||
|
lockClass = 'lock';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lockClass = 'lock unlocked';
|
||||||
|
}
|
||||||
|
|
||||||
return e('div', null,
|
return e('div', null,
|
||||||
e(Switch, {ontoggle: toggleViewMode}, null),
|
e('div', { className: 'header' },
|
||||||
e('h5', null, title),
|
e('div', {className: 'nav'},
|
||||||
e('ul', null, ...labels.map(x => ListItem(Label(x)))),
|
displayIfEnabled(e('button', { onClick: () => setViewMode(ViewModes.MOD), className: modButtonClass}, 'Modulators')),
|
||||||
e('div', {id: 'grid'}, ...grid)
|
displayIfEnabled(e('button', { onClick: () => setViewMode(ViewModes.ENUM), className: enumButtonClass }, 'Enumerators'))
|
||||||
|
),
|
||||||
|
e('button', { onClick: toggleEnabled, id: 'hide-button'}, toggleEnabledText),
|
||||||
|
|
||||||
|
//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)
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,8 +610,15 @@ if (!DEBUG){
|
|||||||
window.dispatchEvent(new CustomEvent('saveDict', { 'detail': dictId }));
|
window.dispatchEvent(new CustomEvent('saveDict', { 'detail': dictId }));
|
||||||
});
|
});
|
||||||
|
|
||||||
window.max.bindInlet("param", (inst, paramName, val) => {
|
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.dispatchEvent(new CustomEvent('param', { 'detail': [inst, paramName, val] }));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -455,15 +630,25 @@ if (!DEBUG){
|
|||||||
window.dispatchEvent(new CustomEvent('maxTicks', { 'detail': val }));
|
window.dispatchEvent(new CustomEvent('maxTicks', { 'detail': val }));
|
||||||
});
|
});
|
||||||
|
|
||||||
window.max.bindInlet("userWave", (...points) => {
|
window.max.bindInlet("userWave", (index, ...points) => {
|
||||||
window.dispatchEvent(new CustomEvent('userWave', {'detail' : points}));
|
let data = { points, index };
|
||||||
|
window.dispatchEvent(new CustomEvent('userWave', { 'detail': data }));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.max.bindInlet("viewMode", (mode) => {
|
||||||
|
window.dispatchEvent(new CustomEvent('viewMode', { 'detail': parseInt(mode) }));
|
||||||
|
});
|
||||||
|
|
||||||
/* window.max.binInlet("userWave", (...points) => {
|
window.max.bindInlet("userFunction", (index, ...points) => {
|
||||||
window.dispatchEvent(new CustomEvent('userWave', {'detail' : [points]}));
|
//list of 101 points between 0-100
|
||||||
log("received user points");
|
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(() => {
|
setInterval(() => {
|
||||||
window.dispatchEvent(new CustomEvent('tick'));
|
window.dispatchEvent(new CustomEvent('tick'));
|
||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
|
|
||||||
var TYPEOPTIONS = ["LFO", "Noise"];
|
var TYPEOPTIONS = ["LFO", "Noise"];
|
||||||
var SHAPETYPES = ["Sine", "SawUp", "SawDown", "Tri", "Square", "Custom"];
|
var SHAPETYPES = ["Sine", "SawUp", "SawDown", "Tri", "Square", "Custom_1", "Custom_2", "Custom_3", "Custom_4"];
|
||||||
var NOISETYPES = ["Rand", "Line Int.", "Sine Int."]
|
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",
|
const MODPARAMOPTIONS = ["NONE", "stream", "pulse_length", "eventfulness", "event_length", "metriclarity",
|
||||||
"harmoniclarity", "melodic_cohesion", "melody_scope", "tonic_pitch", "pitch_center", "pitch_range", "dynamics",
|
"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"));
|
return e('select', {className: 'control-type'}, Option("LFO"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function DataCell(element) {
|
||||||
|
return e('td', null, element);
|
||||||
|
}
|
||||||
|
|
||||||
function LfoRow(props){
|
function LfoRow(props){
|
||||||
|
|
||||||
@@ -34,34 +36,42 @@ function LfoRow(props){
|
|||||||
let typeOption = null;
|
let typeOption = null;
|
||||||
|
|
||||||
if (props.type == "LFO"){
|
if (props.type == "LFO"){
|
||||||
typeOption = ListItem(DropDown({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"){
|
else if (props.type == "Noise"){
|
||||||
typeOption = ListItem(DropDown({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'},
|
let content = e('tr', {className: 'lfo-item'},
|
||||||
ListItem(DropDown({onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
|
DataCell(DropDown({locked:props.locked, onChange: props.setInstanceNum, value:props.instanceNum, options: INSTANCEOPTIONS})),
|
||||||
ListItem(DropDown({options: TYPEOPTIONS, onChange: props.setType, value:props.type})),
|
DataCell(DropDown({locked:props.locked, options: TYPEOPTIONS, onChange: props.setType, value:props.type})),
|
||||||
typeOption,
|
typeOption,
|
||||||
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
|
DataCell(DropDown({locked:props.locked, onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
|
||||||
ListItem(e("input", {onChange:props.setFreq, value:props.freq, className:"timeInput"}, null)),
|
DataCell(e("input", {onChange:props.setFreq, value:props.freq, className:"timeInput"}, null)),
|
||||||
ListItem(e(NumberBox, {onChange:props.setMin, value:props.min, step:0.1}, null)),
|
DataCell(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)),
|
DataCell(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)),
|
//DataCell(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)),
|
DataCell(e(NumberBox, {onChange:props.setPhase, value:props.phase, step:0.1}, null)),
|
||||||
ListItem(e("div", {className:"base-val"}, center.toString())),
|
DataCell(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}`})),
|
DataCell(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)),
|
DataCell(e(Button, {text:'+', onClick: props.addLfo, locked: props.locked}, null)),
|
||||||
ListItem(e(Button, {text:'-', onClick: props.removeLfo}, null)),
|
DataCell(e(Button, {text:'-', onClick: props.removeLfo, locked: props.locked}, null)),
|
||||||
ListItem(e("div", {className:"linked"}, linkedText)),
|
DataCell(e("div", {className:"linked"}, linkedText)),
|
||||||
);
|
);
|
||||||
if (props.visible){
|
if (props.visible){
|
||||||
return content
|
return content;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function indexWave(type, phase, userDefinedWave){
|
function indexUserWave(phase, index, userDefinedWaves){
|
||||||
|
return parseFloat(userDefinedWaves[index][Math.floor(phase * 50)]) / 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
function indexUserFunction(phase, index, userDefinedFunctions){
|
||||||
|
return parseFloat(userDefinedFunctions[index][Math.floor(phase * 101)]) / 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
function indexWave(type, phase, userDefinedWaves, userDefinedFunctions, userDefinedTypes){
|
||||||
switch (type){
|
switch (type){
|
||||||
case "Sine":
|
case "Sine":
|
||||||
return (Math.sin(phase * Math.PI * 2) / 2) + 0.5;
|
return (Math.sin(phase * Math.PI * 2) / 2) + 0.5;
|
||||||
@@ -73,12 +83,18 @@ function indexWave(type, phase, userDefinedWave){
|
|||||||
return phase > 0.5? (1-phase) * 2 : phase * 2;
|
return phase > 0.5? (1-phase) * 2 : phase * 2;
|
||||||
case "Square":
|
case "Square":
|
||||||
return +(phase > 0.5);
|
return +(phase > 0.5);
|
||||||
case "Custom":
|
case "Custom_1":
|
||||||
return parseFloat(userDefinedWave[Math.floor(phase * 50)]) / 127
|
return userDefinedTypes[0] == 0 ? indexUserWave(phase, 1, userDefinedWaves) : indexUserFunction(phase, 1, userDefinedFunctions);
|
||||||
|
case "Custom_2":
|
||||||
|
return userDefinedTypes[1] == 0 ? indexUserWave(phase, 2, userDefinedWaves) : indexUserFunction(phase, 2, userDefinedFunctions);
|
||||||
|
case "Custom_3":
|
||||||
|
return userDefinedTypes[2] == 0 ? indexUserWave(phase, 3, userDefinedWaves) : indexUserFunction(phase, 3, userDefinedFunctions);
|
||||||
|
case "Custom_4":
|
||||||
|
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, userDefinedWave, 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++){
|
for (let i=0; i<paramNames.length; i++){
|
||||||
if (visibleArr[i]){
|
if (visibleArr[i]){
|
||||||
|
|
||||||
@@ -92,7 +108,7 @@ function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, cent
|
|||||||
let output = 0;
|
let output = 0;
|
||||||
|
|
||||||
if (typeArr[i] == "LFO")
|
if (typeArr[i] == "LFO")
|
||||||
output = operateLFO(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWave, 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
|
else
|
||||||
output = operateNoise(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, name, noiseData, currTime, beatsInMeasure, ticks);
|
output = operateNoise(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, name, noiseData, currTime, beatsInMeasure, ticks);
|
||||||
if (name !== "NONE")
|
if (name !== "NONE")
|
||||||
@@ -101,7 +117,7 @@ function operateModulators(visibleArr, typeArr, instanceNumArr, paramNames, cent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function operateLFO(center, inst, timeBaseStr, min, max, waveType, phaseArr, phaseIndex, userDefinedWave, 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 amp = parseFloat(max) - parseFloat(min);
|
||||||
let phaseType;
|
let phaseType;
|
||||||
let timeBase;
|
let timeBase;
|
||||||
@@ -113,7 +129,7 @@ function operateLFO(center, inst, timeBaseStr, min, max, waveType, phaseArr, pha
|
|||||||
phase = (currTime * timeBase + parseFloat(phaseArr[phaseIndex])) % 1.00;
|
phase = (currTime * timeBase + parseFloat(phaseArr[phaseIndex])) % 1.00;
|
||||||
else if (phaseType === PhaseTypes.MUSICAL)
|
else if (phaseType === PhaseTypes.MUSICAL)
|
||||||
phase = (maxTicks % timeBase) / timeBase;
|
phase = (maxTicks % timeBase) / timeBase;
|
||||||
let unscaled = indexWave(waveType, phase, userDefinedWave);
|
let unscaled = indexWave(waveType, phase, userDefinedWaves, userDefinedFunctions, userDefinedTypes);
|
||||||
syncDisplay(inst, name, unscaled);
|
syncDisplay(inst, name, unscaled);
|
||||||
|
|
||||||
return unscaled * amp + center + parseFloat(min);
|
return unscaled * amp + center + parseFloat(min);
|
||||||
@@ -142,27 +158,24 @@ function operateNoise(center, inst, timeBaseStr, min, max, waveType, phaseArr, i
|
|||||||
else if (phaseType === PhaseTypes.MUSICAL)
|
else if (phaseType === PhaseTypes.MUSICAL)
|
||||||
phase = (maxTicks % timeBase) / timeBase;
|
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
|
||||||
|
|
||||||
if (noiseData.cachedNoiseValueArr[index][0] == 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.cachedNoiseValueArr[index][0] = noiseData.cachedNoiseValueArr[index][1];
|
noiseData.cachedNoiseValueArr1[index] = Math.random();
|
||||||
if (noiseData.cachedNoiseValueArr[index][0] == 0)
|
noiseData.setCachedNoiseValueArr1(noiseData.cachedNoiseValueArr1);
|
||||||
noiseData.cachedNoiseValueArr[index][0] = center;
|
noiseData.setCachedNoiseValueArr2(noiseData.cachedNoiseValueArr2);
|
||||||
|
|
||||||
noiseData.cachedNoiseValueArr[index][1] = Math.random();
|
|
||||||
noiseData.setCachedNoiseValueArr(noiseData.cachedNoiseValueArr);
|
|
||||||
}
|
}
|
||||||
noiseData.lastPhaseArr[index] = phase;
|
noiseData.lastPhaseArr[index] = phase;
|
||||||
noiseData.setLastPhaseArr(noiseData.lastPhaseArr);
|
noiseData.setLastPhaseArr(noiseData.lastPhaseArr);
|
||||||
|
|
||||||
let sinePhase = (Math.sin(Math.PI + Math.PI * phase) + 1) / 2
|
|
||||||
|
|
||||||
//let unscaled = (noiseData.cachedNoiseValueArr[index][1] - noiseData.cachedNoiseValueArr[index][0]) * sinePhase + noiseData.cachedNoiseValueArr[index][0];
|
//let unscaled = (noiseData.cachedNoiseValueArr[index][1] - noiseData.cachedNoiseValueArr[index][0]) * sinePhase + noiseData.cachedNoiseValueArr[index][0];
|
||||||
let unscaled = interpolateNoise(noiseData.noiseTypeArr[index], noiseData.cachedNoiseValueArr[index][0], noiseData.cachedNoiseValueArr[index][1], phase);
|
let unscaled = interpolateNoise(noiseType, noiseData.cachedNoiseValueArr1[index], noiseData.cachedNoiseValueArr2[index], phase);
|
||||||
syncDisplay(inst, name, unscaled);
|
syncDisplay(inst, name, unscaled);
|
||||||
|
|
||||||
return unscaled * amp + center + parseFloat(min);
|
return unscaled * amp + center + parseFloat(min);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function interpolateNoise(type, cachedVal1, cachedVal2, phase){
|
function interpolateNoise(type, cachedVal1, cachedVal2, phase){
|
||||||
Reference in New Issue
Block a user