Introducing Fraccut v3, the next generation in fractal cutting. Fraccut has always been a solid plugin. Unfortunately, it's also been a relatively slow plugin due to the volume of information it handles. AHK heavily bottlenecks the data transfer since the language lacks OOP capabilities. With the c++ library in place, it's time to give Fraccut a serious speed boost.
Beyond the performance gains, the third generation of the Fraccut engine will also leverage the power of the mGN Library's RandomSource abstract interface to draw random numbers. This should allow for much greater flexibility in configuring the random component of fractal cutting.
Some additional features that Fraccut v3 will aim to support in the future include:
- Context-sensitive cutting parameters
- Pay attention to phrasing
- Optional grammar conversion (use the cutting blocks as controllers for a grammar, see Fractal Grammar)
- Incorporation of Markov engine for added stylistic coherence
- Loading/saving Markov styles
- Linkage with gMSE for advanced style options
It's almost mid-March already. I don't like that fact the the samples haven't improved appreciably in a while. As I noted earlier, it's mostly due to the fact that I've been upgrading internals rather than working on sound. Still, it's time to step on it.
Over the past few weeks, I've been working like mad to re-code all the old engines in c++, taking advantage of the massive optimizations possible therein. So far, the following engines are now at least partially-functional as part of the new c++ library:
- Artificial Neural Network Engine (was actually never implemented in AHK and has yet to be used in a plugin)
- Contour Grammar
- Evolutionary Engine
- Markov Engine
- Multi-State Engine
ALL of the new implementations are better than their predecessors, both in terms of efficiency and ease-of-use. Certain complex engines such as the Markov engine may see speed increases of over a thousand fold thanks to redesigning.
By the end of the month, these myriad engines should be coming together to form some really powerful new plugins. All it takes is code.
For some time now I have been thinking about using random cutting as a "base" method for a hybrid engine, using the cutting space to control the behavior of another process. These thoughts came to a head a few nights ago when, despite an enormous amount of brainstorming and coding, contour grammar failed to deliver the immediate results for which I was looking. I wasn't joking when I suggested a "fractal grammar" in the last post. Indeed, having now toyed around with implementations of the idea, I believe that this hybrid technique will capitalize on both the contextual coherence of random cutting as well as the internal consistency of grammatical systems. I will refer to the method as fractal grammar from now on.
Fractal grammar is, to put it simply, a grammar system driven by a random cutting engine (which, as discussed previously, falls under the category of fractal methods - specifically, Brownian motion). The engine first performs the same preliminary steps used in Fraccut, placing cutting blocks on the roots (or another specified interval) of each chord, then performing random cutting to subdivide the blocks. Instead of mapping the subdivided blocks directly to pitch space, however, the fractal grammar engine maps block offsets to indexes of words.
Here's an overview of the basic fractal grammar process:
- Create a space for random cutting
- Map chord progression to blocks in the cutting space
- Perform random cutting on the space
- Create a phrase (in the style of Contour Grammar)
- Map the cutting space to the phrase
- Iterate through blocks, for each:
- Map the vertical position (traditionally pitch offset) to the index of a word and add the corresponding word to the active phrase
- Map the width (traditionally duration) to the duration of the specific element of the active phrase
- Convert the phrase into a polystream
- Apply final mappings (offset->pitch, time scaling, etc.)
- Convert the polystream to a pattern
Note that the first three steps are precisely the steps taken by Fraccut, while the last three steps are precisely those taken by Contour Grammar. The middle steps, then, are the most important - it is the mapping between the fractal engine and the grammar system that is most crucial to the final product.
Thankfully, fractal grammar has already produced some nice results. Though not quite up to par with Fraccut yet, I have no doubt that the fractal grammar method, when it reaches maturity, will far surpass the abilities of random cutting and contour grammar.
Sample 15, the first in three months, will come online shortly!
Finally, having completed a basic implementation of Contour Grammar, I am getting to see what the idea sounds like in musical form. Indeed, some very interesting effects have been achieved thanks to the functional phrase language as well as the use of coherent random sources (which I will discuss at some point in another post). However, even this idea is lacking the coherence of Fraccut, and it bothers me enormously that such an elaborate idea as Contour Grammar can't even beat a relatively simple implementation of random fractal cutting, a rudimentary mathematical process.
Of course, it's very obvious why Fraccut still holds the record for best melodies. Since the cutting engine essentially starts with the chord progression as a seed, coherence is almost guaranteed. It's a powerful effect. Yet, the reality is that Fraccut is hardly aware of what it is doing. In a sense, the coherence generated by Fraccut is nothing more than a cheap trick stemming from the clever picking of the seed. Nonetheless, it undeniably works better than anything else. In the end, I am concerned only with the audible quality of the results, not with the route taken to achieve said results.
That being said, the big question now is: how can Contour Grammar pay closer attention to context in order to achieve greater contextual coherence? It would be nice to somehow combine the internal consistency of Contour Grammar with the external, contextual coherence of Fraccut.
Grammatical fractal cutting, anyone?
After a very successful life, Fraccut has finally received a full upgrade to version 2. The key difference in the second generation Fraccut plugin lies in the implementation of the random cutting engine. While the first version used a custom random cutting engine (the first I ever wrote), the second version exploits the simplicity and power of the XIAS generalized random cutting engine.
The XIAS engine has already helped eliminate some of the strange artifacts present in Fraccut melodies generated with the old engine. The old cutting method had a few flaws that I identified as contributing to a non-uniform distribution of rhythmic and tonal patterns (that is, certain patterns occurred far more frequently than others). There was, in fact, a single rhythmic pattern that kept appearing in almost every Fraccut melody. Perhaps an observant listener will be able to discern this repeated pattern from the samples. This repetition was starting to wear on my nerves, considering the fact that I had not intended for Fraccut to maintain any stylistic coherence across multiple executions. Regardless, the new cutting modes available in the XIAS engine eliminated this strange repetition.
The increased compositional ability of Fraccut v2 has already been observed in several pieces. I am uploading Sample 12 at this very moment to showcase the new incarnation of a great plugin.
Though Fraccut only has a very basic variation system right now, it's enough to almost ruin the coherence that, during the early stages, sounded so promising. But there are plenty of ways to fix that. Repetition of ideas has been almost totally destroyed, especially when multiple Fraccut parts come together. There are several problems with the method of generation right now:
- Each variation is pseudorandom, so there exists an infinite number of "permutations" of the idea. Does this not completely defeat the purpose of the seeding engine?
- Other than the single "styleclass" parameter that the generative modules get each movement, there is essentially no way of coordinating ideas across multiple modules. The lack of coordination module functionality is starting to bring everything else down. This avoidance won't be able to go on much longer, as it's quickly becoming the system's bottleneck.
- Variation is based on seeds right now...maybe it would be smarter to base variation on a separate variation engine? Perhaps some kind of sub-module that could be used across multiple generative modules and offers a variety of variation algorithms? Sounds like it'd be worth a try.
- Variation is performed on both seed strings. It would probably be more coherent to only perform variation on the offset string. I'll see to this once the new fractal cutting engine is in place.
On the side, the new cutting engine (still without a name) is coming along nicely. The OS data structure is performing well and code readability is better than ever.
It'll be exciting to see how the fractal structure module will perform in comparison to Manual and Easy Contoured Structure.
Alas, Fraccut has purported to offer equality to its block slices, but has done so falsely until now. The equality parameter, as I just discovered, is completely broken. No wonder I haven't heard any lovely arpeggiations from Fraccut. I set the equality to 100% and the slices are still rhythmically as normal as a tangent graph. Which isn't good.
A long night of bug-hunting awaits.
MGen is in great need of an algorithmic structure module with some degree of order. Fraccut has enjoyed such great success in the area of melody generation; I figure it can't hurt to try applying the fractal cutting engine to structure modules.
The good news is that it won't be hard to beat a manual structure. The ideas attached below seem pretty promising.
Work has begun on the Fraccut variation algorithms. The real question is how to control when the seed strings should be variated. Should a simple modification be made every measure? Should these modifications be saved so that all 2nd measures, for example, should be identical? What ensures that a modification will make musical?
It's difficult to answer these questions since the variation engine, unlike most implemented before, is decidedly nonlinear. Due to the nature of the pseudorandom generator, a tiny change in the seed string could completely alter the musical "idea." This being said, how does one ensure some kind of regularity in the musical ideas expressed by such a pseudorandom seed-string system?
All these questions must be tackled before Fraccut will come to completion.
Tonight's work, which consisted of implementing the Gaussian distributed random function for Fraccut, as well as implementing octave and interval settings in Fraccut, resulted in some fantastic compositions.
The new Gaussian random generator pulled everything together and really helped coherence. The octave settings differentiated the Fraccut parts and allowed three simultaneous Fraccut plugins to sound distinct and harmonious because of octave separation. Interval settings really fleshed out the sound; harmonies can now be heard quite clearly.
It was a great night for compositions. I'll post a sample or two from tonight's batch tomorrow. As usual, I am astounded with Fraccut's capabilities.