Sounds of the Subconscious Seas
A Soundscape for the "Seas of the Subconscious" experience that took place in the basement of the San Francisco Mint building for the 2013 "All Worlds Fair".
The soundscape is generative, so it can be infinitely long. Here is a sample:
Sounds of the subconscious seas.
It is written in SuperCollider, start of my framework for developing soundscapes:
github.com/colinsullivan/seas-of-subconscious
SuperCollider
Checkout this play method of my SoundscapeElement class. This class is a parent class of all elements in the soundscape that are triggered at a particular rate
/**
* @file SoundscapeElement.sc
*
* @author Colin Sullivan <colin [at] colin-sullivan.net>
*
* Copyright (c) 2013 Colin Sullivan
* Licensed under the MIT license.
**/
/**
* @class Base class for all soundscape elements that are triggered with
* a particular frequency.
**/
SoundscapeElement : Object {
var <>outChannel,
/**
* A unique symbol to use for this element. Override in child
* classes.
**/
<>key,
// reference to Soundscape instance
<>soundscape,
// instrument we are triggering
<>instr,
// transition on and off envelope duration
<>transitionTime,
// maximum time this sound will be played for
<>onTimeMax,
// minimum time this sound will be played for
<>onTimeMin,
// minimum duration between previous off and next on
<>offTimeMin,
// maximum duration between previous off and next on
<>offTimeMax,
// amount of reverb :)
<>reverbLevel;
...
/**
* Called from soundscape when it starts up.
**/
play {
var onTime,
offTime;
/**
* Main run loop.
**/
{
while({ true }, {
// prepare instrument
this.instr = this.create_next_patch();
this.outChannel.play(this.instr);
// wait for the desired off time
offTime = rrand(this.offTimeMin, this.offTimeMax);
offTime.wait();
// turn sound on
this.instr.set(\gate, 1);
// wait for transition time
this.transitionTime.wait();
// wait for on time
onTime = rrand(this.onTimeMin, this.onTimeMax) - (2.0 * this.transitionTime);
onTime.wait();
// turn sound off
this.instr.set(\gate, 0);
// off envelope time is same as on time
this.transitionTime.wait();
// stop patch (just for safety)
this.instr.stop();
});
}.fork();
}
}
Then to use this superclass, I only have to define a few member variables and write the method that creates the patch. There are a few other things that I didn't have time to move to the superclass as well, like creating the mixer channel for the reverb.
/**
* @file FogHornElement.sc
*
* @author Colin Sullivan <colin [at] colin-sullivan.net>
*
* Copyright (c) 2013 Colin Sullivan
* Licensed under the MIT license.
**/
/**
* @class Foghorn action.
**/
FogHornElement : SoundscapeElement {
var <>outLevelMin,
<>outLevelMax,
<>bufKeys;
init {
arg args;
super.init(args);
this.outChannel.newPreSend(
this.soundscape.reverbReturn,
-10.0.dbamp()
);
this.bufKeys = [\fogHornBuf, \fogHorn02Buf];
this.outLevelMin = -18.0.dbamp();
this.outLevelMax = -20.0.dbamp();
this.offTimeMin = 30.0;
this.offTimeMax = 80.0;
/*this.offTimeMin = 5.0;*/
/*this.offTimeMax = 5.0;*/
this.transitionTime = 0.1;
}
create_next_patch {
var bufKey,
bufSection,
buf;
super.create_next_patch();
bufKey = this.bufKeys.choose();
buf = this.soundscape.bufs[bufKey];
("preparing fog horn" ++ bufKey).postln();
this.onTimeMin = buf.duration;
this.onTimeMax = buf.duration;
this.outChannel.level = rrand(this.outLevelMin, this.outLevelMax);
^Patch("cs.sfx.PlayBuf", (
buf: buf,
attackTime: this.transitionTime,
releaseTime: this.transitionTime,
gate: KrNumberEditor.new(0, \gate.asSpec())
));
}
}


