ArrayArrayArrayArrayArrayArrayArrayArray
Statistics: Posted by woodslanding — 28 Jan 2023, 02:13 Statistics: Posted by senso — 26 Jan 2023, 08:19 Statistics: Posted by woodslanding — 25 Jan 2023, 20:47
Both saveToFile() and loadFromFile() still don't work when I put them in processIdle() though.... and excecution stops at that line, so if I put a flag after the command it is never reached, and I get an endless loop.
I'm hoping these text files are small enough and read/write quickly enough not to cause dropouts when run directly in callback().... they work fine when called from there.
]]>
]]>
If you change the selector back, the loop stops. But the file never gets saved....
EDIT: in this version, it does not loop, but it still fails to write, even when the correct folder exists.
I cannot get any version of this script to malfunction under v.221115.
I will try to make a simplified version that malfunctions the same way, but I am out of time for today.
EDIT: vastly simplified version attached.
But maybe someone else can verify it does the same thing on their system?
]]>
CODE:
const DBUG_ON = TRUE;const CHAN = '1';const PRESET_FOLDER = 'PRESETS';const TEXT_TAGS = ['details'];const INT_TAGS = ['midi-in-ch','transpose','audio-in','cc-to-pitch','mw-midi','at-midi','params-on']; //+ param nums + param channels, 8 buttons, 4 encoder button pairs, 8 encodersconst FLOAT_TAGS = ['input-trim','output-trim','hue','saturation'];const TYP_STR = 0; const TYP_INT = 1; const TYP_FLT = 2;//subpatchesconst TAGS = ['param','text','param','step','param','range.maxpos','range.minpos'];const SUBS = ['renaming','renaming','macros','macros','controls','controls','controls'];const TYPES = [TYP_INT, TYP_STR, TYP_INT, TYP_INT, TYP_INT, TYP_FLT, TYP_FLT];const POLYS = [6,6,4,4,4,4,4];//added to address of subpatches aboveconst SUBPATCH = 'instparamctl.1.';//added to all addressesconst PREFIX = 'patch.sidepanel.1.bankdata.1.';const EXTENSION = '.bank';const DTAG = 'bankManager_';const DELIMITER = '=';const DOT = '.';const NADA = '';var dataPathIN,recallIN,saveIN,channelIN,bankIN, instIN, bankLoadedOUT: tParameter;var gDataString, gTags, gAddresses, gTypes: tStringlist;var i,j: integer;var gReadyToWrite, gReadyToLoad, gListsCreated : boolean;procedure init;var i: integer;begin SetModuleColor($808080+496999); dataPathIN := CreateParam('data path',ptTextField,pioInput); recallIN := CreateParam('recall',ptButton,pioInput); saveIN := CreateParam('save',ptButton,pioInput); instIN := CreateParam('inst name',ptTextField, pioInput); bankIN := CreateParam('bank name',ptTextField, pioInput); bankLoadedOUT := CreateParam('bank loaded', ptDataField, pioOutput); bankLoadedOUT.asInteger(1); //we turn this off during loading, and back on when done gDataString.create; gTags.create; gAddresses.create; gTypes.create;end;procedure destroy; begin gDataString.free; gTags.free; gAddresses.free; gTypes.free; end;procedure debug(s: string); begin if DBUG_ON then strace(DTAG + CHAN + ': ' +s); end;procedure iDebug(s: string; num : integer) begin debug(s + ' ' + intToStr(num)); end;procedure tsDebug(ts: tStringlist; note: string); var i: integer;begin Debug(note); for i := 0 to ts.count - 1 do debug(intToStr(i) + ': ' + ts.getStrings(i));end;function stringsMatch(string1:string;string2:string) : boolean;begin //debug('matching strings:' + string1 + ', '+string2); result := (upperCase(trim(string1)) = uppercase(trim(string2))); end;function getBankPath() : string; var path: string;begin path := dataPathIN.asString + instIN.asString + PathDelim() + bankIN.asString + EXTENSION; debug('bank path = ' + path); result := path; end;function getDataForLine(s: string) : string;var data: string;begin data := copy(s,pos(Delimiter,s) + 1,length(s)); //debug('got data for line: ' + data); result := data;end; function getTagForLine(s: string) : string;var tag: string;begin tag := copy(s, 1, pos(DELIMITER,s) - 1); //debug('got line: ' + s); //debug('got tag for line: ' + tag); result := tag;end; function extractData(data : tStringlist; tag: string) : string; var line: string;var i: integer;begin for i := 0 to data.count - 1 do begin if stringsMatch(tag, getTagForLine(data.getStrings(i))) then result := getDataForLine(data.getStrings(i)); end;end; procedure updateLists(tag: string; discard: string; subpatch: string; dtype: integer);begin gTags.add(subpatch + tag); gAddresses.add(PREFIX + discard + subpatch + tag); gTypes.add(intToStr(dtype));end;procedure createLists();var name, paramName: string;paramNum: integer;begin gTags.clear; gAddresses.clear; gTypes.clear; for i := 0 to (length(INT_TAGS) - 1) do updateLists(INT_TAGS[i], NADA, NADA, TYP_INT); for i := 0 to (length(FLOAT_TAGS) - 1) do updateLists(FLOAT_TAGS[i], NADA, NADA, TYP_FLT); for i := 0 to (length(TEXT_TAGS) - 1) do updateLists(TEXT_TAGS[i], NADA, NADA, TYP_STR); //for subpatches for i := 0 to (length(TAGS) - 1) do for j := 1 to (POLYS[i]) do updateLists(TAGS[i],SUBPATCH, SUBS[i] + DOT + intToStr(j) + DOT, TYPES[i]); //for i := 0 to (gAddresses.count - 1) do begin debug(gAddresses.getStrings(i)); debug(gTags.getStrings(i)); end; end;procedure sendData(idx: integer; data: string);begin //debug(gAddresses.getStrings(idx)); //debug( data ); if StrToInt(gTypes.getStrings(idx)) = TYP_INT then setObjectInteger(gAddresses.getStrings(idx), strToInt(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_FLT then setObjectFloat(gAddresses.getStrings(idx), strToFloat(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_STR then setObject(gAddresses.getStrings(idx), data);end;procedure recall();begin gReadyToLoad := TRUE;endprocedure initSave();var int: integer;var fl: single;var st: string;begin gDataString.clear; for i := 0 to (gTags.count - 1) do if StrToInt(gTypes.getStrings(i)) = TYP_INT then begin int := getObjectInteger(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + intToStr(int)); end else if strToInt(gTypes.getStrings(i)) = TYP_FLT then begin fl := getObjectFloat(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + floatToStr(fl)); end else if strToInt(gTypes.getStrings(i)) = TYP_STR then begin st := getObject(gAddresses.getStrings(i)); //st := VarToStr(v); gDataString.add(gTags.getStrings(i) + DELIMITER + st); end endprocedure Callback(n:integer);begin iDebug('callback input: ',n); //set the lists up first thing if not gListsCreated then begin createLists; gListsCreated := FALSE; debug('created lists'); end; CASE n of saveIN: if saveIN.asInteger > 0 then gReadyToWrite := TRUE; recallIN: if (recallIN.asInteger > 0)then //and FileExists(getBankPath()) then //not supported in 221115 begin gReadyToLoad := TRUE; bankLoadedOUT.asInteger(0); end; end;end;Procedure processidle;var i,j: integer;var line, tag: string; BEGIN if gReadyToWrite then begin initSave(); debug('saving:' + getBankPath()); tsDebug(gDataString, 'data: '); gDataString.SaveToFile(getBankPath()); gReadyToWrite := FALSE; end; if gReadyToLoad then begin debug('recalling: ' + getBankPath()); gDataString.clear; gDataString.loadfromFile(getBankPath()); for i := 0 to (gDataString.count - 1) do begin line := gDataString.getStrings(i); //debug('line = ' + line); //check each tag in our list to match with the dataStringIn line for j := 0 to (gTags.count - 1) do begin tag := gTags.getStrings(j); //debug('tag found: ' + tag); if stringsMatch(tag,getTagForLine(line)) then sendData(j, getDataForLine(line)); end; end; gReadyToLoad := FALSE; bankLoadedOUT.asInteger(1); endENDStatistics: Posted by woodslanding — 25 Jan 2023, 18:47
Statistics: Posted by woodslanding — 25 Jan 2023, 17:40
Statistics: Posted by senso — 25 Jan 2023, 08:14
CODE:
const DBUG_ON = TRUE;const CHAN = 'TEST';const PRESET_FOLDER = 'PRESETS';const TEXT_TAGS = ['details'];const INT_TAGS = ['midi-in-ch','transpose','audio-in','cc-to-pitch','mw-midi','at-midi','params-on']; //+ param nums + param channels, 8 buttons, 4 encoder button pairs, 8 encodersconst FLOAT_TAGS = ['input-trim','output-trim','hue','saturation'];const TYP_STR = 0; const TYP_INT = 1; const TYP_FLT = 2;//subpatchesconst TAGS = ['param','text','param','step','param','range.maxpos','range.minpos'];const SUBS = ['renaming','renaming','macros','macros','controls','controls','controls'];const TYPES = [TYP_INT, TYP_STR, TYP_INT, TYP_INT, TYP_INT, TYP_FLT, TYP_FLT];const POLYS = [6,6,4,4,4,4,4];//added to address of subpatches aboveconst SUBPATCH = 'instparamctl.1.';//added to all addressesconst PREFIX = 'patch.sidepanel.1.bankdata.1.';const EXTENSION = '.bank';const DTAG = 'bankManager_';const DELIMITER = '=';const DOT = '.';const NADA = '';var dataPathIN,recallIN,saveIN,channelIN,bankIN, instIN, bankLoadedOUT: tParameter;var gDataString, gTags, gAddresses, gTypes: tStringlist;var i,j: integer;var gReadyToWrite, gReadyToLoad, gListsCreated : boolean;procedure init;var i: integer;begin SetModuleColor($808080+496999); dataPathIN := CreateParam('data path',ptTextField,pioInput); recallIN := CreateParam('recall',ptButton,pioInput); saveIN := CreateParam('save',ptButton,pioInput); instIN := CreateParam('inst name',ptTextField, pioInput); bankIN := CreateParam('bank name',ptTextField, pioInput); bankLoadedOUT := CreateParam('bank loaded', ptDataField, pioOutput); gDataString.create; gTags.create; gAddresses.create; gTypes.create;end;procedure destroy; begin gDataString.free; gTags.free; gAddresses.free; gTypes.free; end;procedure debug(s: string); begin if DBUG_ON then strace(DTAG + CHAN + ': ' +s); end;procedure iDebug(s: string; num : integer) begin debug(s + ' ' + intToStr(num)); end;procedure tsDebug(ts: tStringlist; note: string); var i: integer;begin Debug(note); for i := 0 to ts.count - 1 do debug(intToStr(i) + ': ' + ts.getStrings(i));end;function stringsMatch(string1:string;string2:string) : boolean;begin //debug('matching strings:' + string1 + ', '+string2); result := (upperCase(trim(string1)) = uppercase(trim(string2))); end;function getBankPath() : string; var path: string;begin path := dataPathIN.asString + instIN.asString + PathDelim() + bankIN.asString + EXTENSION; //debug('bank path = ' + path); result := path; end;function getDataForLine(s: string) : string;var data: string;begin data := copy(s,pos(Delimiter,s) + 1,length(s)); //debug('got data for line: ' + data); result := data;end; function getTagForLine(s: string) : string;var tag: string;begin tag := copy(s, 1, pos(DELIMITER,s) - 1); //debug('got line: ' + s); //debug('got tag for line: ' + tag); result := tag;end; function extractData(data : tStringlist; tag: string) : string; var line: string;var i: integer;begin for i := 0 to data.count - 1 do begin if stringsMatch(tag, getTagForLine(data.getStrings(i))) then result := getDataForLine(data.getStrings(i)); end;end; procedure updateLists(tag: string; discard: string; subpatch: string; dtype: integer);begin gTags.add(subpatch + tag); gAddresses.add(PREFIX + discard + subpatch + tag); gTypes.add(intToStr(dtype));end;procedure createLists();var name, paramName: string;paramNum: integer;begin gTags.clear; gAddresses.clear; gTypes.clear; for i := 0 to (length(INT_TAGS) - 1) do updateLists(INT_TAGS[i], NADA, NADA, TYP_INT); for i := 0 to (length(FLOAT_TAGS) - 1) do updateLists(FLOAT_TAGS[i], NADA, NADA, TYP_FLT); for i := 0 to (length(TEXT_TAGS) - 1) do updateLists(TEXT_TAGS[i], NADA, NADA, TYP_STR); //for subpatches for i := 0 to (length(TAGS) - 1) do for j := 1 to (POLYS[i]) do updateLists(TAGS[i],SUBPATCH, SUBS[i] + DOT + intToStr(j) + DOT, TYPES[i]); //for i := 0 to (gAddresses.count - 1) do begin debug(gAddresses.getStrings(i)); debug(gTags.getStrings(i)); end; end;procedure sendData(idx: integer; data: string);begin //debug(gAddresses.getStrings(idx)); //debug( data ); if StrToInt(gTypes.getStrings(idx)) = TYP_INT then setObjectInteger(gAddresses.getStrings(idx), strToInt(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_FLT then setObjectFloat(gAddresses.getStrings(idx), strToFloat(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_STR then setObject(gAddresses.getStrings(idx), data);end;procedure recall();begin gReadyToLoad := TRUE;endprocedure saveBank();var int: integer;var fl: single;var st: string;begin debug('saving:' + getBankPath()); gDataString.clear; for i := 0 to (gTags.count - 1) do if StrToInt(gTypes.getStrings(i)) = TYP_INT then begin int := getObjectInteger(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + intToStr(int)); end else if strToInt(gTypes.getStrings(i)) = TYP_FLT then begin fl := getObjectFloat(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + floatToStr(fl)); end else if strToInt(gTypes.getStrings(i)) = TYP_STR then begin st := getObject(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + st); end //tsDebug(gDataString, 'data: '); debug('string created'); //Prints out fine. gDataString.SaveToFile(getBankPath()); // This is a valid path, in my case, from trace: [68790] bankManager_1: saving:D:\HH 5\RIG\PRESETS\Keyscape\Pianos.bank debug('file saved'); //THIS LINE IS NEVER REACHEDendprocedure Callback(n:integer);begin iDebug('callback input: ',n); //set the lists up first thing if not gListsCreated then begin createLists; gListsCreated := TRUE; debug('created lists'); bankLoadedOUT.asInteger(1); //we turn this off during loading, and back on when done end; CASE n of saveIN: if (saveIN.asInteger() > 0) then gReadyToWrite := TRUE; recallIN: if (recallIN.asInteger > 0) and FileExists(getBankPath()) then begin gReadyToLoad := TRUE; bankLoadedOUT.asInteger(0); end; end;end;Procedure processidle;var i,j: integer;var line, tag: string; BEGIN if gReadyToWrite then begin gReadyToWrite := FALSE; //if I put this AFTER saveBank() it saves the bank continuously!!! saveBank(); end; if gReadyToLoad then begin debug('recalling: ' + getBankPath()); gDataString.clear; gDataString.loadfromFile(getBankPath()); for i := 0 to (gDataString.count - 1) do begin line := gDataString.getStrings(i); //debug('line = ' + line); //check each tag in our list to match with the dataStringIn line for j := 0 to (gTags.count - 1) do begin tag := gTags.getStrings(j); //debug('tag found: ' + tag); if stringsMatch(tag,getTagForLine(line)) then sendData(j, getDataForLine(line)); end; end; gReadyToLoad := FALSE; bankLoadedOUT.asInteger(1); endENDStatistics: Posted by woodslanding — 25 Jan 2023, 05:26
Statistics: Posted by woodslanding — 28 Jan 2023, 02:13
Statistics: Posted by senso — 26 Jan 2023, 08:19
Statistics: Posted by woodslanding — 25 Jan 2023, 20:47
CODE:
const DBUG_ON = TRUE;const CHAN = '1';const PRESET_FOLDER = 'PRESETS';const TEXT_TAGS = ['details'];const INT_TAGS = ['midi-in-ch','transpose','audio-in','cc-to-pitch','mw-midi','at-midi','params-on']; //+ param nums + param channels, 8 buttons, 4 encoder button pairs, 8 encodersconst FLOAT_TAGS = ['input-trim','output-trim','hue','saturation'];const TYP_STR = 0; const TYP_INT = 1; const TYP_FLT = 2;//subpatchesconst TAGS = ['param','text','param','step','param','range.maxpos','range.minpos'];const SUBS = ['renaming','renaming','macros','macros','controls','controls','controls'];const TYPES = [TYP_INT, TYP_STR, TYP_INT, TYP_INT, TYP_INT, TYP_FLT, TYP_FLT];const POLYS = [6,6,4,4,4,4,4];//added to address of subpatches aboveconst SUBPATCH = 'instparamctl.1.';//added to all addressesconst PREFIX = 'patch.sidepanel.1.bankdata.1.';const EXTENSION = '.bank';const DTAG = 'bankManager_';const DELIMITER = '=';const DOT = '.';const NADA = '';var dataPathIN,recallIN,saveIN,channelIN,bankIN, instIN, bankLoadedOUT: tParameter;var gDataString, gTags, gAddresses, gTypes: tStringlist;var i,j: integer;var gReadyToWrite, gReadyToLoad, gListsCreated : boolean;procedure init;var i: integer;begin SetModuleColor($808080+496999); dataPathIN := CreateParam('data path',ptTextField,pioInput); recallIN := CreateParam('recall',ptButton,pioInput); saveIN := CreateParam('save',ptButton,pioInput); instIN := CreateParam('inst name',ptTextField, pioInput); bankIN := CreateParam('bank name',ptTextField, pioInput); bankLoadedOUT := CreateParam('bank loaded', ptDataField, pioOutput); bankLoadedOUT.asInteger(1); //we turn this off during loading, and back on when done gDataString.create; gTags.create; gAddresses.create; gTypes.create;end;procedure destroy; begin gDataString.free; gTags.free; gAddresses.free; gTypes.free; end;procedure debug(s: string); begin if DBUG_ON then strace(DTAG + CHAN + ': ' +s); end;procedure iDebug(s: string; num : integer) begin debug(s + ' ' + intToStr(num)); end;procedure tsDebug(ts: tStringlist; note: string); var i: integer;begin Debug(note); for i := 0 to ts.count - 1 do debug(intToStr(i) + ': ' + ts.getStrings(i));end;function stringsMatch(string1:string;string2:string) : boolean;begin //debug('matching strings:' + string1 + ', '+string2); result := (upperCase(trim(string1)) = uppercase(trim(string2))); end;function getBankPath() : string; var path: string;begin path := dataPathIN.asString + instIN.asString + PathDelim() + bankIN.asString + EXTENSION; debug('bank path = ' + path); result := path; end;function getDataForLine(s: string) : string;var data: string;begin data := copy(s,pos(Delimiter,s) + 1,length(s)); //debug('got data for line: ' + data); result := data;end; function getTagForLine(s: string) : string;var tag: string;begin tag := copy(s, 1, pos(DELIMITER,s) - 1); //debug('got line: ' + s); //debug('got tag for line: ' + tag); result := tag;end; function extractData(data : tStringlist; tag: string) : string; var line: string;var i: integer;begin for i := 0 to data.count - 1 do begin if stringsMatch(tag, getTagForLine(data.getStrings(i))) then result := getDataForLine(data.getStrings(i)); end;end; procedure updateLists(tag: string; discard: string; subpatch: string; dtype: integer);begin gTags.add(subpatch + tag); gAddresses.add(PREFIX + discard + subpatch + tag); gTypes.add(intToStr(dtype));end;procedure createLists();var name, paramName: string;paramNum: integer;begin gTags.clear; gAddresses.clear; gTypes.clear; for i := 0 to (length(INT_TAGS) - 1) do updateLists(INT_TAGS[i], NADA, NADA, TYP_INT); for i := 0 to (length(FLOAT_TAGS) - 1) do updateLists(FLOAT_TAGS[i], NADA, NADA, TYP_FLT); for i := 0 to (length(TEXT_TAGS) - 1) do updateLists(TEXT_TAGS[i], NADA, NADA, TYP_STR); //for subpatches for i := 0 to (length(TAGS) - 1) do for j := 1 to (POLYS[i]) do updateLists(TAGS[i],SUBPATCH, SUBS[i] + DOT + intToStr(j) + DOT, TYPES[i]); //for i := 0 to (gAddresses.count - 1) do begin debug(gAddresses.getStrings(i)); debug(gTags.getStrings(i)); end; end;procedure sendData(idx: integer; data: string);begin //debug(gAddresses.getStrings(idx)); //debug( data ); if StrToInt(gTypes.getStrings(idx)) = TYP_INT then setObjectInteger(gAddresses.getStrings(idx), strToInt(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_FLT then setObjectFloat(gAddresses.getStrings(idx), strToFloat(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_STR then setObject(gAddresses.getStrings(idx), data);end;procedure recall();begin gReadyToLoad := TRUE;endprocedure initSave();var int: integer;var fl: single;var st: string;begin gDataString.clear; for i := 0 to (gTags.count - 1) do if StrToInt(gTypes.getStrings(i)) = TYP_INT then begin int := getObjectInteger(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + intToStr(int)); end else if strToInt(gTypes.getStrings(i)) = TYP_FLT then begin fl := getObjectFloat(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + floatToStr(fl)); end else if strToInt(gTypes.getStrings(i)) = TYP_STR then begin st := getObject(gAddresses.getStrings(i)); //st := VarToStr(v); gDataString.add(gTags.getStrings(i) + DELIMITER + st); end endprocedure Callback(n:integer);begin iDebug('callback input: ',n); //set the lists up first thing if not gListsCreated then begin createLists; gListsCreated := FALSE; debug('created lists'); end; CASE n of saveIN: if saveIN.asInteger > 0 then gReadyToWrite := TRUE; recallIN: if (recallIN.asInteger > 0)then //and FileExists(getBankPath()) then //not supported in 221115 begin gReadyToLoad := TRUE; bankLoadedOUT.asInteger(0); end; end;end;Procedure processidle;var i,j: integer;var line, tag: string; BEGIN if gReadyToWrite then begin initSave(); debug('saving:' + getBankPath()); tsDebug(gDataString, 'data: '); gDataString.SaveToFile(getBankPath()); gReadyToWrite := FALSE; end; if gReadyToLoad then begin debug('recalling: ' + getBankPath()); gDataString.clear; gDataString.loadfromFile(getBankPath()); for i := 0 to (gDataString.count - 1) do begin line := gDataString.getStrings(i); //debug('line = ' + line); //check each tag in our list to match with the dataStringIn line for j := 0 to (gTags.count - 1) do begin tag := gTags.getStrings(j); //debug('tag found: ' + tag); if stringsMatch(tag,getTagForLine(line)) then sendData(j, getDataForLine(line)); end; end; gReadyToLoad := FALSE; bankLoadedOUT.asInteger(1); endENDStatistics: Posted by woodslanding — 25 Jan 2023, 18:47
Statistics: Posted by woodslanding — 25 Jan 2023, 17:40
Statistics: Posted by senso — 25 Jan 2023, 08:14
CODE:
const DBUG_ON = TRUE;const CHAN = 'TEST';const PRESET_FOLDER = 'PRESETS';const TEXT_TAGS = ['details'];const INT_TAGS = ['midi-in-ch','transpose','audio-in','cc-to-pitch','mw-midi','at-midi','params-on']; //+ param nums + param channels, 8 buttons, 4 encoder button pairs, 8 encodersconst FLOAT_TAGS = ['input-trim','output-trim','hue','saturation'];const TYP_STR = 0; const TYP_INT = 1; const TYP_FLT = 2;//subpatchesconst TAGS = ['param','text','param','step','param','range.maxpos','range.minpos'];const SUBS = ['renaming','renaming','macros','macros','controls','controls','controls'];const TYPES = [TYP_INT, TYP_STR, TYP_INT, TYP_INT, TYP_INT, TYP_FLT, TYP_FLT];const POLYS = [6,6,4,4,4,4,4];//added to address of subpatches aboveconst SUBPATCH = 'instparamctl.1.';//added to all addressesconst PREFIX = 'patch.sidepanel.1.bankdata.1.';const EXTENSION = '.bank';const DTAG = 'bankManager_';const DELIMITER = '=';const DOT = '.';const NADA = '';var dataPathIN,recallIN,saveIN,channelIN,bankIN, instIN, bankLoadedOUT: tParameter;var gDataString, gTags, gAddresses, gTypes: tStringlist;var i,j: integer;var gReadyToWrite, gReadyToLoad, gListsCreated : boolean;procedure init;var i: integer;begin SetModuleColor($808080+496999); dataPathIN := CreateParam('data path',ptTextField,pioInput); recallIN := CreateParam('recall',ptButton,pioInput); saveIN := CreateParam('save',ptButton,pioInput); instIN := CreateParam('inst name',ptTextField, pioInput); bankIN := CreateParam('bank name',ptTextField, pioInput); bankLoadedOUT := CreateParam('bank loaded', ptDataField, pioOutput); gDataString.create; gTags.create; gAddresses.create; gTypes.create;end;procedure destroy; begin gDataString.free; gTags.free; gAddresses.free; gTypes.free; end;procedure debug(s: string); begin if DBUG_ON then strace(DTAG + CHAN + ': ' +s); end;procedure iDebug(s: string; num : integer) begin debug(s + ' ' + intToStr(num)); end;procedure tsDebug(ts: tStringlist; note: string); var i: integer;begin Debug(note); for i := 0 to ts.count - 1 do debug(intToStr(i) + ': ' + ts.getStrings(i));end;function stringsMatch(string1:string;string2:string) : boolean;begin //debug('matching strings:' + string1 + ', '+string2); result := (upperCase(trim(string1)) = uppercase(trim(string2))); end;function getBankPath() : string; var path: string;begin path := dataPathIN.asString + instIN.asString + PathDelim() + bankIN.asString + EXTENSION; //debug('bank path = ' + path); result := path; end;function getDataForLine(s: string) : string;var data: string;begin data := copy(s,pos(Delimiter,s) + 1,length(s)); //debug('got data for line: ' + data); result := data;end; function getTagForLine(s: string) : string;var tag: string;begin tag := copy(s, 1, pos(DELIMITER,s) - 1); //debug('got line: ' + s); //debug('got tag for line: ' + tag); result := tag;end; function extractData(data : tStringlist; tag: string) : string; var line: string;var i: integer;begin for i := 0 to data.count - 1 do begin if stringsMatch(tag, getTagForLine(data.getStrings(i))) then result := getDataForLine(data.getStrings(i)); end;end; procedure updateLists(tag: string; discard: string; subpatch: string; dtype: integer);begin gTags.add(subpatch + tag); gAddresses.add(PREFIX + discard + subpatch + tag); gTypes.add(intToStr(dtype));end;procedure createLists();var name, paramName: string;paramNum: integer;begin gTags.clear; gAddresses.clear; gTypes.clear; for i := 0 to (length(INT_TAGS) - 1) do updateLists(INT_TAGS[i], NADA, NADA, TYP_INT); for i := 0 to (length(FLOAT_TAGS) - 1) do updateLists(FLOAT_TAGS[i], NADA, NADA, TYP_FLT); for i := 0 to (length(TEXT_TAGS) - 1) do updateLists(TEXT_TAGS[i], NADA, NADA, TYP_STR); //for subpatches for i := 0 to (length(TAGS) - 1) do for j := 1 to (POLYS[i]) do updateLists(TAGS[i],SUBPATCH, SUBS[i] + DOT + intToStr(j) + DOT, TYPES[i]); //for i := 0 to (gAddresses.count - 1) do begin debug(gAddresses.getStrings(i)); debug(gTags.getStrings(i)); end; end;procedure sendData(idx: integer; data: string);begin //debug(gAddresses.getStrings(idx)); //debug( data ); if StrToInt(gTypes.getStrings(idx)) = TYP_INT then setObjectInteger(gAddresses.getStrings(idx), strToInt(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_FLT then setObjectFloat(gAddresses.getStrings(idx), strToFloat(data)) else if strToInt(gTypes.getStrings(idx)) = TYP_STR then setObject(gAddresses.getStrings(idx), data);end;procedure recall();begin gReadyToLoad := TRUE;endprocedure saveBank();var int: integer;var fl: single;var st: string;begin debug('saving:' + getBankPath()); gDataString.clear; for i := 0 to (gTags.count - 1) do if StrToInt(gTypes.getStrings(i)) = TYP_INT then begin int := getObjectInteger(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + intToStr(int)); end else if strToInt(gTypes.getStrings(i)) = TYP_FLT then begin fl := getObjectFloat(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + floatToStr(fl)); end else if strToInt(gTypes.getStrings(i)) = TYP_STR then begin st := getObject(gAddresses.getStrings(i)); gDataString.add(gTags.getStrings(i) + DELIMITER + st); end //tsDebug(gDataString, 'data: '); debug('string created'); //Prints out fine. gDataString.SaveToFile(getBankPath()); // This is a valid path, in my case, from trace: [68790] bankManager_1: saving:D:\HH 5\RIG\PRESETS\Keyscape\Pianos.bank debug('file saved'); //THIS LINE IS NEVER REACHEDendprocedure Callback(n:integer);begin iDebug('callback input: ',n); //set the lists up first thing if not gListsCreated then begin createLists; gListsCreated := TRUE; debug('created lists'); bankLoadedOUT.asInteger(1); //we turn this off during loading, and back on when done end; CASE n of saveIN: if (saveIN.asInteger() > 0) then gReadyToWrite := TRUE; recallIN: if (recallIN.asInteger > 0) and FileExists(getBankPath()) then begin gReadyToLoad := TRUE; bankLoadedOUT.asInteger(0); end; end;end;Procedure processidle;var i,j: integer;var line, tag: string; BEGIN if gReadyToWrite then begin gReadyToWrite := FALSE; //if I put this AFTER saveBank() it saves the bank continuously!!! saveBank(); end; if gReadyToLoad then begin debug('recalling: ' + getBankPath()); gDataString.clear; gDataString.loadfromFile(getBankPath()); for i := 0 to (gDataString.count - 1) do begin line := gDataString.getStrings(i); //debug('line = ' + line); //check each tag in our list to match with the dataStringIn line for j := 0 to (gTags.count - 1) do begin tag := gTags.getStrings(j); //debug('tag found: ' + tag); if stringsMatch(tag,getTagForLine(line)) then sendData(j, getDataForLine(line)); end; end; gReadyToLoad := FALSE; bankLoadedOUT.asInteger(1); endENDStatistics: Posted by woodslanding — 25 Jan 2023, 05:26