September 14, 2004

Music Hacking - Observations

Recently, I got the environment working here on vader, first using just the beep program, and later with OSC messages to SuperCollider. I'm hearing a lot of static, though, which makes me think that kernel latency issues might be cropping up.


Getting the thing working with beep was easy (although Beep::Linux, like most other non-core modules, needed to be compiled from CPAN -- the OSC modules even needed a separate patch). Installing SuperCollider was likewise a snap, from Debian packages.

Trouble ensued. The biggest source of difficulty arose from my failing to understand that the sclang client is also an OSC server in it's own right, and that the messages from are actually intended for the language engine, to trigger routines that, in turn, tell SC to do stuff. So I wrote a launch script for SC so I could be sure of where it was, and a conf file for sclang for the same reason (and while I was at it, made sure everyone was automatically talking to Jack correctly, so I could stop constantly relaunching it and redefining the connections), and lo, the messages flowed, and beats resulted.

My suspicion is that if I can get Jack running at appropriate priority, the sound quality will be better. However, it may be the case that SC also needs priority.

Code ~= Tunes

Obviously, considerable experimentation will be needed to get anything pretty out, although I've already noodled around a bit with modular arithmatic as applied to both polyrhythms and manipulations of tone sequences, with not wholly unpleasant results.

The first works something like this:

{ ...
$s->play($note1) if ($beat % 4 == 0);
$s->play($note2) if ($beat % 7 == 2);
... }

Obviously, this will give you a recurring pattern with a period of 28 beats; throw in more moduli to ramp up the LCM and eventually you could wind up with a pattern of substantial length. This will not give you much in the way of tonal structure, though, which suggests the second approach:

{ ...
    @notes = qw( A B C D E F G );
    %m = ( C => 60, ... );
    $s->play( $m{ $notes[ $beat % 7 ] } );
... }

This will produce a really boring (and without some division, quite up-tempo) do-re-mi sequence. But throwing in some additional arithmatic:

@notes = qw( 60 61 62 ... );
{ ...
    $notes[ $beat % $#notes ] -= 3 if ( $beat % ($#notes - 2) == 3 );
... }

The result is that the (now once-initialized, rather than being continually reset) note list gets morphed over time, as individual elements are transposed. Since the morph period doesn't match the list length, the transposition will march through the list in LCM[ $#notes, $#notes - 2 ] time. There should be compensating up-transposing members in there as well, to make sure the notes don't run off the bottom of the scale -- but exactly when this happens depends on the relative modulii.

More experiments will follow. But for the sake of my ears, only after I have the sound quality issues worked out.

Posted by mill1974 at September 14, 2004 2:37 PM