|
Helpful Links and Info
|
|
|
Forum Rules & FAQ
New to the forums? Read this to learn the basics:
|
Helpful Resources
Need help with a product? Please check these pages:
|
|
|
|
|

30-01-2005, 16:47
|
|
NI Product Owner
|
|
|
Join Date: Jun 2005
Posts: 460
|
|
|
Macro that prevents Value from sending on startup/on-off?
I am working on a macro that uses Value modules to store event values and send them later on into an event table. The macro works fine--except on start up (when the instrument is loaded, when Reaktor power goes on and off).
The problem is that an event is sent from the Value out on these occasions, and this writes garbage values into a table. I have tried all sort of things to ensure that this doesn't happen, but none of them have been successful; eventually the Value out is connected with the table, the Value in is assessed, and garbage goes out.
Does anybody have a macro that can store a value to be sent on an event trigger, but that does not send any value at all to output until you explicitly want it to? I realize the last bit is ambiguous in terms of what is going on in Reaktor, so what I really want, is a macro that doesn't send a value to output until a user generated interface event hits its input. I've tried all sorts of things to prevent the the input from being fired on start up: putting a router between it and the event that supposed to fire it an having the router close after a delay with a constant wired to it; using a counter so that the input or output only goes through after the first event, and so on, and I just can't get it to work. It seems like I am only delaying the moment when a calculation happens that sends the value to output.
I hope this is clear, if not please ask.
|

30-01-2005, 18:02
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
|
The EventValue module itself does not send a value on start-up, but any module that takes no input parameters does. This includes constants. It probably also includes whatever "useinterface element" you're talking about. After all, what's the difference between when the user moves a knobs and when it sends it's value on startup - OTHER THAN the fact that other knobs, switches, buttons, and constants may not have initialized yet? Nothing.
The solution may depend on what it is that should trigger the write (mouse movements from an XY might allow for a different solution from MIDI input), and what's the source for the data being written (just constants, constants and knob values, XY movements, MIDI data, etc).
Like I said, the only difference between an event coming from a knob at start up and "while it's running" is that at startup all of the other values in the instrument have not been initialized yet (or may not have been initialized yet - you don't know for sure). So you need to correct an ordering problem. Perhaps just putting a 10ms delay on the knob (or whatever) that's supposed to trigger the event-value "in" input is the answer, so everything has a chance to settle before the first event hits the structure - but there is no generic solution for this problem, you need to give us more specifics on what's upstream of the "val" input and upstream of the "in" input. So we can see why bogus data would be at "val" when the first event arrives at "in".
- CList
|

30-01-2005, 19:49
|
|
NI Product Owner
|
|
Join Date: Dec 2005
Posts: 3,872
|
|
|
Re: Macro that prevents Value from sending on startup/on-off?
Originally posted by Rameau
I am working on a macro that uses Value modules to store event values and send them later on into an event table. The macro works fine--except on start up (when the instrument is loaded, when Reaktor power goes on and off).
The problem is that an event is sent from the Value out on these occasions, and this writes garbage values into a table. I have tried all sort of things to ensure that this doesn't happen, but none of them have been successful; eventually the Value out is connected with the table, the Value in is assessed, and garbage goes out.
Does anybody have a macro that can store a value to be sent on an event trigger, but that does not send any value at all to output until you explicitly want it to? I realize the last bit is ambiguous in terms of what is going on in Reaktor, so what I really want, is a macro that doesn't send a value to output until a user generated interface event hits its input. I've tried all sorts of things to prevent the the input from being fired on start up: putting a router between it and the event that supposed to fire it an having the router close after a delay with a constant wired to it; using a counter so that the input or output only goes through after the first event, and so on, and I just can't get it to work. It seems like I am only delaying the moment when a calculation happens that sends the value to output.
I hope this is clear, if not please ask.
|
I think i have solved it:
user library : MEMORY
you can try all what you want:
write a value to the memory (in the ensemble it is a constant (5.5)). Read it. Then push the on/off knob of reaktor - all is working fine, no input in the memory and no output.
next: clear memory. You will see that the meter shows still 5.5. now push on/off knob of R4. Nothing happens: memory is still 0, meter shows 5.5! You can change memory and meter in running and stopped mode.
ciao herw
|

30-01-2005, 20:32
|
|
NI Product Owner
|
|
Join Date: Dec 2005
Posts: 3,872
|
|
|
Re: Re: Macro that prevents Value from sending on startup/on-off?
addition: MEMORY 1.1
now remembers after loading too
ciao herw
|

30-01-2005, 21:57
|
|
NI Product Owner
|
|
|
Join Date: Jun 2005
Posts: 460
|
|
|
Clist and herw,
Thanks for the work. I understand your point CList, and I did try to delay input into the in of Value, but it doesn't work, because of the overall setup. Herw, thanks for the memory work--I tried splicing in this idea but I don't think it's going to work because...oh dear...the circuit involves iterators that are not speed limited, and I don't think the idea of using tables for storage is working. Anyway, I've to to do some other work, so what I've done is posted the ensemble in the library: Schoenberg Phone Home. You'll see that once you click init in the tone row generator, things work properly--but when you load or turn reaktor on off, some extra values get written into the row.
I believe the problem is with the value modules circled in the gif. You can find them by opening TwelveToneRowGenerate> ToneRow> TransformRow.
So maybe somebody can find a solution.
|

31-01-2005, 06:53
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
|
Rameau,
Hope you don't mind if I get critical, it's a learning process here, and I'm writing to anyone who's listening, so forgive me if I state things you know already...
I beleive your problem is that you are not accounting for the constants in your math everywhere. You are in some places - wonderfully - but not everywhere.
E.g., you've got constants connected to the input of modulo's inside the ToneRow macro. Those modulos will send events when they receive an event on either input. (Hopefully) the "A" inputs will not receive an event on startup, but the B inputs will, because constants fire events on start-up. The "A" inputs are assumed to be zero when the B inputs receive their events. The module outputs zeros at startup (A mod B = 0), but they should not output anything. As it turns out, the modules will output 2 events – one from the “100” constants, and one from the “-1” constant upstream, so the module might have A set to 0 or –1 at startup depending on the initialization order which is hard to define.
To make a big series of things happen when only one input receives an event, and not at any other time, you need to "order-value" it using EventOrder's and EventValues. This is also a good way to cut down on extra event and extra processing further downstream in your ensemble.
(Side-Note: for modules with two event outputs - like the modulo - the upper output always fires before the lower output, so the order-by in front of the modulo's is redundant.)
The funny thing is, you got it right in your BubblePermute, and your Retrograde structures! They are beautiful.
So, let's take it apart a bit. Here is your BubblePermute structure, this one is built correctly. The Prm input is connected to a trigger-button. The button will be at 0 and will fire a zero at start-up, but that event will die at the separator - just what you want. All of the constant events you have in your math will fire but they will all die at the "Val" input to the EventValue. Only triggered events coming from the button, and making it past the separator, will cause the math to be evaluated, and after it's all evaluated, each iterated event come out of the macro - thanks to the "2" output of the EventOrder.
|

31-01-2005, 06:56
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
|
This other structure, however, is bad news. (The structure is below).
Events arriving at Wtr, Wsr, and In will cause writes to the table, and events will arrive at all of those inputs on start-up because they will flow straight there from the constants. The first thing I’d change is the “subtract 1”. Since the XChg input is driven from 2 properly designed structures, the separator is not needed, and you need to get the “-1” out of this structure or order-value it because it’s firing an event. I would move the “-1” into both the BubblePermute and Retrograde structures before the “Val” inputs of the event-values, just so you don't need to introduce another order-value structure. (actually it looks like you’re currently adding one in those 2 structures before the output – so just get rid of that!)
|

31-01-2005, 06:58
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
|
After that, I’d change the structure like so, to get the Order-Values right, and you should be good to go.
- CList
|

31-01-2005, 07:03
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
|
Oh yeah - don't forget to take that -65535 out of there (in the parent structure) when you get rid of the separator - it doesn nothing now, and will screw things up when the separator's gone.
|

31-01-2005, 17:26
|
|
NI Product Owner
|
|
|
Join Date: Jun 2005
Posts: 460
|
|
|
CList, wow, thanks for the careful analysis and explanation. I'll have to go through that step by step later. Your analysis is clearly getting at the problem I thought I had, and gives sound advice for getting around it.
The -1 and +1 business was an attempt to keep 0 event from firing an exchange. And the -65535 must be from another effort to fix the problem that I didn't scrub out.
I'll let you know how it goes.
|

31-01-2005, 17:32
|
|
NI Product Owner
|
|
|
Join Date: Jun 2005
Posts: 460
|
|
|
CList,
Also, you clearly have a finely detailed comprehension of calculation order and so on in Reaktor. Do you have a words of wisdom list embodying this knowledge somewhere? Your FAQ isn't this detailed.
Also, it looks like, in your analysis, more eventorders will be needed. I've always been hesitant with these, thinking they'd lead to a performance hit because Reaktor would take extra cycles to do things in order...but am I totally wrong about that? Is it the case that eventorders are just making explicit an event ordering that would be implicit anyway? So, for example, if I have module A wired to B, C, D, or reaching them in some way, and I now stick an order module between A and B, C, D, I am just making explicit an ordering of sending to B, C, D that would have been implicit and set by the order in which I actually connected things up? Or is Reaktor trying to simulate all calculations happening simultaneously in a clock cycle, so that ordering adds steps in this process?
I hope this is clear rather than muddled. And I guess I wish NI specified something more about the internal algorithm they are using.
|

31-01-2005, 19:22
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
you clearly have a finely detailed comprehension of calculation order and so on in Reaktor. Do you have a words of wisdom list embodying this knowledge somewhere? Your FAQ isn't this detailed.
Thanks. As for documenting it better... ...er, yeah, one day  . I hate writing documentation unless I'm really in the mood or answering a specific question. I doubt anyone could pay me enough to do it, I'd much rather write code, but maybe one day. I'll wait to see how NI does with the next release of the user manual first, I think you'll see some improvement there.
Is it the case that eventorders are just making explicit an event ordering that would be implicit anyway? So, for example, if I have module A wired to B, C, D, or reaching them in some way, and I now stick an order module between A and B, C, D, I am just making explicit an ordering of sending to B, C, D that would have been implicit and set by the order in which I actually connected things up?
Exactly!
...and it will all happen in the same "click" either way. I beleive the cpu impact is effectively zero. It shold be about the same for an eventorder as it is for an eventmerge.
I'd link you to the R5 Wish List thread where this came up, but it has over 200 posts, so I'll excerpt it here...
Clist spoke thusly:
|
the structure below works exactly the same as an EventOrder (in terms of "a single event being acted upon by three consecutive down-stream processes"), but with an EventOrder you know the order in which those three down-stream structures will be reached by the event. OTOH, with the structure in this gif, the order is undefined. It may be 1,2,3, or 2,1,3, or whatever. Additionally that order - whatever it is - will not change once the structure is built. The point is that it will always hit each downstream structure one at a time in some defined order - the problem is that you have no control over that order.
|
...and like I said, everything will happen in one "click" when an event arrives at the input.
This last point can cause some confusion as well - the timing does not have to happen at the same time as the "control-rate clock". Events can happen at any time. The control rate clock only tells the system when to output events for things like the AtoE module and the LFO.
- CList
p.s. I do hope you're using the EventWatcher macro to test this stuff! Putting it in signal path at different places, working your way upstream fromt he write input while turning reaktor off and on can help isolate these little bug-a-boos very quickly.
|

31-01-2005, 19:40
|
|
NI Product Owner
|
|
Join Date: Dec 2005
Posts: 3,872
|
|
Originally posted by Rameau
... And I guess I wish NI specified something more about the internal algorithm they are using.
|
CList is great in exploring event order and processing order and ....
If you follow his comments you always will find that he is strickly thinking in a right order like programming a linear algorithm with decisions.
I can only say: if you have problems with order and value (specially events) use his great tool event watcher. It helps to understand a great part how NI has made R4. But NI is not able to give a simple answer how some modules are implemented. You can test it (sometimes) with very simple "ensembles" f.i. you insert (first) only a constant and (then) a knob and an add Modul. Now connect constant, knob and output of add-module to the event watcher. Starting the ensemble will give you four values. Now change the knobs value: two new events.
Now create a new ensemble but with another order: first insert the knob then the constant then the add. How is the order of the events changing and so on. Complex structures will have complex event order.
An interesting thing is to delete and insert some knobs and constant and insert again!
ciao herw
PS : cetero censeo ... event watcher (many thanks to CList)
|

01-02-2005, 01:24
|
|
NI Product Owner
|
|
|
Join Date: Jun 2005
Posts: 460
|
|
|
Clist,
Thanks very much. First I should say you are good at doing documenting. Second I should say that it now seems to work. Third I should say that I want to understand why, and I am not in your mindset, so let me put it in my own words, and see if this clicks. Again, thanks for taking the time. And this was a learning experience.
(A) I got rid of the +1 up stream of the xchg terminal and -1 downstream of it. For what follows, (B), this is crucial. Why? Because now an event goes through xchg into the EventOrder only when the permute or retro buttons are fired and generate events. (Whereas before constants on math operators caused an evaluation and an event to be fired from math outputs into xchg on startup.)
(B) Any math module with a constant on even a single input will generate an event output, even if no event has arrived at other inputs; those inputs will be assessed as having value 0.* So I was getting events coming out of my modulo modules, which ended up going to WTr and WSr. Likewise for the +1 going to In. Now all of those are 'insulated' with EventValue modules that only let values through when an event comes through xchg, or init.
*I find this unintuitive, but I can see why the programmers would do this, just like I can see why they have decided that a value divided by 0 is equal to 0. Need to keep values determinate even in undefined boundary conditions. And I seem to remember from previous posts that there are more event outs from math modules than you'd think, like one event each time an input changes so 1+1=2=2, is that it?
|

01-02-2005, 02:16
|
|
Moderator
|
|
Join Date: May 2005
Posts: 3,355
|
|
|
...
OK, you've got it right.
Here's some things to think about...
1. A math module will send an event out when an event arrives at any of it's inputs.
2. An event input holds the value of the last event it received until it receives a new event
3. An unconnected input gets set to zero, but never triggers an event at the output
4. Based on 1 & 3 a multiply module with only one input connected is the same as an EventValue with the 'Val' input set to 0.
5. Pretty much any module with only outputs - including constants - send an event during a Global System Reset (GSR).
6. GSRs happen when the structure changes, when a switch is pressed (which causes a structure change), at start-up, when the reaktor 'power' button is turned on and off, when you change the sample rate, and maybe some other times...
The 1+1=2=2 thing is sort of explained by item #1 - IF each input receives an event. Item #2 makes it clear that if you have x+1, where 1 is a constant and x is an incoming event, the only time you'll have 2 events coming out is at a GSR when the constant of 1 will fire it's event - otherwise you'll only get one event out for each NEW event in at the 'x' input. Let's take a slightly different example, a [+] module with 2 constants connected, a 1 and a 5. At startup ONLY one of two things will happen;
1+5=1,6
or
5+1=5,6
- you'll always get 2 events, the first one will always be added to zero because the second input will not have been initialized. Which of those two scenarios will actually take place is based on the order you pasted modules
into the structure, but the NI developers have told me that you should NEVER build structures based on that assumption - the order could change at any time. The final value will, of course, always be '6', I call that the
'settled' value, because all events have been "resolved" at that point. That is ONLY AT STARTUP. After that, for every GSR that happens you'll get;
1+5=6,6
or
5+1=6,6
...because each input will be remembering it's value from before the GSR as each event comes in, and one event will come in for each of the constant modules.
Like Herw said, playing with the EventWatcherDemo ensemble in my Test Equiptment Pack in the user lib. - with really simple structures is the best way to see this stuff first hand and get a real understanding of it.
- CList
|
| Thread Tools |
Search this Thread |
|
|
|
| Rate This Thread |
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|