yes, I admit I am a menace
This has to do with computeOutputData(), output strings and a output-parameter-bound kuiml action trigger that helps me to keep cxx and ui in synch.
The finding is that only output string 0 and output string 1 will find their way into kuiml action trigger in in the current cycle.
Very difficult to explain... here's some code (commented excerpts)
KUIML:
important is CLICKEDCHORDNAME, script_output_string2 and updateChords().
If certain changes occur in the DSP part, computeOutputData() will update values in script_output_string0 and script_output_string2 (proven that it does) and increase value of OP_CHORDCHANGETYPE, in order to trigger updateChords() in KUIML.
=================================
Code: Select all
:
:
<STRING id="CLICKEDCHORDNAME" default="---"/>
<STRING id="ARRCHORDNAME0" default="---" persistent="false"/>
<STRING id="ARRCHORDNAME1" default="---" persistent="false"/>
<STRING id="ARRCHORDNAME2" default="---" persistent="false"/>
<STRING id="ARRCHORDNAME3" default="---" persistent="false"/>
<STRING id="CHORDCANDIDATENAME0" default="---" persistent="false"/>
<STRING id="CHORDCANDIDATENAME1" default="---" persistent="false"/>
<STRING id="CHORDCANDIDATENAME2" default="---" persistent="false"/>
<STRING id="CHORDCANDIDATENAME3" default="---" persistent="false"/>
<PARAM id="CHORDCANDIDATEINFO0" type="integer" min="0" max="2147483647" default="0" exposed="false" persistent="false"/>
<PARAM id="CHORDCANDIDATEINFO1" type="integer" min="0" max="2147483647" default="0" exposed="false" persistent="false"/>
<PARAM id="CHORDCANDIDATEINFO2" type="integer" min="0" max="2147483647" default="0" exposed="false" persistent="false"/>
<PARAM id="CHORDCANDIDATEINFO3" type="integer" min="0" max="2147483647" default="0" exposed="false" persistent="false"/>
:
<ACTION_TRIGGER event_ids="custom_out_param6.value_changed" script="updateChords(custom_out_param6);"/>
<=== gets triggered when computeOutputData() changes (increases) out param 6 value
:
:
<SCRIPT .....
:
void updateChords( uint updateChordType )
{
CLICKEDCHORDNAME = $script_output_string2$; <==== CORPUS DELICTI !!
$script_output_string2$ always contains value from PREVIOUS computeOutputData()
string arrChordNames=$script_output_string1$; <==== SEEMS GOOD, BUT CANT PROVE THAT ITS GOOD IN ANY CASE
array<string> aChords=arrChordNames.split(",");
if( aChords.length > 0) {
firstAC= aChords[0];
ARRCHORDNAME0=aChords[0];
ARRCHORDNAME1=aChords[1];
ARRCHORDNAME2=aChords[2];
ARRCHORDNAME3=aChords[3];
}
firstCC = "empty";
string ccNames=$script_output_string0$; <==== GOOD IN ANY CASE, contains always the value of CURRENT computeOutputData()
chordCandidates = $script_output_string0$;
array<string> aCcChords=ccNames.split(",");
if( aChords.length > 0) {
firstCC= aCcChords[0].substr(5);;
CHORDCANDIDATENAME0=aCcChords[0].substr(7);
CHORDCANDIDATENAME1=aCcChords[1].substr(7);
CHORDCANDIDATENAME2=aCcChords[2].substr(7);
CHORDCANDIDATENAME3=aCcChords[3].substr(7);
CHORDCANDIDATEINFO0 = parseInt(aCcChords[0].substr(0,7));
CHORDCANDIDATEINFO1 = parseInt(aCcChords[1].substr(0,7));
CHORDCANDIDATEINFO2 = parseInt(aCcChords[2].substr(0,7));
CHORDCANDIDATEINFO3 = parseInt(aCcChords[3].substr(0,7));
} else {
/*firstCC = "empty";*/
}
updatesMade = updatesMade+1;
}CXX:
=================================
Code: Select all
OP_CHORDCHANGETYPE = op("ChordChangeType", "", 0,65535,0,".0"); <== OUTPUT PARAM 6 (triggers kuiml action trigger)
:
OPS_CHORDCANDIDATENAMES = ops("ChordCandidateNames"); <== OUTPUT STRING 0
OPS[OPS_CHORDCANDIDATENAMES] = "";
OPS_ARRCHORDNAMES = ops("ArrChordNames"); <== OUTPUT STRING 1
OPS[OPS_ARRCHORDNAMES] = "";
OPS_CHORDNAME = ops("ChordName"); <== OUTPUT STRING 2
OPS[OPS_CHORDNAME] = "";
:
:
void computeOutputData()
{
chordTypesToUpdate = 0;
if( chordChanged ) {
if( chordDetector.hasResults()) {
chordTypesToUpdate |= 1;
OPS[OPS_CHORDNAME] = curChordInfoName; <=== CORPUS DELICTY
(output string 2) I can prove from logs that it actually gets changed each expected time
to a current value, but in kuiml (action trigger) always arrives the PREVIOUSLY computed
value.
}
chordChanged=false;
}
if( arrChordsChanged ) {
string arrChordNames;
for( uint i=0; i<15;i++) {
arrChordNames+=curArrChordNames[i]+",";
}
arrChordNames+=curArrChordNames[15];
OPS[OPS_ARRCHORDNAMES] = arrChordNames; <=== (output string 1) Seems to work (but cant prove if always, cause this changes only once in a while)
chordTypesToUpdate |= 2;
arrChordsChanged = false;
}
if( chordCandidatesChanged ) {
string arrChordNames;
for( uint i=0; i<3;i++) {
arrChordNames += formatInt(int64(curChordCandidatesInfo[i]), "0", 7);
arrChordNames += curChordCandidateNames[i]+",";
}
arrChordNames += formatInt(int64(curChordCandidatesInfo[3]), "0", 7);
arrChordNames+=curChordCandidateNames[3];
OPS[OPS_CHORDCANDIDATENAMES] = arrChordNames; <=== (output string 0) Can prove that this gets updated each expected time along with output string 2,
output string 0 gets into kuiml action trigger with this CURRENT value
chordTypesToUpdate |= 4;
chordCandidatesChanged = false;
}
uint uiUpdateMsg = (chordTypesToUpdate > 0 ? (chordTypesToUpdate << 8 | nrOfUIUpdates) : 0);
if( (KittyDSP::Utils::roundDoubleToInt(OP[OP_CHORDCHANGETYPE]) != uiUpdateMsg) && chordTypesToUpdate>0) {
nrOfUIUpdates = (nrOfUIUpdates+1) % 256;
OP[OP_CHORDCHANGETYPE] = uiUpdateMsg; <=== if i want tht UI to update,
put a new value into OP[OP_CHORDCHANGETYPE] (out param 6), so kuiml triggers
}
}
Conclusion is that output string 0 and output string 1 will have their most current values when KUIML triggers updateChords(...), but output string 2 still has the value of the previous computeOutputData() cycle.
The funny thing is that I've swapped output string indexes. Before, output string 0 was OPS_CHORDNAME and output string 2 was OPS_CHORDCANDIDATENAMES (now 2 and 0).
And guess what ... before, OPS_CHORDNAME was always good and OPS_CHORDCANDIDATENAMES contained always the value of the previous computeOutputData() cycle.... the same thing that now happens to OPS_CHORDNAME at OPS position 2.
So.... this seems to me as if only a certain amount of output strings gets updated INTO kuiml before action trigger (in this case OPS_0 and OPS_1 ; OPS_2 stays behind)...
or if updateChords() gets triggered BEFORE kuiml finished the update of all changed OPS.
I am not sure if all this explains the problem properly. My code is still an experimental mess, but if it helps to find out what happens, just give me a ping and i'll send it.
Have a nice weekend
Cheers
Rudi