polyend / TrackerBetaTesting

Beta firmware and reporting. For official releases go to https://polyend.com/downloads/
251 stars 24 forks source link

[Suggestion] Probabilistic Pattern Sequencing #1041

Open henry-ehlers opened 3 years ago

henry-ehlers commented 3 years ago

Probabilistic Pattern Sequencing

Introduction

Before commencing, I thought I'd first thank the Polyend team for the continued support and updates. Love my Tracker, and am sure I will only come to love it even more with more time. The Tracker is already great for properly 'composed' pieces of music, i.e. a linear progression through patterns. However, within the context of generative music making I see some room for improvement (see also my suggestion #928). More specifically, I hope that these suggestion can be implemented in such as away as to not violate the Tracker's streamlined workflow, and not be too resource intensive (which I understand to be one of the limiting factor on the hardware level).

Importantly, if this has suggested elsewhere and I simply missed it when checking, I apologize. Just let me know and I will take this down.

Context

Here, I wish to propose an additional pattern sequencer. Consider a simple project with 3 defined patterns, named A, B, and C for simplicity. Using the tools currently available, we can manually string together a sequence of these three patterns. However, I wish to suggest an alternative sequencing mode which allows us to string patterns together probabilistically. To illustrate the concept, assume we wish to start our aforementioned song on Pattern A, randomly alternate between Patterns A and B as a function of predefined probabilities, and finally end on Pattern C. We could represent this as a probabilistic (cyclic) network as illustrated below.

3 Pattern Network

In this example, the three nodes represent the three patterns. Pattern A is represented as a square as it is the start node. The arrows represent the possible sequence paths, i.e. which patterns can occur after one another. Please note that these are directional edges, i.e. if moving from B to C is possible that does not mean the reverse is possible! In addition, you may notice numbers attached to these edges. They represent the probability with which a particular path is taken. Moreover, if a node has outgoing edges, all these outgoing edge probabilities must sum to 1, i.e.

Outgoing A = P(A -> A) + P(A -> B) = 0.4 + 0.6 = 1 Outgoing B = P(B -> A) + P(B -> C) = 0.8 + 0.2 = 1

Pattern C has no going edges, so this does not directly apply to it. Instead, it is necessarily the terminus of this network, and thus the end of the song's probabilistic sequence.

NOTE: I should add that a network such as this does not require a terminus node / pattern. All nodes could be in some way connected, meaning the song could go on forever. In such a situation it would be at the user's discretion when the sequencer stops.

The Suggestion

Song Mode - Representing the Network

The above visual representation may be useful for conceptual demonstrations, but it becomes increasingly cumbersome the larger the network gets. As the Polyend Tracker supports a total of 255 patterns, this would be prohibitively complex (not only visually but also computationally). Additionally, having to reason about probabilities directly (and more specifically dealing with its sum to 1 constraint) is also cumbersome when building a such a network. Thus, I propose such a probabilistic sequencer be represented as a Weighted Incidence Matrix. The previous example would thus be represented as follows:

A B C
A 4 6 0
B 8 0 2
C 0 0 0

Now, instead of needing to visualizing the entire network, we can simply reason about the network's edges directly, i.e. the possibly probabilistic paths through our song's patterns. In such a representation, each pattern / node is present as both a column and row, where a row represents a hypothetical current state and each column represents a possible new state. Each cell represents the probability of a move from that row's pattern to that column's pattern. This representation also preserves the directed nature of the network. However, instead of reasoning about probabilities directly, we can simply define the network in terms of weights instead. Now, we can increase and decrease the weight of one connection without needing to constantly update all other weight, as these weights need not sum to any specific value. They do still however allow us to reason about the relative probability of taking one path over another.

As an example, consider our song is currently playing Pattern A, and must now decide where to go next. In order to determine the probabilities that dictate the next move, we simply need to compare the weight of moving to one specific node and compared that to the total of all weights present. For example, in order to obtain the probability of playing Pattern A again (as illustrated in Figure 1), one would simply calculate

P(A->A) = (WeightA) / (WeightTotal) P(A->A) = (WeightA) / ( WeightA + WeightB + WeightC ) P(A->A) = 4 / (4 + 6 + 0) P(A->A) = 0.4

This representation is simple to render, and importantly allows for very quick editing of weights even during a performance (in-line with the efficient workflow of trackers). I would suggest that when in Probabilistic Sequence Mode, the default Song Mode screen is replaced with such a matrix. Additionally, in order to preserve the Tracker's workflow, I would suggest the following implementation:

Live Performance and Flow Control in Song Mode

One key advantage of this representation,is that it readily lends itself to live performances. While the tracker is playing, a user may simply edit the weights in the matrix as they please, in order to shape the performance. However, one key issue remains that I wish to address here by suggestion two simply features. To illustrate, please consider the following figure. As the exact probabilistic weights of each edge are unimportant for this example, I have opted to omit them for simplicity. Instead, I hope to draw attention to the following: this song consists of two clear parts; one part which consists of patterns A, B, C, and D, and part two which consists of patterns E, F, G, and H, separated by the red-colored edge. A is the start node and H the network's terminus.

8 Pattern Newtork

Consider a situation in which the user wants to control WHEN the sequencer jumps from part to part. As discussed previously, the user could simply edit the probabilistic weights directly in order to force the sequencer to move from pattern D to E. However, if either node D or node E were more connected, editing all of the probabilities of all their incoming or outgoing edges in order to shape the flow of the song would be cumbersome and time consuming. Hence, I suggest two tools for such cases, to be accessible in Song Mode:

  1. Disable/enable toggle a particular node using one of the eight screenkeys. When navigating the weighted incidence matrix, one can hit one of the screenkeys in order to either disable or enable the currently selected column (this could be represented visually by greying out the column in question). In essence, all this would do is temporarily overwrite a column's defined weights with 0 (when disabling that column), and conversely set that column's weights back to their defined weights (when re-enabling that column). Remember that a column represents a pattern's incoming edges. Thus by disabling a column, we make that node unreachable.
  2. Queue a particular node using one of the eight screenkeys. Simply put, we can simply overwrite the random sequencer's next step, and define and force the next pattern to be played. When navigating the weighted incidence matrix, on one can simply hit one of the Tracker's screenkeys in order to queue the currently selected row to play next. Reminder, (just like the columns) each row corresponds to a patter.

These two functions could stand in addition to existing pattern sequencing features, such as as Stop/Continue Song and Set / Change Tempo.

Reproducibility and Seeding

Lastly, one may be interested in reproducing a particular probabilistic sequence, especially when performing a song with other gear or even live musicians. One option would be for the tracker to keep track of the random sequence generated while performing, and convert this into a conventional Tracker sequence (as we are used to in normal Song Mode). Alternatively (or additionally), one could give users the ability to specify the random seed of the Tracker. This would ensure that the random sequence generated by the Tracker is always the same provided the user does not alter the network during the performance.

Conclusion

The ideas suggested here are quite a departure from the old-school tracker workflow that inspired the Polyend Tracker. However, I do believe that the Tracker can well beyond its ancestral origins, and become an immensely powerful tool for generative music making, while staying true to the streamlined workflow already present.

It is of course easy for me to throw ideas out there - I do not have the skills or background necessary to implement any of this. Nonetheless, I hope that, provided others share my interest in combining the Tracker's workflow and probabilistic / generative composition, something like this could become a reality one day :)

EDIT 1: some spelling mistakes were taken care of. EDIT 2: added a small note on network terminus nodes.

x2db commented 3 years ago

Can I simplify above 3 page excerpt to "a Mutation function based on more than one pattern" ? If yes then I love it. The challenge is FX1 and FX2, the implementation needs to be smart enough not to mess up with effects when randomizing, so different weights for different FX... BTW there are a few modules in modular world they are doing this ;Amoeba (beast-tek), Trax (future-retro) and others >:

henry-ehlers commented 3 years ago

Can I simplify above 3 page excerpt to "a Mutation function based on more than one pattern" ? If yes then I love it. The challenge is FX1 and FX2, the implementation needs to be smart enough not to mess up with effects when randomizing, so different weights for different FX... BTW there are a few modules in modular world they are doing this ;Amoeba (beast-tek), Trax (future-retro) and others >:

Dear x2db,

Regarding the requested 'simplication': I am afraid I do not fully understand what you mean by "a mutation function based on more than function" or how this relates to the two FX channels :/ Would you be willing to elaborate a bit further?

Regarding modular sequencers: I am of course aware that there exist a number of powerful modular sequencers which can use incoming CV-modulation to add variety. Indeed, it was that very functionality of modular synthesis that inspired this comment :)

However, I would argue there is a distinct difference between my proposal and what already exists on the modular market: most modular sequencers (that I have seen) only allow for compositional control and CV modulation at the note-level only. The proposed probabilistic sequencer here operates on the sequence / pattern -level. Importantly however, a user is of course still open to probabilistically program each of the Trackers patterns on the note-level if they please.

This ability to control the probabilistic flow of patterns, not only the probabilistic flow of individual notes, is in my opinion an important aspect of making generative compositions musically meaningful. Moreover, this particular approach to generative music making is one I do not see in any currently available Eurorack sequencer module, or any piece of software for that matter. As such, I think this would be an incredibly niche for the Polyend Tracker to fill.

Cheers, Henry

EDIT: I cut-down my slightly long-winded explanation into something simpler. My apologies.

77377 commented 3 years ago

So you want Markov chain sequencing? Cool! I do too! I second this proposal.

OP has a pretty long winded way of explaining a pretty basic concept though. (;

henry-ehlers commented 3 years ago

@77377 Am sorry for the long winded explanation, I just wanted to also explore the possible presentation / implementation from the user's perspective. But yes - it is just Markov Chain-based Sequencing ;)