Page 1 of 1

Posted: 22 Nov 2015, 18:54
by sm_jamieson
There are arrays parameter types ptArray (data array), ptIpAddress, ptSmpte.
It would be very useful to have an "array of strings" parameter.).

Simon.

Posted: 22 Nov 2015, 20:13
by sephult
Using commatext as your input and ptTextField you can achieve a method to read into a TString list I believe.
I agree would be just simple to read into as an array and have standard method for the arrays.
Would be much simpler

-s

Posted: 17 Dec 2015, 10:57
by senso
there is several new data flows to implement.
but string array is not so easy.
I'll think about it.

Posted: 23 Feb 2016, 15:54
by sm_jamieson
Several new data flows ?

One problem that arises often in Usine is that most data types are floating point (with the exception of Colors). This makes if difficult to send integer values where the exact bits must be preserved (typical example is trying to send color values in an array, which is floating point.

The other issue is that all flows are "signals" in usine and if you want to send one-off messages, you have to arrange for the signal to be shut off after a bloc by setting length to -1.

A new "message" type of data flow would be useful. Apparently some other DAW has this (not sure which). It would connect between new "message" parameter types and either sit on the wire for one bloc, or until it is "delivered".

A "message" could just be a binary blob of a certain number of bytes in size (a bit like a module "chunk" being sent over the wire).

Simon.

Posted: 02 Mar 2016, 00:55
by ahonoe
I agree with Simon. A message type would be very useful. I am in the process of building my own messaging system using comma delimited strings however I'm running into issues enqueuing these for processing. A message flow that provided enqueuing would be really handy.

Posted: 02 Mar 2016, 02:03
by oli_lab
did you have a look at my module call AntiOPe ?

http://www.sensomusic.org/downloadaddon ... 202015.zip

could help you send OSC lines to Processing

I actually use it to send lines to a Minitel via OSC.

https://en.wikipedia.org/wiki/Minitel

What I found best is to load comma text from text files (one for each pages of minitel)
I edit the texts from notepad++, much easier than to try to do every thing inside Usine...

Posted: 02 Mar 2016, 10:45
by sm_jamieson
ahonoe wrote:I agree with Simon. A message type would be very useful. I am in the process of building my own messaging system using comma delimited strings however I'm running into issues enqueuing these for processing. A message flow that provided enqueuing would be really handy.
I tried a messaging system based on strings containing binary data. The problem I had was that a zero in the data is regarded as the end of the string and nothing is sent past that point, so zeros cannot be sent. So I changed to using text, i.e. zero is ascii '0' character. Increment everything by 1 and you cannot then send 255 !
A parameter can only have one value per bloc for the other end to pick it up, so I invented a queuing system in the script.
Queuing would be easier in a user module as C++ queue or list classes can be used.
My script queuing code also allows you to code a "delay" into the queue, and to shut fo the signal completely (set length to -1).
The code has to work within the limits of the scripting language (based on Pascal).
My code:

// Parameter Output Queueing functionality - relies on the fact that
// for each process cycle Callback() runs before Process()
//

Type ParamQueueRec = record
strqueue : array [1..MAX_VALQUEUE] of AnsiString;
numqueue : array [1..MAX_VALQUEUE] of Single;
waitqueue : array [1..MAX_VALQUEUE] of integer;
Qstart : integer; // barrel Q so can be FIFO
Qend: integer;
queueNext : boolean; // something sent this bloc so anything else must be queued
wantReset : boolean; // want param set to length -1 when queue exhausted
resetLength : integer; // length to reset the paramter to
End;

var ParamOutQueue : Array[1..MAX_PARAMS] of ParamQueueRec; // must be big enough
var procdQinCallback: boolean := false;

procedure resetQueuedParam(p : integer);
var i : integer;
begin
with ParamOutQueue[p] do begin
if Qstart < 0 then Qstart := 0; // preparing for queueing
queueNext := true;
wantReset := true;
end;
end;

procedure processQ(instance : integer);
var i: integer;
begin
for i := 1 to MAX_PARAMS do begin
with ParamOutQueue do begin
if Qstart < 0 then continue;
if Qstart > 0 then begin
// take value off start of barrel Q and send it
if strQueue[Qstart] <> AnsiString(nil) then begin
setLength(i,1);
setStringValue(i,strQueue[Qstart]);
sTrace('Zoner inst ' + inttostr(instance) + ' Qstart ' + IntToStr(Qstart) + ', sending string value ' + strQueue[Qstart]);
end else if waitQueue[Qstart] > -1 then begin
// delay entry, decrement wait count
waitQueue[Qstart] := waitQueue[Qstart] - 1;
sTrace('queued delay, count is now ' + inttostr(waitQueue[Qstart]));
if waitQueue[Qstart] > -1 then exit; // do not lose queue item
end else begin
setLength(i,1);
setValue(i,numqueue[Qstart]);
sTrace('queued val sending ' + inttostr(Trunc(numqueue[Qstart])));
end;

if Qstart = Qend then begin
Qstart := 0; // done last one, no queue left
end else begin
Qstart := Qstart + 1;
if Qstart > MAX_VALQUEUE then Qstart := 1; // wrap round
end;

end else begin
if (wantReset) then begin
sTrace('Closing parameter ' + IntToStr(i));
setLength(i,resetLength);
wantReset := false;
end;
Qstart := -1; // indicates that reset has been done if required
queueNext := false;
end;
end;
end;
end;

procedure processQfromCallback;
// Call this at the start of the Callback routine
var i:integer;
begin
// Q should only be processed on first callback per bloc
if procdQinCallback = false then begin
processQ(1);
procdQinCallback := true;
end;
end;

procedure processQfromProcess;
// Call this at the start of the Process routine
var i:integer;
begin
if procdQinCallback then begin
// callback will have processed the Q and maybe set some more
procdQinCallback := false;
exit;
end;
processQ(2);
end;

Function allocQueuedParam(p:tparameter) : integer;
begin
// alloc space in the queue and return new index

with ParamOutQueue[p] do begin
if Qstart < 1 then begin
Qstart := 1;
Qend := 1; // first entry in queue
end else begin
Qend := Qend + 1;
if Qend > MAX_VALQUEUE then Qend := 1;
end;
// Set default values in new Q entry
numQueue[Qend] := -1; // why not
strQueue[Qend] := AnsiString(nil); // indicates not a string value
waitQueue[Qend] := -1; // indicates not a wait entry
end;
exit(ParamOutQueue[p].Qend);
end;

procedure setQueuedParam(p:tparameter; num:single);
var newentry : integer;
begin
// Set numeric paramter value, queueing if more than 1 in same bloc
with ParamOutQueue[p] do begin
if (queueNext) then begin
newentry := allocQueuedParam(p);
numQueue[newentry] := num;
wantReset := true;
sTrace('queuing value ' + inttostr(Trunc(num)));
end else begin
SetLength(p,1);
SetValue(p, num);
Qstart := 0; // reset from -1
queueNext := true;
wantReset := true;
sTrace('not queueing value ' + inttostr(Trunc(num)));
end;
end;
end;

procedure setQueuedStrParam(p:tparameter; str:AnsiString);
var newentry : integer;
begin
// Set string parameter, queueing if more than 1 in same bloc
with ParamOutQueue[p] do begin
if (queueNext) then begin
newentry := allocQueuedParam(p);
strQueue[newentry] := str;
wantReset := true;
end else begin
SetLength(p,1);
SetStringValue(p, str);
Qstart := 0; // reset from -1
queueNext := true;
wantReset := true;
end;
end;
end;

procedure setQueuedDelay(p:tparameter; delay:integer);
var newentry : integer;
begin
// Set delay taking up specified number of blocs
with ParamOutQueue[p] do begin
newentry := allocQueuedParam(p);
waitQueue[newentry] := delay;
queueNext := true;
end;
end;

// END OF QUEUED PARAMETER FUNCTIONALITY

Posted: 02 Mar 2016, 23:51
by ahonoe
Really interesting approach, Simon. I'm going to review this now. Thanks for sharing it.