!Epoch, for the next 4 years

Official support for: loomer.co.uk
Locked New Topic
RELATED
PRODUCTS

Post

grinzler wrote:I believe most people working on something this much of an evolution compared to their previous work, would be proud to publicize the development process in detail (like over coffee in the morning once a week or such). Especially when you are asking for so much patience.
Alternatively one could admire Colin's persistence and determination

---and still admire our patience :)

Post

I guess a few (cropped) screenshots wouldn't hurt too much. A number of the icons and elements are either placeholders or not finalised, and the entire transport panel from the top of the interface is removed for editorial reason, but you should get the gist.

Image

The Graph view is where you create modules and connect them together. Events and data flow between the modules. The example below is from a test I'm using to fix an issue with some list processing modules. It consists, with the modules on the left, of a static polyphonic sequence, and a generative drum sequence on the right.

The icons loosely group each module into its type. The Begin, End, Length, and Rate modules are all UI elements, in this case sliders, which you can style and place onto the Panel view to build your patch's UI. You can also see a few constant modules, which are the modules without the inlet bars. We only need one type of constant module because the variable type within is inferred: 1 is an integer; 1.5 is a double; "this" is a string; true is a boolean; ["things", "in", "brackets", "are", "lists"], etc. Note that in the properties window, constants, like many other modules, have an "Initial Signal" attribute. Enabling this means that the module can automatically send its output when the preset loads, minimising how much plumbing it needed to initialise the preset.

Image
You can split the UI to have multiple views open at once. Everything is in the one window, with no floating dialogs to manage. Here we see a Poly Step Sequencer module, with its contents visible in the bottom split. Hovering the mouse cursor over a module will show the pin names, which are usually hidden, as will dragging a cable near the module. The pins themselves can also be hidden; the green + icon in the properties allows you to only see which pins you need.

Below that, I've also opened the console. You can click any console message to be instantly taken to the source module.

Image

The "quick create list" is the recommended way to add new modules. There are other options: a right-click context menu and, and pinable tree browser also show all the modules and fragments. But the fastest way is simply to start typing the name of a module, which pops-up this dialog. New modules are aligned below each other, ready for wiring up.

(Notice that the List Set module is showing an error. This corresponds to the "unexpected token type" you can see in the console. When an errors occurs, the event associated with the error stops, but other events will continue to process.)

And I don't think I've mentioned fragments before. A fragment is simply a collection of one or more modules which have been exported to your user library. Previously you could only export macros and scripts, but now you can export anything. I, for example, have fragments of styled up sliders and buttons, which means I can have instant access to some styled UI elements.

Everything is vector, scaleable, and customisable. The screenshots are zoomed in at 150%, which seems to be my preference for simple presets. I tend to zoom out as the graph gets larger. The entire UI is also scaleable, looking crisp on everything from low resolution laptop screens to 4K monitors.
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

:o :o :o
:tu: :clap:

Post

:)

Post

Wow!! :clap: Looks like a hybrid between Bidule/Metaplugin and Rapidcomposer so far. Great work! I'm really curious. :)

Post

How does the signal flow work - I'm getting nervous now as it's starting to look somewhat like Max, which I have a love/hate relationship with - their concept of positioning of components on the canvas determining signal ordering is (IMHO) a nightmare.

Compare it with something like Unreal Engine, where there's an obvious 'signal' line to show the ordering - I realise they're not the same thing, but you'll get the gist of what I'm asking.

Other than that, it looks great - maybe you need some alpha/beta feedback about the signal flow :lol:

I'm glad there's a visual sequencer component though - I'd really like to see the timeline aspect, as that's (for me) one of the most important aspects, after signalling. I am available to sign NDAs if they're necessary :hug:

Post

With the caveat that I've not written anything significant using Unreal Blueprint, I'd say that the event flow is somewhere between Max and Unreal. The leftmost green inlet, which you can see on the List Get, Uniform Int Distribution, List Roll, and List Set modules, correspond to Unreal's signal line. Events to other inlets are cached until the module gets the signal (which can be literally any data type.) Perhaps I could colour the cables to these inlets to reflect that they are signalling connections? That could be quite nice actually, I'll give that a try this weekend.

But - and brace yourself koalaboy - low-level signal flow is ultimately dictated by module and inlet position. I did try various other methods, such as basing it on module id, but having an order dictated by something non-visual just felt wrong: two presets that looked identical could function differently due to them having modules created in a different order. And whilst call order is predictable, if you don't want to rely on position, there is an explicit Order module that can call modules in what-so-ever order you choose.

Unreal's event model is nice, but I suspect - and it's too close to the weekend for me to think through the implications clearly, so feel free to correct me - that Unreal doesn't allow recursion in their execution. If I get a chance over the next few days, I'll take a closer look at Blueprint and see what I can 'borrow' from them.

And noted, timeline screenshots will be next.
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

1st wait, what ? signal flow is based on a modules position visually ?
I just misunderstood that, right ?
2nd Grinzler, will you either go away or actually make some sense, you actually typed that this project is so so so so so complicated, colin doesn't have the experience, why does it take so long booohooobooohoo, and you don't even see the stupidity in that, if somebody does not have the experience, then it will take longer you silly silly child.
Duh

Post

Only in two situations does a module's position come into play.

i) For event sources occurring simultaneously. Just to get the terminology straight, an event source is a module that can produce an event, but doesn't require an internal upstream event. Modules that fall into this category include the metronome modules, MIDI inputs (which respond to external events) and UI widgets.

Imagine you have a patch with two MIDI input modules connected to two different MIDI devices. Someone plays these two devices at exactly the same time, which means at the same tick, both MIDI inputs must produce events. But which goes first? The answer here is simple: the right-most one, because we always process right-to-left, top-to-bottom. Predictability is a good thing.

ii) When a module's outlet has two or more downstream connections. In these cases, we need to pick one destination module to be processed before the other, and so we again order based on the destination module's position.

To clarify, if module A's outlet goes to both module B and module C, we can accurately predicate which of B or C will process first by their position, relying on the implicit order. (Or we can make it explicit and insert an Order module.)
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

You can't always get what you waaaant...

Post

Im guessing right to left is going to be confusing to a lot of people, most people (western at least) would always count left to right, so
1/2/3
Having 3 be before 2 and before 1 would confuse people if you know what i mean
Duh

Post

Although it may sounds backwards when compared to standard reading direction, in coding terms it works nicely. Right-to-left makes sense here because the signal inlet, the one that actually tells the module to do it's thing, is always the left-most. In theory, swapping the order isn't a big issue, but this way has always felt most natural to me, it being, more or less, a standard in several other flow-based languages. Still, as always, feedback appreciated, and I'll try the other direction to see how it feels.
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

colin@loomer wrote:Only in two situations does a module's position come into play.

i) For event sources occurring simultaneously. Just to get the terminology straight, an event source is a module that can produce an event, but doesn't require an internal upstream event. Modules that fall into this category include the metronome modules, MIDI inputs (which respond to external events) and UI widgets.

Imagine you have a patch with two MIDI input modules connected to two different MIDI devices. Someone plays these two devices at exactly the same time, which means at the same tick, both MIDI inputs must produce events. But which goes first? The answer here is simple: the right-most one, because we always process right-to-left, top-to-bottom. Predictability is a good thing.

ii) When a module's outlet has two or more downstream connections. In these cases, we need to pick one destination module to be processed before the other, and so we again order based on the destination module's position.

To clarify, if module A's outlet goes to both module B and module C, we can accurately predicate which of B or C will process first by their position, relying on the implicit order. (Or we can make it explicit and insert an Order module.)
I think this is where it gets more confusing than it has to, as it's combining signal flow with the time domain. Why can't the signal just go through A, then B and then C, disallowing multiple outputs... they can still all output sound on the same 'tick' - you just have an element of latency between the signal passing and the tick time.

If you allow multiple outputs, you're effectively implying parallelism which will vary depending on the modules (and where they go) and we know how well multi-threaded code is understood by programmers... parallel *anything* is just asking for trouble in most cases, and if it's not parallel, just make it a sequential flow.

Perhaps part of the problem is if the signal represents a value, other than just being a flow signal. Again, in UE, the signal is just telling the module to read from its inputs, do any processing, and populate the outputs - nothing more. This means that you always have a sequential flow but multiple modules can read from a single source - they just don't read until they're told to. For instance, in your example, B would be triggered and then C, both reading the value from A and acting upon it.

I realise many people like Max, and seem to get on fine with it, but this is the exact same problem I have with it. It is deterministic, but in a backwards way for my brain :dog:

Post

I did experiment with something similar to what you suggested, with modules pulling data from upstream in response to a signal, but no other event system - and I tried literally tens of variations - ever quite felt right to me. I've a 200 page A4 pad full of events design notes, and I really hope you don't make me have to open that tome again.
I realise many people like Max, and seem to get on fine with it, but this is the exact same problem I have with it. It is deterministic, but in a backwards way for my brain
I've been there. Not with Max, but certainly with other coding constructs, where it took me a long while for my head to click with how it works. I struggled with functional programming for a long old while until one morning, apropos of nothing, everything just fell into place and I realised that all my grumbles about how it doesn't make sense were entirely me misunderstanding a very logical system.

I think you just need to move away from the idea that multiple outputs implies parallelism; it doesn't, it just means that a module's event will go to two or more other modules, but sequentially, not concurrently. In truth though, I don't seem to spend much time thinking about which module, B or C, will run first: as long as you connect the left-most activation signal correctly - easily done because in most cases it just means the left-most outlet goes to the left-most inlet of the next downstream processing module - the order seems to take care of its self.

The event system was a delicate compromise between various ideals: events had to occur at a specific time, so that a MIDI event entering the system at tick 23 would also exit at tick 23; it had to be flexible; it had to minimise extraneous 'scaffolding' modules when trying to articulate simple concepts, recursion and feedback must be allowed, etc. This was the only design - or at least, the only one I've came across - that managed to fulfil all the criteria, but of course, as ever, I'm open to suggestions.

Also, koalaboy, would be happy to get access to the closed alpha test builds, when it's ready for such things? I'd love to get your thoughts on the event system prior to beta, and I feel trying to explain it without you using it is a little like dancing about architecture.
Architect, the modular MIDI toolkit, beta now available for macOS, Windows, and Linux.

Post

colin@loomer wrote:Although it may sounds backwards when compared to standard reading direction, in coding terms it works nicely. Right-to-left makes sense here because the signal inlet, the one that actually tells the module to do it's thing, is always the left-most. In theory, swapping the order isn't a big issue, but this way has always felt most natural to me, it being, more or less, a standard in several other flow-based languages. Still, as always, feedback appreciated, and I'll try the other direction to see how it feels.
I would suggest not locking it down until you get a beta in the wild, you have to remember that what feels natural to a coder, may not feel natural to joe blogs, a lot of the reason why Reapers UX is a complete mess for instance.
Duh

Locked

Return to “Loomer”