Dimensions and Crossroads

Tonight’s goal was to get the base model to stumble towards simple rhythm generation. The problem with that is that it’s the slow, agonizing, evolution towards the end model, and this is all about inspired, and possibly intelligent, design.

There’s just no clear evolutionary path from simple tones to the full model without at least filling in the stump classes of the relevant pieces before hand. So tonight was a sort of rehash of the model of music:

Picture a cube, or better yet a room. Make it the one you’re in.

Look at the corner of the ceiling ahead of you, to the left. That’s the nexus. That’s point (0, 0, 0, 0, 0, … 0). You won’t ever hear anything there, but it is the singularity of the sound space.

Spanning the ceiling from the nexus towards the back wall, passing to your left, is T. T is intersect time. It’s the dimension where music and consciousness coexist, and it is the axis along which we’re allowed to perceive music. At the nexus, is T(0), the start, and at the back wall is T(n), some arbitrary length of the sound space. If you move back and forth along this line, you are scrubbing forwards and back along the time of the song.

From the nexus, along the ceiling, to the right wall, is t0, the timbral axis. This corresponds to the natural, expressive duration of a sound. Snappy sounds to spacious sounds; left to right. Frequency plays in waves from this axis, but by and large it is noise selection. A violin and cello will find themselves ordered from left to right along this axis, with some overlay–not that you should imagine that instruments determine anything just yet… that comes later.

From the nexus to the floor is t1, the pulse axis. It is tightly correlated to t0, in that a steady belting of tones matching their timbral length would occur at t1(1). That is to say that is a piano note at middle C has a timbral value of ~500ms, a pulse length at t1(1) would also equal ~500ms. A stead pounding of quarter notes, if you will. t1 is a multiplicative axis, and it is tightly linked to t0. If t1 were mapped out in absolute, rather than multiplicative terms, is would form a natural trending diagonal from the nexus to the bottom right, and then projected, or extruded, forward.

Standing facing the wall, with the nexus in your upper left hand corner, and rotating your head will give you a sense of spin: these are folded dimensions, and there are, at this point, two to consider. The first is t2, velocity. These are the dynamic values of song you might otherwise understand as expressiveness or emotion. The second, related term, is t3, silence: Arrangement owes much of it’s power to this dimension. With it, entire strands can be silenced or brought into sharp focus.

And what moves through these spaces? You may have already guessed, but it is the sound filament, which exists within a timbral range (this will be important for the orchestral loops later), and contains functions which express themselves along each of tn axes expressed as a function of T: as such, any note value can be determined through the function tn(T).

It will of course, be a mater of implementation to determine how these all get implemented, but with the model down, we can at least begin to make an effort.

The plan from here will be to create empty shells to correspond to each of these components, and then to let the program slowly work up to full functionality, starting with droning tones and moving up to music.

[music: Amon Tobin]

Ah! The updates…

Alright… long time, no post… My bad…

To be fair, I’m not in love with the blog format of the site, but frankly, I’m not going to make anything impressive until the software is up and running… which on one hand means that I can focus on the code itself, and on the other that I have more time to finish the graphical styling for what will be the new site.

I like what I’m planning; I hope you will too.

Anyway, the music.

Well, it occurred to me that no one was going to get to hear anything if I kept coding the way I was: all the math sounded beautiful, in my head, but not a note was played.

So the development model is being shifted towards an agile framework, what this means for now is that there will be a nice and simple progression of sound files being posted, which will slowly be tethered back to the existing code base. Initially, these are going to sound absurd, but slowly you’ll start to hear where this is all heading.

As always, stand by.

[music: Noise]

Threading the needle

The posts have been slow of late for a couple of reasons; December was a slow month for development, and I don’t always feel like writing as I do something, or after it.

Really, the point of this site is to act as a sort of development journal, so I am trying to make an effort writing down exactly what I’m trying to do before I go ahead and code–somehow I suspect this discipline will let the code come out cleaner, sort of like the Teddy-Bear principle.

Tonight, I have to code in the stump code for all of the sound forces’ interfaces so that the section and sound space can properly react with the model.

One thing I constantly struggle with when making these sorts of interfaces is in deciding when a given data structure merits it’s own object class. Most of this project is in python, and it’s not exactly difficult to code up new classes as needed, but at the same time, at well thought out series of dictionaries and tuples seem to be able to encode most things. At this point, I’m just trying to keep everything testable, which seems to weigh more on the dict/tup half of the decision.

Hopefully I’ll begin posting pictures of the diagrams soon so that there will be some sense of the hierarchy of classes and responsibilities here.

For now, lets just see if I can successfully complete what should be a trivial exercise in following the plan.

[music: Max Richter, Infra]

Song done… Section going

The genetic algorithm fueling the song seems to be working at 99%; all of the environmental parameters were tweaked well enough to allow for maximum diversity and still maximize the value of the entity.

We’re onto the third level down the rabbit hole then; the Section level. This is the subdivision of a song, like a chorus, refrain, or however you want to think about it. It’s substantiated with a Force Complex (more on that later) and in turn creates a Sound Space object. Largely, it’s primary facing function is to compile down when given an intensity index, and to create note objects to be translated into MIDI commands in the future.

The complexity of this function is largely due to it’s task of interfacing components of the Force Complex, and mediating with the Sound Space, treating it like a canvas to draw the forces on.

As I said, this is level 3. All the maps and schema up until now point to what should only be a 7 level project–on the model side. So hopefully this will be the 50% point for phase I. Phase II involves the mapping of the songs and notes to instruments, so that the Sound page will have something to play. Phase III is the creation of a stage show, so that everyone can see it in person when it’s done.

Let us hope.

GATC

The genetic algorithm for song structure is complete (-ish). Currently it passes through 1,000 generations, with a population size of 1,000, in approximately 18 seconds, which is far too long. Tweaking the population size down to 100 only yields the expected linear improvement (~1.8 seconds) and the results seem to be normalized by then.

At this point, the fitness function is only really selecting on two criteria, but hopefully it will be running on a third shortly, which should give us a better indication of what the parameters ought to be.

As soon as the GA is all wrapped, we move onto the next level of the program, and descend into Section creation, which will be much more interesting, I’m sure.

Mercurial, Unit Tests and Genetic Algorithms

Progress has been very slow lately, owing to other more important things taking up my time. This sort of fragmented and punctuated development cycle has been increasingly the norm lately, so we’ve been under pains to adopt more “real world” practices for dealing with them; namely the sorts of practices that let you keep as little information juggled in your head as possible.

TDD and micro-functions are definitely part of it; it’s almost impossible to have enough uninterrupted time to actually complete a single function lately, so we’ve taken to a very flexible routine of authorship: in the parent function or method, an inline comment denotes where the intentions is, this is the seed. Then, a stump function gets written with anticipated variables, and a doc string is typed in to remind me of what it’s supposed to do. Next, a unit test gets written; if I’m interrupted during the unit test writing, that’s fine, because the doc string should tell me what I’m supposed to be testing for. Finally, with the unit test complete, and failing, I can begin coding. This way, no matter how many times I get interrupted, I can always just execute the code in the test window and it will show me which test line is failing, and I can just work off of that.

I have to admit, TDD seemed like a whole lot of flashy bureaucracy before this weekend, but there have been two advantages to including it that I’ve seen which have paid off; first is the aforementioned To-Do list use outlined above, and second is that I’m forced to write much better functions and methods if they’re going to be tested. A win all around. I was worried that they would add too much time to my overhead, but to be fair, it’s time I generally spend idling as I think anyway, so the added exercise of reviewing intention and keeping the fingers moving is a bonus.

Anyway, it turns out the backpacking solution is too naive for this problem; there isn’t a recursively called packing function to optimize. Part of me was happy to discover this, because Plan C was to use a genetic algorithms. Usually it’s best to avoid coding your own library when doing these sorts of things, but frankly, I’ve always wanted to implement my own GE, so there will be notes as to the structure and implementation forthcoming. Soon, hopefully.

PS The Mercurial component of the story is that owing to my confusing with the state of my VC system, I managed to somehow lose the changes to the Song and testSong files, though thankfully the Emacs buffer saved my Song file. Sadly, version control has cost me my Song test file. I’m sure the enthusiasts will tell what I did wrong and how I could have salvaged the situation, but frankly, by the time I’m committing, I’m exhausted, probably over the Balmer curve, and in no condition to learn new and splendid command line arguments. Thankfully, I can reverse engineer my unit tests tomorrow as an exercise.

Backpacks

A while ago, MIT was kind enough to release the video lectures from some select undergrad courses, for free. I downloaded all I could, if only because it’s such a wonderful resource to have, and it’s finally come in handy.

There’s a slight problem with the music program trying to efficiently place the correct number of song sections into a song’s pattern, and it matches up with something known in computer science as a backpack problem. Well, it doesn’t quite match up, but it gets pretty close.

Hopefully in the next couple of days I’ll have posted some sample code and an explanation of the problem. Stay tunned.

Tonight’s hacks…

Tonight’s goal is to complete a full refactoring of the model, breaking out the components to facilitate unit testing. We’ll be breaking apart everything possible in the hopes of making our test worth something.

11:00 Dummy Objects…
We want to start by making sure the entire chain can call down and up, with empty objects at every level. Where there’s existing code, we’ll be inserting early returns with “stump code” objects of the correct type, but otherwise meaningless.
Every one of these stumps will be labeled with a “# STUMP” to ensure a text search can find them for future coding…
Music: Dr. Steel

12:00 Chasing Threads…
So just picking up dummy objects left right and center is a bit more ambitious that originally expected. With so much functionality already caked in, the refactoring got an early stall at the level of the Song object, (that’s about at level A4 in the original model, but is being raised to a second class object, A2, in this refactoring).
Clearing out the Song function by function is proving to be interesting, as it’s first act is to do some heavy mutation on a rather critical B object, the ForceComplex.
Music: Amon Tobin

12:45 Emacs and me…
After fighting with Emacs .el files for a bit, I managed to recover my preferred window arrangement for the Test>Fail>Code>Test>Pass cycle… unfortunately it cost me time. The edge gets lost quickly when I’m tired. Sleep is needed.
I’ll pick up on the completion of the Song refactoring next.

Stay tunned.

Economies of Time

Why a WordPress site? It saves me all the time of half-executing a decent real design. So I can code. Which is the point of all of this. Enjoy.

Return top

Tristea

n. [L] sorrows, sad song, lament.