Thursday, January 16, 2014

Source Code for the First Piece I Ever Wrote in SuperCollider

This is presented more as an example of how not to write music in SuperCollider - it was within the first week or 2 of me trying things out.

The piece is a drone piece based on an instrument that plays a set of overtones of a base frequency, and slowly bends those frequencies by a microtonal increment over a period of several minutes - creating cascading overtones at higher frequencies as the sound waves cross in space and cancel each other out.
The piece starts with a base drone over 20hz and later fades in complementary drones at (20*21/16)hz and (20*4/3)hz - a septimal major third and perfect fourth.
The piece ends after 30 minutes - when the pitch bending of first drone cycle returns to a unison.
This pattern of slow pitch bending in sine clusters was something I experimented for several years. I still write a piece in this style every now and then for fun. I've learned a lot about sound design since then so it's always good to go back and apply those learnings. Orbital Slingshot - composed in late 2011 is the most recent piece I've released in this style.
Commentary follows the source code.

(

SynthDef("sine-phase-additive",  {
arg baseFreq = 32, baseFreqLFORate = 1/3600, baseFreqLFOMult = 0.01, baseFreqLFOPhase = 0 , baseFreqLFOAdd = 2, pan = 0, amp = 0.03, partials = #[1,2,4,8,16,32,3,6,9,12,18,24,25,27,36,40,48,54,56,60,64];

var base;

base = baseFreq * SinOsc.kr(baseFreqLFORate, baseFreqLFOPhase, baseFreqLFOMult, baseFreqLFOAdd);

Out.ar(0,(Mix.ar(Pan2.ar(FSinOsc.ar(base*partials,0,amp),pan))));
}).load(s);
)

s=Server.local;
s.boot;




s.sendMsg("/s_new", "sine-phase-additive", 1005);
s.sendMsg("/n_set", 1005, "baseFreq",20*(4/3));
s.sendMsg("/n_set", 1005, "pan", 0);
s.sendMsg("/n_set", 1005, "amp", 0.013);
s.sendMsg("/n_set", 1005, "baseFreqLFOPhase", 0);
s.sendMsg("/n_set", 1005, "baseFreqLFOMult", 0.0125);
s.sendMsg("/n_set", 1005, "baseFreqLFORate",1/300);
s.sendMsg("/n_set", 1005, "pan", 0.3);

s.sendMsg("/s_new", "sine-phase-additive", 1001);
s.sendMsg("/n_set", 1001, "baseFreq",20*(21/16));
s.sendMsg("/n_set", 1001, "pan", 0);
s.sendMsg("/n_set", 1001, "amp", 0.012);
s.sendMsg("/n_set", 1001, "baseFreqLFOPhase", pi);
s.sendMsg("/n_set", 1001, "baseFreqLFOMult", 0.0325);
s.sendMsg("/n_set", 1001, "baseFreqLFORate",1/120);
s.sendMsg("/n_set", 1001, "pan", -0.3);


(





s.sendMsg("/s_new", "sine-phase-additive", 1000);
s.sendMsg("/n_set", 1000, "baseFreq", 20);
s.sendMsg("/n_set", 1000, "pan", 0);
s.sendMsg("/n_set", 1000, "amp", 0.030);
s.sendMsg("/n_set", 1000, "baseFreqLFOPhase",0);
s.sendMsg("/n_set", 1000, "baseFreqLFOMult", 0.00325);
s.sendMsg("/n_set", 1000, "baseFreqLFORate",1/1200);
s.sendMsg("/n_set", 1000, "pan", 1.0);





//static drone
s.sendMsg("/s_new", "sine-phase-additive", 1003);
s.sendMsg("/n_set", 1003, "baseFreq", 20);
s.sendMsg("/n_set", 1003, "amp", 0.040);
s.sendMsg("/n_set", 1003, "baseFreqLFOMult", 0.0);
s.sendMsg("/n_set", 1003, "baseFreqLFOPhase",0);
s.sendMsg("/n_set", 1003, "pan", 0.0);


//base  hourly cycle drone
s.sendMsg("/s_new", "sine-phase-additive", 1002);
s.sendMsg("/n_set", 1002, "baseFreq", 20);
s.sendMsg("/n_set", 1002, "amp", 0.030);
s.sendMsg("/n_set", 1002, "baseFreqLFOMult", 0.00125);
s.sendMsg("/n_set", 1002, "baseFreqLFOPhase",0);
s.sendMsg("/n_set", 1002, "baseFreqLFORate", 1/1800);
s.sendMsg("/n_set", 1002, "pan", -1.0);





SystemClock.sched(480.0, {

s.sendMsg("/s_new", "sine-phase-additive", 1001);
s.sendMsg("/n_set", 1001, "baseFreq",20*(21/16));
s.sendMsg("/n_set", 1001, "pan", 0);
s.sendMsg("/n_set", 1001, "amp", 0.012);
s.sendMsg("/n_set", 1001, "baseFreqLFOPhase", pi);
s.sendMsg("/n_set", 1001, "baseFreqLFOMult", 0.0325);
s.sendMsg("/n_set", 1001, "baseFreqLFORate",1/120);
s.sendMsg("/n_set", 1001, "pan", -0.3);


 });

SystemClock.sched(1200.0, {

s.sendMsg("/s_new", "sine-phase-additive", 1005);

s.sendMsg("/n_set", 1005, "baseFreq",20*(4/3));
s.sendMsg("/n_set", 1005, "pan", 0);
s.sendMsg("/n_set", 1005, "amp", 0.013);
s.sendMsg("/n_set", 1005, "baseFreqLFOPhase", 0);
s.sendMsg("/n_set", 1005, "baseFreqLFOMult", 0.0125);
s.sendMsg("/n_set", 1005, "baseFreqLFORate",1/300);
s.sendMsg("/n_set", 1005, "pan", 0.3);



 });

SystemClock.sched(1800.0, {

s.sendMsg("/n_free",1000);
s.sendMsg("/n_free",1001);
s.sendMsg("/n_free",1002);
s.sendMsg("/n_free",1003);
s.sendMsg("/n_free",1005);
 }


)

At this point I wasn't using either the Synth or Routine abstractions. I was creating a synth and giving it attributes by sending osc messages directly to the server, and manually allocating a node ID for each synth. My timing routine was to create events on the system clock at the outset and then delay them before being played - so the command to end the piece (by freeing the synth nodes, not sending them any kind of envelope) after 1800 seconds is already set when the piece starts.
Among things I hadn't learned about synth design yet - envelopes, gates and amplitude balancing. Amplitude balancing with additive synthesis can be a little tricky. I'm starting with a base frequency (20hz in this case) and sending it an array of partials = #[1,2,4,8,16,32,3,6,9,12,18,24,25,27,36,40,48,54,56,60,64] ) which is all well and good (note that there are no multiples of 5 until you get into the highest octave). 2 things to note about amplitude for your partials - 1) sound waves at the same amplitude carry more energy at higher frequencies (more wavefronts are hitting your ears over the same span of time) so they sound louder. Also, when you're creating an array of integers, there will always be more integers in the higher range of the array. To use the standard harmonic series as an example - in the 1st octave, there are only overtones at 1 and 2 times the fundamental frequency. 3 octaves up you have 8 overtones at 8,9,10,11,12,13,14,15,16. The higher you go, the more tones are likely to fit into your tuning scheme, even if you eliminate overtones that have factors higher than some number. For this reason, you should compensate for your amplitude using something like amp = (1/(f**k)) where f is your frequencies and k is a constant - usually from 1 (pink noise) to 2 (brown noise).

Monday, January 6, 2014

Snowday

This was an album I originally wrote in January 2000. The first sketches came together during a day off work (from excessive snow, naturally). This was one of the first things that I wrote in Buzz that felt like I was getting a handle on something more than just beat-oriented stuff. The source materials include some samples I found on mp3.com and some drawings from early blogs that I ran thru Metasynth. All of that has been gone from the internet for almost a decade. Track 5 was improvised in one take and remains one of my favorite noise / drone pieces. The title of track 1 is the punchline to an inside joke I've forgotten. The piano sample is from the opening of the last movement of Beethoven's "Hammerklavier" sonata.

Thursday, December 19, 2013

Chicago Boss: an Erlang Web Framework

This looks really exciting. The goal of the project is to cut operations cost of web apps by 90% through better processor and memory utilization.

Monday, November 25, 2013

"Decoherence" Music Video


Decoherence from backtrace music on Vimeo.

I've started making some music videos to go with the tracks from Pythagorean Clouds and a few other pieces.  I got a new computer last week with a GPU card which, combined with the new OpenCL rendering in the new version of Mandelbulber (1.19) lets me render certain kinds of animations very quickly.

The animation in this video is a transformation of a Mandelbox, which took about half a day to render at 1280x720px.  The current OpenCL implementation only allows for a few basic fractal formulas to be rendered, and it's a little crashy on Windows. But it's super fast - cranking out almost 100 frames per minute sometimes, compared to maybe getting 1 frame per minute if I was lucky with my previous setup.  I can't do anything with volumetric shaders right now, but I'm kind of getting into this aesthetic.  Flat surfaces, "perfect" lighting with no depth of field.  (I feel like if there's too many shading effects, you fall into the uncanny valley of being super conscious that you're watching a computer-generated video, and not really being able to experience the visuals for what they are)  Because the algorithm gets glitchy when you zoom too close, I've been trying out different effects where the camera stays still and the fractal morphs around it. Overall though I like working within the constraints of a medium, especially when it's kind of minimal and lo-fi, so this works for me.

Tuesday, October 29, 2013

Circles and Euclidian Rhythms

Circles and Euclidean Rhythms: Off the Grid, a Few Music Makers That Go Round and Round

Imagine an alternate universe in which Raymond Scott’s circle machine – a great, mechanical disc capable of sequencing sounds – became the dominant paradigm. We might have circles everywhere, in place of left-to-right timelines now common in media software. Regardless, it’s very likely Scott’s invention inspired Bob Moog’s own modular sequencers; it was almost certainly the young Moog’s exposure to the inventions in Scott’s basement that prompted that inventor to go into the electronic music business, thus setting the course for music technology as we know it.
This blog entry includes some nice software examples.

Wednesday, October 23, 2013

"Horizontal Movements"


I composed these 2 pieces almost 2 years ago, but even though they are very autobiographical, I never really talked about the inspiration for them. So I've added a description on SoundCloud.
Like a lot of my music, these 2 pieces are autobiographical, at least in the sense that they were composed during and immediately in response to some significant events in my life - in this case my involvement in the Occupy Wall Street protests. They were composed in late December 2011 through early January 2012, while I was taking some time off from activism to recuperate after police chaos and setbacks of late November and December. The "Frozen Zone" of the titles refers to both the blockade that the NYPD set up in the Financial District in the middle of the night as they evicted protesters from Liberty Square, and more metaphorically to all systemic injustice.

Although the music doesn't convey any overt political messages, the act of writing it was kind of a meditation on the idea of leaderless organizing (the anarchist political philosophy of "Horizontalidad / Horizontalism"). I think of the sounds as being "horizontal" in the sense that there's no hierarchy working to organize them. The musical parts aren't divided into "instruments or "voices" - there's just a single algorithm generating clusters of sine waves. Those individual sine waves, which only differ in pitch and amplitude, converge temporarily to create harmonies, and then dissipate.

Sunday, October 13, 2013

MIDI in the web browser, 2013 style

My first homepage (on AOL) included a lengthly MIDI composition that auto-played upon loading the page.  Browsers don't support MIDI natively anymore but there are JS libraries that will load sound fonts and let you create midi compositions in JS.

midi.js is a good starting point.
Jasmid for reading MIDI files with JS.