I had the opportunity to interview with the podcast and radio show To the Best of Our Knowledge on Wisconsin Public Radio for their episode on "The Quantified Self." Other interviewees for the episode included Nicholas Felton, Stephen Wolfram, Natasha Dow Schüll, and Sarah Manguso.
In addition to the interview, I composed a data sonification for the podcast featuring 100 days of the host's online activity across several categories of websites.
Approach
The sonification maps five categories of web activity — communication, entertainment, news, reference, and software development — to five distinct SuperCollider instruments. Each instrument's timbre, pitch, rhythm, and spatial position shift in response to the volume of activity in its category on a given day.
Communication is represented by resonant metallic tones triggered by impulse generators, with the frequency and density of strikes reflecting the amount of email and messaging activity. Entertainment uses a percussive brush-and-hat texture that ebbs and flows with streaming and media consumption. News employs phase modulation synthesis, producing warm, organ-like tones whose depth of modulation corresponds to how much time was spent reading news. Reference generates crystalline, bell-like timbres from resonant filter banks, reflecting research and reference browsing. Software development drives a stepped oscillator pattern whose speed and amplitude track coding activity.
As the sonification plays through each of the 100 days, the listener hears the daily rhythms and weekly cycles of a person's digital life rendered as an evolving, five-voice composition. Periods of intense work produce dense, layered textures; quieter days thin out into sparse, ambient passages.
SuperCollider Code
s.boot;
(
~csv=CSVFileReader.readInterpret("/Users/mbk5020/Desktop/trial.csv").post;
~data=~csv.flop;
)
///////////////////////////////////////////////////////////////////////Communication
(
~masteramp=0.2;
~timedelta=1;
~communication=~data.at(1).normalize(200, 800);
~communicationimp=~data.at(1).normalize(0, 8);
~communicationamp=~data.at(1).normalize(0, 0.08);
~entertainment=~data.at(3).normalize(1, 8);
~entertainmentamp=~data.at(3).normalize(0, 0.2);
~news=~data.at(4).normalize(100, 200);
~newsmul=~data.at(4).normalize(0.1, 6);
~newsamp=~data.at(4).normalize(0, 1.8);
~reference=~data.at(5).normalize(200, 1200);
~referenceamp=~data.at(5).normalize(0, 2.2);
~software=~data.at(8).normalize(10, 100);
~softwarespeed=~data.at(8).normalize(0.001, 1);
~softwareamp=~data.at(8).normalize(0, 0.2);
)
(
SynthDef(\communication, {|freq=900, imp=4, mul=0.4, add=0, amp=0.2, out=0, pan=0, rate=3, dur=0.1, gate=1|
var env, env2, src;
env = EnvGen.kr(Env.asr(0.1, 1, 1), gate);
src=DynKlank.ar(`[[freq!4], [0.1, 0.4]], Impulse.ar(imp), decayscale:0.5);
src=GrainIn.ar(1, Impulse.ar(freq), dur, src, pan);
src=LPF.ar(src, 200);
src=Pan2.ar(src*env, pan);
Out.ar(0, src*env*amp);
}).add;
SynthDef(\entertainment, {
|
freq=8, out=0, arousal=100, arousalvol=0.2, buf =2, amp=0.3, pan=0, rate=0.1 t_trig =1
|
var src, brush, hat, thud, env, tempo, value;
tempo = Impulse.ar(freq);
env=EnvGen.ar(Env([1, 1], [2, 2]));
brush = BrownNoise.ar(Decay2.ar(PulseDivider.ar(tempo, 8, 1), 0.005, 0.5));
hat= Mix.ar([WhiteNoise.ar(Decay2.ar(PulseDivider.ar(tempo, 4, 2), 0.005, 0.5))*SinOsc.ar(400)]);
src=Pan2.ar((brush + hat)*amp*env, pan);
Out.ar(out, src);
}).add;
SynthDef(\news, {|freq=400, car=400, amp=30, pan=0, out=0, mul=1, mod=3, rcalmul=0.2, rcalroom=0.8, gate=1|
var src, env;
env = EnvGen.kr(Env.asr(0.1, 1, 1), gate);
src=PMOsc.ar(freq, car, SinOsc.kr(0.01).range(0.1, 30))*SinOsc.kr(mul);
src=BPF.ar(src, freq, rcalmul);
src=FreeVerb.ar(src, 0.3, rcalroom);
src=Pan2.ar(src, pan);
Out.ar(out, src*env*amp*~masteramp);
}).add;
SynthDef(\reference, {
|
freq=900, mul=0.4, add=0, amp=20, out=0, pan=0, rate=3, dur=0.1, gate=1
|
var env, env2, src;
env=EnvGen.kr(Env.asr(0.01, 1), gate, doneAction:2);
src=DynKlank.ar(`[[freq!4], [1, 0.4]], Impulse.ar(4), decayscale:0.5);
src=GrainIn.ar(1, Impulse.ar(6), dur, src, pan);
src=LPF.ar(src, 100);
src=Pan2.ar(src*env, pan);
Out.ar(0, src*env*amp);
}).add;
SynthDef(\software, {
|
freq=100, trig=10, pan=0, out=0, amp=0.8, decay=7, t_gate=1, gate=1, speed=0.1
|
var src, env;
env=EnvGen.kr(Env.asr(0.01, 1), gate, doneAction:2);
src=SinOsc.ar(Stepper.ar(Impulse.ar(freq), 1, 4, 10, 4)*SinOsc.kr(0.1, 0, 50, 100))*LFTri.ar(2);
src=Decay2.ar(src, 0.03, decay);
src=Pan2.ar(src, pan);
Out.ar(out, src*env*amp)
}).add;
)