Package com.meapsoft.visualizer

Source Code of com.meapsoft.visualizer.SingleFeatureWaveformPanel$Point

/*
*  Copyright 2006-2007 Columbia University.
*
*  This file is part of MEAPsoft.
*
*  MEAPsoft is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License version 2 as
*  published by the Free Software Foundation.
*
*  MEAPsoft is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with MEAPsoft; if not, write to the Free Software
*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
*  02110-1301 USA
*
*  See the file "COPYING" for the text of the license.
*/



package com.meapsoft.visualizer;

import gnu.getopt.Getopt;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JFrame;

import com.meapsoft.AudioReader;
import com.meapsoft.AudioReaderFactory;
import com.meapsoft.EDLFile;
import com.meapsoft.FeatChunk;
import com.meapsoft.FeatFile;
import com.meapsoft.MEAPUtil;

/**
*
* @author douglas@music.columbia.edu
*
*/

/*
* NOTE: this is broken and kinda stupid! See SpectrumPanel for details.
*
*/
public class SingleFeatureWaveformPanel extends SingleFeaturePanel
  private static final long serialVersionUID = 1L;
 
  Vector waveformPoints = new Vector();
  boolean waveformPointsValid = false;
 
  int totalNumSamples = 0;
 
  boolean updating = false;
 
  //2 means recompute spectrum every 2 zoom levels
  public int zoomLevelRecomputeMod = 2;
 
  static String pngFileName = null;
  boolean useBlack = false;

  public SingleFeatureWaveformPanel()
  {
    super();

    numDrawableFeatures = 1;
    setProgress(new DefaultBoundedRangeModel());
  }
 
  public SingleFeatureWaveformPanel(String[] args)
  {
    super();
   
    parseCommands(args);
    parseWaveformCommands(args);
   
    numDrawableFeatures = 1;
    setProgress(new DefaultBoundedRangeModel());
   
    String fileName = args[args.length - 1];
    FeatFile fF = null;
    EDLFile eF = null;
   
    String featName = "ChunkLength";//args[args.length-1];
   
    try
    {
      fF = new FeatFile(fileName);
      fF.readFile();
     
      if (edlFileName != null)
      {
        System.out.println("making EDLFile from " + edlFileName);
        eF = new EDLFile(edlFileName);
        eF.readFile();
      }
       
    }
    catch(Exception e)
    {
      e.printStackTrace();
      return;
    }

    if (initialize(fF, eF, featName) == -1)
    {
      System.out.println("hmm, something wrong, bailing.");
      return;
    }
   
    if (useBlack)
      this.setForegroundColor(Color.black);
   
    repaint();
   
    if (pngOutputFileName != null)
    {
      writeImageToPNG(pngOutputFileName);
      System.exit(0);
    }
  } 
  public String getDisplayType()
  {
    return "Waveform";
  }
 
  //we don't need a feature name for this since we're just doing the waveform.
  public int initialize(FeatFile featFile)
  {
    return initialize(featFile, null, "ChunkLength");
  }
 
  public int initialize(FeatFile featFile, String featureName)
  {
    return initialize(featFile, null, featureName);
  }

  public int initialize(FeatFile featFile, EDLFile edlFile, String featureName)
  {   
    this.featFile = featFile;
    this.featureName = featureName;
   
    highestValue = 0.0d;
    lowestValue = 0.0d;
    featureRange = 0.0;
    firstEventTime = 0.0;
    lastEventTime = 0.0;
    endTime = 0.0;
    timeRange = 0.0;
   
    totalNumSamples = 0;
   
    //System.out.println("initializing: " + featFile.filename);
   
    //check to see if our feature is in the input file
    featureNumber = featFile.getFeatureNumberForName(featureName);
      //verifyFeature(featureName);
    if (featureNumber == -1000)
    {
      System.out.println("hmm, I don't find that feature! Bye.");
      return -1;
    }
   
    featureSize = 1;   
   
    events = featFile.chunks;
 
    //extract feature data, find highest/lowest feature values
    numChunks = events.size();
   
    //System.out.println("numChunks: " + numChunks);
 
    double totalLength = 0.0;
   
   
    for (int i = 0; i < numChunks; i++)
    {     
      FeatChunk fC = (FeatChunk)events.get(i);
     
      if (fC.startTime < firstEventTime)
        firstEventTime = fC.startTime;
     
      if (fC.startTime > lastEventTime)
        lastEventTime = fC.startTime;
     
      if (fC.startTime + fC.length > endTime)
        endTime = fC.startTime + fC.length;
     
      totalLength += fC.length; 
     
    }
    timeRange = endTime - firstEventTime;

    //System.out.println("waveform sez: tR: " + timeRange +
    //    " eT: " + endTime +
    //    " fET: " + firstEventTime +
    //    " tR: " + timeRange);
   
//    System.out.println("fET: " + firstEventTime + " endTime: " + endTime + " timeRange: " + timeRange +
//        " totalLength: " + totalLength);

    //FeatChunk lastChunk = (FeatChunk)events.lastElement();
    //System.out.println("last change sT + length: " + (lastChunk.startTime + lastChunk.length));
   
    String fileNameParts[] = featFile.filename.split(slash);
    shortFileName = fileNameParts[fileNameParts.length - 1];

    initialized = true;
    return 1;
  }

  public void drawData(Graphics g)
  { 
    //don't draw if we don't have any points!
    if (!initialized)
    {
      System.out.println("can't draw, not initialized.");
      return;
    }
    //avoid concurrent modification exceptions when drawing overlaps with window switch
    else if (updating)
    {
      return;
    }
    //if we have data but we haven't collected waveformPoints yet...
    else if (initialized && waveformPoints.size() == 0)
    {
      //System.out.println("seems to be first time drawing, need to updateWaveformPoints...");
      updateWaveformPoints();
    }
   
    //System.out.println("redrawing at zoomLevel: " + zoomLevel);
    //what?  * 4/4 = 1!!! why are we doing this?
    double zoomMulti = (zoomLevel * 4.0)/4.0;
    int w = (int)(this.getWidth() * zoomMulti) - 1;
    int h = this.getHeight();
   
    g.setColor(bgColor);
    g.fillRect(0, 0, w, h);   
    g.setColor(fGColor);

    Iterator it = waveformPoints.iterator();

    double xIncr = (double)w/(double)waveformPoints.size();
    double x = 0.0;
    int xPrev = 0;
   
    //System.out.println("waveform panel seyz: zoomMulti: " + zoomMulti + " w: " + w + " h: " + h +
    //    " xIncr: " + xIncr);
   
    while (it.hasNext())
    {
      Point p = (Point)it.next();
      g.drawLine((int)x, p.yH, (int)x, p.yL);
     
      //take care of blank spots when xIncr > 1
      if ((int)x - xPrev > 1)
        g.drawLine((int)x - 1, p.yH, (int)x - 1, p.yL);

      xPrev = (int)x;
      x += xIncr;
    }
  }
 
  public void zoomIn()
  {
    super.zoomIn();
    if (this.zoomLevel % zoomLevelRecomputeMod == 1)
      updateWaveformPoints();
  }
 
  public void zoomOut()
  {
    super.zoomOut();
    if (this.zoomLevel % zoomLevelRecomputeMod == 1)
      updateWaveformPoints();
  }

  public void resetZoom()
  {
    super.resetZoom();
    updateWaveformPoints();
  }

  public void incrFirstChunkToDraw()
  {
    super.incrFirstChunkToDraw();
    updateWaveformPoints();
  }

  public void decrFirstChunkToDraw()
  {
    super.decrFirstChunkToDraw();
    updateWaveformPoints();
  }
 
  //just for consistency from superclass...
  public void updateData()
  {
    updateWaveformPoints();
  }
 
  public void updateWaveformPoints()
  {
    // TODO
    // HEY! This is broken for segment files that have more than one srcFile, you know?

    if (events.size() == 0)
    {
      //System.out.println("events.size() == 0, returning.");
      return;     
    }
    else if (this.getWidth() == 0)
    {
      //System.out.println("width == 0, returning.");
      return;
    }

    updating = true;
       
    waveformPoints = new Vector();
   
    double zoomMulti = (zoomLevel * 4.0)/4.0;
    int w = (int)(this.getWidth() * zoomMulti) - 1;
    int h = getHeight();
   
    //double xScaler = w/timeRange;
    double yScaler = h/2.0;
    FeatChunk fCTD = (FeatChunk)events.get(firstChunkToDraw);
    double localFirstEventTime = fCTD.startTime;
   
   
        // keep track of our progress:
        progress.setMinimum(0);
        progress.setMaximum(w);
        progress.setValue(0);
       

    // don't need hirez data for display...
    //AudioFormat format = new AudioFormat(8000, 8, 1, MEAPUtil.signed,
    //    MEAPUtil.bigEndian);
   
    //don't need hirez data for waveform display...
      AudioFormat format = new AudioFormat(8000, 16, 1, MEAPUtil.signed,
                                             MEAPUtil.bigEndian);
   
        AudioReader reader = null;
    try
    {
            //reader = new AudioReader(fCTD.srcFile, format);
            reader = AudioReaderFactory.getAudioReader(fCTD.srcFile, format);
    }
    catch (IOException e1)
    {
      e1.printStackTrace();
      return;
    }
    catch (UnsupportedAudioFileException e1)
    {
      e1.printStackTrace();
      return;
    }
   
    //double startTime = fC.startTime;   
   
        int frameSize = format.getFrameSize();
        double frameRate = (double)format.getFrameRate();
       
    long fileFrameLength = reader.getFrameLength();
    double fileTimeLength = ((double)fileFrameLength / frameRate);// / frameSize;
   
    int framesPerPixel = (int) Math.ceil((double)fileFrameLength/(double)w);
    double timePerPixel = ((double)framesPerPixel / frameRate);// / frameSize;

    firstEventTime = localFirstEventTime;
    timeRange = fileTimeLength - localFirstEventTime;
   
    //System.out.println("waveform seyz: timeRange: " + timeRange + " fileTL: " + fileTimeLength +
    //    " firstET: " + firstEventTime);
   
    //System.out.println("waveform seyz: frameSize: " + frameSize + " frameRate: " + frameRate +
    //    " fileFrameLength: " + fileFrameLength + " fileTimeLength: " + fileTimeLength +
    //    " framesPerPixel: " + framesPerPixel + " timePerPixel: " + timePerPixel + " w: " + w);

        try
        {
            // One sample per frame because we converted the file to mono.
            long n = reader.skipSamples((long)(localFirstEventTime * frameRate));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    int x = 0;
    while (x < w)
    {
      double[] samples = new double[framesPerPixel];
            //double[] samples = new double[100];
      try
      {
                int n = reader.readSamples(samples);
      }
      catch (Exception e)
      {
        e.printStackTrace();
      }
     
      int numSamps = samples.length;
     
      double highest = 0.0;
      double lowest = 0.0;
     
      for (int sampNum = 0; sampNum < numSamps; sampNum++)
      {
        double sample = samples[sampNum];
       
        if (sample > highest)
          highest = sample;
        else if (sample < lowest)
          lowest = sample;
      }
     
      int yL = (int)((lowest + 1.0) * yScaler);
      int yH = (int)((highest + 1.0) * yScaler);

      waveformPoints.add(new Point(yL, yH));
     
      x++;
     
      progress.setValue(progress.getValue()+1);
    }
   
    updating = false;
  }

    public void componentResized(ComponentEvent e)
    {
      //System.out.println(e.getComponent().getClass().getName() + " --- Resized ");
      updateWaveformPoints();
    }

  class Point
  {
    //int x;
    int yL;
    int yH;
   
    Point(int yL, int yH)
    {
      //this.x = x;
      this.yL = yL;
      this.yH = yH;
    }
  }

  /**
   * special waveform commands
   */
  public void parseWaveformCommands(String[] args)
  {
    String argString = "b";
    Getopt opt = new Getopt("SingleFeatureWaveformPanel", args, argString);
    opt.setOpterr(false);
   
    int c = -1;
    while ((c = opt.getopt()) != -1)
    { 
      if (c == 'b')
        useBlack = true;
    }
  }
 
  public static void printUsageAndExit()
  {
    System.out
        .println("Usage: SingleFeatureWaveformPanel [-options] featuresFile.feat \n\n"
            + "  where options include:\n"
            + getStandardUsage()
            + "\n    -b draw waveform in black (default is random pastel color)"
            );
    System.out.println();
    System.exit(0);
  }
 
  public static void main(String[] args)
  {
    //final String argArray[] = args;
   
    if (args.length < 1)
    {
      printUsageAndExit();
    }
   
    SingleFeatureWaveformPanel sFP = new SingleFeatureWaveformPanel(args);

    if (sFP.pngOutputFileName == null)
    {
      JFrame frame = new JFrame("SingleFeatureWaveformPanel");
      frame.setContentPane(sFP);
      frame.pack();
      //frame.setBounds(100, 100, 600, 400);
      frame.setVisible(true);
    }
  }
}
TOP

Related Classes of com.meapsoft.visualizer.SingleFeatureWaveformPanel$Point

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.