Package com.meapsoft.visualizer

Source Code of com.meapsoft.visualizer.SingleFeatureSpectrumPanel

/*
*  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 java.awt.Graphics;
import java.awt.event.ComponentEvent;
import java.io.IOException;
import java.util.List;
import java.util.Vector;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

import com.meapsoft.AudioReader;
import com.meapsoft.AudioReaderFactory;
import com.meapsoft.EDLFile;
import com.meapsoft.FeatChunk;
import com.meapsoft.FeatExtractor;
import com.meapsoft.FeatFile;
import com.meapsoft.MEAPUtil;
import com.meapsoft.featextractors.AvgMelSpec;

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


/*
*
* NOTE: this one is weird! It ignores the chunks and just reads from the soundfile.
* This is a bad idea! It doesn't work if there are multiple src files,
* and it can't display the spectrum in EDL order. Bah!
*
*/
public class SingleFeatureSpectrumPanel extends SingleFeatureColorBarsPanel
{
  private static final long serialVersionUID = 1L;

  List shortEvents = new Vector();

  int numShortChunks = 0;

  boolean updating = false;

  // 2 means recompute waveform every 2 zoom levels
  public int zoomLevelRecomputeMod = 2;

  public SingleFeatureSpectrumPanel()
  {
    numDrawableFeatures = -1;
  }

  public SingleFeatureSpectrumPanel(String[] args)
  {
    super();
   
    parseCommands(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;
    }
   
    repaint();
   
    if (pngOutputFileName != null)
    {
      writeImageToPNG(pngOutputFileName);
      System.exit(0);
    }
  }

  public String getDisplayType()
  {
    return "Spectrum";
  }


  //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");
  }

  // override initialize for special spectrum weirdness
  public int initialize(FeatFile featFile, 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;

    featureSize = 1;

    events = featFile.chunks;

    // extract feature data, find highest/lowest feature values
    numChunks = events.size();
    // numChunks = featFile.chunks.size();

    for (int i = 0; i < numChunks; i++)
    {
      for (int j = 0; j < featureSize; j++)
      {
        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;
      }
    }

    featureRange = 1.0;// highestValue - lowestValue;
    timeRange = endTime - firstEventTime;

    String fileNameParts[] = featFile.filename.split(slash);
    shortFileName = fileNameParts[fileNameParts.length - 1];

    initialized = true;

    return 1;
  }
 
  public void zoomIn()
  {
    super.zoomIn();
    if (this.zoomLevel % zoomLevelRecomputeMod == 1)
      updateSpectra();
  }

  public void zoomOut()
  {
    super.zoomOut();
    if (this.zoomLevel % zoomLevelRecomputeMod == 1)
      updateSpectra();
  }

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

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

  public void decrFirstChunkToDraw()
  {
    super.decrFirstChunkToDraw();
    updateSpectra();
  }

  // just for consistency from superclass...
  public void updateData()
  {
    updateSpectra();
  }

  public void updateSpectra()
  {
    // 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;

    double zoomMulti = (zoomLevel * 4.0) / 4.0;
    int w = (int) (this.getWidth() * zoomMulti) - 1;
    FeatChunk fCTD = (FeatChunk) events.get(firstChunkToDraw);
    double localFirstEventTime = fCTD.startTime;

    AudioReader reader = null;

    // don't need hirez data for display...
    AudioFormat format = new AudioFormat(8000, 16, 1, MEAPUtil.signed,
        MEAPUtil.bigEndian);

    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;
    }

    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("spectrum seyz: timeRange: " + timeRange + " fileTL: " + fileTimeLength +
    //    " firstET: " + firstEventTime);
   
    //System.out.println("spectrum seyz: frameSize: " + frameSize + " frameRate: " + frameRate +
      //  " fileFrameLength: " + fileFrameLength + " fileTimeLength: " + fileTimeLength +
      //  " framesPerPixel: " + framesPerPixel + " timePerPixel: " + timePerPixel + " w: " + w);
   
    FeatFile fF = new FeatFile("small_chunks_temp.feat");

    double currTime = localFirstEventTime;
    String srcFileName = fCTD.srcFile;

    for (int x = 0; x < w; x++)
    {
      FeatChunk fC = new FeatChunk(srcFileName, currTime, timePerPixel, null);
      fF.chunks.add(fC);
      currTime += timePerPixel;
    }

    try
    {
      fF.writeFile();
    }
    catch (IOException e1)
    {
      e1.printStackTrace();
    }

    Vector extractors = new Vector();
    extractors.add(new AvgMelSpec());

    FeatFile spectrumFeats = new FeatFile("temp.feat");

    FeatExtractor fE = new FeatExtractor(fF, spectrumFeats, extractors);

    fE.setProgress(progress);

    try
    {
      fE.setup();
      fE.processFeatFiles();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    int elementsPerFeature[] = { 0 };

    elementsPerFeature = spectrumFeats.getFeatureLengths();
    featureSize = elementsPerFeature[0];

    featureNumber = 0;

    shortEvents = spectrumFeats.chunks;
    numShortChunks = shortEvents.size();

    for (int i = 0; i < numShortChunks; i++)
    {
      for (int j = 0; j < featureSize; j++)
      {
        FeatChunk fC = (FeatChunk) shortEvents.get(i);
        int[] dim = { featureNumber + j };
        double feature = fC.getFeatures(dim)[0];

        if (feature < lowestValue)
          lowestValue = feature;

        if (feature > highestValue)
          highestValue = feature;
      }
    }

    featureRange = highestValue - lowestValue;

    updating = false;
  }

  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;
    }
    else if (updating)
    {
      return;
    }
    // if we have data but we haven't collected waveformPoints yet...
    else if (initialized && shortEvents.size() == 0)
    {
      // System.out.println("seems to be first time drawing, need to
      // update spectra...");
      updateSpectra();
    }

    double zoomMulti = (zoomLevel * 4.0) / 4.0;
    int w = (int) (this.getWidth() * zoomMulti) - 1;
    int h = this.getHeight();

    double xScaler = w / timeRange;

    g.setColor(bgColor);
    g.fillRect(0, 0, w, h);

    double yIncr = (double) h / featureSize;

    double localFirstEventTime = ((FeatChunk) events
        .get(firstChunkToDraw)).startTime;
   
    //System.out.println("spectrum panel seyz: zoomMulti: " + zoomMulti + " w: " + w + " h: " + h +
      //  " xScaler: " + xScaler + " yIncr: " + yIncr);

    int x = 0;
    for (int i = firstChunkToDraw; i < numShortChunks && x < getWidth(); i++)
    {
      FeatChunk fC = (FeatChunk) shortEvents.get(i);
      x = (int) ((fC.startTime - localFirstEventTime) * xScaler);
      int width = (int) (fC.length * xScaler) + 1;

      //System.out.println("spectrum: x: " + x);
      // adjust to zero
      double dataPoints[] = fC.getFeatures();// featureData[i];
      // System.out.println("dataPoints.length: " + dataPoints.length);

      for (int j = 1; j < featureSize + 1; j++)
      {
        double dataPoint = dataPoints[j - 1] - lowestValue;
        double colorIndex = (dataPoint / featureRange) * 255.0;
        double y = j * yIncr;
        // System.out.println("i: " + i + " j: " + j + " x: " + x + " y:
        // " + y + " h: " + h + " yIncr: " + yIncr);
        // System.out.println("x: " + x + " y: " + y + "cI: " +
        // colorIndex);
        // try
        // {
        g.setColor(colormap.table[(int) colorIndex]);
        /*
         * } catch (Exception e) { e.printStackTrace();
         * System.out.println("j: " + j + " x: " + x + " y: " + y + "
         * cI: " + colorIndex); System.out.println("dataPoints[j - 1]: " +
         * dataPoints[j - 1]); System.out.println("lowestValue: " +
         * lowestValue + " highestValue: " + highestValue + "
         * featureRange: " + featureRange); return; }
         */
        g.fillRect(x, h - (int) (y), width, (int) yIncr + 1);
      }
    }
  }

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

  public static void printUsageAndExit()
  {
    System.out
        .println("Usage: SingleFeatureSpectrumPanel [-options] features.feat \n\n"
            + "  where options include:\n"
            + getStandardUsage()
            );
    System.out.println();
    System.exit(0);
  }
 
  public static void main(String[] args)
  {
    //final String argArray[] = args;
   
    if (args.length < 1)
    {
      printUsageAndExit();
    }
   
    SingleFeatureSpectrumPanel sFP = new SingleFeatureSpectrumPanel(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.SingleFeatureSpectrumPanel

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.