phase calculated from ticks

This commit is contained in:
trian-gles 2024-09-03 11:34:32 +02:00
parent c794b5bc2f
commit 45847fbae4
3 changed files with 98 additions and 59 deletions

View File

@ -10,7 +10,7 @@
} }
, ,
"classnamespace" : "box", "classnamespace" : "box",
"rect" : [ 34.0, 76.0, 981.0, 763.0 ], "rect" : [ 34.0, 76.0, 1155.0, 763.0 ],
"bglocked" : 0, "bglocked" : 0,
"openinpresentation" : 0, "openinpresentation" : 0,
"default_fontsize" : 12.0, "default_fontsize" : 12.0,
@ -39,6 +39,44 @@
"subpatcher_template" : "", "subpatcher_template" : "",
"assistshowspatchername" : 0, "assistshowspatchername" : 0,
"boxes" : [ { "boxes" : [ {
"box" : {
"fontname" : "Arial",
"fontsize" : 13.0,
"id" : "obj-29",
"maxclass" : "newobj",
"numinlets" : 2,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"patching_rect" : [ 465.0, 141.0, 210.0, 23.0 ],
"text" : "metro @interval 40 ticks @active 1"
}
}
, {
"box" : {
"id" : "obj-28",
"maxclass" : "button",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "bang" ],
"parameter_enable" : 0,
"patching_rect" : [ 826.0, 79.0, 24.0, 24.0 ]
}
}
, {
"box" : {
"id" : "obj-3",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 817.0, 147.0, 80.0, 22.0 ],
"text" : "prepend ticks"
}
}
, {
"box" : { "box" : {
"id" : "obj-54", "id" : "obj-54",
"maxclass" : "newobj", "maxclass" : "newobj",
@ -156,7 +194,7 @@
"numoutlets" : 1, "numoutlets" : 1,
"outlettype" : [ "" ], "outlettype" : [ "" ],
"patching_rect" : [ 385.0, 715.0, 84.0, 36.0 ], "patching_rect" : [ 385.0, 715.0, 84.0, 36.0 ],
"text" : "metriclarity 22.176645" "text" : "metriclarity 0.5"
} }
} }
@ -244,18 +282,6 @@
"text" : "prepend timesig" "text" : "prepend timesig"
} }
}
, {
"box" : {
"id" : "obj-52",
"maxclass" : "newobj",
"numinlets" : 1,
"numoutlets" : 1,
"outlettype" : [ "" ],
"patching_rect" : [ 545.0, 135.0, 89.0, 22.0 ],
"text" : "prepend tempo"
}
} }
, { , {
"box" : { "box" : {
@ -299,8 +325,7 @@
"numinlets" : 1, "numinlets" : 1,
"numoutlets" : 5, "numoutlets" : 5,
"outlettype" : [ "preset", "int", "preset", "int", "" ], "outlettype" : [ "preset", "int", "preset", "int", "" ],
"patching_rect" : [ 934.0, 27.0, 100.0, 40.0 ], "patching_rect" : [ 934.0, 27.0, 100.0, 40.0 ]
"pattrstorage" : "storage"
} }
} }
@ -784,6 +809,27 @@
"source" : [ "obj-27", 1 ] "source" : [ "obj-27", 1 ]
} }
}
, {
"patchline" : {
"destination" : [ "obj-47", 0 ],
"source" : [ "obj-28", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-47", 0 ],
"source" : [ "obj-29", 0 ]
}
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-3", 0 ]
}
} }
, { , {
"patchline" : { "patchline" : {
@ -886,8 +932,8 @@
} }
, { , {
"patchline" : { "patchline" : {
"destination" : [ "obj-52", 0 ], "destination" : [ "obj-3", 0 ],
"source" : [ "obj-47", 4 ] "source" : [ "obj-47", 7 ]
} }
} }
@ -904,13 +950,6 @@
"source" : [ "obj-5", 0 ] "source" : [ "obj-5", 0 ]
} }
}
, {
"patchline" : {
"destination" : [ "obj-2", 0 ],
"source" : [ "obj-52", 0 ]
}
} }
, { , {
"patchline" : { "patchline" : {

View File

@ -52,7 +52,7 @@ function MasterLfoHandler(){
const [modCenterVals, setModCenterVals] = React.useState({'1':{}, '2':{}, '3':{}, '4':{}}); const [modCenterVals, setModCenterVals] = React.useState({'1':{}, '2':{}, '3':{}, '4':{}});
const [bpm, setBpm] = React.useState(100); const [ticks, setTicks] = React.useState(0);
const [beatsInMeasure, setBeatsInMeasure] = React.useState(4); const [beatsInMeasure, setBeatsInMeasure] = React.useState(4);
const [shapeArr, setShapeArr] = React.useState(Array(MAXLFOS).fill('Sine')); const [shapeArr, setShapeArr] = React.useState(Array(MAXLFOS).fill('Sine'));
@ -200,11 +200,8 @@ function MasterLfoHandler(){
function handleTick(event) { function handleTick(event) {
let time = (Date.now() - firstUpdateTime) / 1000; let time = (Date.now() - firstUpdateTime) / 1000;
operateModulators(modVisibleArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, phaseArr, userDefinedWave, time, bpm, beatsInMeasure);
}
function handleBpm(event) { operateModulators(modVisibleArr, modInstanceNumArr, djParamArr, modCenterVals, freqArr, minArr, maxArr, shapeArr, phaseArr, userDefinedWave, time, beatsInMeasure, ticks);
setBpm(event.detail);
} }
function handleTimeSig(event) { function handleTimeSig(event) {
@ -215,15 +212,19 @@ function MasterLfoHandler(){
setUserDefinedWave(event.detail); setUserDefinedWave(event.detail);
} }
function handleMaxTicks(event){
setTicks(event.detail);
}
window.addEventListener('loadDict', handleLoad); window.addEventListener('loadDict', handleLoad);
window.addEventListener('saveDict', handleSave); window.addEventListener('saveDict', handleSave);
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('tempo', handleBpm);
window.addEventListener('timesig', handleTimeSig); window.addEventListener('timesig', handleTimeSig);
window.addEventListener('userWave', handleChangeUserWave); window.addEventListener('userWave', handleChangeUserWave);
window.addEventListener('maxTicks', handleMaxTicks);
return () => { return () => {
window.removeEventListener('loadDict', handleLoad); window.removeEventListener('loadDict', handleLoad);
@ -231,11 +232,11 @@ function MasterLfoHandler(){
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('tempo', handleBpm);
window.removeEventListener('timesig', handleTimeSig); window.removeEventListener('timesig', handleTimeSig);
window.removeEventListener('userWave', handleChangeUserWave); window.removeEventListener('userWave', handleChangeUserWave);
window.removeEventListener('maxTicks', handleMaxTicks);
}; };
}, [...allModArrays, ...allEnumArrays, ...allEnumMats, modCenterVals, render, bpm, beatsInMeasure]); }, [...allModArrays, ...allEnumArrays, ...allEnumMats, modCenterVals, render, beatsInMeasure, ticks]);
function CheckLinked(inst, param, checkInstArr, checkParamArr){ function CheckLinked(inst, param, checkInstArr, checkParamArr){
@ -432,14 +433,14 @@ if (!DEBUG){
window.dispatchEvent(new CustomEvent('param', {'detail' : [inst, paramName, val]})); window.dispatchEvent(new CustomEvent('param', {'detail' : [inst, paramName, val]}));
}); });
window.max.bindInlet("tempo", (val) => {
window.dispatchEvent(new CustomEvent('tempo', {'detail' : val}));
});
window.max.bindInlet("timesig", (top, bottom) => { window.max.bindInlet("timesig", (top, bottom) => {
window.dispatchEvent(new CustomEvent('timesig', {'detail' : [top, bottom]})); window.dispatchEvent(new CustomEvent('timesig', {'detail' : [top, bottom]}));
}); });
window.max.bindInlet("ticks", (val) => {
window.dispatchEvent(new CustomEvent('maxTicks', {'detail' : val}));
});
window.max.bindInlet("userWave", (...points) => { window.max.bindInlet("userWave", (...points) => {
window.dispatchEvent(new CustomEvent('userWave', {'detail' : points})); window.dispatchEvent(new CustomEvent('userWave', {'detail' : points}));
}); });

View File

@ -66,7 +66,7 @@ function indexWave(type, phase, userDefinedWave){
} }
} }
function operateModulators(visibleArr, instanceNumArr, paramNames, centers, freqs, mins, maxs, waveTypes, phaseArr, userDefinedWave, currTime, bpm, beatsInMeasure){ function operateModulators(visibleArr, instanceNumArr, paramNames, centers, freqs, mins, maxs, waveTypes, phaseArr, userDefinedWave, 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]){
@ -76,24 +76,26 @@ function operateModulators(visibleArr, instanceNumArr, paramNames, centers, freq
if (centers[inst].hasOwnProperty(name)){ if (centers[inst].hasOwnProperty(name)){
center = centers[inst][name]; center = centers[inst][name];
} }
let output = operateModulator(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWave, name, currTime, bpm, beatsInMeasure); let output = operateModulator(center, inst, freqs[i], mins[i], maxs[i], waveTypes[i], phaseArr, i, userDefinedWave, name, currTime, beatsInMeasure, ticks);
if (name !== "NONE") if (name !== "NONE")
window.dispatchEvent(new CustomEvent('enum', {'detail' : [inst, name, output]})); window.dispatchEvent(new CustomEvent('enum', {'detail' : [inst, name, output]}));
} }
} }
} }
function operateModulator(center, inst, freq, min, max, waveType, phaseArr, phaseI, userDefinedWave, name, currTime, bpm, beatsInMeasure){ function operateModulator(center, inst, timeBaseStr, min, max, waveType, phaseArr, phaseI, userDefinedWave, name, currTime, beatsInMeasure, maxTicks){
let amp = parseFloat(max) - parseFloat(min); let amp = parseFloat(max) - parseFloat(min);
let phaseType; let phaseType;
let timeBase;
freq, phaseType = parseLfoTime(freq, bpm, beatsInMeasure); [timeBase, phaseType] = parseLfoTime(timeBaseStr, beatsInMeasure);
let phase; let phase;
if (phaseType === PhaseTypes.TIME) if (phaseType === PhaseTypes.TIME)
phase = (currTime * freq + parseFloat(phaseArr[phaseI])) % 1.00; phase = (currTime * timeBase + parseFloat(phaseArr[phaseI])) % 1.00;
else if (phaseType === PhaseTypes.MUSICAL) else if (phaseType === PhaseTypes.MUSICAL)
phase = 0; // needs to be worked on phase = (maxTicks % timeBase) / timeBase;
let unscaled = indexWave(waveType, phase, userDefinedWave); let unscaled = indexWave(waveType, phase, userDefinedWave);
let el = document.getElementById(`slider-${inst}-${name}`); let el = document.getElementById(`slider-${inst}-${name}`);
@ -103,33 +105,30 @@ function operateModulator(center, inst, freq, min, max, waveType, phaseArr, phas
return unscaled * amp + center + parseFloat(min); return unscaled * amp + center + parseFloat(min);
} }
// actual returns the period for musical timing, to avoid floating point errors
function parseLfoTime(lfoTime, bpm, beatsInMeasure){ function parseLfoTime(lfoTime, beatsInMeasure){
if (lfoTime.slice(-2) == "hz"){ if (lfoTime.slice(-2) == "hz"){
return parseFloat(lfoTime.slice(0, -2)), PhaseTypes.TIME; return [parseFloat(lfoTime.slice(0, -2)), PhaseTypes.TIME];
} }
else if (lfoTime.slice(-2) == "ms"){ else if (lfoTime.slice(-2) == "ms"){
return 1000 / parseFloat(lfoTime.slice(0, -2)), PhaseTypes.TIME; return [1000 / parseFloat(lfoTime.slice(0, -2)), PhaseTypes.TIME];
} }
else if (lfoTime.slice(-1) == "s"){ else if (lfoTime.slice(-1) == "s"){
return 1 / parseFloat(lfoTime.slice(0, -1)), PhaseTypes.TIME; return [1 / parseFloat(lfoTime.slice(0, -1)), PhaseTypes.TIME];
} }
else if ((lfoTime.match(/:/g) || []).length == 2){ else if ((lfoTime.match(/:/g) || []).length == 2){
return 1 / moment.duration(lfoTime).asSeconds(), PhaseTypes.TIME; return [1 / moment.duration(lfoTime).asSeconds(), PhaseTypes.TIME];
} }
else if ((lfoTime.match(/\./g) || []).length == 2){ else if ((lfoTime.match(/\./g) || []).length == 2){
return musicalTimingToFreq(...lfoTime.split('.'), bpm, beatsInMeasure), PhaseTypes.MUSICAL return [musicalTimingToFreq(...lfoTime.split('.'), beatsInMeasure), PhaseTypes.MUSICAL];
} }
else { else {
return 0; return [0, PhaseTypes.TIME];
} }
} }
function musicalTimingToFreq(bars, beats, ticks, bpm, beatsInMeasure){ function musicalTimingToFreq(bars, beats, ticks, beatsInMeasure){
let totalTicks = (parseFloat(bars) * parseFloat(beatsInMeasure) + beats) * 480 + parseFloat(ticks); let totalTicks = (parseFloat(bars) * parseFloat(beatsInMeasure) + parseFloat(beats)) * 480 + parseFloat(ticks);
let tpm = bpm * 480; return totalTicks;
let cyclesPerMinute = tpm / totalTicks;
let hz = cyclesPerMinute / 60;
return hz;
} }