-
Notifications
You must be signed in to change notification settings - Fork 0
Home
The classification of what BoxySeq is, resides somewhere between sequencer and arpeggiator.
The core concept of BoxySeq is to use a window-manager-like window-placement-algorithm to generate pitch and velocity data as it sequences events in real time (via the JACK Audio Connection Kit’s MIDI API).
The behaviour of the placement algorithm is based upon the behaviour of the Fluxbox Window Manager. There are three binary options for the placement strategy: Row-Smart or Column-Smart placement, Left-to-Right or Right-to-Left, and lastly, Top-to-Bottom or Bottom-to-top.
Implementation wise, an array is used in combination with bit manipulation to store the ‘used’ state for each element in the 128 × 128 grid.
This placement algorithm is strict. No placement will ever be made which causes overlap to occur. Any event which cannot be placed is dropped, discarded, tossed away, ignored, not sequenced.
Pitch and velocity data is generated for each event sequenced by BoxySeq by a placement algorithm. Up until the placement algorithm places an event in a two dimensional grid, the event does not have meaningful pitch/velocity data. The event is placed as a 2D box with width and height into a grid where it will fit without overlapping any other currently placed event. The coordinates of the box determine the pitch and velocity of the event that box represents, with X mapping to pitch, and Y mapping to velocity.
BoxySeq will output MIDI data for each event. The range of values for MIDI pitch data is 0 to 127 (integer). The range of values for MIDI velocity data is 0 to 127. The grid that events can be placed within is therefor 128 × 128 elements.
- Events can only be placed within a boundary located within the 128 × 128 grid.
- Multiple boundaries can appear within the grid and can overlap each other such that the placement of events within overlapping boundaries interacts. Note that overlapping boundaries does not mean the events within one boundary can overlap events within another boundary.
- The options defining the placement strategy are defined within the boundary and not the grid. Therefor, each boundary can utilize a different placement strategy.
- The pattern is the rhythmic sequence of events. No event within the pattern holds meaningful pitch and velocity data.
- The pattern defines minimum and maximum values for the width and height properties of the boxes that are placed within the grid.
- When the pattern sequences an event, it randomly generates the width and height for the event, which is used by the placement algorithm to determine where the event can be placed, if at all.
Given a MIDI port and channel, BoxySeq assumes one voice per pitch, in other words, two voices may not play the same pitch on the same channel to the same MIDI port. Therefor, two event boxes both placed with X 60 causes a problem. BoxySeq will either utilize the width of the second event box to find a pitch somewhere between X and X + Width, or, the second event box will become a block box, or, the second event box will be dropped, discarded, tossed away, and not placed.
- Boxyseq is being implemented such that multiple patterns can output events into a single boundary, a single pattern can output to multiple boundaries, multiple to multiple, and single to single.
- A single boundary can output events to a single MIDI output (a MIDI output here being the BoxySeq abstraction for a MIDI port), or to multiple MIDI outputs. Multiple boundaries can output events to multiple MIDI ports, or to a single MIDI output.
- A Boxyseq port is an abstraction which sits between a pattern and a boundary. Events are written to the port by the pattern. Events are read from the port by the boundary.
- A BoxySeq port cannot read input or write output to any other BoxySeq port.
- Ie, the routing ability of BoxySeq is currently and intentionally limited until such a time that development is ready for a fuller implementation or requires it before development can continue. Ie, there are certain ways of making connections that this approach cannot handle.
- Block Boxes. A static box the purpose of which is purely to prevent events from being placed in the area it occupies. These boxes are (typically) placed by the user, but various scenarios may arise which cause BoxySeq itself to place block boxes. The user may move, resized, and perform other (as yet unforseen) manipulations upon block boxes.
- Block Box Repositioning. How to handle a reposition of a block box that consequently overlaps event boxes presents something of a problem which is yet to be tackled. The problem arises from the fact that the freespace_state code is not designed to handle layers. Some other mechanism is going to be required to act as perhaps a middle-man.
- Block Box Ownership. The block boxes will be owned by the grid they are placed within.
-
MIDI input into a pattern
This will cause MIDI events to loose their pitch and velocity information and be incorporated into the pattern. Where they then go depends on where the pattern outputs to.
-
MIDI input into a boundary
The boundary will act as a filter for MIDI events, filtering out events with pitch/velocity data outside of it’s area, playing as normal those that lie within its area range. The events will follow the boundary’s output path.
-
MIDI input into the grid
The grid will place any MIDI NOTE-ON event input into it as a block box for the duration of that event.
- Use scales for generating pitch. The scale to use for placement set per boundary (note: this would not cause gaps to appear when box 2 is placed next to box 1 if the pitch between the two is not part of the scale).
-
Grid Switching
It may be possible to have multiple grids and to switch between them much like you use virtual workspaces in typical Open Source Desktop Environments. As mentioned above, block boxes will be owned by (or tied to) a particular grid. It may be possible to also provide a ‘sticky’ flag much like many window managers do such that those block boxes with such a flag set will appear on all grids (though due to the nature of the freespace_state, a sticky flag for block boxes may be a lot more trouble than it’s worth).
-
Grid Switching and Boundaries
Boundaries would default to the sticky state and always appear on the currently visible (selected) grid, and consequently the events placed by a boundary would always be placed only on the currently visible grid.
The general idea behind this is that by placing block boxes in different arrangements on each grid, you have a device for switching between phrases in the composition (but this pulls in further questions related to the as yet non-tackled problem of pattern arrangement). To see a rudimentary example of grid switching, you could do worse than run the xwinmidiarptoy BASH script (see media for details) and then switch between virtual workspaces each with different window arrangements upon them.