Main Page   Packages   Class Hierarchy   Compound List   File List   Compound Members  

SpectrogramPanel.java

00001 package com.meapsoft.gui;
00002 
00003 /*
00004  * Copyright 1999-2004 Carnegie Mellon University.  
00005  * Portions Copyright 2002-2004 Sun Microsystems, Inc.  
00006  * Portions Copyright 2002-2004 Mitsubishi Electric Research Laboratories.
00007  * All Rights Reserved.  Use is subject to license terms.
00008  * 
00009  * See the file "README" for information on usage and
00010  * redistribution of this file, and for a DISCLAIMER OF ALL 
00011  * WARRANTIES.
00012  *
00013  */
00014 
00015 /*
00016  * Extended for use in MEAPsoft by Ron Weiss (ronw@ee.columbia.edu).
00017  *
00018  * These modifications are Copyright 2006 Columbia University.
00019  */
00020 
00021 //package edu.cmu.sphinx.tools.audio;
00022 
00023 import java.awt.Color;
00024 import java.awt.Dimension;
00025 import java.awt.Graphics;
00026 import java.awt.Image;
00027 import java.awt.image.BufferedImage;
00028 import java.awt.image.FilteredImageSource;
00029 import java.awt.image.ImageFilter;
00030 import java.awt.image.ImageObserver;
00031 import java.awt.image.ReplicateScaleFilter;
00032 import java.util.Arrays;
00033 
00034 import javax.swing.JPanel;
00035 
00036 
00041 public class SpectrogramPanel extends JPanel {
00045     private BufferedImage spectrogram = null;
00046 
00050     private Image scaledSpectrogram = null;
00051 
00055     private float zoom = 1.0f;
00056     private float vzoom = 1.0f;
00057 
00062     private double offsetFactor;
00063 
00067     private double[][] data;
00068 
00069     private int width;
00070     private int height;
00071 
00072     private ColorMap cmap = ColorMap.getJet(64);
00073     //private static float minZoom = .1f;
00074     
00075     private double minVal; 
00076     private double maxVal; 
00077 
00081     public SpectrogramPanel(double[][] dat) {
00082         data = dat;
00083         width = dat.length;
00084         height = dat[0].length;
00085         //audio.addChangeListener(new ChangeListener() {
00086         //        public void stateChanged(ChangeEvent event) {
00087         //            computeSpectrogram();
00088         //        }
00089         //    });
00090         computeSpectrogram();
00091     }
00092 
00096     private void computeSpectrogram() {
00097         try {
00098             // prepare the data:
00099             maxVal = 0;
00100             minVal = Integer.MAX_VALUE;
00101             for(int x = 0; x < width; x++)
00102             {
00103                 for(int y = 0; y < height; y++)
00104                 {
00105                     if (data[x][y] > maxVal) 
00106                         maxVal = data[x][y];
00107                     if (data[x][y] < minVal)
00108                         minVal = data[x][y];
00109                 }
00110             }
00111             double minIntensity = Math.abs(minVal);
00112             double maxIntensity = maxVal + minIntensity;
00113 
00114             int maxYIndex = height - 1;
00115             Dimension d = new Dimension(width, height);
00116         
00117             setMinimumSize(d);
00118             setMaximumSize(d);        
00119             setPreferredSize(d);
00120 
00121             /* Create the image for displaying the data.
00122              */
00123             spectrogram = new BufferedImage(width,
00124                                             height,
00125                                             BufferedImage.TYPE_INT_RGB);
00126             
00127             /* Set scaleFactor so that the maximum value, after removing
00128              * the offset, will be 0xff.
00129              */
00130             double scaleFactor = ((0x3f + offsetFactor) / maxIntensity);
00131             
00132             for (int i = 0; i < width; i++) {                
00133                 for (int j = maxYIndex; j >= 0; j--) {
00134                     
00135                     /* Adjust the grey value to make a value of 0 to mean
00136                      * white and a value of 0xff to mean black.
00137                      */
00138                     int grey = (int)((data[i][j] + minIntensity) * scaleFactor
00139                                       - offsetFactor);
00140                     //System.out.println(grey);
00141                     
00142                     // use grey as an index into the colormap;
00143                     spectrogram.setRGB(i, maxYIndex - j, cmap.getColor(grey));
00144                 }
00145             }
00146 
00147             ImageFilter scaleFilter = 
00148                 new ReplicateScaleFilter((int) (zoom * width), (int)(vzoom*height));
00149             scaledSpectrogram = 
00150                 createImage(new FilteredImageSource(spectrogram.getSource(),
00151                                                     scaleFilter));
00152             Dimension sz = getSize();
00153             repaint(0, 0, 0, sz.width - 1, sz.height - 1);
00154         } catch (Exception e) {
00155             e.printStackTrace();
00156         }
00157     }
00158 
00168     public void setOffsetFactor(double offsetFactor) {
00169         this.offsetFactor = offsetFactor;
00170         computeSpectrogram();
00171     }
00172 
00177     protected void vzoomSet(float vzoom) {
00178         this.vzoom = vzoom;
00179         zoom();
00180     }
00181 
00186     protected void hzoomSet(float zoom) {
00187         zoomSet(zoom);
00188     }
00189 
00194     protected void zoomSet(float zoom) {
00195         this.zoom = zoom;
00196         zoom();
00197     }
00198 
00199     private void zoom()
00200     {
00201         if (spectrogram != null) 
00202         {
00203             int width = spectrogram.getWidth();
00204             int height = spectrogram.getHeight();
00205             
00206             // do the zooming
00207             width = (int) (zoom * width);
00208             height = (int)(vzoom*height);
00209 
00210             ImageFilter scaleFilter = 
00211                 new ReplicateScaleFilter(width, height);
00212             scaledSpectrogram = 
00213                 createImage(new FilteredImageSource(spectrogram.getSource(),
00214                                                     scaleFilter));
00215 
00216             // so ScrollPane gets notified of the new size:
00217             setPreferredSize(new Dimension(width, height));
00218             revalidate();
00219             
00220             repaint();
00221         }
00222     }
00223 
00224     public float getVZoom()
00225     {
00226         return vzoom;
00227     }
00228 
00229     public float getHZoom()
00230     {
00231         return zoom;
00232     }
00233     
00234     public SpectrogramPanel getColorBar()
00235     {
00236         int barWidth = 20;
00237         
00238         double[][] cb = new double[barWidth][cmap.size];
00239 
00240         for(int x = 0; x < cb.length; x++)
00241             for(int y = 0; y < cb[x].length; y++) 
00242                 cb[x][y] = y;
00243 
00244         return new SpectrogramPanel(cb);
00245     }
00246 
00247     public double getData(int x, int y)
00248     {
00249         return data[x][y];
00250     }
00251 
00252     public int getDataWidth()
00253     {
00254         return width;
00255     }
00256 
00257     public int getDataHeight()
00258     {
00259         return height;
00260     }
00261 
00262 
00268     public void paint(Graphics g) {
00272         Dimension sz = getSize();
00273 
00274         g.setColor(Color.WHITE);
00275         g.fillRect(0, 0, sz.width - 1, sz.height - 1);
00276     
00277         if(spectrogram != null) {
00278             g.drawImage(scaledSpectrogram, 0, 0, (ImageObserver) null);
00279         }
00280     }
00281 }

Generated on Tue Feb 6 19:02:27 2007 for MEAPsoft by doxygen1.2.18