solo-act
Fractal Fanatic
Do you recognize this language? Several forum members are looking to continue development of the Lemur iPad editor and we need interested coders. Below are a few random samples from the last template the developer released before he vanished with zero communication.
You can view more code by downloading these:
The Lemur editor, included in the download links:
https://liine.net/en/support/lemur
The template for the Lemur Axe-Fx editor:
https://dl.dropbox.com/u/54889552/AxeForLemur.3.06.zip
Launch the editor, open the template and click on the objects in the folders to see more scripts.
Lemur V4 for iPad still works. Lemur V5 changed a communication protocol somewhere.
As you'll see, the bulk of the work has already been done. It just needs to be tweaked to add the latest axe-fx features and make it compatible with Lemur V5. I have several ideas for further development, and several forum members have expressed interest in paying for an updated template, not to mention we'd be doing great good for the axe-fx community.
Any interest, thoughts and insights that contribute to re-starting development are highly welcome, and thanks for the consideration.
SAMPLE 1:
decl b, p, a, mb, mp, j, mbps;
cV.bpobj = getfirst(cMain);
for(;{
mbps = getexpression(cV.bpobj, 'bps'); // new way uses less memory
if(sizeof(mbps)>=6){
b = {mbps[0], mbps[1]};
p = {mbps[2], mbps[3]};
if(b[hw]>99 && b[hw]<200){
if(cV.bypStates[b[hw]-100]>0){ // query blocks that exist in preset
a = 0;
if(cV.BlocksToRefresh[0] == 0)
a = 1; // query all
else
for(j=0;j<sizeof(cV.BlocksToRefresh);j++){
if(b==cV.BlocksToRefresh[j]) a=1; // query blocks listed in BlocksToRefresh
}
if(a == 1){ // add block and param num to list
cS.addRefreshParam(b[hw],p[hw]);
++cV.numcontrols;
}
}
cV.bpobj=getnext(cV.bpobj); // check all objects in the container
if(cV.bpobj==0)break;
if(cV.numcontrols==750) break; // prevent buffer overflow
continue;
}
}
mb = getexpression(cV.bpobj, 'bids'); // multislider support
if(hw==0)
mp = getexpression(cV.bpobj, 'pids');
else mp = getexpression(cV.bpobj, 'pids2');
if((sizeof(mb)>1) && (sizeof(mp)>1)){ // finds containers with pids and bids expressions
if(mb[hw]>99 && mb[hw]<200){ // sanity check block num
a = 0;
if(cV.BlocksToRefresh[0] == 0)
a = 1; // query all
else
for(j=0;j<sizeof(cV.BlocksToRefresh);j++){
if(mb==cV.BlocksToRefresh[j]) a=1;
}
if(a==1){
for(j=0;j<sizeof(mp);j++){ // the number of elements in pids
if(cV.bypStates[mb[hw]-100]>0){ // query blocks that exist in preset
cS.addRefreshParam(mb[hw],mp[j]);
++cV.numcontrols;
if(cV.numcontrols==750) break; // prevent buffer overflow
}
}
}
}
}
cV.bpobj=getnext(cV.bpobj); // check all objects in the container
if(cV.bpobj==0)break;
if(cV.numcontrols==750) break; // prevent buffer overflow
}
// **********************************
SAMPLE 2
// p1 is source block on the grid (0 to 47)
// p2 is destination block on the grid (0 to 47)
// flag is 0 to disconnect, 1 to connect
//send Axe-FX II Connect Effect message
decl mess, outmess, checksum;
if(!hw){
mess = {
0xF0,0,1,0x74,3,6,
floor(clamp(p1,0,47)),
floor(clamp(p2,0,47)),
floor(f)
};
checksum = cS.calcchecksum(mess);
outmess = {mess, {checksum, 0xF7}};
}
else {
// axefx ultra and std Connect Effect message
outmess = {
0xF0,0,1,0x74,aUser.cMidi.hwids[tidx],6,
floor(clamp(p1,0,47)),
floor(clamp(p2,0,47)),
floor(f),
0xF7
};
}
midiout(aUser.cMidi.targets[tidx], outmess);
// **********************************
SAMPLE 3// b is block number; 200 = place shunt; 0 = clear block
// pos is location on the grid (0 to 47)
// flag is 0 to clear block, 1 to place block
//send Axe-FX II Place Effect Block
decl mess, outmess, checksum;
if(!hw){
mess = {
0xF0,0,1,0x74,3,5,
floor(b) & 0x7F,
(floor(b) >> 7) & 0x7F,
floor(clamp(pos,0,47)),
floor(flag)
};
checksum = cS.calcchecksum(mess);
outmess = {mess, {checksum, 0xF7}};
}
else {
// axefx ultra and std Place Effect Block
outmess = {
0xF0,0,1,0x74,aUser.cMidi.hwids[tidx],5,
b & 0xF,
(b >> 4) & 0xF,
floor(clamp(pos,0,47)),
floor(flag),
0xF7
};
}
midiout(aUser.cMidi.targets[tidx], outmess);
// **********************************
You can view more code by downloading these:
The Lemur editor, included in the download links:
https://liine.net/en/support/lemur
The template for the Lemur Axe-Fx editor:
https://dl.dropbox.com/u/54889552/AxeForLemur.3.06.zip
Launch the editor, open the template and click on the objects in the folders to see more scripts.
Lemur V4 for iPad still works. Lemur V5 changed a communication protocol somewhere.
As you'll see, the bulk of the work has already been done. It just needs to be tweaked to add the latest axe-fx features and make it compatible with Lemur V5. I have several ideas for further development, and several forum members have expressed interest in paying for an updated template, not to mention we'd be doing great good for the axe-fx community.
Any interest, thoughts and insights that contribute to re-starting development are highly welcome, and thanks for the consideration.
SAMPLE 1:
decl b, p, a, mb, mp, j, mbps;
cV.bpobj = getfirst(cMain);
for(;{
mbps = getexpression(cV.bpobj, 'bps'); // new way uses less memory
if(sizeof(mbps)>=6){
b = {mbps[0], mbps[1]};
p = {mbps[2], mbps[3]};
if(b[hw]>99 && b[hw]<200){
if(cV.bypStates[b[hw]-100]>0){ // query blocks that exist in preset
a = 0;
if(cV.BlocksToRefresh[0] == 0)
a = 1; // query all
else
for(j=0;j<sizeof(cV.BlocksToRefresh);j++){
if(b==cV.BlocksToRefresh[j]) a=1; // query blocks listed in BlocksToRefresh
}
if(a == 1){ // add block and param num to list
cS.addRefreshParam(b[hw],p[hw]);
++cV.numcontrols;
}
}
cV.bpobj=getnext(cV.bpobj); // check all objects in the container
if(cV.bpobj==0)break;
if(cV.numcontrols==750) break; // prevent buffer overflow
continue;
}
}
mb = getexpression(cV.bpobj, 'bids'); // multislider support
if(hw==0)
mp = getexpression(cV.bpobj, 'pids');
else mp = getexpression(cV.bpobj, 'pids2');
if((sizeof(mb)>1) && (sizeof(mp)>1)){ // finds containers with pids and bids expressions
if(mb[hw]>99 && mb[hw]<200){ // sanity check block num
a = 0;
if(cV.BlocksToRefresh[0] == 0)
a = 1; // query all
else
for(j=0;j<sizeof(cV.BlocksToRefresh);j++){
if(mb==cV.BlocksToRefresh[j]) a=1;
}
if(a==1){
for(j=0;j<sizeof(mp);j++){ // the number of elements in pids
if(cV.bypStates[mb[hw]-100]>0){ // query blocks that exist in preset
cS.addRefreshParam(mb[hw],mp[j]);
++cV.numcontrols;
if(cV.numcontrols==750) break; // prevent buffer overflow
}
}
}
}
}
cV.bpobj=getnext(cV.bpobj); // check all objects in the container
if(cV.bpobj==0)break;
if(cV.numcontrols==750) break; // prevent buffer overflow
}
// **********************************
SAMPLE 2
// p1 is source block on the grid (0 to 47)
// p2 is destination block on the grid (0 to 47)
// flag is 0 to disconnect, 1 to connect
//send Axe-FX II Connect Effect message
decl mess, outmess, checksum;
if(!hw){
mess = {
0xF0,0,1,0x74,3,6,
floor(clamp(p1,0,47)),
floor(clamp(p2,0,47)),
floor(f)
};
checksum = cS.calcchecksum(mess);
outmess = {mess, {checksum, 0xF7}};
}
else {
// axefx ultra and std Connect Effect message
outmess = {
0xF0,0,1,0x74,aUser.cMidi.hwids[tidx],6,
floor(clamp(p1,0,47)),
floor(clamp(p2,0,47)),
floor(f),
0xF7
};
}
midiout(aUser.cMidi.targets[tidx], outmess);
// **********************************
SAMPLE 3// b is block number; 200 = place shunt; 0 = clear block
// pos is location on the grid (0 to 47)
// flag is 0 to clear block, 1 to place block
//send Axe-FX II Place Effect Block
decl mess, outmess, checksum;
if(!hw){
mess = {
0xF0,0,1,0x74,3,5,
floor(b) & 0x7F,
(floor(b) >> 7) & 0x7F,
floor(clamp(pos,0,47)),
floor(flag)
};
checksum = cS.calcchecksum(mess);
outmess = {mess, {checksum, 0xF7}};
}
else {
// axefx ultra and std Place Effect Block
outmess = {
0xF0,0,1,0x74,aUser.cMidi.hwids[tidx],5,
b & 0xF,
(b >> 4) & 0xF,
floor(clamp(pos,0,47)),
floor(flag),
0xF7
};
}
midiout(aUser.cMidi.targets[tidx], outmess);
// **********************************