gen~ : 'blocks' to auto-generated genexpr code issue ..??
I’m getting crazy with an issue in gen~ (MAX 7.2.1, but also previous versions were affected).
Let’s say at first I’m developing using MAX/gen~ 64-bit, Windows.
I made a patch using gen~ ‘blocks’ and everything works great. The next step for me is to enable/disable the processing of different portions of the code,
sub-routine is on => process
sub-routine is off => sleep
To make this, I have to do :
1–Go to the gen~ patch/abstraction (made by using "gen~ blocks")
2–click on "C" on the right of the screen, the auto-generated genexpr code is displayed
3–copy all the genexpr code in the -> right window
4–paste all the code inside a "gen~ Codebox"
5–link Codebox’s output to the main output of the patch and delete all the previously used ‘gen~ blocks’
6–place an IF-ELSE in the code to enable-disable the processing of different portions of the code.
If I use this method with simple patches, everything works fine.
If I use this method with very complex patches (700+ lines of genexpr are auto-generated), some Params /values that worked fine when the patch was written using ‘blocks’, do not work fine when the patch is written copying-pasting the auto-generated genexpr code -> inside a Codebox.
I remember I had the same issue using MAX version 7.1 : using the method above caused malfunctioning in the code.
At that point I repeated the procedure above BUT, before step #2, I simply disconnected the Param cord and suddenly I reconnected it to its original block/position (disconnect-reconnect a param to the same destination block). After that, following all steps #2,#3,#4… I noticed the Param worked fine as expected.
BUT now in MAX 7.2.1 this "sort of fix" do not work anymore.
Can I ask please if anybody in the forum (or also specially gen~ developers from C74 team/support) :
– have more detail on this, maybe it is related to some gen~ known bug…?
– or maybe know if there’s ANY WAY to enable-disable processing directly using gen~ blocks ?
– or anything else: if happened also to other people, if it is a known issue to be fixed and when, etc… ?
-or maybe it happen only with the (MAX/gen~ 64-bit, Windows)? Maybe the 32-bit Windows / OSX versions are safe ?
Thank you so much, any help would be really greatly appreciated !
Any hint please? Downloaded MAX version 7.2.2. But the bug still here.
Additionally I did this :
1- I disconnected one plug and suddenly reconnected it to its previous position.
2- Then I copied the auto-generated genexpr code, pasted into a Codebox, linked the output and…
And this time that specific param worked correctly !
But if I do the same for any other param, then (after copy-paste the auto-generated genexpr code , bla bla bla…), the previous param (I disconnected-reconnected previously) again stop working correctly.
Maybe an issue/malfunctioning in the way gen~ names/renames all the variables in the auto-generated genexpr code ?
If my explanation is not fully clear for you or you need more details, I can try to explain better… :)
It’s a bit hard to follow, because I’m not sure what you mean by blocks. If you mean visual patching, why not just disconnect the output patch cords. If you mean codebox, you can easily disable sections with /* */ block commenting.
If theres an error showing after pasting code view code into a codebox, can you post it (the entire gen patcher)? Thanks
Hi Graham , my apologies it is very difficoult to say with words…:)
At first can you give more infos about this : you said "If you mean visual patching, why not just disconnect the output patch cords…"
You mean disconnecting the output patch cords should fix something (maybe by doing this, the genexpr-auto-generator is forced to "re-organize" its code ?)
Then, below I’ll try to re-explain my experience/issue with an example, I really wish it could be helpful for you.
PS: with the term "gen abstractions" I mean one or more "gen sub-patches" contained inside a "gen patch".
I have a simple gen patch made using the visual patching approach (blocks connected with wires).
Then, I want to obtain the corresponding genexpr code of that patch/abstraction, so I can replace the whole patch/abstraction with a single CODEBOX piece of code.
So I go inside that patch, I press the "C" icon on the right, I get the corresponding genexpr code, I copy/paste it inside a CODEBOX object/block.
I reconnect the patch inputs/outputs to the in/out of CODEBOX and everything works fine, as the same as it worked when that patch was made using gen objects.
Now, I repeat the same procedure with a very COMPLEX gen patch/abstraction (again, using blocks connected with wires), a gen patch/abstraction containing 10s+ of gen abstractions (sub-patches) inside itself.
So again, I go inside that COMPLEX patch/abstraction, I press the "C" icon on the right, I get the corresponding genexpr code, I copy/paste it inside a CODEBOX object/block.
I reconnect the patch inputs/outputs to the ins/outs of CODEBOX and this time if I play that patch/abstraction, it has a totally different behaviour (malfunctioning like this for example: parameters values are not scaled properly as they were where the same patch was made using gen ‘objects’).
In these days I noticed that if I repeat the procedure above (substituting gen blocks/wires with the equivalent auto-generated genexpr inside a codebox) for ANY SINGLE abstraction contained inside the main abstraction, and AT LAST I do it also for the main abstraction itself, some issues seem to disappear (the genexpr code is generated correctly)…
I really hope my infos can be helpful for future improvements, :)
I think I understand. If you could post the actual patcher, I could look into it.
However, I still wonder — why do you want to convert the entire patcher to a codebox? It will not be more efficient, and if you built it by visual patching, I presume visual patching will be easier for you to continue working with.
If you want to compare with sections removed, you can just delete them, then undo :-)
my apologies Graham, I can’t provide the patcher since it is a HUGE patcher/abstraction and it is made for a commercial product.
My final scope in converting from ‘visual patching’ to Codebox is that I’m adding the REAL-TIME process/sleep functionality for different portions of the code/software (not just //commenting code :)).
And this can be done only using genexpr DIRECTLY.
By the way, here’s the fact: I’m pretty sure (99%) that all of this malfunctioning/issues are due to a ‘conflict’ with the automatic naming/renaming of gen_variables.
When using ‘building blocks and wires’ everything works fine because variables are correctly named/renamed using the internal gen~ engine "auto-genexpr" generator (counter).
For example, from a ‘blocks and wires’ gen patcher, gen auto-generates genexpr variables (and expressions, etc…) named :
"gen_1, gen_2, …, gen_100,…"
"mul_1, mul_2, …, mul_100,…"
"div_1, div_2, …, div_100,…"
To simplify everything in my explanation below, let’s consider a case/patcher where all variables are named "gen_" + a number.
The issue happen when picking genexpr from a Codebox and converting variables names.
When using Codebox, it could happen that some variable names used INSIDE a Codebox are already used in other areas of the patcher.
This may cause a ‘conflict’ between names of existing variables (auto-generated from visual patching) and names auto-generated from Codebox objects. For ‘conflict’ I mean they spot the same name, and then their values OVERWRITE each other.
Maybe to fix this, when the variable names are picked from a Codebox object, a different operation should be done, for example:
Step #1 : pick the original variable name (gen_799) used INSIDE Codebox. At this point (as already happen) (also for runtime), gen engine needs to rename that variable, in order to be used OUTSIDE Codebox, in the main gen patcher.
Step #2 : instead of auto-renaming it to (gen_800), rename it to (gen_799_fromCodeboxNumberOne).
(obviously "_fromCodeboxNumberOne" is just to make an example, other markers can/should be used instead, for example "_01"," _02", so the final name will be "gen_799_01", "gen_799_02", etc…).
I propose this because (gen_800) variable name may be already used by another abstraction/sub-patch inside the main gen patcher!
99% of the times, variables are correctly named with the current gen internal auto-counter. But when a patcher is VERY complex and it picks code also from a Codebox where vars are internally named (gen_897, gen_78628, etc…), when the auto-genexpr-generator generates the final gen~ code of the main patcher (before runtime), an error may occur and some variables could be not ‘named to be 100% unique’, as it should be. And then some variables value may OVERWRITE other’s having the same name.
I wish the issue scenario is now more clear to you Graham, (I made of my best with the explanation :)) for any additional clarification just ask, I’ll be happy to help you improving gen~.
I wish you/Cycling74 Team will keep the GREAT work you already made with the amazing gen~ !
PS: the Rule I suggested above in my previous post :
renaming "gen_799" to -> "gen_799_01" , "gen_799_02", etc…
renaming "gen_799" to -> "gen_800", "gen_801" etc…)
should be applied only in the case of picking genexpr code from a Codebox.
This should be safe and don’t generate issues (if I’m missing somethig just let me know).
Does the name clashing happen if you select the entire top-level patcher and paste its codeview into a new gen~’s codebox? If so, this is a bug that will need to be fixed. That’s why it would be helpful if you could send me a patcher (you can send it privately to graham @ cycling74 dot com if you don’t want to share it).
Otherwise, I think what you are using the codeview for might not be something fully supported. The codeview is first and foremost a patching aid, to help understand what the patcher is doing . It is actually showing the variable renaming (and code re-organizing) that happens among the earlier passes that convert the patcher into machine code. The renaming is a necessary step and will always happen in this way. The codeview is also secondarily a convenience to guide how to use genexpr, and to allow copy-pasting into a new gen~ codebox. As you see the variable renaming will not make this the most readable code, but this isn’t going to change.
It’s a very strange issue… I did as you suggested :
1- I have my HUGE patcher. All works great. No errors. No inaccuracies. When I turn DSP engine "On" (on MAX) everything works great. No bugs at all.
2 – I don’t modify anything. In my TOP-LEVEL gen~ patcher, I press ‘C’ on the right side. Now, genexpr code is displayed. I copy all the 5000+ lines of genexpr inside a codebox. I connect codebox ins/outs to the main ins/outs off the patcher.
NOW I TAKE TWO DIFFERENT WAYS (I’ll do point 3A or point 3B separately):
3A – From previous point (2), I disconnect all the "patching blocks" (previously used, currently not used) WIRES from the main outputs (BUT ALL THE DISCONNECTED "patching blocks" are still present in the patcher ! ). ONLY Codebox is connected to the outputs.
In this scenario, everything works FINE!
3B – From previous point (2), this time I DELETE ALL THE "patching blocks" (previously used, currently not used)WIRES+BLOCKS, with the exception of the Codebox (where the equivalent, auto-generated genexpr code has been copied in point(2)). Codebox is now the only ‘gen block’ present in the patcher and connected to the outputs.
In this scenario, THE BUG HAPPEN!
By the way, in the next weeks I’ll try to find out some time to isolate the bug, so I can be more specific on this issue (in what circumstances it happens exctly) and then let you know. If you/C74 team have any idea of what the issue could be, please let me know.
Please try this:
1. select entire top-level gen patcher
2. open the codeview (C icon)
3. copy the code in the code view
4. make a new patcher
5. make a new gen~, and open it up
6. delete the default in1/in2/+/out1 patcher contents
7. create a new codebox
8. paste into that
9. turn on audio
Does it work?
I followed all the steps you mentioned : the patcher DOES HAVE THE ISSUE.
There are no errors in the compiling process, it is compiled successfully and it runs in MAX/GEN.
But its behaviour is DIFFERENT from the same patcher made using "patching blocks" (the original project from wich we started).
The issue remains : some values/params are not scaled properly as they were in the same patcher made using "patching blocks".
OK — then I can log this as a bug. However to proceed on fixing it I will need an example patcher that demonstrates the problem — it doesn’t have to be everything (and it’s better for me if it is smaller of course), but so far I have not been able to reproduce any issue in my own testing. You can send it to me privately, I will not share it.
Sure Graham, in the next weeks I’ll try to find out some time to isolate the bug and then I’ll give the patcher to you so you can see what’s wrong with it. Thank you so much for your support.
FOUND THE ISSUES/BUGS IN GEN
Let’s call it the "brackets bug". They are actually TWO different bugs in two objects:
1- the EXPR object with an "input" ;
2- the gen abstractions "gen @title …" , the way it accept/sum inputs ;
Take a look to the patcher (ATTACHED to this post), everything is explained there.
Basically in both cases, expressions like :
1 / ( 2 / 3 );
In GEN (engine, run-time code generated from the "patching blocks") they are translated as : 1 / ( 2 / 3 );
BUT IN GEN (‘C’ icon, the read-only genexpr displayed on the right side of the GUI) they are translated as : 1 / 2 / 3;
Keep me informed Graham,
Thanks so much for the very clean example of the issue. It is now logged as #9985 and I’m working on it now — hopefully should be fixed in the next update.
do you think the next Max/Gen update will come in "reasonable" times ? :)
Thank you for your quick support,
It’s out now :-)
just checked it, "brackets bug" and "divide by samplerate bug" are now fixed.
gen has never been so beautiful ! :)
Forums > Gen