SamuKata
colugomusic
colugomusic

patreon


Dev Log #67 - Macros implementation progress

I'm now well and truly underway implementing the new macro system. I have a pretty good idea now of how all the pieces fit together so it is just a case now of consuming a lot of caffeine and powering through it.

I estimate it will take at least a month for the next build and it won't be a full implementation of the macro system.

For v0.26 I am probably going to aim for this basic stuff to be working:

This might also be in v0.26 but might be left for later:

Things that probably won't be in v0.26 but will come later:

Things that definitely won't be in v0.26 because they will be part of other systems that are yet to be developed:

I am currently making some huge changes to the codebase to support the macro concept. I knew I would have to so this but wasn't sure exactly the nature of the changes until I started working on it.

Technical details

None of the following will be necessary to know for the user once it's all done. It's just some insight into the shit I am currently wading through for anyone interested.

Ever since I added the cloning system, Blockhead has had a structure something like this:


In this case there is one block, and two references to it (e.g. you have one "block" on the workspace and ctrl+shift+C to create a single clone of it, ending up with two "block refs" to the same "block".)

The "block" contains data which will be the same for every reference to it, whereas each "block ref" contains any data which could be different, which includes a copy of all the base parameter data after any manipulations have been performed.

The audio system doesn't know anything about the concept of block cloning. From its perspective there is no distinction between "block" and "block reference", there are just blocks. So the audio system traverses over the workspace and each "block" it encounters has to have all the information required to play it back. Therefore each Block Ref packs both the "base block" data and its own "block ref" data into a structure for the audio system to read.

So the base block data is actually duplicated for every block reference, which might seem a bit dumb but it actually vastly simplifies the audio system and makes it so the audio thread has to do less work to piece things together. The base block data is also generally very small anyway.

With the introduction of macros things are now starting to look more like this (bear with me):


This is extremely simplified but I think maybe it gets across the basic idea.

A macro contains another workspace inside it. It's more or less exactly like the existing Blockhead workspaces. The inner workspace contains a block ref. The part of the block ref that needs to interface with the audio system has been moved into something which i am calling the "core block". A rule of thumb is that the user still interacts with blocks via the block ref interface, whereas the core block is this hidden away thing which is responsible for synchronizing the final data with the audio system.

The core block on the left will only ever be used when the macro is opened up by the user. In this case the workspace inside the macro takes up the full screen just like regular workspaces now. The audio system only plays back one workspace at a time.

For every macro that is created there will also be at least one "micro workspace" created (and multiple if the macro is cloned).

The "micro" terminology is just a word that I decided on because I needed a way in code to refer to this concept which doesn't have a name.

The micro objects are completely invisible to the user but are what are used for rendering the contents of macros from the outside (i.e. when the macro is closed). So when a macro is open and being edited by the user, the core block on the left is used. When it is closed the core block on the right is used.

Each micro workspace has a real workspace which it is connected to and any time the user makes edits to the real workspace, the changes are replicated in the micro workspace. This means every real block ref also has a "micro block" connected to it inside the "micro workspace".

Cloning a macro block should just be a case of creating more micro workspaces which connect to the original inner workspace.

I am trying to make these "micro" objects as simple as I possibly can. They basically consist of just the data that is required by the audio system, and have no capability to be directly interacted with by the user.

The micro blocks also need to interact with the baking system and need to be individually bake-able just like regular block refs. Macros will be able to accept audio input from the lanes above, and will also output audio to the lanes below, so this means block refs and micro blocks need to be able to look in and out of the macro boundaries to see what is affecting what.


More Creators