• fullscreen
  • classMusicData.pde
  • classes.pde
  • keyboard.pde
  • shortminimFFT.pde
  • class Displayer
    {
      float [] [] data;
      String path;
      int audioLength, buffer;
      boolean isPlaying = true;
      
      Displayer (String path, int buffer)
      {
        this.path = path;
        this.buffer = buffer;
        
        loadData ();
      }
      
      int getAudioLength()
      {
        return audioLength;
      }
      
      boolean isPlaying ()
      {
        return isPlaying;
      }
      
      void setisPlaying ()
      {
        isPlaying = !isPlaying;
      }
      
      float [] data (int pos)
      {
        pos = constrain (pos, 0, audioLength-1);
        
        float [] currentData = new float [buffer];
        
        for (int i = 0; i < buffer; i++)
        {
          currentData [i] = data [pos] [i];
        }
        
        return currentData;
      }
      
      void loadData ()
       {
    
         String [] rowText = loadStrings (path + ".txt");
         audioLength = rowText.length;
         data = new float [audioLength] [buffer];
         
         for (int i = 0; i < audioLength; i++)
         {
           String index = rowText [i];
           String [] dataAtIndex = splitTokens (index, " ");
           
           for (int j = 0; j < buffer; j++)
           {
             data [i] [j] = float (dataAtIndex[j]);
           }
         }
       }
    }
    
    class Saver
    {
      ArrayList musicData;
      int buffer;
      int audioLength;
      String path;
    
      Saver (int buffer, String path)
      {
        this.buffer = buffer;
        this.path = path;
        musicData = new ArrayList();
        audioLength = 0;
       }
    
      void setElement(float data)
      {
        musicData.add (new Float (data));
      }
        
      void increaseLength ()
      {
        audioLength++;
      }
      
      String getPath()
      {
        return path;
      }
      
      int getBuffer ()
      {
        return buffer;
      }
    
      void saveData ()
      {
        
        String dataAsString = " ";
        String [] exportData = new String [audioLength];
        
        for (int i = 0; i < audioLength; i++)
        {
          dataAsString = " ";
          for (int j = 0; j < buffer; j++)
          {
            int index = i*buffer + j;
            float data = (Float) musicData.get (index);       
            dataAsString += str (data) +  " ";
          }
          
          exportData [i] = dataAsString;
        }
    
        saveStrings (path + ".txt", exportData);
        //exit();
      }
    }
    
    
    void keyPressed ()
    {
      if (keyCode == KeyEvent.VK_S)
      {
        if (displayer != null) 
        {
          if (displayer.isPlaying()) 
          {
            offsetFrame = frameCount;
            if (playMusic && groove.isPlaying()) groove.pause();
          }
          else {
            if (playMusic && !groove.isPlaying()) groove.play(frameCount % displayer.getAudioLength()*100/3);
          }
          displayer.setisPlaying();
        }
      }
    
      if (keyCode == KeyEvent.VK_P)
      {
        if (displayer.isPlaying()) 
        {
          playMusic = !playMusic;
          if (groove.isPlaying()) groove.pause();
          else {
            groove.play(frameCount % displayer.getAudioLength()*100/3);
          }
        }
      }
    }
    
    
    // what this is doing
    // (1 if boolean saved = true) display music with the help of a common library
    // (2 if boolean saved = true) save the music data in an array
    // (3 if boolean saved = true) export this data into a .txt file
    // (4) load this text file and display it
    
    // Code by Diana Lange
    // www.diana-lange.de
    
    // Music: CocoRosie - The Moon asked the crow
    // http://www.cocorosieland.com/
    // http://www.myspace.com/cocorosie
    
    
    import ddf.minim.*;
    
    Minim minim;
    AudioPlayer groove;
    Saver saver;
    Displayer displayer;
    
    PFont font;
    boolean saved = true, loaded = false, playMusic = false;
    int offsetFrame = 0;
    
    void setup()
    {
      size(512, 200);
      background (255);
    
      frameRate (30);
    
      minim = new Minim(this);
      int buffer = 1024;
      String path = "data/data";
    
      font = createFont("Arial", 12);
      textFont(font, 12);
    
      groove = minim.loadFile("coco_short.mp3", buffer);
      saver = new Saver (buffer, path);
    
      if (!saved || playMusic) groove.play();
    
      fill (0);
      stroke (0);
    }
    
    void draw()
    {
      background(255);
      if (!saved) saveMusicData ();
      else displayMusicData();
    }
    
    void displayMusicData()
    {
      if (!loaded)
      {
        displayer = new Displayer (saver.getPath(), saver.getBuffer());
        loaded = true;
        
      }
      
      if (!displayer.isPlaying()) frameCount = offsetFrame;
      if (frameCount > displayer.getAudioLength())
      {
        frameCount = 0;
        if (playMusic) groove.play(frameCount % displayer.getAudioLength()*100/3);
      }
      
      text ("Is Displayling. " + "FrameRate: " + nf (frameRate, 2, 1) + ", current Frame: " + str (frameCount % displayer.getAudioLength()), 20, 20);
      float [] currentData = displayer.data (frameCount % displayer.getAudioLength());
      
      beginShape();
      for (int i = 0; i < currentData.length; i++)
      {
         float x = i * ((float) width/ (float) currentData.length);
         float y = height/2 + currentData [i];
         
         float x2 = width/2 + cos (TWO_PI / currentData.length * i) * (50+currentData [i]);
         float y2 = height/2 + sin (TWO_PI / currentData.length * i) * (50+currentData [i]);
         
         vertex (lerp (x, x2, (float)mouseX/(float)width), lerp (y, y2,(float)mouseY/(float)height));
      }
      endShape();
    }
    
    void saveMusicData ()
    {
      text ("Is Saving. " + "FrameRate: " + nf (frameRate, 2, 1) + ", current Frame: " + str (frameCount), 20, 20);
    
      if (groove.isPlaying())
      {
        for (int i = 0; i < groove.bufferSize(); i++)
        {
          int x = i * width/groove.bufferSize();
          float y = (groove.left.get(i)+groove.right.get(i)) * 20;
    
          point (x, height/2+y);
    
          saver.setElement(y);
        }
    
        saver.increaseLength();
      }
      else 
      {
        saver.saveData();
        saved = true;
      }
    }
    
    
    void stop()
    {
      groove.close();
      minim.stop();
      super.stop();
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Diana Lange

    Display, Export, Import Sound

    Add to Faves Me Likey@! 19
    You must login/register to add this sketch to your favorites.

    This is an example, how to save audio data to a text file, and load this text file, prepare and display it. This is very important if you want to visualize music in non-realtime (e.g. the visualization is too complex).

    Check Video Tutorial:
    http://www.vimeo.com/27642353

    And some of my results using this workflow:
    http://www.vimeo.com/dianalange

    Controls:
    p = play/mute music
    s = play/pause
    mousePosition

    Music: CocoRosie - The moon asked the crow

    joe stevens
    8 Oct 2011
    tried to follow the vimeo lesson, but couldn't get it to work. Then tried downloading these files and get an error

    1st error was
    "The file "data/data.txt" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable."

    so I created a blank txt file in correct place. then I got
    "ArithmeticException: / by zero"
    presumably because the txt file is blank?

    any ideas on where i correct the code?
    joe stevens
    9 Oct 2011
    my mistake - have to be very careful with the caps, ie sometimes float & sometimes Float. Also applies to string, being String.

    thanks Diana all works good
    have to get my head around how it all pieces together ;)
    Diana Lange
    11 Oct 2011
    It is important to distinguish between the data type 'float' and the class 'Float'
    joe stevens
    19 Oct 2011
    great tutorial Diane, have been enjoying working on variables to visualize music. Now looking at the 2nd bit about translating audio data to a text file (numbers). Very curious to know how the numbers generated relate to the sound. IS it the frequency, the pitch, the sound level, or a mix ...
    joao fonseca
    29 Nov 2011
    Hi Joe!

    I'm having the same problems with the code that you had!

    "
    1st error was
    "The file "data/data.txt" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable."

    so I created a blank txt file in correct place. then I got
    "ArithmeticException: / by zero"
    presumably because the txt file is blank?
    "

    but i can't figure how to solve it. Perhaps you can help me.

    By the way great work Diana!

    thanks in advance
    João
    joe stevens
    30 Nov 2011
    Hi João
    u have to do the whole exercise. At the start Diane shows you how to turn the sound file into a text file. This file is then used for the 2nd part of the exercise.
    You need to login/register to comment.