fully functional, with enums

This commit is contained in:
Kieran McAuliffe 2024-07-19 13:55:05 +02:00
parent 148e8211b3
commit 87b6237b19
4 changed files with 131 additions and 75 deletions

View File

@ -3,9 +3,10 @@
/////////////////////////
// NOT A REACT FUNCTIONAL COMPONENT. MERELY RETURNS AN ARRAY WHICH IS UNPACKED
function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames, setEnumNames){
let items = []
let items = [];
for (let i = 0; i < MAXENUMPOINTS; i++){
items.push(ListItem(e(TextBox, {onChange: CreateMatrixParamChanger(enumNames, setEnumNames, index, i), value: enumNames[index][i]}, null)));
@ -17,7 +18,7 @@ function EnumeratorItems(index, enumBreakPoints, setEnumBreakPoints, enumNames,
function EnumeratorRow(props){
let content = e('ul', {className: 'lfo-item'},
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: PARAMOPTIONS})),
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
ListItem(e(NumberBox, {onChange: props.setEnumItemCounts, step:1, value:props.enumItems, className: 'enum-count'}, null)),
ListItem(e(NumberBox, {onChange: CreateMatrixParamChanger(props.enumBreakPoints, props.setEnumBreakPoints, props.index, 0), value:props.enumBreakPoints[props.index][0], step:0.1}, null)),
...(EnumeratorItems(props.index, props.enumBreakPoints, props.setEnumBreakPoints, props.enumNames, props.setEnumNames).slice(0, props.enumItems * 2)),
@ -29,12 +30,13 @@ function EnumeratorRow(props){
};
}
// FIX THIS
function enumerate(name, inval, count, keys, vals){
let output = "OUT OF RANGE";
for (let i=0; i < count; i++){
if (inval >= keys[i]){
output = vals[i - 1];
for (let i=0; i < count + 1; i++){
if (inval <= keys[i]){
if (i > 0)
output = vals[i - 1];
break
}
}

View File

@ -3,14 +3,14 @@
"fileversion" : 1,
"appversion" : {
"major" : 8,
"minor" : 6,
"revision" : 2,
"minor" : 5,
"revision" : 6,
"architecture" : "x64",
"modernui" : 1
}
,
"classnamespace" : "box",
"rect" : [ 292.0, 100.0, 799.0, 715.0 ],
"rect" : [ 741.0, 148.0, 799.0, 715.0 ],
"bglocked" : 0,
"openinpresentation" : 0,
"default_fontsize" : 12.0,
@ -40,25 +40,86 @@
"assistshowspatchername" : 0,
"boxes" : [ {
"box" : {
"id" : "obj-17",
"id" : "obj-27",
"linecount" : 2,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 520.0, 441.0, 150.0, 34.0 ],
"text" : "question for Georg: what should `phase` do?"
"patching_rect" : [ 664.0, 443.0, 150.0, 33.0 ],
"text" : "BUG - LOADING AMP DOESN'T WORK"
}
}
, {
"box" : {
"id" : "obj-13",
"id" : "obj-25",
"maxclass" : "newobj",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"patching_rect" : [ 454.0, 27.5, 48.0, 22.0 ],
"text" : "del 200"
}
}
, {
"box" : {
"id" : "obj-24",
"linecount" : 3,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 120.0, 230.0, 254.0, 47.0 ],
"presentation_linecount" : 4,
"text" : "This parameter is not defined by either the Modulators or Enumerators, so it will be passed directly to the output"
}
}
, {
"box" : {
"id" : "obj-23",
"linecount" : 2,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 126.0, 135.0, 197.0, 33.0 ],
"text" : "This parameter is defined in the mMcenter value for that LFO"
}
}
, {
"box" : {
"id" : "obj-21",
"linecount" : 10,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 111.0, 353.0, 253.0, 141.0 ],
"text" : "The operation runs\n\nInput > Modulators > Enumerators > Output\n\nA parameter from the input not established by a Modulator will be passed directly to the Enumerators\n\nLikewise, the Enumerators will pass not established parameters"
}
}
, {
"box" : {
"id" : "obj-15",
"maxclass" : "message",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 130.0, 183.0, 88.0, 22.0 ],
"text" : "param pass 30"
"patching_rect" : [ 146.0, 193.0, 121.0, 22.0 ],
"text" : "param metriclarity 40"
}
}
, {
"box" : {
"id" : "obj-17",
"linecount" : 2,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 734.0, 39.0, 150.0, 33.0 ],
"text" : "question for Georg: what should `phase` do?"
}
}
@ -69,22 +130,10 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 228.0, 294.0, 129.0, 22.0 ],
"patching_rect" : [ 146.0, 281.0, 129.0, 22.0 ],
"text" : "param attenuation 200"
}
}
, {
"box" : {
"id" : "obj-5",
"maxclass" : "button",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"parameter_enable" : 0,
"patching_rect" : [ 365.0, 582.0, 24.0, 24.0 ]
}
}
, {
"box" : {
@ -102,9 +151,9 @@
"box" : {
"data" : {
"data" : {
"enumArrays" : [ [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ 2, 2, "4", "2", "2", "2", "2", "2", "2", "2" ] ],
"enumMats" : [ [ [ 0, "4", 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ "-4", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, "-1", "5", 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ], [ [ "asd", "wae", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "asr", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ] ] ],
"modArrays" : [ [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "Sine", "SawDown", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine" ], [ "melody_scope", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation" ], [ "3", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "1", "6", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "0", "2", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ] ]
"enumArrays" : [ [ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "2", 2, 2, "2", "2", "2", "2", "2", "2", "2" ], [ "event_length", "meter", "stream", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation" ] ],
"enumMats" : [ [ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ "0", "1", "2", 3, 4, 5, 6, 7, 8, 9, 10 ], [ "0", "1", "2", 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ], [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] ], [ [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "3 4", "7 8", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "0", "1", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ], [ "param", "param", "param", "param", "param", "param", "param", "param", "param", "param" ] ] ],
"modArrays" : [ [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ], [ "Sine", "SawUp", "SawUp", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine", "Sine" ], [ "metriclarity", "stream", "meter", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation", "attenuation" ], [ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "30", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1" ], [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" ] ]
}
}
@ -112,12 +161,11 @@
"id" : "obj-4",
"maxclass" : "newobj",
"numinlets" : 2,
"numoutlets" : 5,
"outlettype" : [ "dictionary", "", "", "", "" ],
"patching_rect" : [ 693.0, 69.0, 159.0, 22.0 ],
"numoutlets" : 4,
"outlettype" : [ "dictionary", "", "", "" ],
"patching_rect" : [ 548.0, 604.0, 159.0, 22.0 ],
"saved_object_attributes" : {
"embed" : 1,
"legacy" : 1,
"parameter_enable" : 0,
"parameter_mappable" : 0
}
@ -132,7 +180,7 @@
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 318.894733190536499, 420.473682403564453, 91.0, 22.0 ],
"patching_rect" : [ 424.52631402015686, 484.473682403564453, 91.0, 22.0 ],
"text" : "print @popup 1"
}
@ -144,7 +192,7 @@
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 438.52631402015686, 27.5, 150.0, 34.0 ],
"patching_rect" : [ 504.0, 6.0, 150.0, 33.0 ],
"text" : "required due to the asynchronous operation"
}
@ -164,11 +212,12 @@
, {
"box" : {
"id" : "obj-45",
"linecount" : 5,
"maxclass" : "comment",
"numinlets" : 1,
"numoutlets" : 0,
"patching_rect" : [ 732.0, 34.0, 150.0, 20.0 ],
"text" : "Storage for the matrix"
"patching_rect" : [ 557.0, 520.0, 150.0, 74.0 ],
"text" : "Storage for the matrix. Unfortunately, jsweb dictionary handling isn't great, so we can't use it like a native dict object"
}
}
@ -191,7 +240,7 @@
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 594.789473533630371, 65.842105150222778, 39.0, 22.0 ],
"patching_rect" : [ 623.789473533630371, 69.0, 39.0, 22.0 ],
"text" : "dump"
}
@ -227,7 +276,7 @@
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 319.0, 125.0, 552.0, 245.0 ],
"patching_rect" : [ 428.894733190536499, 104.0, 459.105266809463501, 323.0 ],
"rendermode" : 0,
"url" : "file://lfogui.html"
}
@ -244,14 +293,14 @@
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-13", 0 ]
"source" : [ "obj-14", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-14", 0 ]
"source" : [ "obj-15", 0 ]
}
}
@ -272,15 +321,6 @@
, {
"patchline" : {
"destination" : [ "obj-10", 0 ],
"order" : 1,
"source" : [ "obj-2", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-5", 0 ],
"order" : 0,
"source" : [ "obj-2", 0 ]
}
@ -300,10 +340,26 @@
"source" : [ "obj-20", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-15", 0 ],
"source" : [ "obj-25", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-16", 0 ],
"order" : 1,
"source" : [ "obj-3", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-25", 0 ],
"order" : 0,
"source" : [ "obj-3", 0 ]
}
@ -316,19 +372,6 @@
}
],
"parameters" : {
"parameterbanks" : {
"0" : {
"index" : 0,
"name" : "",
"parameters" : [ "-", "-", "-", "-", "-", "-", "-", "-" ]
}
}
,
"inherited_shortname" : 1
}
,
"dependency_cache" : [ ],
"autosave" : 0
}

View File

@ -56,12 +56,13 @@ function MasterLfoHandler(){
const allModArrays = [modVisibleArr, shapeArr, djParamArr, freqArr, ampArr, phaseArr];
const allModSetters = [setModVisibleArr, setShapeArr, setDjParamArr, setFreqArr, setAmpArr, setPhaseArr];
const modBlankVals = [true, SHAPETYPES[0], PARAMOPTIONS[0], '1', '1', '0'];
const modBlankVals = [true, SHAPETYPES[0], MODPARAMOPTIONS[0], '1', '1', '0'];
/// ENUMERATOR ARRAYS
const [enumVisibleArr, setEnumVisibleArr] = React.useState(initVisArr);
const [enumItemCounts, setEnumItemCounts] = React.useState(Array(MAXENUMPOINTS).fill('2'));
const [enumDjParamArr, setEnumDjParamArr] = React.useState(Array(MAXENUMPOINTS).fill('attenuation'));
let baseEnumBreakpoints = Array(MAXENUMS).fill(0).map(x => Array(MAXENUMPOINTS+ 1).fill(0));
for (let i = 0; i < MAXENUMS; i++){
@ -83,8 +84,8 @@ function MasterLfoHandler(){
let baseEnumNames = Array(MAXENUMS).fill(0).map(x => Array(MAXENUMPOINTS).fill('param'));
const [enumNames, setEnumNames] = React.useState(baseEnumNames);
const allEnumArrays = [enumVisibleArr, enumItemCounts];
const allEnumArrSetters = [setEnumVisibleArr, setEnumItemCounts];
const allEnumArrays = [enumVisibleArr, enumItemCounts, enumDjParamArr];
const allEnumArrSetters = [setEnumVisibleArr, setEnumItemCounts, setEnumDjParamArr];
const allEnumMats = [enumBreakPoints, enumNames];
const allEnumMatSetters = [setEnumBreakPoints, setEnumNames];
@ -100,13 +101,21 @@ function MasterLfoHandler(){
function handleLoad(event) {
window.max.getDict(event.detail, (dict) => {
for (let i = 0; i<MAXLFOS; i++) {
for (let i = 0; i<allModArrays.length; i++) {
allModSetters[i](dict.data.modArrays[i]);
}
for (let i = 0; i<allEnumArrays.length; i++) {
allEnumArrSetters[i](dict.data.enumArrays[i]);
}
for (let i = 0; i<allEnumMats.length; i++) {
allEnumMatSetters[i](dict.data.enumMats[i]);
}
})
}
@ -129,7 +138,7 @@ function MasterLfoHandler(){
// if none of the Enums use this param, then we output it
let i = 0;
while (i < MAXENUMS){
if (enumVisibleArr[i] && enumNames[i] == name)
if (enumVisibleArr[i] && enumDjParamArr[i] == name)
break;
i++
}
@ -137,7 +146,7 @@ function MasterLfoHandler(){
window.max.outlet(name + ' ' + val);
}
else {
window.max.outlet(name + ' ' + val);
enumerate(name, val, enumItemCounts[i], enumBreakPoints[i], enumNames[i]);
}
@ -270,6 +279,8 @@ function MasterLfoHandler(){
enumNames: enumNames,
setEnumNames: setEnumNames,
visible: enumVisibleArr[i],
djParam: enumDjParamArr[i],
setDjParam: CreateParamChanger(enumDjParamArr, setEnumDjParamArr, i),
addEnum: () => {
if (id < MAXLFOS - 1){
if (enumVisibleArr[id + 1]){ // if we need to open up space

View File

@ -3,9 +3,9 @@
/////////////////////////
var SHAPETYPES = ["Sine", "SawUp", "SawDown", "Tri", "Square"];
const PARAMOPTIONS = ["pulse_length", "eventfulness", "event_length", "metriclarity",
const MODPARAMOPTIONS = ["stream", "pulse_length", "eventfulness", "event_length", "metriclarity",
"harmoniclarity", "melodic_cohesion", "melody_scope", "tonic_pitch", "pitch_center", "pitch_range", "dynamics",
"attenuation", "chordal_weight"]
"attenuation", "chordal_weight", "tonality-profile", "ostinato-buffer", "ostinato", "meter", "scale"];
function ControlType(){
return e('select', {className: 'control-type'}, Option("LFO"));
@ -17,7 +17,7 @@ function LfoRow(props){
let content = e('ul', {className: 'lfo-item'},
ListItem(ControlType()),
ListItem(DropDown({onChange: props.setShape, value:props.shape, options: SHAPETYPES})),
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: PARAMOPTIONS})),
ListItem(DropDown({onChange: props.setDjParam, value: props.djParam, options: MODPARAMOPTIONS})),
ListItem(e(NumberBox, {onChange:props.setFreq, value:props.freq, 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)),
@ -32,7 +32,7 @@ function LfoRow(props){
function indexWave(type, phase){
switch (type){
case "Sine":
return Math.sin(phase * Math.PI * 2);
return (Math.sin(phase * Math.PI * 2)/2) + 1;
case "SawUp":
return phase;
case "SawDown":