diff --git a/synthesis/index.html b/synthesis/index.html
new file mode 100644
index 0000000..99d7c0c
--- /dev/null
+++ b/synthesis/index.html
@@ -0,0 +1,17 @@
+
+
+
+ http micro tempo
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/synthesis/lib/hhhh.js b/synthesis/lib/hhhh.js
new file mode 100644
index 0000000..d482065
--- /dev/null
+++ b/synthesis/lib/hhhh.js
@@ -0,0 +1,55 @@
+
+var modfactor = 750.0;
+var modfactor_gain = 10750.0;
+
+function create_none_synth() {
+ var s = new FMSynth('triangle', 100, 'saw', 2, 300);
+ s.add_filter(new LowPassFilter());
+ s.update = function(val) {
+ this.modulator_freq(val / modfactor);
+ };
+ return s;
+}
+
+function create_ad_synth() {
+ var s = new SimpleOscillator('square', 100);
+ s.add_filter(new NoiseConvolver());
+ s.update = function(val) {
+ this.modulator_freq(val / 25);
+ };
+ return s;
+}
+
+function create_tracker_synth() {
+ var s = new PinkNoiseGenerator();
+ //s.add_filter(new NoiseConvolver());
+ s.update = function(val) {
+ this.modulator_gain(val / modfactor_gain);
+ };
+ return s;
+}
+
+function create_analytics_synth() {
+ var s = new WhiteNoiseGenerator();
+ //s.add_filter(new DistortionShaper(55));
+ s.update = function(val) {
+ this.modulator_gain(val / modfactor_gain);
+ };
+ return s;
+}
+
+function create_widget_synth() {
+ var s = new PinkNoiseGenerator();
+ s.update = function(val) {
+ this.modulator_gain(val / modfactor_gain);
+ };
+ return s;
+}
+
+function create_privacy_synth() {
+ var s = new WhiteNoiseGenerator();
+ s.update = function(val) {
+ this.modulator_gain(val / modfactor_gain);
+ };
+ return s;
+}
diff --git a/synthesis/lib/nnnn.js b/synthesis/lib/nnnn.js
new file mode 100644
index 0000000..b058204
--- /dev/null
+++ b/synthesis/lib/nnnn.js
@@ -0,0 +1,60 @@
+var refresh_rate_ms = 4;
+var bb;
+
+function draw(url) {
+
+ if(/csv$/.test(url)) {
+ url = url + '.svg';
+ } else {
+ return;
+ }
+
+ d3.xml(url, function(xml) {
+ svg_node = document.importNode(xml.documentElement, true);
+ svg = d3.select('#track');
+ svg.style('width', svg_node.width.baseVal.value);
+ svg.style('height', svg_node.height.baseVal.value);
+ svg.node().appendChild(svg_node);
+
+ d3.select(svg_node)
+ .attr('id', 'svg_track');
+
+ //
+ var g = d3.select(svg_node).append('g');
+ var b = g.append('foreignObject')
+ .attr('x', '85')
+ .attr('y', '350')
+ .attr('width', '100')
+ .attr('height', '100')
+ .append('xhtml:body');
+ bb = b.append('input')
+ .attr('type', 'button')
+ .attr('value', 'synthesise')
+ .attr('onclick', 'go()');
+
+ var line = svg.append('svg:line')
+ .attr('x1', 0)
+ .attr('y1', 0)
+ .attr('x2', 0)
+ .attr('y1', svg_node.height.baseVal.value)
+ .style('stroke', 'rgb(255,0,0)')
+ .style('stroke-width', 1);
+
+ window.setInterval( function() {
+ line.attr('x1', tick_cnt); //var tick_cnt = 0; // from ssss.js
+ line.attr('x2', tick_cnt);
+ }, refresh_rate_ms);
+
+ });
+}
+
+function go() {
+ if(bb.attr('value') == 'pause') {
+ bb.attr('value', 'synthesise');
+ stop_all_synths();
+ } else {
+ bb.attr('value', 'pause');
+ start_all_synths();
+ }
+}
+
diff --git a/synthesis/lib/ssss.js b/synthesis/lib/ssss.js
new file mode 100644
index 0000000..71c5f48
--- /dev/null
+++ b/synthesis/lib/ssss.js
@@ -0,0 +1,193 @@
+var data = [];
+var start_times_dict = {};
+var end_times_dict = {};
+var start_times = [];
+var end_times = [];
+
+var next_start = 0;
+var next_end = 0;
+
+var processing_data = [];
+
+// timer parameters
+var tick_cnt = 0; /// this is passed to the drawing
+var time_incr_ms = 2;
+var time_end = 0;
+var interval_id = 0;
+
+var p = true;
+
+var params = {
+ "-" : {'bytes': 0, 'synth': null, 'active': 0},
+ "ad" : {'bytes': 0, 'synth': null, 'active': 0},
+ "tracker" : {'bytes': 0, 'synth': null, 'active': 0},
+ "analytics" : {'bytes': 0, 'synth': null, 'active': 0},
+ "widget" : {'bytes': 0, 'synth': null, 'active': 0},
+ "privacy" : {'bytes': 0, 'synth': null, 'active': 0}
+};
+
+function synthesise(csv_input_file_url) {
+
+ $.ajax({
+ type: 'GET',
+ url: csv_input_file_url,
+ dataType: 'text',
+ success: function(resp) {
+ data = $.csv.toObjects(resp);
+ start_times = {};
+ end_times = {};
+
+ for(var i = 0; i < data.length; i++) {
+
+ var start = +data[i]['Start Time (ms)'];
+ var end = +data[i]['End Time (ms)'];
+ var size = +data[i]['Object Size'];
+
+ if(!(start in start_times_dict)) {
+ start_times_dict[start] = [];
+ }
+ start_times_dict[start].push(i);
+
+ if(!(end in end_times_dict)) {
+ end_times_dict[end] = [];
+ }
+ end_times_dict[end].push(i);
+
+ data[i].incr = linear_increment(start, end, size);
+ data[i].incr_tick = 0;
+
+ if(end > time_end) time_end = end;
+ }
+
+ $('#end').html(time_end);
+
+ start_times = Object.keys(start_times_dict);
+ end_times = Object.keys(end_times_dict);
+
+ start_times.sort(function(a, b){
+ return a - b;
+ });
+ end_times.sort(function(a, b) {
+ return a - b;
+ });
+
+ // create synths
+
+ params['-'].synth = create_none_synth();
+ params['ad'].synth = create_ad_synth();
+ params['tracker'].synth = create_tracker_synth();
+ params['analytics'].synth = create_analytics_synth();
+ params['widget'].synth = create_widget_synth();
+ params['privacy'].synth = create_privacy_synth();
+
+ stop_all_synths();
+
+ interval_id = window.setInterval(tick, time_incr_ms);
+
+ },
+ error: function(xhr, status, error) {
+ console.log("error loading -- " + csv_input_file);
+ }
+ });
+}
+
+function linear_increment(start_ms, end_ms, size_bytes) {
+ return size_bytes / (end_ms - start_ms);
+}
+
+function start_all_synths() {
+ p = false;
+ params['-'].synth.start();
+ params['ad'].synth.start();
+ params['tracker'].synth.start();
+ params['analytics'].synth.start();
+ params['widget'].synth.start();
+ params['privacy'].synth.start();
+}
+
+function stop_all_synths() {
+ p = true;
+ params['-'].synth.stop();
+ params['ad'].synth.stop();
+ params['tracker'].synth.stop();
+ params['analytics'].synth.stop();
+ params['widget'].synth.stop();
+ params['privacy'].synth.stop();
+}
+
+
+function tick() {
+
+ if(p) return;
+
+ $('#time').html(tick_cnt);
+ if(tick_cnt >= time_end + 1) {
+ window.clearInterval(interval_id);
+ stop_all_synths();
+ } else if(tick_cnt == 0) {
+ start_all_synths();
+ }
+
+ if(start_times[next_start] == tick_cnt) {
+ var start_indices = start_times_dict[tick_cnt];
+ processing_data = processing_data.concat(start_indices)
+ for(var i = 0; i < start_indices.length; i++) {
+ var d = data[start_indices[i]]
+ params[d.bug_type].active = params[d.bug_type].active + 1;
+ }
+ next_start++;
+ }
+ if(end_times[next_end] == tick_cnt) {
+
+ var end_indices = end_times_dict[tick_cnt];
+ for(var i = 0; i < end_indices.length; i++) {
+ var processing_indx = processing_data.indexOf(end_indices[i]);
+ if(processing_indx != -1) {
+ var d = data[end_indices[i]]
+ processing_data.splice(processing_indx, 1);
+ params[d.bug_type].bytes -= parseInt(d['Object Size']);
+ params[d.bug_type].active = params[d.bug_type].active - 1;
+ } else {
+ console.log('not proccesed -- ' + end_indices[i]);
+ }
+ }
+
+ next_end++;
+ }
+
+ for(var i = 0; i < processing_data.length; i++) {
+ var d = data[processing_data[i]];
+ params[d.bug_type].bytes += d.incr;
+ d.incr_tick = d.incr_tick + 1;
+ }
+
+ params['-'].synth.update(params['-'].bytes);
+ params['ad'].synth.update(params['ad'].bytes);
+ params['tracker'].synth.update(params['tracker'].bytes);
+ params['analytics'].synth.update(params['analytics'].bytes);
+ params['widget'].synth.update(params['widget'].bytes);
+ params['privacy'].synth.update(params['privacy'].bytes);
+
+ // $('#none').html(params['-'].active);
+ // $('#none_bytes').html(Math.ceil(params['-'].bytes));
+
+ // $('#ad').html(params['ad'].active);
+ // $('#ad_bytes').html(Math.ceil(params['ad'].bytes));
+
+ // $('#tracker').html(params['tracker'].active);
+ // $('#tracker_bytes').html(Math.ceil(params['tracker'].bytes));
+
+ // $('#analytics').html(params['analytics'].active);
+ // $('#analytics_bytes').html(Math.ceil(params['analytics'].bytes));
+
+ // $('#widget').html(params['widget'].active);
+ // $('#widget_bytes').html(Math.ceil(params['widget'].bytes));
+
+ // $('#privacy').html(params['privacy'].active);
+ // $('#privacy_bytes').html(Math.ceil(params['privacy'].bytes));
+
+
+ tick_cnt++;
+
+}
+
diff --git a/synthesis/lib/tttt.js b/synthesis/lib/tttt.js
new file mode 100644
index 0000000..577df6d
--- /dev/null
+++ b/synthesis/lib/tttt.js
@@ -0,0 +1,20 @@
+
+var svg_repo_url = "http://gauthiier.github.io/www-micro-temporalities/img/scores/";
+var csv_repo_url = "https://raw.githubusercontent.com/gauthiier/www-micro-temporalities/master/webpagetest/filtered/";
+
+var data_ref = get_param('ref');
+
+if(data_ref === "") {
+ console.log('no ref aborting...');
+} else {
+ console.log('ref: ' + data_ref);
+ draw(svg_repo_url + data_ref);
+ synthesise(csv_repo_url + data_ref);
+}
+
+function get_param(name) {
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ var regex = new RegExp("[\\?&]" + name + "=([^]*)"),
+ results = regex.exec(location.search);
+ return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+}
\ No newline at end of file
diff --git a/synthesis/lib/yyyy.js b/synthesis/lib/yyyy.js
new file mode 100644
index 0000000..ec863d8
--- /dev/null
+++ b/synthesis/lib/yyyy.js
@@ -0,0 +1,302 @@
+////////////
+////////////////////////////
+////////////
+
+var AudioContext = window.AudioContext || window.webkitAudioContext;
+
+var audioCtx = new AudioContext();
+
+function Modulator(waveform, freq, gain) {
+ // actual modulating freq
+ this.osc = audioCtx.createOscillator();
+ this.osc.type = waveform;
+ this.osc.frequency.value = freq;
+ // not sure about this -- but the gain is what modulates
+ this.gain = audioCtx.createGain();
+ this.gain.gain.value = gain;
+ // connect
+ this.osc.connect(this.gain);
+}
+
+function Carrier(waveform, freq) {
+ this.osc = audioCtx.createOscillator();
+ this.osc.type = waveform;
+ this.osc.frequency.value = freq;
+ this.gain = audioCtx.createGain();
+ this.osc.connect(this.gain);
+}
+
+function FMSynth(waveform_c, freq_c, waveform_m, freq_m, gain_m) {
+
+ this.carrier = new Carrier(waveform_c, freq_c);
+ this.modulator = new Modulator(waveform_m, freq_m, gain_m);
+
+ this.bitcrusher_filter = new BitCrusherFilter();
+
+ this.modulator.gain.connect(this.carrier.osc.frequency);
+ this.carrier.gain.connect(audioCtx.destination);
+
+ this.started = false;
+
+ this.start = function() {
+ if(!this.started) {
+ this.carrier.osc.start();
+ this.modulator.osc.start();
+ this.started = true;
+ } else {
+ this.carrier.gain.gain.value = 1.0;
+ }
+ }
+
+ this.stop = function() {
+ this.carrier.gain.gain.value = 0.0;
+ }
+
+ this.modulator_freq_incr = function(incr) {
+ this.modulator.osc.frequency.value = this.modulator.osc.frequency.value + incr;
+ }
+
+ this.modulator_freq = function(freq) {
+ this.modulator.osc.frequency.value = freq;
+ }
+
+ this.add_filter = function (filter) {
+ this.filter = filter;
+ this.carrier.osc.disconnect(this.carrier.gain);
+ this.carrier.osc.connect(this.filter);
+ this.filter.connect(this.carrier.gain);
+ }
+
+}
+
+function SimpleOscillator(waveform, freq) {
+
+ this.oscillator = new Carrier(waveform, freq);
+ this.oscillator.gain.connect(audioCtx.destination);
+
+ this.started = false;
+
+ this.start = function() {
+ if(!this.started) {
+ this.oscillator.osc.start();
+ this.started = true;
+ } else {
+ this.oscillator.gain.gain.value = 1.0;
+ }
+ }
+
+ this.stop = function() {
+ this.oscillator.gain.gain.value = 0.0;
+ }
+
+ this.modulator_freq_incr = function(incr) {
+ this.oscillator.osc.frequency.value = this.modulator.osc.frequency.value + incr;
+ }
+
+ this.modulator_freq = function(freq) {
+ this.oscillator.osc.frequency.value = freq;
+ }
+
+ this.add_filter = function (filter) {
+ this.filter = filter;
+ this.oscillator.osc.disconnect(this.oscillator.gain);
+ this.oscillator.osc.connect(this.filter);
+ this.filter.connect(this.oscillator.gain);
+ }
+
+
+}
+
+function WhiteNoiseGenerator() {
+
+ // generates 2 sec noise buffer
+ var bufferSize = audioCtx.sampleRate * 2;
+ var noiseBuffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
+ var out = noiseBuffer.getChannelData(0);
+ for(var i = 0; i < bufferSize; i++) {
+ out[i] = Math.random() * 2 - 1;
+ }
+
+ this.whitenoise = audioCtx.createBufferSource();
+ this.whitenoise.buffer = noiseBuffer;
+ this.whitenoise.loop = true;
+
+ this.gain = audioCtx.createGain();
+ this.whitenoise.connect(this.gain);
+ this.gain.connect(audioCtx.destination);
+
+ this.started = false;
+
+ this.start = function() {
+ if(!this.started)
+ this.whitenoise.start(0);
+ this.started = true;
+ }
+
+ this.stop = function() {
+ this.gain.gain.value = 0.0;
+ this.started = false;
+ }
+
+ this.modulator_gain_incr = function(incr) {
+ this.gain.gain.value = this.gain.gain.value + incr;
+ }
+
+ this.modulator_gain = function(gain) {
+ this.gain.gain.value = gain;
+ }
+
+ this.add_filter = function(filter) {
+ this.filter = filter;
+ this.whitenoise.disconnect(this.gain);
+ this.whitenoise.connect(this.filter);
+ this.filter.connect(this.gain);
+ }
+
+}
+
+function PinkNoiseGenerator() {
+
+ var bufferSize = 4096;
+ this.pinknoise = audioCtx.createScriptProcessor(bufferSize, 1, 1);
+ var b0, b1, b2, b3, b4, b5, b6;
+ b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;
+ this.pinknoise.onaudioprocess = function(e) {
+ var out = e.outputBuffer.getChannelData(0);
+ for(var i = 0; i < bufferSize; i++) {
+ var white = Math.random() * 2 - 1;
+ b0 = 0.99886 * b0 + white * 0.0555179;
+ b1 = 0.99332 * b1 + white * 0.0750759;
+ b2 = 0.96900 * b2 + white * 0.1538520;
+ b3 = 0.86650 * b3 + white * 0.3104856;
+ b4 = 0.55000 * b4 + white * 0.5329522;
+ b5 = -0.7616 * b5 - white * 0.0168980;
+ out[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;
+ out[i] *= 0.11; // (roughly) compensate for gain
+ b6 = white * 0.115926;
+ }
+ };
+
+ this.gain = audioCtx.createGain();
+ this.pinknoise.connect(this.gain);
+ this.gain.connect(audioCtx.destination);
+
+ this.started = false;
+
+ this.start = function() {
+ }
+
+ this.stop = function() {
+ this.gain.gain.value = 0.0;
+ this.started = false;
+ }
+
+ this.modulator_gain_incr = function(incr) {
+ this.gain.gain.value = this.gain.gain.value + incr;
+ }
+
+ this.modulator_gain = function(gain) {
+ this.gain.gain.value = gain;
+ }
+
+ this.add_filter = function(filter) {
+ this.filter = filter;
+ this.pinknoise.disconnect(this.gain);
+ this.pinknoise.connect(this.filter);
+ this.filter.connect(this.gain);
+ }
+
+}
+
+//////////// Filters
+
+function BitCrusherFilter() {
+ var bufferSize = 4096;
+ var node = audioCtx.createScriptProcessor(bufferSize, 1, 1);
+ node.bits = 14; // between 1 and 16
+ node.normfreq = 0.1; // between 0.0 and 1.0
+ var step = Math.pow(1/2, node.bits);
+ var phaser = 0;
+ var last = 0;
+ node.onaudioprocess = function(e) {
+ var input = e.inputBuffer.getChannelData(0);
+ var output = e.outputBuffer.getChannelData(0);
+ for (var i = 0; i < bufferSize; i++) {
+ phaser += node.normfreq;
+ if (phaser >= 1.0) {
+ phaser -= 1.0;
+ last = step * Math.floor(input[i] / step + 0.5);
+ }
+ output[i] = last;
+ }
+ };
+ return node;
+}
+
+function LowPassFilter() {
+ var bufferSize = 4096;
+ var node = audioCtx.createScriptProcessor(bufferSize, 1, 1);
+ var prev = 0;
+ node.onaudioprocess = function(e) {
+ var input = e.inputBuffer.getChannelData(0);
+ var out = e.outputBuffer.getChannelData(0);
+ for (var i = 0; i < bufferSize; i++) {
+ out[i] = (input[i] + prev) / 2.0;
+ prev = out[i];
+ }
+ };
+ return node;
+}
+
+//////////// Convolvers
+
+function NoiseConvolver() {
+ var convolver = audioCtx.createConvolver();
+ var noiseBuffer = audioCtx.createBuffer(2, 0.5 * audioCtx.sampleRate, audioCtx.sampleRate);
+ var left = noiseBuffer.getChannelData(0);
+ var rigth = noiseBuffer.getChannelData(1);
+ for(var i = 0; i < noiseBuffer.length; i++) {
+ left[i] = Math.random() * 2 - 1;
+ rigth[i] = Math.random() * 2 - 1;
+ }
+ convolver.buffer = noiseBuffer;
+ return convolver;
+}
+
+//////////// WaveShapers
+
+function DistortionShaper(distortion_val) {
+ this.waveshaper = audioCtx.createWaveShaper();
+
+ this.makeDistortionCurve = function(amount) {
+ var k = typeof amount === 'number' ? amount : 50,
+ n_samples = 44100,
+ curve = new Float32Array(n_samples),
+ deg = Math.PI / 180,
+ i = 0,
+ x;
+ for ( ; i < n_samples; ++i ) {
+ x = i * 2 / n_samples - 1;
+ curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
+ }
+ return curve;
+ }
+
+ this.distortion = function(amount) {
+ this.waveshaper.curve = this.makeDistortionCurve(amount);
+ }
+
+ this.waveshaper.curve = this.makeDistortionCurve(distortion_val);
+
+ return this.waveshaper;
+}
+
+
+
+
+
+
+
+
+
+