Daud

Daud is a data sonification (audioization) library for the browser.

Simple example

This is just a basic example. By default, we assume the data is just the number of seconds to play a sound. This is similar to the NYT article "Fractions of a Second: An Olympic Musical".

var basic = new Daud({
  data: [0.65, 1.01, 1.33, 1.36, 1.8, 2, 2.5, 3, 3.2, 4.7, 4.8, 6]
});

Another dimension

What if we have another dimension to our data; for instance we want to hear the height of the skier. We can represent this in the pitch (or note) where a higher pitch is a taller person.

var notes = ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4'];
var dimension = new Daud({
  note: function(d, i, t, p) {
    // Adjust note/pitch to height in one octave
    return notes[Math.floor((d.height / 2) * 6)];
  },
  time: function(d, i, t, p) {
    // Tell daud that the time is the value in seconds
    return d.value * 1000;
  },
  data: [
    { value: 0.5, height: 1.5 },
    { value: 0.95, height: 1.9 },
    { value: 1.2, height: 0.9 },
    { value: 1.5, height: 1.2 },
    { value: 1.89, height: 0.3 },
  ]
});

Panning dimension

What if we instead using panning to translate the height into a binary listening experience. This uses some randomly generated data.

var panning = new Daud({
  panning: function(d, i, t, p) {
    // Use stero panning to go left and right depending on height
    return (d.height < 1) ? -1 : 1;
  },
  time: function(d, i, t, p) {
    // Tell daud that the time is the value in seconds
    return d.value * 1000;
  },
  data: _.map(_.range(30), function(r, ri) {
    return {
      value: (ri / 3) + (Math.random() / 0.2),
      height: Math.random() * 2
    };
  })
});

One more dimension

We can add another dimention to the data. This time, on top of changing pitch for the height, we change the "instrument" based on a 3rd variable. There are some built-in instruments, but checkout Wad documention for more info. Instrument can be a string for a preset, or an object config.

var instrument = new Daud({
  note: function(d, i, t, p) {
    // Adjust note/pitch to height in one octave
    return notes[Math.floor((d.height / 2) * 6)];
  },
  instrument: function(d, i, t, p) {
    // Use the color to change the instrument
    return (d.color === 'red') ? 'piano' : 'flute';
  },
  time: function(d, i, t, p) {
    // Tell daud that the time is the value in seconds
    return d.value * 1000;
  },
  data: [
    { value: 0.2, height: 1.2, color: 'red' },
    { value: 0.5, height: 1.3, color: 'blue' },
    { value: 0.55, height: 1.4, color: 'blue' },
    { value: 0.6, height: 0.3, color: 'red' },
    { value: 0.9, height: 0.5, color: 'red' },
    { value: 1.3, height: 0.2, color: 'blue' },
    { value: 1.39, height: 1.2, color: 'red' },
    { value: 2, height: 0.9, color: 'blue' },
    { value: 2.1, height: 0.3, color: 'red' },
    { value: 2.5, height: 0.5, color: 'red' },
    { value: 3.11, height: 0.2, color: 'blue' },
    { value: 3.18, height: 1.2, color: 'red' },
    { value: 3.9, height: 0.9, color: 'blue' }
  ]
});

Real world example

As part of Harlem Heat, sensors were put inside apartments in Harlem (mostly) without air conditioning. The astounding thing is that inside the apartment, the temperature will gradually rise over days as it gets hot outside, but unlike the outside temperature, the temperature inside remains hot even at night. Play the outside heat index for an average day, then do the same for the inside, and you can hear how the outside goes up and down in pitch (heat index), while the inside does not.

var heatNotes = [
  'C2', 'D2', 'E2', 'F2', 'G2', 'A2', 'B2',
  'C3', 'D3', 'E3', 'F3', 'G3', 'A3', 'B3',
  'C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4',
  'C5', 'D5', 'E5', 'F5', 'G5', 'A5', 'B5',
  'C6', 'D6', 'E6', 'F6', 'G6', 'A6', 'B6'
];
var outsideHeat = new Daud({
  note: function(d, i, t, p) {
    // Adjust note/pitch heat index
    // Make 75 deg middle C
    return heatNotes[Math.floor(d.hi) - 80 + 14];
  },
  time: function(d, i, t, p) {
    // Tell daud that the time is determined by the hours
    return d.hour * 1000;
  },
  instrument: function(d, i, t, p) {
    // Hold the note a bit longer
    var instrument = JSON.parse(JSON.stringify(this.instruments.piano));
    instrument.env.release = 1;
    return instrument;
  },
  data: [
    {"hour":0,"hi":80.06},
    {"hour":0.5,"hi":79.46},
    {"hour":1,"hi":78.87},
    {"hour":1.5,"hi":78.81},
    // ...
  ]
});