The B Loop @ Stark

The B-Loop @ Stark is the first of (hopefully) several posts that detail the transformation of common, everyday audio recordings into musical expressions. The original 55-second .wav file was captured with a mobile phone across the street from Stop 13597 of the Portland Streetcar.

The B-Loop @ Stark:

 
The recording was processed in SuperCollider; the code is detailed below. A Pbindef player plays 8-second, overlapping windows as the excitation source for parallel CombN and Ringz filters. The overlap provides some nice repetition of audio features during the playback, which is sequential in the example but could easily take another form (random, random walk, sequenced, etc). The most notable audio features are the whooshing of cars and the whine of the motors as the streetcar departs the station. Other features include conversations from people across the street and general urban background sounds.

A mobile device is fantastic for capturing audio features of everyday life in an non-intrusive, impulsive way. I’m a huge fan of the AudioShare app by Kymatica¬†for this purpose. In particular, it has a wonderful WiFi Drive feature to transfer recordings via a local network. I’ve used the built-in microphone, which seems fine considering the level of post-processing, but I do plan to experiment with other hardware in the near future. But without a doubt, the built-in microphone is easy and non-intrusive.

In the course of this project, I’ve also become a huge fan of using Pbindef constructions in SuperCollider. They’re really convenient for quickly prototyping Patterns for various arguments, and are uniquely suited for live coding. They may also be incorporated in Tdef or other Routine/Task functions, and their Patterns or values can be modified as long as the related Pbindef expressions are re-evaluated. I’ve also used Pdef/Pbind/Pdefn combinations for this purpose, which work great too.

source recording:

 
// use a 1-channel audio file
~path01 = PathName("add your own path to an audio file here");
~aBuf01 = Buffer.read(s, ~path01.fullPath);

// a function to generate a chord for \midinote
// args: num, [baseNote], [scale]
(
~fnChord01 = {
arg num = 2, baseNote = [36, 48, 60], scale = [0, 2, 3, 5, 7, 10];
var chord;
chord = Array.fill(num, {baseNote.choose + scale.choose});
};
)

(
SynthDef.new(\grainbuf05b, {
arg out = 0, ampMin = 0.05, ampMax = 0.2, aBuf, freq = 220, detuneFreq = 0.2, rate = 0.5, envBuf = -1, aBufRate = 1.0, trigger = 1, pos = 0, loop = 1, dtRingz = 1.0, dtCombN = 1.0, ampCombN = 0.5, ampRingz = 0.1, xfade = 0.0, balance = 0.8, numDA = 2, atk = 4.0, sus = 4.0, rel = 4.0, c1 = 1, c2 = 0, c3 = -2;
var sig, sig1, sig2, env, amp;

env = EnvGen.ar(Env.new([0, 1, 1, 0], [atk, sus, rel], [c1, c2, c3]), doneAction:numDA);

freq = {freq * LFNoise1.kr(rate, detuneFreq).midiratio}!2;
balance = LFNoise1.kr(rate/Rand(1.0, 3.0)).range(-1 * balance, balance);
amp = LFNoise1.kr(rate/Rand(1.0, 3.0)).range(ampMin, ampMax);

sig = PlayBuf.ar(1, aBuf, aBufRate * BufRateScale.kr(aBuf), trigger, pos, loop, doneAction:numDA);

sig1 = CombN.ar(sig, 1.0, 1/freq, dtCombN) * ampCombN;
sig2 = Ringz.ar(sig, freq, dtRingz) * ampRingz / dtRingz;

sig = XFade2.ar(sig1, sig2, xfade);
sig = Balance2.ar(sig[0], sig[1], balance);
sig = sig * env * amp;
sig = Compander.ar(sig, sig, 0.5, 1.0, 0.3, 0.005, 0.1);

Out.ar(out, sig);

}).add;
)

(
Pbindef(\bufPlayer05,
\instrument, \grainbuf05b,
\aBuf, ~aBuf01,
\dur, 8.0,
\pos, s.sampleRate * Pseries(0.0, Pkey(\dur)/3, ~aBuf01.duration),
\midinote, Pfuncn({~fnChord01.value(rrand(1, 3))}, inf),
\detuneFreq, 0.2,
\rate, Pwhite(0.25, 1.0, inf),
\dtCombN, Pwhite(1.0, 5.0, inf),
\ampCombN, 0.5,
\dtRingz, Pwhite(1.0, 2.0, inf),
\ampRingz, 0.1,
\atk, Pkey(\dur),
\sus, Pkey(\dur),
\rel, Pkey(\dur),
\xfade, Pwhite(-0.4, 0.4, inf),
\balance, 0.8,
\ampMin, 0.05,
\ampMax, 0.2,
);
)

Pbindef(\bufPlayer05).play;

 

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Leave a Reply

Your email address will not be published. Required fields are marked *