Release_Augmented Audification

Hanns Holger Rutz edited this page Nov 26, 2015 · 5 revisions

'Augmented Audification' Sonification

:back: Release Workshop

:package: Download Template


The sonification targets one-dimensional data. It can be played directly as so-called "audification", using a normally high sampling rate (in the order of several thousand samples per second), or zoom into a region of the data set with a pitch shift and modulation, leading to an "auditory graph".

You may find details on the sound synthesis in this paper:

The time dimension is used to unroll the data in time during playback.


  • Speed (1/s): number of data points (samples) played per second. (For audification, use, e.g., a sampling rate of 44100 Hz.)
  • Data min: provide the minimum of the data values for correct normalization
  • Data max: provide the maximum of the data values for correct normalization
  • Pitch modulation (octaves): spreads the perceived pitch of (normalized) data values of +/- 1 by +/- one octave
  • Frequency shift (Hz): To be used if the sampling rate is too low for the audible range; suggested factor is between 200-800 Hz.

Data Sets

The sonification can be used with any one-dimensional data set.

For the template, we use:

  • TOA Incident Shortwave radiation: (yearly values, i.e., only 156 values - only an auditory graph makes sense here)
  • Data from the WegenerNet,
    • Air temperature (at 2m) and surface temperature in Feldbach from 11/2007 to 11/2008
    • Air temperature (at 2m) and surface temperature in Feldbach from 11/2011 to 11/2012 (hourly values over one year; missing values have been interpolated before)

The data can be either played with high sampling rate (Speed, e.g., 11000 with Pitch modulation = Frequency shift = 0), or it is possible to zoom into a small area of interest (speed, e.g., 48, i.e. 2 days per second, with a pitch modulation of 1 and a frequency shift of 200).


// Version: 25-Nov-15_1

def mkDelay(in: GE, buf: GE): GE = {
  val dt =, dt, dt)

// returns (delayed source, shift90)
def HilbertFIR(in: GE, buf: GE): (GE, GE) = {
  val fft   = FFT(buf, in)
  val pv    = PV_PhaseShift90(fft)
  val dly   = mkDelay(in, buf)
  val shift =
  (dly, shift)

val v       = Var("var")
val dTime   = Dim(v, "time")
val speed   = UserValue("Speed (1/s)", 44100).kr
val lo      = UserValue("Data min" , 0.0).kr
val hi      = UserValue("Data max", 1.0).kr
val time    =, maxFreq = 22000)
val raw     =, interp = /* 1 */ 2) \ 0
val ok      =, post = 0) sig_== 0
val clean   =, ok)
// raw .poll(
// time.poll(
val sig     = clean.linlin(lo, hi, 0 /* -1 */, 1).clip(0, 1)
val c       = UserValue("Pitch modulation", 0.0).kr
val df      = UserValue("Frequency shift (Hz)", 0).kr
val fMod    = df * 2.pow(sig * c)
val sin     =, phase = 0.0)
val cos     =, phase = 0.5 * math.Pi)
val hlbBuf  = LocalBuf(4096)
val (hilbRe, hilbIm) = HilbertFIR(sig, hlbBuf)
val env     = mkDelay(, 1, 0.1), hlbBuf)
val out     = * sin - hilbIm * cos) * env

Elapsed := time
output  := * -6.0.dbamp)
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.