Synchronization between functions

EDIT - sorry for the continual edits, just lots to think about — Is the ElectraOne OS single threaded? In other words, if I am sitting in a while loop spinning and waiting, does any other processing take place in the LUA code while I spin? What about processing external inputs (MIDI, knobs, screen)?

Summary - I’m trying to request and process a bank of patches from a synth one at a time with no success so far.

pseudo code for how I have it now:

-- synchronization variable
processed = 0

function getOne(patchNum)
   processed = 0
   -- send sysex to request the patch
end

function getAll()
  for i = 1, 127 do
      getOne(i)
      while (processed == 0) do
         print("Waiting ...")
      end
   end
end

function patch.onResponse()
   -- read sysex message
   -- do lots of stuff with the data
   processed = 1
end

What happens is usually I see the “Waiting …” message in the log file a lot and then nothing else ever happens. It definitely never cycles through multiple sends/responses. Not sure how LUA handles variables in a loop like that. Since it’s not a local, I would have thought the global was checked each time through, but that doesn’t appear to be the case.

My second thought (this morning on the drive in - currently untested) would be to change it up slightly.
My fear with this version though is that I might blow the stack out since patch.onResponse() is invoked before it finishes.

numPatches = 128

function getOne(patchNum)
   -- send sysex to request the patch
end

function getAll()
   getOne(1)
end

function patch.onResponse()
   -- read sysex message
   -- do lots of stuff with the data
   i = i + 1
   if (i < numPatches) then
       getOne(i)
   end
end

I had issues as well trying to fetch all parameter from the parameterMap in a for loop
The code below works only for printing the ids from 33 to 0 or the other way arround.
But I not able to just print the parameterData from the map
Fetching a single parameter works but just not in a for loop.

Am I doing it wrong? or is this related to the issue you describe?

PioneerSp16DeviceId = 4


function getAllParameters()

device = devices.get (PioneerSp16DeviceId)

-- parameter ID's' = 0 - 33

local channel = device:getChannel()


for i = 33,0,-1 

 do 

   print(i) 

   local parameterNumber = i

   parameterData = parameterMap.get (mirageSoundProcessDeviceId, PT_CC7, parameterNumber )

   print(parameterData)



end

end

one thought - are all your controls MIDI CC 7 or is there some NRPNs and/or sysex controls?

I know Martin has said both the control type as well as the ID make an object unique. That could be causing it to kick out early.

Loops in general work as designed. If it is not fully processing all of something with a local variable declared for loop control, then it’s something else that is causing the issue, not the loop itself.

the 33 controls are CC7 only. I wil try to just fetch them 1 by one.
If that works its still unknown to me why it would not work in a loop.

for me, I would just use the loop variable i directly in the call to parameterMap.get() rather than assigning it to another variable.

What does print() do? spit out garbage, the same value, or nothing happens at all?

The other thing (probably just because of cut and paste from the code) is at the top you have it defined as PioneerSp16DeviceId = 4 and in the parameterMap.get() call you are using mirageSoundProcessingDeviceId

Yeah that was just a copy past thing.

print(i) works fine

parameterData = parameterMap.get (mirageSoundProcessDeviceId, PT_CC7, i)
doesn’t work.

But I now see the range of the loop is from 33 to 0 it should be from 33 to 1. perhaps that’s the issue.
As parameter 0 does not exist.
But the loops starts at 33 so even so it should… wil try.

sometimes it pays to read the documentation front to back…

There is a brief mention in the beginning about the structure of a script and it says about the Setup section that if any user functions reference the setup data (stuff outside a function), it should be declared below all the functions that use it.

This is different than all other programming languages I’ve used, but once I moved the variables below all functions, the initial code I pasted is working.

well, mostly. The synchronization is definitely better and I do see the repeated calls in the log file, but the ElectraOne still isn’t happy after about 30 iterations.

The idea is that setup() is called as the first Lua function when the script is loaded. This is much inspired by the Arduino. Once the the setup() is completed, all subsequent Lua calls are event drived (user actions, midi, timer, etc.). Processing of events is done in serial fashion, one by one in given time periods.

I will take a look at your example code (above) to see what is happening there.

The docs I was looking at talked about a setup section, but the implication was that it was simply any/all code outside of callbacks and user functions.

I was doing some work using my Mac Mini (all previous stuff was done on a Windows 10 box) and it seemed to me that if I had the synchronization variable declared at the top of the LUA code, the functions would just hang and if I moved it to the very bottom, it worked.

Is that possible or was something else in play to give me those results? Also, I was back using 2.13 and not the 2.14 because the extra logging was obscuring my test messages. That could be why after about 35 iterations it locked up. I will test on 2.14 some time soon, although here in the US we have a holiday approaching this Thursday, which means extra family and relatives will be in town this week and limit my ability to sneak away for some more coding/testing.

I would think that your issue will not happen on 2.14.
so definitely worth to try it.
the lockup might be related my issue which had to do with garbage collection.
2.14 contains a fix for that.

2.14 allowed me to pull down 127 individual patch dumps and process them, so yes, 2.14 is definitely more solid in that regard. :+1: