data sonification

edited September 2015 in How To...

Hello!

Is there a way to sonify DSM (Digital Suface Model) data?

And, does anyone know which is the best way/site to find and download DSM data from all over the world?

This is so important.

Thank you all in advance.

Tagged:

Answers

  • Please, anyone? :(

  • this is a complex and broad question...

    can you post an example?

    can you ask somewhere else, e.g. in a forum for musician or in a company that produces DSM? Maybe they have some free dsm...?

    I don't even know what it is...

    ;-)

  • Answer ✓

    **Is that it? **

    https://en.wikipedia.org/wiki/Digital_elevation_model

    QUOTE:

    A free DEM of the whole world called GTOPO30 (30 arcsecond resolution, approx. 1 km) is available, but its quality is variable and in some areas it is very poor. A much higher quality DEM from the Advanced Spaceborne Thermal Emission and Reflection Radiometer (ASTER) instrument of the Terra satellite is also freely available for 99% of the globe, and represents elevation at 30 meter resolution.

    idea

    maybe you can post the data of one square kilometer here and we have a look ;-)

    see

    http://www.dlr.de/hr/en/desktopdefault.aspx/tabid-2317/

    ASTER

    on ASTER you'll find WinVICAR - not sure if this and the other tools on ASTER are opensource

    http://asterweb.jpl.nasa.gov/winvicar.asp

    also data there.

    ;-)

  • My aim is to sonify terrain elevation data coming from a delimited area I chose. I thought it could be possible converting DSM/DEM data to sound. I also thought about printing a 3d map out of that data, looking around online i found it can be possible to print a 3d model out of elevation data. I'd prefer DSM. Surfaces represented by a Digital Surface Model (DSM) include buildings and other objects. Digital Terrain Models represent the bare ground.

    I'm checking those sites you wrote and try to start something out of it. ;)

  • Sounds interesting

    But you have to find a way to parse the data to arrive at some data to play sounds

    Hm...

    I just checked wikipedia for you

  • edited September 2015

    I understand what you mean.

    I also found out other similar previous works like http://www.o-art.org/history/Computer/TerrainReader/Songlines.DEM.html

    Now, I figured out how to convert many many times data to create a file printable in 3d.

    I can't understand how to upload that data in Processing and try to find a way to sonify it.

  • you wrote

    Now, I figured out how to convert many many times data to create a file printable in 3d.

    can you post the code for that?

    can you post the data you used to do so?

  • edited September 2015

    Not using Processing, but here is a way to do it:

    dl.dropboxusercontent.com/u/11089897/3druckench/maps_to_3D.pdf

  • in which format is the terrain data?

    csv?

    can you post it?

  • the url in the pdf:

    http://www.viewfinderpanoramas.org/Coverage map viewfinderpanoramas_org3.htm

    shows a clickable map. that'll get you a zip file containing 4 (in my case) .hgt files (height?)

    these are pure binary (2 byte signed, big endian)

    http://gis.stackexchange.com/questions/43743/how-to-extract-elevation-from-hgt-file

  • oh darn

    but how can processing read this??

    a kml or xml or json would be better

  • loadBytes()?

    that said, my attempt currently looks terrible.

  • edited September 2015

    Guys, i found .kml and .csv format of the area i need! Providing Lat Long Alt

    I also found this in openprocessing openprocessing.org/sketch/28298

    This work uses SRTM .hgt binary format

  • Answer ✓
    // acd 2015-09-22 p1.5.1
    // heightmap using data from
    // www.viewfinderpanoramas.org/Coverage map viewfinderpanoramas_org3.htm
    
    import peasy.*;
    import processing.opengl.*;
    
    PeasyCam cam;
    String FILE = "S09W079.hgt";
    int W = 1201;
    int H = 1201;
    short[][] data;
    
    void setup() {
      size(640, 480, OPENGL);
      cam = new PeasyCam(this, 1000);
      data = load(FILE);
    }
    
    void draw() {
      background(255);
      //translate(-width / 2, -height / 2);
      for (int y = 0 ; y < H ; y += 10) {
        for (int x = 0 ; x < W ; x += 10) {
          point(x - (W / 2), -data[x][y] / 20, y - (H / 2));
        }
      }
    }
    
    short[][] load(String filename) {
      // load the bytes into the array
      byte[] b = loadBytes(filename);
      // and copy them into the data array, two at a time
      short[][] data = new short[W][H];
      int index = 0;
      for (int y = 0 ; y < H ; y++) {
        for (int x = 0 ; x < W ; x++) {
          // messy
          int b0 = b[index];
          b0 = b0 >= 0 ? b0 : 256 + b0;
          int b1 = b[index + 1];
          b1 = b1 >= 0 ? b1 : 256 + b1;
          data[x][y] = (short)(b0 * 256 + b1);
          index += 2;
        }
      }
      return data;
    }
    
  • edited September 2015

    I've not dealt with dsm or dem data before but a quick look online gives me the sense that it might come down to a grid of (x,y) points, each with associated z for height (e.g. a two dimensional function z = f(x,y). The synthesis parallel should be wave terrain synthesis. I assume it is possible with Minim or another sound library. I don't know about any ready made wave terrain stuff. A friend adviced me to choose spectral synthesis (sweep over x or y using the z's as amplitudes of spectral bins for inverse FFT)

    This is really important and any help and advice will be amazing for me and i won't know how to thank you.

    I'm dedicating this project to my brother who passed away at the end of last year, during an accident which reasons are still unknown and investigations are still on going..

    I'd give anything to find out how to make this sonification possible and it might sound bothering or not to ask for help, but i'm more than desperate doing this.

  • edited September 2015

    Can i load a .csv or .kml file to this code?

    When I download the .zip file in the clickable map on viewfinderpanorama I get too much .hgt files and also, I guess, for the whole Swiss area (in my case). I want to load just a selected area, which I already have in .csv or .kml. (lat,long,alt)

  • Answer ✓

    csv's are easily manipulated with Table class. You can load csv into it, using loadTable(). And you can make a method then that iterates through table and makes a 2-dimensional array, as in example above.

  • Not sure if it was the table class or the XML (or both). But one of them doesn't work for large files. You might want to take this into consideration.

  • edited October 2015

    @koogs I tried to use your code loading csv instead. It's not working, of course i've done something wrong... My question now is : how do I sonify it? Do I use Minim, Sound library, what? i'm a total beginner, so i apologize in advance.

  • What about an easier way to exercise. What about starting with sonifying a form, a shape instead of a csv file?

  • can youpost somelines of the csv?

  • you'd use minim

    lots of examples

    maybe you find a library for parsing kml or gpx

    what is your idea for sound?

    i mean when go through an area of a state

    let's say a rect

    then you lay a grid over it

    let's say you follow it cell by cell: first line, all cells, from west to east, next line again from west to east and so on from north to south

    then for each cell you have height (mountain or valley)

    you can take this height and interpret as a frequency (your tone / melody)

    so you play each like for 0,5 seconds

    use map to map all values of the heights to the frequency range you need.

    ok?

    I am willing to help you

    Chrisir

  • do you agree with this approach?

    do you want this?

  • Yes it is what i'd like to do

  • Thank you

  • In the meanwhile, I'd like to exercise on sonifying something else, like a 3D cube. Is it possible?

    What Minim example do you refer to for creating sound from shape?

    @ddf

  • No....

    For a cube you got 8 corners and 12 edges

    You need to tell how you want to translate that into Sound...

    what is amplitude, duration, frequency

  • Any other 3D shape?

  • //  file is regarded as one set of points x and y plus a height z.  
    //  z is used for color and sound 
    
    // see also http: // code.compartmental.net/minim/minim_method_getlineout.html
    
    import ddf.minim.* ;
    import ddf.minim.signals.* ;
    import ddf.minim.effects.* ;
    import ddf.minim.ugens.*;
    
    Minim minim;
    AudioOutput au_out;
    Oscil wave;
    
    // your txt file 
    String nameOfMyTextfile = "dem taverne.csv";
    
    // your target: where you store you points  
    PointClass[] points ;
    
    int maxPoints = 1500;
    final int undefined = -100;
    
    // the max and mins in the 3 columns 
    float minx=1111, miny=1111, minz=1111;
    float maxx=-111, maxy=-111, maxz=-111;
    
    int currentPointNumber=0; 
    boolean firstTime = true; 
    
    // --------------------------------------------------
    
    void setup() {
      size(900, 600);
    
      // all points 
      points = new PointClass[ maxPoints ];
      resetPoints();
    
      // load 
      loadTheTextfileIntoMySetsOfPoints (nameOfMyTextfile );
    
      minim = new Minim(this) ;
      au_out = minim.getLineOut() ;
    
      // create a sine wave Oscil, set to 440 Hz, at 0.5 amplitude
      wave = new Oscil( 440, 0.5f, Waves.SINE );
      // patch the Oscil to the output
      wave.patch(   au_out );
    
      background(0);
    
      // fast
      frameRate(100);
    
      println("End of setup().  ----------------------------");
    } // func
    //
    void draw() {
      background(0);
    
      // loop points and display them 
      for (int i=0; i< maxPoints; i++) {
        // if point not defined  
        if (points[i].x == undefined) { 
          break; // go on
        } else
        {
          // display 
          points[i].display(false, !firstTime);
        } // else
      } // for
    
      currentPointNumber++;
      if (currentPointNumber==2)
      {
        delay(999);
        noLoop();
        au_out.mute();
      }
      currentPointNumber=currentPointNumber % maxPoints;
    
      firstTime = false;
      // fast 
      frameRate(100);
    } // func
    
    // ---------------------------------------------------------------
    
    void resetPoints() { 
      // init 
      // pre-defined color 
      color white = color (255, 255, 255);
    
      // loop points 
      for (int i=0; i< maxPoints; i++) {
        // set as undefined 
        points[i] = new PointClass (undefined, undefined, undefined, white );
      } // for
    } // func 
    
    void loadTheTextfileIntoMySetsOfPoints ( String currentNamesOfMyTextfile ) {
    
      String [] TestCSV = null;
    
      // loadStrings   
      TestCSV = loadStrings (currentNamesOfMyTextfile);
    
      if (TestCSV==null) {
        // failed 
        println (currentNamesOfMyTextfile 
          + " not found.");
        exit(); 
        return;
      } else 
      {
        // all good 
        println ("TestCSV.length is for: " 
          + currentNamesOfMyTextfile 
          + " : " 
          + TestCSV.length  
          + ".");
    
        // one color (random)
        color currentSetColor = color (random(255), random(255), random(255));
    
        int border = TestCSV.length;
        if (border > maxPoints) {
          border = maxPoints;
          println ("maxPoints to low for file " +currentNamesOfMyTextfile );
        }
        maxPoints=border; 
    
        println("---------------------------------------------- ");
        println("START of for ---------------------------------------------- ");
        println("---------------------------------------------- "); 
    
        int i=0;
    
        // loop csv and copy into points 
        for (int i2=0; i2<border; i2++) {
    
          // split one line to get its values 
          String[] a1 = split(TestCSV [i2], "\",");
    
          println ("a1.length for TestCSV ["+i2+"] is " + a1.length  + ".");
          println (
          float (format(a1[0])), 
          float(format(a1[1])), 
          float(format(a1[2]))
            );
    
          if (float (format(a1[0]))<1000) {
    
            // make a new point-object of x and y value from this line 
            PointClass newPoint = new PointClass (float (format(a1[0])), 
            float(format(a1[1])), 
            float(format(a1[2])), 
            currentSetColor );
    
    
            // ----------------------------
            // the max and mins in the 3 colums 
    
            if (newPoint.x<minx) {
              minx=newPoint.x;
            }
            if (newPoint.y<miny) {
              miny=newPoint.y;
            }
            if (newPoint.z<minz) {
              minz=newPoint.z;
            }
    
            // ----------------------------
    
            if (newPoint.x>maxx) {
              maxx=newPoint.x;
            }
            if (newPoint.y>maxy) {
              maxy=newPoint.y;
            }
            if (newPoint.z>maxz) {
              maxz=newPoint.z;
            }
    
            // copy the object at the end of our array points   
            points[i] = newPoint;
            i++;
          }
        } // for
    
        // done
        println("---------------------------------------------- ");
        println("End of for ---------------------------------------------- ");
        println("---------------------------------------------- "); 
        println("File "
          +currentNamesOfMyTextfile
          +". Array points length is " 
          + border 
          + ".");
    
        // the max and mins in the 3 colums 
        println(" min ", minx, miny, minz);
        println(" max ", maxx, maxy, maxz);
      } // else
    } // func 
    
    String format(String inString) {
      //
      inString=inString.replace("\"", "");
      inString=trim(inString); 
      inString=inString.replace(",", ".");
      return inString;
    }
    
    void stop()
    {
      minim.stop();
      super.stop() ;
    }
    
    //
    // ===============================================================
    //
    class PointClass {
    
      float x, y, z;
    
      color col;  // not in use 
    
      // float sizeOfPoint = 11;
    
      // constructor 
      PointClass(float x_, float y_, float z_, 
      color col_) {
        x=x_;
        y=y_;
        z=z_;
    
        col=col_; // not in use
      } // constructor
      //
      void display(boolean highlight, // not in use
      boolean playSound) {
    
        float border = 12;
    
        // now we use the min and max values to map the values from the csv to the ranges we need. 
        float x1=map(x, minx, maxx, 0+border, width-border);   // window width 
        float y1=map(y, miny, maxy, 0+border, height-border);  // window height
        float z1=map(z, minz, maxz, 0, 255);                   // color range
    
        float z2=map(z, minz, maxz, 261.63, 1523.25);           // sound range
    
        if (playSound) {
          playZ(z2);
        }
    
        if (highlight) {
          // bigger ellipse 
          fill(z1, 255, 0);
          noStroke();
          ellipse (x1, y1, 
          6, 6);
        } else 
        {
          // small point 
          stroke (z1, 255, 0);
          point(x1, y1);
        }
      } // method
    
      void playZ (float note1) {
        wave.setFrequency( note1 );
        delay(211);
      }  //  method
    } // class
    //
    
  • edited October 2015

    the beginning of the csv looks like this

    "46,06477","8,930678",347
    "46,064684","8,931068",347
    "46,064662","8,93153",349
    
  • edited October 2015

    the data is not so interesting, since most z-values (3rd column) are the same. They also don't represent a grid but more height lines of some kind, I think.

    Setup of the sketch

    You need to download and install minim (menu sketch | import library | add library)

    you need to copy the csv into the sketch folder

    remarks

    there are some tricks in the sketch, e.g. \" just means " etc.

    also in English, instead of 3,14 (German, Switzerland...) we say 3.14

    so there is some stuff going on to parse the lines like "46,06477","8,930678",347

  • You're a superhero. Now I can just learn from this code.

    I see. In fact it is not a place with high elevations since it's the area of a city's railway station. :(

    Yeah I already have Minim and ran the sketch. I'm now trying to understand how the code exactly works.

    I'd like to know your opinion....do you think some different elevation data would be more interesting?

  • yes

    a greater variety on z

Sign In or Register to comment.