Welcome to %s forums

BrainModular Users Forum

Login Register

New matrix combo for HH

I need help on a Patch
Post Reply
woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 10 Aug 2013, 07:57

I'm trying to get a combo going with the new matrix.

This one uses the first column to select pages, and the rest of the cells update accordingly. It can take a number in, and send a number out via a click on the matrix. I swapped the x and y axes, because I like to read down more than across....

It's basically working fine, but two small problems:

1. If I put any spaces in my pages commatext, it is mis-parsed into two elements. It looks at it as 'spaceText'.....
2. Although I'm only setting values of 1 or 0 for 'cells out', I'm seeing a lot of very small values, and the matrix buttons are changing shades (randomly?) when the first button in column 2 is pressed.

Here's the patch:
http://www.sensomusic.com/forums/upload ... omboHH.pat

and here's the code:

Code: Select all

////////////////////////////////////////////////////////////////////////////////////////////////

CONST BUTTON_COUNT = 32;  //should be a multiple of page count
CONST PAGE_COUNT = 8;


VAR cellsOUT, namesOUT, presetOUT, presetsIN, pagesIN, clickedIN, presetIN: tParameter;
VAR pages, presets,buttonNames : TStringList;
var page, preset, presetCount, pageMax, ROW_COUNT, COL_COUNT, MATRIX_SIZE    : integer;
                   
// destroy
procedure Destroy;
begin  
 pages.free;
 presets.free;  
 buttonNames.free;
end;   


PROCEDURE Init;
BEGIN
    pagesIN := CreateParam('pages', ptTextfield); SetIsOutput(pagesIN, FALSE);
    presetsIN := CreateParam('presets', ptTextfield); SetIsOutput(presetsIN, FALSE);
    clickedIN := CreateParam('last clicked', ptDatafield); SetIsOutput(clickedIN, FALSE);
    presetIN := CreateParam('preset num', ptDatafield); SetIsOutput(presetIN, FALSE);
    cellsOut := CreateParam('cells out', ptArray); SetIsInput(cellsOut, FALSE);
    namesOut := CreateParam('captions out', ptTextfield); SetIsInput(namesOut, FALSE);
    presetOut := CreateParam('preset out', ptDatafield); SetIsInput(presetOut, FALSE);

    MATRIX_SIZE := PAGE_COUNT + BUTTON_COUNT;
    COL_COUNT := BUTTON_COUNT div PAGE_COUNT;
    ROW_COUNT := PAGE_COUNT;
    setLength(cellsOUT, MATRIX_SIZE );
    pages.Create;
    presets.Create;
    buttonNames.Create;   

END; // Init

///////////////////////////////////////////////////////////////////////////////////////
// to switch rows and columns.  x = row, y = col.  For x = 0, add the page name.  then
// for x = 1 to 4, get items 0, 8, 16, and 24.  that's page_count * (x-1) + y
//
procedure UpdateButtons;
var col,row,index : integer;
begin
    buttonNames.Clear;
    for row := 0 to (ROW_COUNT - 1) do begin  // for each row
        for col := 0 to COL_COUNT do begin     // for each column--incl page column
            if col = 0 then buttonNames.add(pages.getStrings(row))  // add page row item
            else begin            
                index := (PAGE_COUNT * (col - 1)) + row; // get the row/col adjusted index....
                if ((page * BUTTON_COUNT) + index) >= presetCount then begin
                    buttonNames.add('---');   
                end else begin      
                    buttonNames.add(presets.getStrings((page * BUTTON_COUNT) + index));
                end;
            end;
        end;
    end;
    setStringValue(namesOUT, buttonNames.getCommatext);
end;

PROCEDURE clearMatrix();             //////////////////CLEAR MATRIX////////////////////   
var i : integer;
BEGIN
       for i := 0 to (MATRIX_SIZE - 1) DO   BEGIN
           setDataArrayValue(cellsOUT,i,0); 
           strace('cell zeroed: ' + intToStr(i));
           END;
END;                                               

PROCEDURE enable(index : integer);    /////////////////ENABLE////////////////////////
BEGIN
    setDataArrayValue(cellsOUT, index, 1.0);
END;

PROCEDURE PageChanged();         /////////////////////PAGE CHANGED////////////////
var index, cellNum: integer;
BEGIN
    UpdateButtons();
    ClearMatrix();
    enable(page * (COL_COUNT + 1));
    if (preset div BUTTON_COUNT) = page then  // if the preset is on the current page....
    BEGIN
        index:= preset mod BUTTON_COUNT; // raw preset index
        cellNum:= ((index mod ROW_COUNT) * (COL_COUNT + 1)) + 1 + (index div ROW_COUNT);// actual cell num
        enable(cellNum);
    END;        
END;

PROCEDURE PresetChanged();         /////////////////////PRESET CHANGED////////////////
var index, cellNum: integer;
BEGIN
    page:= preset div BUTTON_COUNT;  // figure out which page the preset is on  
    // strace('page = ' + intToStr(page)); 
    PageChanged();     
    setValue(presetOUT, preset);
END;



PROCEDURE Callback(n : Integer);       ///////////////////////CALLBACK////////////////
    VAR i, x, y, index, clicked, cellNum, column : Integer;
    BEGIN  
     
    CASE n of        
        presetsIN: 
            BEGIN
                presets.setCommaText(GetStringValue(presetsIN));                       
                presetCount:= presets.count;
            END;
        pagesIN: 
            BEGIN
                pages.setCommaText(GetStringValue(pagesIN));  
                
            END;                         
        presetIN:
            BEGIN
                preset:= trunc(getValue(presetIN));
                PresetChanged();
            END;
        clickedIN:
            BEGIN     
                cellNum:= trunc(getValue(clickedIN));  
                column := cellNum mod (COL_COUNT + 1);
                if (column = 0) then BEGIN  // it's a page number
                    page := cellNum div (COL_COUNT + 1);
                    PageChanged();
                END 
                ELSE BEGIN
                    index:= (column * ROW_COUNT) + (cellNum div (COL_COUNT + 1)) - ROW_COUNT;// + ROW_COUNT; 
                    preset:= (BUTTON_COUNT * page) + index;    // compute preset number
                    PresetChanged();
                END; 
            END;          
    END; //case
    
END; // Callback


///////////////////////////////////////////////////////////////////////////////////////

PROCEDURE Process;
BEGIN
END;
any tips most welcome! If I can get it working well, I'll post it to addons.

cheers,
-e
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 17 Aug 2013, 17:31

Just wanted to give this a bump. I tried bypassing all the computational logic when the selected cell is 0 or 1, and I'm still getting the same result. I thought maybe it was a divide by zero issue or something, although there is no logic anywhere to set any cell value to anything but 0 or 1.....

It's eating up tons of processor now, so unusable. Maybe it's a bug.... If anyone can test it out, I'd appreciate it.

Thanks!
-e
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

ynohtna
Member
Posts: 36
Location: Brighton, UK
Contact:

Unread post by ynohtna » 18 Aug 2013, 17:47

I know its not very helpful but I just had a brief look at this and can verify that the problems are reproducible, so it's not happening just to you. :)

Couldn't find any issues in a quick run through the script, though.

I seem to recall having seen similar issues with my scripts when updating individual elements of an output array and not the entire set. What I've been doing is setting a XXX_needs_update boolean inside Callback and then setting the appropriate outputs within Process or ProcessIdle (depending on whether it's realtime or UI related data). Could be worth a try?

Oh, and I've also had the same problem with comma text parsing so I've been using my own split_string function. I'm happy to share the code if you're interested.

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 20 Aug 2013, 01:09

Wow, thanks, I will try the first tip. And yes, it would be great to get your parsing script....

Does processIdle get called at the UI update rate then, I assume? That's probably the right choice for just selecting presets....
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

ynohtna
Member
Posts: 36
Location: Brighton, UK
Contact:

Unread post by ynohtna » 20 Aug 2013, 21:34

Yeah, processIdle is called at the UI rate, so its perfect for deferring visual updates while ensuring all the audio stuff gets maximum CPU. :)

Here's my split_string function. It's not quite an instant drop-in for TStringLists but shouldn't be too hard to figure out. It does not handle embedded quotes, but you can easily add that if you need with an inside_quote boolean or whatever. I haven't added it because my textual definition formats are too simple to need it.

Code: Select all

function split_string(const sep, str: string) : array of string; // {{{2
var i, start, cnt, endpos, seplen: integer;
begin
    if (str = '') then
	begin
		SetArrayLength(Result, 0);
		Exit;
	end;

	if (sep = '') then
	begin
		SetArrayLength(Result, 1);
		Result[0] := str;
		Exit;
	end;

	seplen := Length(sep);
	SetArrayLength(result, (Length(str) div seplen) + 1);

	i := 1;
	start := i;
	cnt := 0;
	while &#40;i <= &#40;Length&#40;str&#41; - seplen + 1&#41;&#41; do
	begin
		if &#40;str&#91;i&#93; = sep&#91;1&#93;&#41; then
			if &#40;Copy&#40;str, i, seplen&#41; = sep&#41; then
			begin
				if &#40;start < i&#41; then
					Result&#91;cnt&#93; &#58;= Copy&#40;str, start, i - start&#41;
				else
					Result&#91;cnt&#93; &#58;= '';
				Inc&#40;cnt&#41;;
				Inc&#40;i, seplen - 1&#41;;
				start &#58;= i + 1;
			end;
		Inc&#40;i&#41;;
	end;

	endpos &#58;= Length&#40;str&#41; + 1;
	if &#40;start < endpos&#41; then
		Result&#91;cnt&#93; &#58;= Copy&#40;str, start, endpos - start&#41;
	else
		Result&#91;cnt&#93; &#58;= '';
	Inc&#40;cnt&#41;;

	SetArrayLength&#40;Result, cnt&#41;;
end;

woodslanding
Member
Posts: 1327
Contact:

Unread post by woodslanding » 28 Aug 2013, 21:44

well, 2 issues with using this code, both straightforward enough...

1. Need the reverse, in order to create ct for output. I assume there are commands for adding to the end of a string, I'll look that up.
2. I assume usine always uses a comma as a delimiter--but we never see them in usine. If we want support for commas in line text is that even possible?? It would be nice if usine used a more robust delimiter, like n. That's what the commatext in usine usually looks like. Anyway, a version of this specific to usine's chosen delimiter would be more usefull for most usine users.

Anyway, I've filed the commatext in scripts issue as a bug, so if Olivier fixes it internally, I won't mess with this. Otherwise I'll see what I can do.
Custom Ryzen 5900x MATX build, Win10, Fireface UFX, touchscreen
Custom 2 manual midi keyboard
Usine, Kontakt, Reaktor, Synthmaster, Byome, Arturia, Soundtoys, Unify

Post Reply

Who is online

Users browsing this forum: No registered users and 34 guests