It's been a while since I last posted. I learned a new programming language (Haskell). Today I completed my first Haskell project, an arpeggiator for Csound score files. It does more than just arpeggios -- it calculates any number of arbitrary parameters and outputs them to the score.
SCO vs. ORC
When I was first learning Csound, I focused on orchestra files. Now, I've come to see there is a lot of potential for controlling instruments -- and composing -- using scorefiles.
The problem was writing the darn things. For a while, I used a spreadsheet. Then I realized there were a number of routine tasks I found myself doing over and over again -- generating repeating patterns, applying mathematical functions. Yes, it can all be done in a spreadsheet, but it's annoying.
The logical thing, here, is to make the computer do all the work. I know a number of computer programming languages ... starting with TRS-80 basic and going up to modern tools such as Python.
Because of a related mathematical project I'm working on, I started learning Haskell.
Before anyone starts Chapter MCMLXVII of The Great Which Programming Language Is Best flamewars, let me just say, none of them are the best. Actually, the best would be like on Star Trek. ("Computer . . . design an arpeggiator which allows me to enter pitch class sets and vary the sound of the notes using mathematical parameters.") But that's not here yet, and probably not here ever, at least not until the day the Terminators or Cylons or whatever come to get us all.
Anyway, Haskell has one excellent feature -- it's strongly typed. Meaning, most of the code I wrote I was able to get going in skeleton form, with only the vaguest definitions of the data and functions -- the compiler checks for errors. Once I had the framework written, I filled in the details.
When it compiled ... it worked as expected.
Those of you who do programming know that's pretty unusual. See, the trick is, I offloaded a lot of my debugging duties to the compiler. Through careful design of the data framework, I was able to get GHC working on my side.
Details to follow
*Edit* I just posted it -- Scorange (Wordpress).
Here's a vague overview of the code: it takes a rhythm and generates a timeline, a series of events. These event are readable in three different ways -- in realtime (seconds), in "barline time" (one bar = 1.0, two bars = 2.0), and in "counter" time (what Lawrence Welk would recognize as "Ah wun, ah two"). Any of the parameter fields past p5 can be filled with arbitrary functions based on the timeline. Or not -- constants are ok, as well as repeating lists.
I have a new convention for scorefiles -- p2 is always going to be note 'on' time. However, I now view p3 as the note's "width." That is, most instruments don't actually stop sounding the moment a new note is played. The "width" of the note is how much it overlaps into the next note (how far its decay period sustains). I now use p4 for the 'off' time.
BTW, the file is called 'Scorpio' ... the name of my Haskell project was 'Scorange', for two reasons.
- It's a combination of 'score' and 'range'.
- It finally gives us a word that rhymes with orange.