// file: $ISIP_IFC/class/java/SpeechDisplay/SpeechDisplay.java
// version: $Id: SpeechDisplay.java 10573 2006-06-28 16:03:42Z rei5 $
//

// import necessary java libraries
//
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.net.*;
import java.io.*;
import java.awt.font.*;
import java.awt.geom.*;
import javax.swing.*;
import java.text.DecimalFormat;
import javax.swing.*;
import java.util.Random;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
import java.lang.Number;
import static java.lang.Math.*;
import java.lang.Math;


/**
 * class: SpeechDisplay.java
 *
 * This class is used to build a base class for displaying speech
 * signal.
 *
 * hierarchy: JPanel->SpeechDisplay
*/
public class SpeechDisplay extends JPanel implements Runnable {
    
    //-------------------------------------------------------------------------
    //
    // public constants
    //
    //-------------------------------------------------------------------------

    /** 
     * Default canvas width.
     */
    public static final int WM_CANVAS_WIDTH = 650;

    /**
     * Default canvas height.
     */
    public static final int WM_CANVAS_HEIGHT = 280;  

    /**
     * Allowance for display percentage
     */
    public static final float ALLOWANCE = (float)0.1;

    /** 
     * Default pixel duration in second
     */
    public static final float WM_DEFAULT_PIXEL_DURATION = (float)0.01;

    /** 
     * Default window length in seconds
     */
    public static final float WM_DEFAULT_WINDOW_DURATION = (float)0.006;
    
    /** 
     * Default hamming coeff
     */
    public static final double WM_DEFAULT_HAMMING_COEFF = 0.54;

    /**
     * Default RMS.
     */
    public static final double WM_DEFAULT_RMS = 1.0;

    /**
     * Default minimum energy amplitude.
     */
    public static final double WM_ENERGY_MIN_AMPLITUDE = 0.0;

    /**
     * Default maximum energy amplitude.
     */
    public static final double WM_ENERGY_MAX_AMPLITUDE = 9.03;

    /**
     * Default minimum energy value.
     */
    public static final double WM_ENERGY_MIN_VALUE = 1.0;

    /**
     * Default minimum energy amplitude.
     */
    public static final double WM_SPECTROGRAM_MIN_AMPLITUDE = 0.0;

    /**
     * Default maximum energy amplitude.
     */
    public static final double WM_SPECTROGRAM_MAX_AMPLITUDE = 9.03;

    /**
     * Default minimum energy value.
     */
    public static final double WM_SPECTROGRAM_MIN_VALUE = 1.0;

    /**
     * Default buffer size.
     */
    public static final int WM_DEFAULT_BUFFER_SIZE = 32000;

    /** 
     * Default resolution scale.
     */
    public static final int WM_DEFAULT_RES_SCALE = 2;

    /**
     * Preemphasis coefficient.
     */
    public static final float WM_DEFAULT_PREMP_COEFF = (float)1.0;

    /**
     * A value for log10(e).
     */
    public static final double WM_ENERGY_LOG10_E = 0.4342944819;

    /**
     * A value for log10(e).
     */
    public static final double WM_SPECTROGRAM_LOG10_E = 0.4342944819;

    /**
     * Default value for number of fft points.
     */
    public static final int WM_DEFAULT_FFT_POINTS = 512; 

    /**
     * Default maximum amplitude for waveform (2^^15). 
     */
    public static final int MAXIMUM_AMPLITUDE = 32767;

    /**
     * Default minimum amplitude for waveform (-(2^^15)-1).
     */
    public static final int MINIMUM_AMPLITUDE = -32768;

    /**
     * Default normalization amplitude (2^^15).
     */
    public static final int NORMALIZATION_AMPLITUDE = 32767;

    /**
     * Default Font used to write string in the display.
     */
    public static Font font = new Font("Times New Roman", Font.PLAIN, 11);

    /**
     * The color defined for graph color.
     */
    public Color GRAPH_COLOR = new Color(205, 221, 246);

    /**
     * The color defined for displaying. 
     */
    public Color MF_COLOR = new Color(45,66,97);

     /**
     * The color defined for displaying the text. 
     */   
    public Color TEXT_COLOR = new Color(205,221,246);
    
    /**
     * The color defined for signal plot.
     */
    public Color SIGNAL_COLOR = new Color(237, 237, 50);
   
    /**
     * The color defined for signal plot.
     */
    public Color SPEC_SIGNAL_COLOR = new Color(130, 192, 255);
       
    /**
     * The color defined for dotted grid.
     */
    public Color GRID_COLOR = new Color(205,221,246);

    /**
     * The fft length
     */
    public int fftLength = 2;  
    
    /**
     * The array for waveform values in realtime mode
     */ 
    public float[] realtime_waveform;
    
    /**
     * The array for waveform values in overall mode
     */ 
    public float[] overall_waveform;

    /** 
     * the colormap type
     */
    public static final int GRAYSCALE = 0;
    
    /** 
     * the colormap type
     */
    public static final int MATLAB = 1;
    
    /** 
     * the colormap type
     */
    public static final int TI = 2;

    /** 
     *  variable to indicate resizing
     */
    public int RESIZED = 0;
    
    /**
     * grayscale map by default
     */
    public int colormap_type = 1;
    
    /**
     * the log of windowduration/sampling frequency
     */
    public float log_nt = 0;
    
    /**
     * contrast value
     */
    public float contrast_d = (float) 0.5;
    
    /**
     * brightness
     */
    public float brightness_d = (float)0.5;

    /**
     * maximum spectral value (dB)
     */
    public float max_spectral_magnitude = 60;
    
    /**
     * minimum spectral value (db)
     */
    public float min_spectral_magnitude = 20;
    
    /**
     * maximum frequency (Hz)
     */
    public float maximum_frequency;
    
    /**
     * minimum frequency (Hz)
     */
    public float minimum_frequency;
    
    /**
     * weighted maximum spectral value (dB)
     */
    public float weighted_max_spectral_magnitude = 0;
    
    /**
     * weighted minimum spectral value (dB)
     */
    public float weighted_min_spectral_magnitude = 0;
    
    /**
     * variable used while normalising the pdf of the spectral
     * magnitudes
     */
    public int num_points = 0;
    
    /**
     *  pdf and the cdf arrays of the spectral magnitudes
     */
    public float pdf_array[] = new float [151];
    public float cdf_array[] = new float [151];
    
    //------------------------------------------------------------------------
    //
    // protected data
    //
    //------------------------------------------------------------------------
    
    /**
     * Default boundary for each subplot.
     */
    protected int boundary = 20;
    
    /**
     * X offset from left side in x-axis.
     */
    protected int x_offset_d = 60;

    /**
     * Y offset from top side in y-axis.
     */
    protected int y_offset_d = 5;
    
    /**
     * An array to hold all the real time energy values to be plotted.
     */
    protected float realtime_energy_d[];
    
    /**
     * An array to hold all the real time energy values to be plotted.
     */
    protected int  spectrogram_color_array[][];
    
    /**
     * An array to hold the overall energy in x-axis values to be
     * plotted.
     */
    protected int overall_energy_x_d[];

    /**
     * An array to hold the overall energy in y-axis values to be
     * plotted.
     */
    protected int overall_energy_y_d[];

    /**
     * An array to hold the overall spectrogram in x-axis values to be
     * plotted.
     */
    protected int overall_spectrogram_x_d[];

    /**
     * An array to hold the overall spectrogram in y-axis values to be
     * plotted.
     */
    protected double overall_spectrogram_y_d[][];

    /**
     * An array to hold the waveform maximum values to be plotted.
     */
    protected float realtime_waveform_max[];
    
    /**
     * An array to hold the waveform minimum values to be plotted.
     */
    protected float realtime_waveform_min[];
   
    /**
     * The total energy points plotted.
     */
    protected int pts_received_energy_d = 0;
    
    /**
     * The total waveform points plotted.
     */
    protected int pts_received_waveform_d = 0;
    
    /**
     * The total spectrogram points plotted.
     */
    protected int pts_received_spectrogram_d = 0;
    
    /**
     * X coordinate of waveform points.
     */
    protected int pts_waveform_x_d[];

    /**
     * Y coordinate of waveform points.
     */
    protected int pts_waveform_y_d[];

    /**
     * X coordinate of waveform points.
     */
    protected int realtime_waveform_x_d[];
    
    /**
     * Y coordinate of waveform points.
     */
    protected float realtime_waveform_y_d[];

    /**
     * An Array to hold the number of samples in each update.
     */
    protected int number_of_samples_d[];

    /**
     * Updated number of data.
     */
    protected int number_updated_data_d = 0;

    /**
     * The current display data.
     */
    protected int current_display_data_d = 0;

    /**
     * Number of data processed up to now.
     */
    protected int number_processed_d = 0;

    /**
     * Number of samples data processed.
     */
    protected int data_processed_d = 0;

    /**
     * Preemphasis coefficient for filter.
     */
    protected float preemph_coef_d;

    /**
     * Window duration in second.
     * Needs to be removed.
     */
    protected float window_duration_d;
    
    /**
     * Window duration in second for energy.
     */
    protected float energy_window_duration_d;
    
    /**
     * Window duration in second for spectrogram.
     */
    protected float spectrogram_window_duration_d;

    /**
     * Pixel duration in second.
     */
    protected float pixel_duration_d;

    /**
     * Window width to display speech signal.
     */
    protected int width_d = 900;

    /**
     * Window height to display speech signal
     */
    protected int  height_d;

    /**
     * Number of seconds to display during realtime given via user.
     */
    protected double user_seconds_d = 3.0;

    /**
     * Bufferimage object to draw the plot.
     */
    protected BufferedImage bimg_d;

    /** 
     * Graphics2D object to plot.
     */
    protected Graphics2D big_d;

    /**
     * Accumulated sample up to now.
     */
    protected int accum_num_samples_d = 0;

    /**
     * Display mode either real time or overall.
     */
    protected boolean realtime_d = true;

    /**
     * The number of samples played or recorded per second.
     */
    protected float sample_rate_d = 16000;

    /**
     * Rectangle2D for displaying rectangle.
     */
    protected Rectangle2D mfRect = new Rectangle2D.Float();

    /**
     * Rectangle2D for displaying the rectangle
     */
    protected Rectangle2D muRect = new Rectangle2D.Float();

    /**
     * An array to store accumulated data points.
     */
    protected float[] accum_points_d; 

    /**
     * The size of the accumulate buffer
     */
    protected int  accum_array_size = (int)(sample_rate_d*user_seconds_d);

    /**
     * Saved overall data points.
     */
    public float[] overall_samples_d; 

    /**
     * Saved realtime data points.
     */
    public float[] realtime_samples_d; 

    /**
     * Energy component height.
     */
    protected int energy_height_d;

    /**
     * Waveform component height.
     */
    protected int waveform_height_d;

    /**
     * Spectrogram component height.
     */
    protected int spectrogram_height_d;

    /**
     * Energy component height.
     */
    protected float energy_percentage_d;

    /**
     * Waveform component height.
     */
    protected float waveform_percentage_d;

    /**
     * Spectrogram component height.
     */
    protected float spectrogram_percentage_d;

    /**
     * X-coordinate for energy display left top point.
     */
    protected int energy_x_d;

    /**
     * Y-coordinate for energy display left top point.
     */
    protected int energy_y_d;

    /**
     * X-coordinate for waveform display left top point.
     */
    protected int waveform_x_d;

    /**
     * Y-coordinate for waveform display left top point.
     */
    protected int waveform_y_d;

    /**
     * X-coordinate for spectrogram display left top point.
     */
    protected int spectrogram_x_d;

    /**
     * Y-coordinate for spectrogram display left top point.
     */
    protected int spectrogram_y_d;

    /**
     * The font ascent of the Font.
     */
    protected int ascent_d;

    /**
     * The font descent of the Font.
     */
    protected int descent_d;

    /**
     * Maximum amplitude in waveform calculation.
     */
    protected float max_ampl_d = 0;

    /**
     * Maximum points to display volume.
     */
    protected int energy_plot_max_points_d = 0;
  
    /**
     * Position to display volume.
     */
    protected int energy_plot_begin_d = 0;

    /**
     * Flag to indicate new data is available when it is true.
     */
    protected boolean refreshed = true;

    /**
     * Flag to indicate new data is available when it is true.
     */
    protected boolean samples_greater_than_pixels = true;
    
    /**
     * Sample data left from last processing
     */
    protected int left_samples_d = 0;

    /**
     * Maximum value for energy.
     */
    protected float maximum_energy_d;

    /**
     * Minimum value for energy.
     */
    protected float minimum_energy_d;

    /**
     * Maximum value for waveform.
     */
    protected float maximum_waveform_d;

    /**
     * Minimum value for waveform.
     */
    protected float minimum_waveform_d;
    
    /**
     * Maximum value for Spectrogram.
     */
    protected float maximum_spectrogram_d = 4000;  // To be changed as frequency later 
    
    /**
     * Minimum value for Spectrogram.
     */
    protected float minimum_spectrogram_d = 0;  // To be changed as frequency later 

    /**
     * Super tick mark for energy.
     */
    protected float e_super_tick_d;

    /**
     * Major tick mark for energy.
     */
    protected float e_major_tick_d;

    /**
     * Minor tick mark for energy.
     */
    protected float e_minor_tick_d;

    /**
     * Vertical tick mark for energy.
     */
    protected float e_vertical_tick_d;

    /**
     * Super tick mark for waveform.
     */
    protected float w_super_tick_d;

    /**
     * Major tick mark for waveform.
     */
    protected float w_major_tick_d;

    /**
     * Minor tick mark for waveform.
     */
    protected float w_minor_tick_d;

    /**
     * Super tick mark for energy.
     */
    protected float s_super_tick_d;

    /**
     * Major tick mark for energy.
     */
    protected float s_major_tick_d;

    /**
     * Minor tick mark for energy.
     */
    protected float s_minor_tick_d;

    /**
     * Vertical tick mark for energy.
     */
    protected float s_vertical_tick_d;

    /**
     * Start time tick.
     */
    protected float start_tick_d;

    /**
     * End time tick.
     */
    protected float end_tick_d;

    /**
     * Scale for energy.
     */
    protected String escale_d;

    /**
     * Scale for spectrogram.
     */
    protected String sscale_d;

    /**
     * Window type.
     */
    protected String window_type_d;

    /**
     * Gain for waveform.
     */
    protected float gain_d;

    /**
     * Number of fft points 
     */
    protected float fft_num_d ;

    /**
     * Stroke use to draw a grid
     */
    protected  BasicStroke bs[] = new BasicStroke[6];
    
    /**
     * read pointer for the energy, waveform, spectrogram buffer.
     */
    protected int read_pointer = 0;

    /**
     * flag to set circule buffer status
     */
    protected int circular_flag_d = 0;
    

    //-------------------------------------------------------------------------
    //
    // public methods
    //
    //-------------------------------------------------------------------------
       
    /**
     * Class constructors.
     */        
    public SpeechDisplay() {

	// set the background color of the jframe
	//
	setBackground(Color.black);
	
	// initilaise the accum array
	//
	accum_points_d = new float[accum_array_size];
	
	// initialise the array that has all the data points
	//
	for (int i = 0; i < accum_array_size; i++) {
	    accum_points_d[i] = 0;
	}
	
	// assign to default values for those variables
	//
	preemph_coef_d = WM_DEFAULT_PREMP_COEFF;
	pixel_duration_d = WM_DEFAULT_PIXEL_DURATION;
	window_duration_d = WM_DEFAULT_WINDOW_DURATION;
	energy_window_duration_d = WM_DEFAULT_WINDOW_DURATION;
	spectrogram_window_duration_d = WM_DEFAULT_WINDOW_DURATION;
	fft_num_d = WM_DEFAULT_FFT_POINTS; 
	
	// reset the variables in constructors
	//
	data_processed_d = 0;
	number_processed_d = 0;
	current_display_data_d = 1;

        // set the basic attributes for the outlines of widget
	//
	float j = 1.1f;
        for (int i = 0; i < bs.length; i++, j += 1.0f) {
            float dash[] = { j };
            bs[i] = new BasicStroke(1.0f, BasicStroke.CAP_BUTT, 
				    BasicStroke.JOIN_MITER, 
				    10.0f, dash, 0.0f);
        }

	// initial super tick mark for energy
	//
	e_super_tick_d = 1.0f;

	// initial major tick mark for energy
	//
	e_major_tick_d = 0.2f;

	// initial minor tick mark for energy
	//
	e_minor_tick_d = 0.1f;

	// set vertical tick for energy
	//
	e_vertical_tick_d = 10;
	
	// initial tick marks for waveform
	//
	w_super_tick_d = 1.0f;
	w_major_tick_d = 0.2f;
	w_minor_tick_d = 0.1f;
	
	// initial tick marks for sectrogram
	//
	s_super_tick_d = 1.0f;
	s_major_tick_d = 0.2f;
	s_minor_tick_d = 0.1f;

	s_vertical_tick_d = 10;

	// assign to default values for the variables
	//
	maximum_waveform_d = MAXIMUM_AMPLITUDE;
	minimum_waveform_d = MINIMUM_AMPLITUDE;

	maximum_energy_d = 100.0f;
	minimum_energy_d = 0.0f;

	maximum_spectrogram_d = 4000.0f;
	minimum_spectrogram_d = 0.0f;

	// initial the gain value for waveform
	//
	gain_d = 1.0f;

	// set start and end tick value
	//
	start_tick_d = 0.0F;
	end_tick_d = 0.0F;

	// set scale for energy and spectrogram
	//
	escale_d = "dB";
	sscale_d = "Hz";

	// set layout
	//
        setLayout(new BorderLayout());
	setPreferredSize(new Dimension(WM_CANVAS_WIDTH, WM_CANVAS_HEIGHT));
    }
   
    /** 
     * User can call this method to repaint the graph.
     */
    public void run() {

	if (!refreshed)
	    return;

	// update the plot
	//
	repaint();
    }
    
    //-------------------------------------------------------------------------
    //
    // class-specific public methods:
    //  set methods
    //
    //-------------------------------------------------------------------------

    /** 
     * This method is used to set the sample rate.
     *
     * @param rate_a the sample rate. 
     *
     * @return a boolean value indicating status.
     **/
    public boolean setSampleRate(int rate_a) {
	
	sample_rate_d = rate_a;

	// reinitialise all the buffers
	//
	accum_array_size = (int)(sample_rate_d * user_seconds_d);
	
	// initialize the data fields
	//
	accum_points_d = new float[accum_array_size];
	
	// initialise the array that has all the data points
	//
	for (int i = 0; i < accum_array_size; i++) {
	    accum_points_d[i] = 0;
	}

	// exit gracefully
	//
	return true;
    }


    /**
     * This method is used to set the mode of display. There are two modes in the demo: real time and overall.
     *
     * @param realtime_a a boolean value to indicate if the mode is
     * real time or not.
     *
     * @return a boolean value indicating status.
     **/
    public boolean setMode(boolean realtime_a) {
	
	// set the mode
	//
	realtime_d = realtime_a;

	// set the status as the new data is available
	//
	refreshed = true;	
	
	// exit gracefully
	//
	return true;
    }
    
    
    /**
     * Method to set the preemphasis coefficient.
     *
     * @param preemph_coef_a a float value represents the preemphasis
     * coefficient.
     *
     * @return a boolean value indicating status.
     **/
    public boolean setPreemphCoef(float preemph_coef_a) {
	
	// set the preemphasis coefficient
	//
	preemph_coef_d = preemph_coef_a;
	
	// exit gracefully
	//
	return true;
    }


    /**
     * Method to set the pixel duration in seconds
     *
     * @param pixel_duration_a a float value represents the pixel
     * duration in seconds
     *
     * @return a boolean value indicating status.
     **/
    public boolean setPixelDuration(float pixel_duration_a) {

	// set the pixel duration
	//
	pixel_duration_d = pixel_duration_a;

	// exit gracefully
	//
	return true;
    }

    /**
     * Method to set the window duration in seconds.
     *
     * @param window_duration_a a float value represents the window
     * duration in seconds.
     *
     * @return a boolean value indicating status.
     **/
    public boolean setEnergyWindowDuration(float window_duration_a) {

	energy_window_duration_d = window_duration_a;

	// exit gracefully
	//
	return true;
    }

    /**
     * Method to set the window duration in seconds.
     *
     * @param window_duration_a a float value represents the window
     * duration in seconds.
     *
     * @return a boolean value indicating status.
     **/
    public boolean setSpecWindowDuration(float window_duration_a) {

	spectrogram_window_duration_d = window_duration_a;

	// exit gracefully
	//
	return true;
    }
    

    /**
     * Method to set maximum energy value.
     *
     * @param maximum_energy_a a float value represents the maximum
     * energy.
     *
     * @return a boolean value indicating status.
     **/
    public boolean setMaximumEnergy(float maximum_energy_a) {
	
	maximum_energy_d = maximum_energy_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set minimum energy value.
     *
     * @param minimum_energy_a a float value represents the minimum
     * energy.
     *
     * @return a boolean value indicating status.
     **/
    public boolean setMinimumEnergy(float minimum_energy_a) {
	
	minimum_energy_d = minimum_energy_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set maximum waveform value.
     *
     * @param maximum_waveform_a a float value represents the maximum
     * waveform.
     *
     * @return a boolean value indicating status.
     */
    public boolean setMaximumWaveform(float maximum_waveform_a) {
	
	maximum_waveform_d = maximum_waveform_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set minimum waveform value.
     *
     * @param minimum_waveform_a a float value represents the minimum
     * waveform.
     *
     * @return a boolean value indicating status.
     */
    public boolean setMinimumWaveform(float minimum_waveform_a) {
	
	minimum_waveform_d = minimum_waveform_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set maximum Spectrogram value.
     *
     * @param maximum_spectrogram_a a float value represents the maximum
     * spectrogram.
     *
     * @return a boolean value indicating status.
     */
    public boolean setMaximumSpectrogram(float maximum_spectrogram_a) {
	
	maximum_spectrogram_d = maximum_spectrogram_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set maximum magnitude value
     *
     * @param  max_spectral_magnitude_a  a float value represents the maximum
     * spectral value.
     *
     * @return a boolean value indicating status.
     */
    public boolean setMaximumMagnitude(float max_spectral_magnitude_a) {
	
	max_spectral_magnitude = max_spectral_magnitude_a;
	
	// exit gracefully
	//
	return true;
    }  

    
    /**
     * Method to set minimum magnitude value
     *
     * @param  min_spectral_magnitude_a  a float value represents the minimum
     * spectral value.
     *
     * @return a boolean value indicating status.
     */
    public boolean setMinimumMagnitude(float min_spectral_magnitude_a) {
	
	min_spectral_magnitude = min_spectral_magnitude_a;
	
	// exit gracefully
	//
	return true;
    }  
    

    /**
     * Method to set brightness value.
     *
     * @param  brightness_a a float value represents the brightness of the spectrogram
     * display.
     *
     * @return a boolean value indicating status.
     */
    public boolean setBrightness(float brightness_a) {
	
	brightness_d = brightness_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set contrast value.
     *
     * @param cotrast_a a float value represents the contrast of the spectrogram 
     * display.
     *
     * @return a boolean value indicating status.
     */
    public boolean setContrast(float contrast_a) {
	
	contrast_d = contrast_a;
	
	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set the mode of spectrogram colormap
     *
     * @param colormap_a a string represents what kind of colormap 
     * is used to display spectrogram.
     *
     * @return a boolean value indicating status.
     */
    public boolean setColormap(String colormap_a) {
	
	if ( colormap_a.equals("TI"))
	    colormap_type = 2;
	if ( colormap_a.equals("MATLAB"))
	    colormap_type = 1;
	if ( colormap_a.equals("GRAYSCALE"))
	    colormap_type = 0;
	
	// exit gracefully
	//
	return true;
    }


    /**
     * Method to set minimum Spectrogram value.
     *
     * @param minimum_spectrogram_a a float value represents the minimum
     * spectrogram value.
     *
     * @return a boolean value indicating status.
     */
    public boolean setMinimumSpectrogram(float minimum_spectrogram_a) {
	
	minimum_spectrogram_d = minimum_spectrogram_a;
	
	// exit gracefully
	//
	return true;
    } 


     /**
     * Method to set the energy plot super tick mark.
     *
     * @param e_super_tick_a a float value represents the super tick
     * mark for energy plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setESuperTick(float e_super_tick_a) {

	e_super_tick_d = e_super_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the energy plot major tick mark.
     *
     * @param e_major_tick_a a float value represents the major tick
     * mark for energy plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setEMajorTick(float e_major_tick_a) {

	e_major_tick_d = e_major_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the energy plot minor tick mark.
     *
     * @param e_minor_tick_a a float value represents the minor tick
     * mark for energy plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setEMinorTick(float e_minor_tick_a) {

	e_minor_tick_d = e_minor_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the energy plot vertical tick mark.
     *
     * @param e_vertical_tick_a a float value represents the vertical tick
     * mark for energy plot in DB.
     *
     * @return a boolean value indicating status.
     */
    public boolean setEVerticalTick(float e_vertical_tick_a) {

	e_vertical_tick_d = e_vertical_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set a scale.
     *
     * @param escale_a a string value represents the scale type (can be
     * DB or LINEAR).
     *
     * @return a boolean value indicating status.
     */
    public boolean setEScale(String escale_a) {

	escale_d = escale_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set a window type.
     *
     * @param window_type_a a string value represents the window type
     * (can be HAMMIN..).
     *
     * @return a boolean value indicating status.
     */
    public boolean setEWindowType(String window_type_a) {

	window_type_d = window_type_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the waveform plot super tick mark.
     *
     * @param w_super_tick_a a float value represents the super tick
     * mark for waveform plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setWSuperTick(float w_super_tick_a) {

	w_super_tick_d = w_super_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the waveform plot major tick mark.
     *
     * @param w_major_tick_a a float value represents the major tick
     * mark for waveform plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setWMajorTick(float w_major_tick_a) {

	w_major_tick_d = w_major_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the waveform plot minor tick mark.
     *
     * @param w_minor_tick_a a float value represents the minor tick
     * mark for waveform plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setWMinorTick(float w_minor_tick_a) {

	w_minor_tick_d = w_minor_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the Spectrogram plot super tick mark.
     *
     * @param s_super_tick_a a float value represents the super tick
     * mark for energy plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setSSuperTick(float s_super_tick_a) {

	s_super_tick_d = s_super_tick_a;

	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set the Spectrogram plot major tick mark.
     *
     * @param s_major_tick_a a float value represents the major tick
     * mark for energy plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setSMajorTick(float s_major_tick_a) {

	s_major_tick_d = s_major_tick_a;

	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set the Spectrogram plot minor tick mark.
     *
     * @param s_minor_tick_a a float value represents the minor tick
     * mark for energy plot in seconds.
     *
     * @return a boolean value indicating status.
     */
    public boolean setSMinorTick(float s_minor_tick_a) {

	s_minor_tick_d = s_minor_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the Spectrogram plot vertical tick mark.
     *
     * @param s_vertical_tick_a a float value represents the vertical tick
     * mark for energy plot in DB.
     *
     * @return a boolean value indicating status.
     */
    public boolean setSVerticalTick(float s_vertical_tick_a) {

	s_vertical_tick_d = s_vertical_tick_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set a scale.
     *
     * @param sscale_a a string value represents the scale type (can be
     * DB or LINEAR).
     *
     * @return a boolean value indicating status.
     */
    public boolean setSScale(String sscale_a) {

	sscale_d = sscale_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set a window type.
     *
     * @param window_type_a a string value represents the window type
     * (can be HAMMIN..).
     *
     * @return a boolean value indicating status.
     */
    public boolean setSWindowType(String window_type_a) {

	window_type_d = window_type_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the gain for the signal.
     *
     * @param gain_a a float value represents the gain for
     * signal. 
     *
     * @return a boolean value indicating status.
     */
    public boolean setGain(float gain_a) {

	gain_d = gain_a;

	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the starting time after end point detector.
     *
     * @param start_a a float value represents the starting time for
     * signal.
     *
     * @return a boolean value indicating status.
     */
    public boolean setStartTime(float start_a) {
	
	if ( start_a <= (float) 0.1 )
	    start_tick_d = start_a;
	else
	    start_tick_d = start_a - (float)0.1;
	
	// exit gracefully
	//
	return true;
    }  


     /**
     * Method to set the end time after end point detector.
     *
     * @param end_a a float value represents the end time for signal.
     *
     * @return a boolean value indicating status.
     */
    public boolean setEndTime(float end_a) {

	end_tick_d = end_a;

	// exit gracefully
	//
	return true;
    }  


    /**
     * Method to set the order of FFT.
     *
     * @param fft_num_a a int value represents the order of fft .
     *
     * @return a boolean value indicating status.
     */
    public boolean setFftOrder(int fft_num_a) {

	fft_num_d = fft_num_a ;

	// exit gracefully
	//
	return true;
    }  


    /**
     * Print data inside this config data
     *
     * @param cfg_data_a a ConfigData object.
     *
     * @return a boolean value indicating status.
     */
    public boolean printData(ConfigData cfg_data_a) {
	
	for (int i = 0; i < cfg_data_a.getAssociation().size(); i++) {
	    
	    System.out.println("ith item=" + i);
	    System.out.println(cfg_data_a.getAssociation().get(i));
	    System.out.println(cfg_data_a.getName().get(i));
	    System.out.println(cfg_data_a.getType().get(i));
	    System.out.println(cfg_data_a.getValue().get(i));
	}
	
	// exit gracefully
	// 
	return true;
    }

    
    /**
     * Method to set the ConfigData object
     *
     * @param data_a a ConfigData object.
     *
     * @return a boolean value indicating status.
     */
    public boolean setConfigData(ConfigData data_a) {


	// data can be energy, waveform and spectrogram or display
	//
	System.out.println("data association for config data=" + 
			   (String)(data_a.getAssociation().get(0)));
	System.out.println(((String)(data_a.getAssociation().get(0))).equals("Energy"));

	// check if it is energy paramters
	//
	if (((String)(data_a.getAssociation().get(0))).equals("Energy")) {
	    setEnergyConfig(data_a);
	}

	// check if it is  waveform paramters
	//
	if (((String)(data_a.getAssociation().get(0))).equals("Waveform")) {
	    setWaveformConfig(data_a);
	}
	
	// check if it is display parameters
	//
	if (((String)(data_a.getAssociation().get(0))).equals("Display")) {
	    setDisplayConfig(data_a);
	}

	// check if it is spectrogram parameters
	//
	if (((String)(data_a.getAssociation().get(0))).equals("Spectrogram")) {
	    setSpectrogramConfig(data_a);
	}

	// exit gracefully
	//
	return true;
    }


     /**
     * Method to set the ConfigData object for energy
     *
     * @param data_a a ConfigData object.
     *
     * @return a boolean value indicating status.
     */
    public boolean setEnergyConfig(ConfigData data_a) {

	// loop all values
	//
	for (int i = 0; i < data_a.getAssociation().size(); i++) {

	    System.out.println("data getName =" + data_a.getName().get(i));
	    System.out.println(data_a.getName().get(i).equals("preemph_coef_d"));

	    // check if it is preemphasis coefficient
	    //
	    if (data_a.getName().get(i).equals("preemph_coef_d")) {
		setPreemphCoef(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is window duration
	    //
	    else if (data_a.getName().get(i).equals("window_duration_d")) {
		setEnergyWindowDuration(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is maximum energy parameter
	    //
	    else if (data_a.getName().get(i).equals("maximum_energy_d")) {
		setMaximumEnergy(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minimum energy parameter
	    //
	    else if (data_a.getName().get(i).equals("minimum_energy_d")) {
		setMinimumEnergy(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is super tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("e_super_tick_d")) {
		setESuperTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is major tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("e_major_tick_d")) {
		setEMajorTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minor tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("e_minor_tick_d")) {
		setEMinorTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is vertical tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("e_vertical_tick_d")) {
		setEVerticalTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is scale parameter
	    //
	    else if (data_a.getName().get(i).equals("escale_d")) {
		setEScale((String)(data_a.getValue().get(i)));
	    }
	    
	    // check if it is window parameter
	    //
	    else if (data_a.getName().get(i).equals("window_type_d")) {
		setEWindowType((String)(data_a.getValue().get(i)));
	    }

	}

	// exit gracefully
	//
	return true;
    }


    /**
     * Method to set the ConfigData object for waveform.
     *
     * @param data_a a ConfigData object include the waveform
     * configuration data.
     *
     * @return a boolean value indicating status.
     */
    public boolean setWaveformConfig(ConfigData data_a) {

	// loop possible values
	//
	for (int i = 0; i < data_a.getAssociation().size(); i++) {
	    
	    // check if it is maximum waveform parameter
	    //
	    if (data_a.getName().get(i).equals("maximum_waveform_d")) {
		setMaximumWaveform(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minimum waveform parameter
	    //
	    else if (data_a.getName().get(i).equals("minimum_waveform_d")) {
		setMinimumWaveform(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is super tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("w_super_tick_d")) {
		setWSuperTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is major tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("w_major_tick_d")) {
		setWMajorTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minor tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("w_minor_tick_d")) {
		setWMinorTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is gain parameter
	    //
	    else if (data_a.getName().get(i).equals("gain_d")) {
		setGain(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	}

	// exit gracefully
	//
	return true;
    }


    /**
     * Method to set the ConfigData object for spectrogram.
     *
     * @param data_a a ConfigData object include the spectrogram
     * configuration data.
     *
     * @return a boolean value indicating status.
     */
    public boolean setSpectrogramConfig(ConfigData data_a) {   
	
	// loop all values
	//
	for (int i = 0; i < data_a.getAssociation().size(); i++) {
	    
	    System.out.println("data getName =" + data_a.getName().get(i));
	    System.out.println(data_a.getName().get(i).equals("preemph_coef_d"));

	    // check if it is preemphasis parameter
	    //
	    if (data_a.getName().get(i).equals("preemph_coef_d")) {
		setPreemphCoef(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is window duration
	    //
	    else if (data_a.getName().get(i).equals("window_duration_d")) {
		setSpecWindowDuration(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is maximum spectral magnitude
	    //
	    else if (data_a.getName().get(i).equals("maximum_spectral_magnitude_d")) {
		setMaximumMagnitude(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minimum spectral magnitude
	    //
	    else if (data_a.getName().get(i).equals("minimum_spectral_magnitude_d")) {
		setMinimumMagnitude(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is maximum spectrogram parameter
	    //
	    else if (data_a.getName().get(i).equals("maximum_spectrogram_d")) {
		setMaximumSpectrogram(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minimum spectrogram parameter
	    //
	    else if (data_a.getName().get(i).equals("minimum_spectrogram_d")) {
		setMinimumSpectrogram(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is super tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("s_super_tick_d")) {
		setSSuperTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }

	    // check if it is major tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("s_major_tick_d")) {
		setSMajorTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is minor tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("s_minor_tick_d")) {
		setSMinorTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is vertical tick mark parameter
	    //
	    else if (data_a.getName().get(i).equals("s_vertical_tick_d")) {
		setSVerticalTick(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is scale parameter
	    //
	    else if (data_a.getName().get(i).equals("sscale_d")) {
		setSScale((String)(data_a.getValue().get(i)));
	    }
	    
	    // check if it is window type parameter
	    //
	    else if (data_a.getName().get(i).equals("window_type_d")) {
		setSWindowType((String)(data_a.getValue().get(i)));
	    }
	    
	    // check if it is color map parameter
	    //
	    else if (data_a.getName().get(i).equals("color_map_d")) {
		setColormap((String)(data_a.getValue().get(i)));
	    }
	    
	    // check if it is brightness parameter
	    //
	    else if (data_a.getName().get(i).equals("brightness_d")) {
		setBrightness(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	    
	    // check if it is contrast parameter
	    //
	    else if (data_a.getName().get(i).equals("contrast_d")) {
		setContrast(Float.parseFloat((String)(data_a.getValue().get(i))));
	    }
	}
	
	// exit gracefully
	//
	return true;
    }
    
    
    /**
     * Method to set the ConfigData object for display.
     *
     * @param data_a a ConfigData object include the display
     * configuration data.
     *
     * @return a boolean value indicating status.
     */
    public boolean setDisplayConfig(ConfigData data_a) {
	
	// local variables
	//
	float energy = 0, waveform = 0, spectrogram = 0;
	
	// loop all possible values
	//
	for (int i = 0; i < data_a.getAssociation().size(); i++) {

	    // check if it is energy percentage parameter
	    //
	    if (data_a.getName().get(i).equals("energy_percentage_d")) {

		energy = Float.parseFloat((String)(data_a.getValue().get(i))) / 100;
	    }
	    
	    // check if it is waveform percentage parameter
	    //
	    if (data_a.getName().get(i).equals("waveform_percentage_d")) {

		waveform = Float.parseFloat((String)(data_a.getValue().get(i))) / 100;
	    }
	    
	    // check if it is spectrogram percentage parameter
	    //
	    if (data_a.getName().get(i).equals("spectrogram_percentage_d")) {

		spectrogram = Float.parseFloat((String)(data_a.getValue().get(i))) / 100;
	    }
	    
	    // check if it is energy percentage parameter
	    //
	    if (data_a.getName().get(i).equals("energy_percentage_d")) {
		
		energy = Float.parseFloat((String)(data_a.getValue().get(i))) / 100;
	    }
	     
	    // check if it is second displayed parameter
	    //
	    if (data_a.getName().get(i).equals("seconds_displayed_d")) {
		
		 user_seconds_d = Float.parseFloat((String)(data_a.getValue().get(i)));
		 accum_array_size = (int)(sample_rate_d*user_seconds_d);
	     }
	    
	}

	// set the display percentage
	//
	setConfiguration(energy, waveform, spectrogram);

	// exit gracefully
	//
	return true;
    }

      
    /**
     * This method is used to set the data points and the number
     * of samples.
     *
     * @param point_a an array of data point.
     *
     * @return a boolean value indicating status.
     */
    public boolean setData(float [] point_a) {

	if(point_a == null) {
	    return true;
	}

	// Need to dynamically know the size of the realtime buffer
	// This calculates it and then determines if we need to resize
	// the buffer because the window has been resized or another
	// factor has changed
	//
	int local_realtime_buffer_length = (int)((double)width_d *
	           (double)sample_rate_d * (double)pixel_duration_d);

	// pre_filter the data : preemphasis the whole block rather than window by window
	//
	pre_filter(point_a,preemph_coef_d,point_a.length);
	
	if (!realtime_d) { 
	
	    // overall display
	    // In the overall calculation, this is only ever done once so just
	    // set the accum buffer equal to what is passed in and normalize
	    // those values.
	    // Need to remember to reset 

	    // allocate memory for overall data array, the size of which is the length of the array point_a
	    //
	    overall_samples_d = new float[(int)point_a.length];
	 
	    // initialize the overall_samples_d array
	    //
	    for (int i = 0; i < point_a.length; i++) {
		overall_samples_d[i] = 
		    (float)(0.25 * NORMALIZATION_AMPLITUDE * point_a[i]);
		
	    }
	    
	    // set accum_num_samples_d as the length of the point_a
	    //
	    accum_num_samples_d = point_a.length;

	}
	else {   // real time display
	    
	    // allocate memory for realtime_samples_d array
	    //
	    realtime_samples_d = new float[(int)point_a.length];	   
	    // set the value for the realtime_sampes_d array
	    //
	    for (int i = 0; i < point_a.length; i++) {
		realtime_samples_d[i] = (float)(0.25 * NORMALIZATION_AMPLITUDE * point_a[i]);
	    }
	    
	    // we use a circular buffer here
	    // shift all the data in accum points by the size of the
	    // new chunk of data
	    try {
		// Need to shift the accum (all realtime samples)
		// around so that we start at 0 always for the sample
		// readings example: accum.length = 8, point_a.length
		// = 3 need to move [0,4] to [3,7]] so (8-3-1) -> (8-1)
		// and then keep subtracting one there can be an
		// optimization to use the accum_num_samples_d here
		// but i dont care enough to do it
		//
		// set the source and destin value 
		int source = accum_points_d.length - point_a.length - 1;
		int destin = accum_points_d.length - 1;

		// when the length of the accum_points_d is not enough
		// to cover the whole window, we need to shift the
		// accum_poitns_a value. In this way, the user can see
		// that all the lastest data comes from the right hand
		// and the move towards left. The columns that can not
		// be covered as we dont have enough data yet will be
		// shown as default color according to different
		// colormap
		while (source < destin && source >= 0 &&
		       destin < accum_points_d.length) {
		    
		    // swtich the data of the accum_points_d to make
		    // sure the data shown from right hand
		    accum_points_d[destin] = accum_points_d[source];
		    source--;
		    destin--;
		}
	    }
	    catch (Exception e) {
		System.out.println(e);	
		e.printStackTrace();
	    }
	    
	    try {
		// We need to make sure we don't go over the length of the
		// accum points array.
		// Let us first assume the incoming points are larger
		// and set the start pt in the accum buffer equal to that
		//
		int accum_destin = point_a.length;

		// Then let's test to make sure we were right
		if (accum_destin >= accum_points_d.length) {
		    accum_destin = accum_points_d.length - 1;
		}

		// so now we know we transfer from the END of point_a to the
		// accum_destin point
		//
		int point_a_source = point_a.length - 1;
		for (; point_a_source >= 0 && accum_destin >= 0;
		     point_a_source--, accum_destin--) {
		    accum_points_d[accum_destin] = 
			gain_d * NORMALIZATION_AMPLITUDE *
			point_a[point_a_source];
		}		
	    }
	    catch (Exception e) {
		System.out.println(e);	
		e.printStackTrace();
	    }

	    // save how many spots of this accum buffer actually have data
	    //
	    accum_num_samples_d += point_a.length;
	    if (accum_num_samples_d > accum_array_size) {
		accum_num_samples_d = accum_array_size;
	    }

	}

	// if realtime mode
	//
	if (realtime_d) {
	    
	    // if screen has been refreshed
	    //
	    if(RESIZED == 1) {
		refresh();
	    }
	    // else
	    //
	    else {
		realTimeCalPlot(realtime_samples_d);
	    }    
	}
	
	// if in overall mode
	// 
	else {

	    // if screen has been refreshed
	    //
	    if(RESIZED == 1) {
		//refresh();
		overallCalPlot(overall_samples_d);
	    }
	    // else
	    //
	    else {
		overallCalPlot(overall_samples_d);
	    }
	}

	// update the display counter
	//
	current_display_data_d++;
	refreshed = true;

	// exit gracefully
	//
	return true;
    }


    /**
     * Display the data using the specified percentage of each
     * component.
     *
     * @param data_a an array of sampled data.
     * @param energy_percentage_a percentage of energy in display.
     * @param waveform_percentage_a percentage of waveform in display.
     * @param spectrogram_percentage_a percentage of spectrogram in
     * display.
     *
     * @return a boolean value indicating status.
     */
    public boolean setDisplay(float [] data_a,
			      float energy_percentage_a,
			      float waveform_percentage_a,
			      float spectrogram_percentage_a) {

	// if there is no data, exit gracefully
	//
	if (data_a == null) {
	    return true;
	}

	// set the config for each percentage of each component    //point_a[i]; 

	//
	setConfiguration(energy_percentage_a,
			 waveform_percentage_a,
			 spectrogram_percentage_a);

	// set the data 
	//
	setData(data_a);

	// exit gracefully
	//
	return true;
    }


    /**
     * Set the configuration for each percentage of each component
     *
     * @param energy_percentage_a percentage of energy in display.
     * @param waveform_percentage_a percentage of waveform in display.
     * @param spectrogram_percentage_a percentage of spectrogram in
     * display.
     *
     * @return a boolean value indicating status.
     */
    public boolean setConfiguration(float energy_percentage_a,
				    float waveform_percentage_a,
				    float spectrogram_percentage_a) {
	// local variable
	//
	float total_percentage;
	
	// save the percentages for changing of a window refresh or the like
	//
	energy_percentage_d = energy_percentage_a;
	waveform_percentage_d = waveform_percentage_a;
	spectrogram_percentage_d = spectrogram_percentage_a;	
	
	// get the size of plot area
	//
	Dimension d = getSize();
	System.out.println("$WIDTH" + d.width + "$HEIGHT" + d.height);
	
	// test whether the plot area is resized
	//	
	if (d.width != width_d || d.height != height_d) {
	    
	    // reset the width and height 
	    //
	    width_d = d.width;
	    height_d = d.height;
	    
	    // reimage the widget
	    //
	    bimg_d = (BufferedImage) createImage(width_d, height_d);
	    big_d = bimg_d.createGraphics();
	    big_d.setFont(font);
	    FontMetrics fm = big_d.getFontMetrics(font);
	    ascent_d = (int) fm.getAscent();
	    descent_d = (int) fm.getDescent();
	    
	}
	
	// initialize the data fields
	//
	realtime_energy_d = new float[width_d];
	fftLength = 2; 
	
	// make adjustment of window size for hamming and fft computation
        //
	while (fftLength < (spectrogram_window_duration_d * sample_rate_d)){
	    
	    // set fftLength value as power of 2
	    //
	    fftLength = fftLength * 2;
	}
	
	// allocate memory for spectrogram and waveform
	//
	spectrogram_color_array = new int[width_d][fftLength];
	realtime_waveform_max = new float[width_d];
	realtime_waveform_min = new float[width_d];

	// calculate the total percentage of display
	//
	total_percentage = energy_percentage_a +
	    waveform_percentage_a +
	    spectrogram_percentage_a;
	
	// check if each element is greater than a certain threshold 
	//
	if (energy_percentage_a < ALLOWANCE)
	    energy_percentage_a = (float)0.0;
	
	// check if each element is greater than a certain threshold 
	//
	else if (waveform_percentage_a < ALLOWANCE)
	    waveform_percentage_a = (float)0.0;
	
	// check if each element is greater than a certain threshold 
	//
	else if (spectrogram_percentage_a < ALLOWANCE)
	    spectrogram_percentage_a = (float)0.0;
	
	// calculate the total percentage of display
	//
	total_percentage = energy_percentage_a +
	    waveform_percentage_a +
	    spectrogram_percentage_a;
	
	// calculate the real height for each component
	//
	energy_height_d = (int)(height_d * 
				energy_percentage_a / total_percentage);
	waveform_height_d = (int)(height_d * 
				  waveform_percentage_a / total_percentage);
	spectrogram_height_d = (int)(height_d * 
				     spectrogram_percentage_a / total_percentage);
	
	// calculate the coordinates of left top corner for each
	// component
	//
	energy_x_d = 0;
	energy_y_d = 0;
	waveform_x_d = 0;
	waveform_y_d = energy_height_d;
	spectrogram_x_d = 0;
	spectrogram_y_d = energy_height_d + waveform_height_d;
	
	// set the read_pointer at the beginning of the array
	//
	read_pointer = 0;
	maximum_frequency = 4000;
	minimum_frequency = 0;
	
	// set the circular buffer flag as we don't have to shift the
	// buffer.
	circular_flag_d = 0;
	
	// allocate memory
	//
	overall_energy_x_d = new int[width_d];
	overall_energy_y_d = new int[width_d];
	pts_waveform_x_d =  new int[2*width_d];
	pts_waveform_y_d = new int [2*width_d];
	overall_waveform = new float [2* width_d];

    weighted_max_spectral_magnitude = 0;
    weighted_min_spectral_magnitude = 0;
    num_points = 0;
    pdf_array = new float [151];
    cdf_array = new float [151];	
	// exit gracefully
	//
	return true;
	
    }
    
    
    //-------------------------------------------------------------------------
    //
    // class-specific public methods:
    //  get methods
    //
    //-------------------------------------------------------------------------
    
    /**
     * Get the sample rate.
     *
     * @return a float value of sample rate.
     */
    public float getSampleRate() {
	return sample_rate_d;
    }

    /** 
     * Method to get the preemphasis coefficient.
     *
     * @return a float value of preemphasis coefficient.
     */
    public float getPreemphCoef() {
	return preemph_coef_d;
    }
    
    /** 
     * Method to get the pixel duration in seconds.
     *
     * @return a float value of pixel duration.
     */
    public float getPixelDuration() {
	return pixel_duration_d;
    }

    /** 
     * Method to get the window duration in seconds.
     *
     * @return a float value of window duration.
     */
    public float getEnergyWindowDuration() {
	return energy_window_duration_d;
    }
    
     /** 
     * Method to get the window duration in seconds.
     *
     * @return a float value of window duration.
     */
    public float getSpecWindowDuration() {
	return spectrogram_window_duration_d;
    }
    
    /**
     * Get the minimum dimensions.
     * @return the minimum dimension. 
     */
    public Dimension getMinimumSize() {
	return getPreferredSize();
    }
    
    /**
     * Get the maximum dimensions.
     * @return the maximum dimension. 
    */
    public Dimension getMaximumSize() {
	return getPreferredSize();
    }
    
    /**
     * Get the preferred dimensions.
     * @return the preferred dimension.
     */
    public Dimension getPreferredSize() {
	return new Dimension(WM_CANVAS_WIDTH, WM_CANVAS_HEIGHT);
    }

    //-------------------------------------------------------------------------
    //
    // class-specific other public methods:
    //  
    //
    //-------------------------------------------------------------------------
    /**
     * Reset the some data field.
     *
     * @return a boolean value indicating status.
     */
    public boolean reset() {

	// reset the total points need to be plotted
	//
	pts_received_energy_d = 0;
	pts_received_waveform_d = 0;
	pts_received_spectrogram_d = 0;

	// clear the sample number of the data accumulated to the present
	//
	accum_num_samples_d = 0;

	// allocate memory for the sample array ( both realtime and overall)
	//	
	overall_samples_d = new float[0];
	realtime_samples_d = new float[0];
	accum_points_d = new float[accum_array_size];
	
	// Note this is the count of each time how many samples are given
	// per read. This should be taken out eventually but right now 160,000
	// is large enough.
	//
	// initialize the accumulate array		
	for (int i = 0; i < accum_array_size; i++) {
	    accum_points_d[i] = 0;
	}
	
	// exit gracefully
	//
	return true;
    }
    

    /**
     * Method to draw the title. 
     *
     * @param big_a Graphic2D object.
     * @param color_a The color used to draw.
     * @param title_a The title string.
     * @param x_offset_a The offset from left in x-axis.
     * @param y_offset_a the offset from top in y-axis.
     *
     * @return a boolean value indicating status.
     */
    public boolean drawTitle(Graphics2D big_a,
			     Color color_a,
			     String title_a, 
			     float x_offset_a, 
			     float y_offset_a) {
	
	// set the color
	//
	big_a.setColor(color_a);
	
	// draw the title string in the specified location 
	//
	big_a.drawString(title_a, x_offset_a, y_offset_a);
	
	// exit gracefully
	//
	return true;
	
    }
    
  
    /**
     * Method to draw grid rows in a specified area.
     *
     * @param big_a the Graphics2D object.
     * @param color_a the color used to draw.
     * @param number_of_line_a number of line to be drawn.
     * @param x_step_a the step in x-axis.
     * @param y_step_a the step in y-axis.
     * @param x_offset_a the offset from left in x-axis.
     * @param y_offset_a the offset from top in y-axis.
     * @param mark_center_a when true draw the center line in red.
     * @param center_location_a when true it is in the middle of the
     * plot, otherwise it will be in the bottom
     * @param super_tick_a super tick mark
     * @param major_tick_a major tick mark
     * @param minor_tick_a minor tick mark
     * @param vertical_a vertical tick mark
     *
     * @return a boolean value indicating status.
     */
    public boolean drawOverallGridRows(Graphics2D big_a,
				       Color color_a,
				       int number_of_line_a,
				       int x_step_a, 
				       int y_step_a,
				       int x_offset_a,
				       int y_offset_a,
				       boolean mark_center_a,
				       boolean center_location_a,
				       float super_tick_a,
				       float major_tick_a,
				       float minor_tick_a,
				       float vertical_a) {

	// set the color
	//
	big_a.setColor(color_a);
	int time_line = 0;
	
	if (!center_location_a)	
	    time_line = (int)(y_offset_a + (number_of_line_a - 1) * y_step_a);
	else
	    time_line = (int)(y_offset_a + (number_of_line_a / 2) * y_step_a);
	
	// to draw energy vertical tick
	//
	if (vertical_a > 1) {
	    int num_rows = (int)((maximum_energy_d - minimum_energy_d) / vertical_a);
	    
	    // draw the graph grid rows for this area
	    //
	    int real_height = (int)(y_offset_a + 
				    (number_of_line_a - 1) * y_step_a);
	    int y_step = (int) (real_height / num_rows);
	    
	    for (int j = 0; j < num_rows; j++) {
		real_height = (int)(time_line - j * y_step);
		big_a.setColor(color_a);

		if (j == 0) {
		    big_a.setStroke(new BasicStroke());
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
		else if (j == num_rows - 1) {
		    big_a.setStroke(new BasicStroke());
		    big_a.drawLine(x_offset_a, y_offset_a, 
				   x_offset_a + 20 * x_step_a, y_offset_a);
		}
		
		else {
		    big_a.setStroke(bs[1]);
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
	    }
	}
	else {
	    
	    for (int j = 0; j < number_of_line_a; j++) {
		int real_height = (int)(y_offset_a +j * y_step_a);
		if ( mark_center_a && j == number_of_line_a / 2) {
		    big_a.setColor(Color.white);
		}
		else {
		    big_a.setColor(color_a);
		}
		if ( j == 0 || 
		     j == number_of_line_a-1) {
		    big_a.setStroke(new BasicStroke());
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
		else {
		    big_a.setStroke(bs[1]);
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
	    }
	}
	accum_num_samples_d = overall_samples_d.length;
	float total_time = accum_num_samples_d / sample_rate_d;
	int pixel_per_sec = (int)((width_d - x_offset_a) / total_time);
	
	// draw the time mark 
	//	
	int super_tick = 0;
	int major_tick = 0;
	int minor_tick = 0;
	
	for (int j = 0; j < width_d; j++) {
	    
	       
	    // draw for the start time tick
	    //
	    if (j == ((int)start_tick_d * pixel_per_sec)) {
		big_a.setColor(Color.white);
		int x_mark = (int)(x_offset_a + start_tick_d *
				   pixel_per_sec);
		big_a.setStroke(new BasicStroke(2));
		big_a.drawLine(x_mark,
			       y_offset_a, 
			       x_mark,
			       y_offset_a + (number_of_line_a - 1) * y_step_a);
	    }
	    
	    // draw for the end time tick
	    //
	    if (j == ((int)end_tick_d * pixel_per_sec)) {
		big_a.setColor(Color.white);
		int x_mark = (int)(x_offset_a + end_tick_d *
				   pixel_per_sec);
		big_a.setStroke(new BasicStroke(2));	    
		big_a.drawLine(x_mark,
			       y_offset_a, 
			       x_mark,
			       y_offset_a + (number_of_line_a - 1) * y_step_a);
	    }

	    // draw for super tick mark
	    //
	    if (j % ((int)(super_tick_a * pixel_per_sec)) == 0) {
	       big_a.setStroke(new BasicStroke(3));	    
	       big_a.setColor(Color.white);
	       float tick_title = super_tick * super_tick_a ;
	       DecimalFormat res_format = new DecimalFormat("0.0");
	       int x_mark = (int)(x_offset_a + super_tick * 
				  super_tick_a * pixel_per_sec);
	       big_a.drawString(String.valueOf(res_format.format(tick_title)) 
				+ "s", 
				x_mark,				
				time_line + 10);
	       big_a.setColor(color_a);
	       big_a.drawLine(x_mark,
			      time_line - 5, 
			      x_mark,
			      time_line);
	       big_a.setStroke(bs[2]);
	       big_a.drawLine(x_mark,
			      y_offset_a, 
			      x_mark,
			      y_offset_a + (number_of_line_a - 1) * y_step_a);
	       super_tick++;
	    }
	    
	    // draw major tick mark
	    //
	    if (j % ((int)(major_tick_a * pixel_per_sec)) == 0) {
		big_a.setStroke(new BasicStroke(2));	    
		big_a.setColor(color_a);
		int x_mark = (int)(x_offset_a + major_tick * 
				  pixel_per_sec * major_tick_a);
		big_a.drawLine(x_mark,
			       time_line - 3, 
			       x_mark,
			       time_line);
		major_tick++;
	    }

	   // draw for minor tick mark
	   //
	    if (j % ((int)(minor_tick_a * pixel_per_sec)) == 0) {
		big_a.setStroke(new BasicStroke(1));	    
		big_a.setColor(color_a);
		int x_mark = (int)(x_offset_a + minor_tick * 
				  pixel_per_sec * minor_tick_a);
		big_a.drawLine(x_mark,
			      time_line - 3, 
			      x_mark,
			      time_line);
		minor_tick++;
	    }
	}

	// exit gracefully
	//
	return true;
    }


    /**
     * Method to draw grid rows in a specified area.
     *
     * @param big_a the Graphics2D object.
     * @param color_a the color used to draw.
     * @param number_of_line_a number of line to be drawn.
     * @param x_step_a the step in x-axis.
     * @param y_step_a the step in y-axis.
     * @param x_offset_a the offset from left in x-axis.
     * @param y_offset_a the offset from top in y-axis.
     * @param mark_center_a when true draw the center line in red.
     * @param center_location_a when true it is in the middle of the
     * plot, otherwise it will be in the bottom
     * @param super_tick_a super tick mark
     * @param major_tick_a major tick mark
     * @param minor_tick_a minor tick mark
     * @param vertical_a vertical tick mark
     *
     * @return a boolean value indicating status.
     */
    public boolean drawRealTimeGridRows(Graphics2D big_a,
				       Color color_a,
				       int number_of_line_a,
				       int x_step_a, 
				       int y_step_a,
				       int x_offset_a,
				       int y_offset_a,
				       boolean mark_center_a,
				       boolean center_location_a,
				       float super_tick_a,
				       float major_tick_a,
				       float minor_tick_a,
				       float vertical_a) {

	// set the color
	//
	big_a.setColor(color_a);
	int time_line = 0;
	
	// adjust display by judging whether it is in the middle of the plot.
	//
	if (!center_location_a) {
	    time_line = (int)(y_offset_a + (number_of_line_a - 1) * y_step_a);
	}
	else {
	    time_line = (int)(y_offset_a + (number_of_line_a / 2) * y_step_a);
	}
	
	// to draw energy vertical tick
	//
	if (vertical_a > 1) {
	    int num_rows = (int)((maximum_energy_d - minimum_energy_d) / vertical_a);
	    
	    // draw the graph grid rows for this area
	    //
	    int real_height = (int)(y_offset_a + 
				    (number_of_line_a - 1) * y_step_a);
	    
	    int y_step = (int) (real_height / num_rows);
		
	    for (int j = 0; j < num_rows; j++) {
		real_height = (int)(time_line - j * y_step);
		big_a.setColor(color_a);
		if (j == 0) {
		    big_a.setStroke(new BasicStroke());
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
		else if (j == num_rows - 1) {
		    big_a.setStroke(new BasicStroke());
		    big_a.drawLine(x_offset_a, y_offset_a, 
				   x_offset_a + 20 * x_step_a, y_offset_a);
		}
		else {
		    big_a.setStroke(bs[1]);
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
	    }
	}
	else {
	    for (int j = 0; j < number_of_line_a; j++) {
		int real_height = (int)(y_offset_a +j * y_step_a);
		if ( mark_center_a && j == number_of_line_a / 2) {
		    big_a.setColor(Color.white);
		}
		else {
		    big_a.setColor(color_a);
		}
		if ( j == 0 || 
		     j == number_of_line_a-1 || 
		     j ==  number_of_line_a / 2) {
		    big_a.setStroke(new BasicStroke());
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
		else {
		    big_a.setStroke(bs[1]);
		    big_a.drawLine(x_offset_a, real_height, 
				   x_offset_a + 20 * x_step_a, real_height);
		}
	    }
	}
	
	int pixel_per_sec = (int)((width_d - x_offset_a) / user_seconds_d);
	
	// draw the time mark 
	//	
	int super_tick = 0;
	int major_tick = 0;
	int minor_tick = 0;
	
	for (int j = 0; j < width_d; j++) {
	    // draw for super tick mark
	    //
	    if (j % ((int)(super_tick_a * pixel_per_sec)) == 0) {
		big_a.setStroke(new BasicStroke(3));	    
		big_a.setColor(Color.white);
		float tick_title = super_tick * super_tick_a ;
		DecimalFormat res_format = new DecimalFormat("0.0");
		int x_mark = (int)(x_offset_a + super_tick * 
				  super_tick_a * pixel_per_sec);
		big_a.drawString(String.valueOf(res_format.format(tick_title)) 
				+ "s", 
				x_mark,				
				time_line + 10);
		big_a.setColor(color_a);
		big_a.drawLine(x_mark,
			       time_line - 5, 
			       x_mark,
			       time_line);
		big_a.setStroke(bs[2]);
		big_a.drawLine(x_mark,
			      y_offset_a, 
			      x_mark,
			      y_offset_a + (number_of_line_a - 1) * y_step_a);
		super_tick++;
	    }

	    // draw major tick mark
	    //
	    if (j % ((int)(major_tick_a * pixel_per_sec)) == 0) {
		big_a.setStroke(new BasicStroke(2));	    
		big_a.setColor(color_a);
		int x_mark = (int)(x_offset_a + major_tick * 
				   pixel_per_sec * major_tick_a);
		big_a.drawLine(x_mark,
			       time_line - 3, 
			       x_mark,
			       time_line);
		major_tick++;
	    }

	   // draw for minor tick mark
	   //
	   if (j % ((int)(minor_tick_a * pixel_per_sec)) == 0) {
	       big_a.setStroke(new BasicStroke(1));	    
	       big_a.setColor(color_a);
	       int x_mark = (int)(x_offset_a + minor_tick * 
				  pixel_per_sec * minor_tick_a);
	       big_a.drawLine(x_mark,
			      time_line - 3, 
			      x_mark,
			      time_line);
	       minor_tick++;
	   }
	}

	// exit gracefully
	//
	return true;
    }


    /**
     * Calculate the Spectrogram for a windowed frame data.
     *
     * @param data_a an array of sampled data.
     *
     * @return a energy value for this frame data.
     */
    public float[] Spectrogram(float [] data_a) {

	float pixel_spectrogram = 0;
	int data_length = data_a.length;
	
	// create an objecct f1 of Fft class
	//
        Fft f1 = new Fft();

	// use a filter y(n) = x(n) - premp_coeff * (x(n-1))
	//
	for (int samp_num = 1; samp_num < data_length; samp_num++) {

	    data_a[samp_num] = data_a[samp_num] - 
		preemph_coef_d * data_a[samp_num - 1];

	}		
	// use the desired window function for the data
	//
	for (int samp_num = 0; samp_num < data_length; samp_num++) {
	    float x_in = data_a[samp_num];
	    data_a[samp_num] = x_in 
		* (float)(WM_DEFAULT_HAMMING_COEFF 
			   - (((float)1.0 - WM_DEFAULT_HAMMING_COEFF)
			      * Math.cos(2.0 * Math.PI * (float)samp_num 
					 / (float)(data_length - 1))));

	}
	
	// compute the spectrogram of the data
	// half the size of the column data to do fft calculation
	//	
	int n_d=(int)fft_num_d/2;
	
	// initialize an array whose size is half of the column number
	//
       	f1.rad2_init_c(n_d);

	// return the array calculated in rad2_real way
	//
        return f1.rad2_real_cc(data_a);

    }


    /**
     * Method to print the config data.
     *
     * @return a boolean value indicating status.
     */
    public boolean printConfigData() {

	// print out the config data in energy block
	//
	System.out.println("=============energy===============");
	System.out.println("preemph_coef_d = " + preemph_coef_d);
	System.out.println("energy_window_duration_d = " + energy_window_duration_d);
	System.out.println("maximum_energy_d = " + maximum_energy_d);
	System.out.println("minimum_energy_d = " + minimum_energy_d);
	System.out.println("e_super_tick_d = " + e_super_tick_d);
	System.out.println("e_major_tick_d = " + e_major_tick_d);
	System.out.println("e_minor_tick_d = " + e_minor_tick_d);
	System.out.println("escale_d = " + escale_d);
	System.out.println("window_type_d = " + window_type_d);

	// print out the config data in waveform block
	//
	System.out.println("===========waveform=================");
	System.out.println("maximum_waveform_d = " + maximum_waveform_d);
	System.out.println("minimum_waveform_d = " + minimum_waveform_d);
	System.out.println("w_super_tick_d = " + w_super_tick_d);
	System.out.println("w_major_tick_d = " + w_major_tick_d);
	System.out.println("w_minor_tick_d = " + w_minor_tick_d);
	System.out.println("gain_d = " + gain_d);

	// print out the config data in spectrogram block
	//
	System.out.println("=============spectrogram===============");
	System.out.println("preemph_coef_d = " + preemph_coef_d);
	System.out.println("spectrogram_window_duration_d = " + spectrogram_window_duration_d);
	System.out.println("maximum_energy_d = " + maximum_energy_d);
	System.out.println("minimum_energy_d = " + minimum_energy_d);
	System.out.println("s_super_tick_d = " + s_super_tick_d);
	System.out.println("s_major_tick_d = " + s_major_tick_d);
	System.out.println("s_minor_tick_d = " + s_minor_tick_d);
	System.out.println("sscale_d = " + sscale_d);
	System.out.println("window_type_d = " + window_type_d);

	// print out the config data for display
	//
	System.out.println("===========display=================");
	System.out.println("energy_height_d = " + energy_height_d);
	System.out.println("waveform_height_d = " + waveform_height_d);
	System.out.println("spectrogram_height_d = " + spectrogram_height_d);

	// exit gracefully
	//
	return true;
    
    }


    /**
     * Method to redraw overall mode display
     *
     * @return a boolean value indicating status.
     */   
    public boolean redrawOverallPlot() {
    
	// as overall mode doesn't need to redraw, it always return
	// false.
	return false;
    }


    /**
     * Method to draw related Graphics.
     */            
    public void paint(Graphics g) {

	if (big_d == null) {
	    return;
	}
	
	// devide the widget height into three equal portios.
	//
	if (energy_height_d == 0 &&
	    waveform_height_d == 0 &&
	    spectrogram_height_d == 0) {
	    energy_height_d = height_d / 3;
	    waveform_height_d = height_d / 3;    
	    spectrogram_height_d = height_d / 3;
	}
	
	// clear the canvas and set the background color
	//
	big_d.setBackground(Color.black);
	big_d.clearRect(0, 0, width_d, height_d);
	big_d.setFont(font);
	
	// if energy component if necessary
	//
	if (energy_height_d > 0) {
	    
	    // draw the title for each subpart
	    //
  	    drawTitle(big_d, TEXT_COLOR, "Energy Monitor", 
		      (float)x_offset_d + 4.0f, (float) ascent_d + 0.5f);
	    
	    // Calculate remaining size
	    //
	    float ssH = ascent_d + descent_d;
	    float remainingHeight = (float) (energy_height_d - boundary - ssH);
	    float blockHeight = remainingHeight / 10;
	    double max_energy = 0.0;
	    
	    // rescale the vertical tick if it's too big
	    //
	    if (e_vertical_tick_d < maximum_energy_d / 20)
		e_vertical_tick_d = maximum_energy_d / 10;

	    // plot energy for realtime.
	    //
	    if (realtime_d) {
		
		big_d.setColor(GRAPH_COLOR);
		int y_step = (int)((energy_height_d - boundary - ssH) / 10.0);
		int x_step = (int)((width_d - boundary) / 20.0);
		
		// draw energy grid. it is special, because we want to display
		// the volume at the left side and aligned with energy
		//
		drawRealTimeGridRows(big_d, GRID_COLOR, 11, 
				     x_step, (int)blockHeight, 
				     x_offset_d, (int)ssH, 
				     true, false,
				     e_super_tick_d,
				     e_major_tick_d,
				     e_minor_tick_d,
				     e_vertical_tick_d);
		
		big_d.setColor(GRAPH_COLOR);
		big_d.drawLine(x_offset_d, (int)ssH, 
			       x_offset_d, (int)(ssH + 10 * blockHeight));
		
		// create a float variable to indicate the plot starting position
		//
		float freeVolume;
		if (energy_plot_begin_d < energy_plot_max_points_d - 1) {
		    freeVolume =  (float) 
			(maximum_energy_d - 
			 realtime_energy_d[energy_plot_begin_d++]);
		}
		else {
		    freeVolume = (float) maximum_energy_d;
		}
		
		// Draw when scale is linear
		if (escale_d.equals("Linear")) {
		    for (int j = 0; j < realtime_energy_d.length; j++) {
			if (maximum_energy_d < realtime_energy_d[j])
			    maximum_energy_d = realtime_energy_d[j];
		    }
		}
		float totalVolume = (float)(maximum_energy_d);
		
		// local variable
		//
		String usedStr;
		
		// .. Draw maximum and minimum energy
		//
		if (escale_d.equals("dB")) {
		    big_d.setColor(TEXT_COLOR);
		    big_d.drawString(String.valueOf((int) totalVolume), 
				     4.0f, (float) ascent_d + 0.5f);
		    usedStr = String.valueOf(((int) (totalVolume - freeVolume))) + "";
		    big_d.drawString(usedStr, 4, energy_height_d - descent_d);
		}
		else {
		    big_d.setColor(TEXT_COLOR);
		    big_d.drawString(String.valueOf((int) totalVolume), 
				     4.0f, (float) ascent_d + 0.5f);
		    usedStr = String.valueOf(((int) (totalVolume - freeVolume))) + "";
		    big_d.drawString(usedStr, 4, energy_height_d - descent_d);
		}

		//begin drawing the volume on the side
		// Calculate remaining size
		//
		float blockWidth = 40.0f;
		float remainingWidth = (float) (width_d - blockWidth - 10);
		
		// .. plot not used part ..
		//
		big_d.setColor(MF_COLOR);
		int MemUsage = (int) ((freeVolume / totalVolume) * 10);
		int i1 = 0;
		for ( ; i1 < MemUsage ; i1++) {
		    mfRect.setRect(5, (float) ssH+i1 * blockHeight,
				   blockWidth,(float) blockHeight - 1);
		    big_d.fill(mfRect);
		}
		
		// .. plot used ..
		//
		big_d.setColor(TEXT_COLOR);
		for ( ; i1 < 10; i1++)  {
		    muRect.setRect(5, (float) ssH+i1 * blockHeight,
				   blockWidth,(float) blockHeight - 1);
		    big_d.fill(muRect);
		} 
		
		big_d.setColor(GRAPH_COLOR);
		
		//end drawing the volume on the side
		//
		int graphX = x_offset_d;
		int graphY = (int) ssH;
		int graphW = (int)(width_d - graphX - 5);
		int graphH = (int) y_step * 10;
		int graphRow = (int) (graphH / 20.0);
		big_d.setColor(SIGNAL_COLOR);
		int ptNum = 0;
		
		// set the value of the ptNum
		//
		if (read_pointer == 0) {
		    // when the read_pointer points to the first
		    // index. That is, the realtime data is no more
		    // than one window.
		    ptNum = pts_received_energy_d;
		}
		
		else if (read_pointer > 0) {
		    // when the read_pointer points to other
		    // position. That is, we need to use circular
		    // buffer.
		    ptNum = width_d - x_offset_d - read_pointer + pts_received_energy_d + 1;
		}
		
		// reset the energy value
		//
		int previous_energy = 0;
		int current_energy = 0;
		
		// an int variable set as the number of energy points
		// to be plotted.
		//
		int circular_time = pts_received_energy_d;
		
		// when the data to be plotted is greater than one
		// window, we need to use circular buffer.
		if (circular_flag_d == 1){
		    // reset the ciruclar_time as the fixed value
		    //
		    circular_time = width_d - x_offset_d;
		}
		
		
		// need previous_energy for element 0 so calculate it
		//
		if (ptNum > 0) {
		    if (circular_flag_d == 1) {
			// when using circular buffer the energy
			// calculation should use index that relates
			// to read_pointer.
			previous_energy = (int)
			    (graphY + graphH  *
			     (maximum_energy_d - realtime_energy_d[read_pointer - 1]) 
			     / maximum_energy_d);
		    }
		    
		    if (circular_flag_d == 0) {
			// when not using circular buffer the energy
			// calculation should use index set by circular_time
			//
			previous_energy = (int)
			    (graphY + graphH  *
			     (maximum_energy_d - realtime_energy_d[circular_time - 1]) 
			     / maximum_energy_d);
		    }
		    
		}
		
		for (int i = read_pointer, num_times = 1; 
		     num_times < circular_time;
		     num_times++,i--) {
		    // when the read_pointer moved through the whole
		    // buffer, reset read_pointer points to the end of
		    // the buffer
		    //
		    if ( i == 0) {
			i = circular_time ;
		    }
			    
		    // Find out the percentage of how high to draw this energy
		    // on the y-axis
		    //		    
		    current_energy = (int)
			(graphY + graphH  *
			 (maximum_energy_d - realtime_energy_d[i - 1]) 
			 / maximum_energy_d);
		    
		    // Either draw a line or a 1-pixel rectange depending on
		    // the relationship between current previous energy
		    //
		    if (current_energy != previous_energy) {
			big_d.drawLine(width_d - (num_times - 1), 
				       current_energy, 
				       width_d - num_times,
				       previous_energy
				       );
		    }
		    else {
			big_d.fillRect(width_d - num_times, current_energy, 1, 1);
		    }

		    // Save the current for next loop's interpolation
		    //
		    previous_energy = current_energy;
		   
		}
		    
	    }
	    
	    // overall mode for energy
	    //
	    else {
		
		// erase all the accum points
		for (int i = 0 ; i < accum_points_d.length; i++)
		    accum_points_d[i] = 0.0f;
		big_d.setColor(GRAPH_COLOR);
		
		// set y_step, x_step variables for ploting
		//
		int y_step = (int)((energy_height_d - boundary - ssH) / 10.0);
		int x_step = (int)((width_d - boundary) / 20.0);
		
		// draw energy grid. it is special, because we want to display
		// the volume at the left side and aligned with energy
		//
		big_d.setColor(GRAPH_COLOR);
		drawOverallGridRows(big_d, GRID_COLOR, 11, 
				    x_step, y_step, 
				    x_offset_d, (int)( ssH), 
				    false, false,
				    e_super_tick_d,
				    e_major_tick_d,
				    e_minor_tick_d,
				    e_vertical_tick_d);
		
		big_d.setStroke(new BasicStroke());
		
		big_d.drawLine(x_offset_d, (int)ssH, 
			       x_offset_d, (int)(ssH + 10 * blockHeight));
		
		// plot the dB scale
		//
		String tmp_str;
		big_d.setColor(TEXT_COLOR);
		
	       	if (escale_d.equals("dB")) {
		    tmp_str = "" + minimum_energy_d +"0 dB";
		    big_d.drawString(tmp_str, 5, energy_height_d - 5);
		    max_energy = maximum_energy_d;
		    tmp_str = "" + (long)max_energy + " dB";
		    big_d.drawString(tmp_str, 5, 10);
		}
		else {
		    tmp_str = "" + minimum_energy_d;
		    big_d.drawString(tmp_str, 5, energy_height_d - 5);
		    max_energy = maximum_energy_d;
		    tmp_str = "" + (long)max_energy;
		    big_d.drawString(tmp_str, 5, 10);
		}
		
		// draw the energy plot on the canvas
		//
		int graphX = x_offset_d;
		int graphY = (int) ssH;
		int graphW = (int)(width_d - graphX - 5);
		int graphH = (int) y_step * 10;
	
		if (escale_d.equals("Linear")) {
		    for ( int i = 0; i < width_d - x_offset_d; i++) {
			if (maximum_energy_d < overall_energy_y_d[i])
			    maximum_energy_d = overall_energy_y_d[i];
		    }
		}

		// set the color
		//	    
		big_d.setColor(SIGNAL_COLOR);
	
		// set up the start point
		//
		int x_old = x_offset_d;
		System.out.println("$E" + overall_energy_x_d[0] + " " + overall_energy_x_d[1]);
		int y_old = (int) (graphY + graphH * (maximum_energy_d - overall_energy_y_d[0]) / maximum_energy_d);
		
		// plot each column energyvalue
		//
		for (int i = 1; i < width_d - x_offset_d; i++) {
		    
		    // use i to control the display order
		    // 
		    try {
			
			int y_new = (int) (graphY + graphH *
					   (maximum_energy_d - 
					    overall_energy_y_d[i]) / 
					   maximum_energy_d);
			
			big_d.drawLine(x_old, y_old, 
				       i + x_offset_d, 
				       y_new);
			
			x_old = i + x_offset_d;
			y_old = y_new;
		    }
		    catch (Exception e) {}
		    
		}
	    }
	    
	}
	
	// draw waveform if necessary
	//
	if (waveform_height_d > 0) {

	    // draw the title for each subpart
	    //
	    drawTitle(big_d, TEXT_COLOR, "Waveform Monitor", 
		      (float)x_offset_d + 4.0f, 
		      (float) waveform_y_d + ascent_d + 0.5f);

	    // Calculate remaining size
	    //
	    float ssH = ascent_d + descent_d;
	    float remainingHeight = (float) (waveform_height_d - boundary - ssH);
	    float blockHeight = remainingHeight / 10;
	    float blockWidth = 40.0f;
	    float remainingWidth = (float) (width_d - blockWidth - 10);

	    
	    // real time mode for waveform
	    //
	    if (realtime_d) {
				
		big_d.setColor(GRAPH_COLOR);
		int y_step = (int)((waveform_height_d - boundary - ssH) / 10.0);
		int x_step = (int)((width_d - boundary) / 20.0);
		
		// draw waveform grid.
		//
		drawRealTimeGridRows(big_d, GRID_COLOR, 11, x_step, y_step, 
				     x_offset_d, (int)(waveform_y_d + ssH), 
				     false, false,
				     w_super_tick_d,
				     w_major_tick_d,
				     w_minor_tick_d, 0);
		
		
		big_d.setColor(GRAPH_COLOR);
		
		big_d.setStroke(new BasicStroke());
		
		// draw the graph grid columns
		//
		big_d.drawLine(x_offset_d, (int)(waveform_y_d + ssH), 
			       x_offset_d, (int)(waveform_y_d + ssH + 10 * blockHeight));
		
		// local variables
		//
		String tmp_str;
		big_d.setColor(TEXT_COLOR);
		
		// draw minimum value
		//
		tmp_str = "" + minimum_waveform_d;
		big_d.drawString(tmp_str, 5, waveform_y_d + 
				 waveform_height_d - 10);

		// draw maximum value
		//
		tmp_str = "" + maximum_waveform_d;
		big_d.drawString(tmp_str, 5, waveform_y_d + boundary);
		
		
		big_d.setColor(GRAPH_COLOR);
		
		// .. Draw History Graph ..
		//
		big_d.setColor(GRAPH_COLOR);
		ssH = ascent_d + descent_d;
		remainingHeight = (float) (height_d - (ssH * 2) - 0.5f);
		int graphX = x_offset_d;
		int graphY = (int) ssH;
		int graphW = (int)(width_d - graphX - 5);
		int graphH = (int) remainingHeight;
		int graphRow = graphH / 20;
		
		// Set the color to be the waveform color
		//
		big_d.setColor(SIGNAL_COLOR);
		
		int ptNum = 0;
		if (read_pointer == 0) {
		    ptNum =2 * pts_received_energy_d;
		}
		else if (read_pointer > 0) {
		    ptNum = 2 * (width_d - x_offset_d - read_pointer + pts_received_energy_d + 1);
		}
		
		// if the number of samples to be plotted is more than twice the 
		// number of pixel width of the screen
		// 
		if (samples_greater_than_pixels == true) {
		
		    int circular_time = pts_received_energy_d;
		    
		    if (ptNum > 0) {
			if (circular_flag_d == 1){

			    // when need circular buffer to shift data
			    //
			    circular_time = width_d - x_offset_d;
			    int x_old =  x_offset_d;
			    int y_old = (int)(realtime_waveform_min[read_pointer - 1] /
					      (double)maximum_waveform_d 
					      * (waveform_height_d / 2.0 - boundary) + 
					      (waveform_y_d + waveform_height_d / 2));
			}
			
			if (circular_flag_d == 0) {

			    // when we dont need circular buffer
			    //
			    int x_old =  x_offset_d;
			    int y_old = (int)(realtime_waveform_min[circular_time - 1] /
					      (double)maximum_waveform_d 
					      * (waveform_height_d / 2.0 - boundary) + 
					      (waveform_y_d + waveform_height_d / 2));
			}
			
		    }

		    big_d.setColor(SIGNAL_COLOR);

		    // use for loop to plot data column by column. we
		    // use read_pointer and circular_time to control
		    // data index.
		    for (int i = read_pointer, num_times = 1; 
			 num_times < circular_time;
			 num_times++,i--) {
			
			if ( i == 0) {
			    i = circular_time ;
			}
			
			// get the min and max value for each column
			// for plotting.
			//
			int min_point = (int)
			    (realtime_waveform_min[i - 1] /
			     (double)maximum_waveform_d 
			     * (waveform_height_d / 2.0 - boundary) + 
			     (waveform_y_d - blockHeight + waveform_height_d / 2 ));
			int max_point = (int)
			    (realtime_waveform_max[i - 1] /
			     (double)maximum_waveform_d  
			     * (waveform_height_d / 2.0 - boundary) + 
			     (waveform_y_d - blockHeight + waveform_height_d / 2 ));
			
			
			// if max/min aren't the same draw a line from the
			// pair of max/min
			//
			if (min_point != max_point) {
			    big_d.drawLine(width_d - num_times, min_point, 
					   width_d - num_times, max_point);
			}
			// if they are the same then just put a single
			// dot there
			//
			else {
			    System.out.println( " in the fillrect function");
			    big_d.fillRect(width_d - num_times,
					   min_point, 1, 1);
			}
			
		    }
		    
		}
		
	    } // end of realtime mode

	    // overall mode for waveform
	    //
	    else {

		big_d.setColor(GRAPH_COLOR);
	    
		int y_step = (int)((waveform_height_d - boundary - ssH) / 10.0);
		int x_step = (int)((width_d - boundary) / 20.0);

		// draw waveform grid. 
		//
		drawOverallGridRows(big_d, GRID_COLOR, 11, 
				    x_step, y_step, 
				    x_offset_d, (int)(waveform_y_d + ssH), 
				    false, false,
				    w_super_tick_d,
				    w_major_tick_d,
				    w_minor_tick_d, 0);
		
		big_d.setColor(GRAPH_COLOR);
		
		big_d.setStroke(new BasicStroke());
		
		// draw the graph grid columns
		//
		big_d.drawLine(x_offset_d, (int)(waveform_y_d + ssH), 
			       x_offset_d, (int)(waveform_y_d + ssH + 10 * blockHeight));
		
		// local variables
		//
		String tmp_str;
		big_d.setColor(TEXT_COLOR);
		
		// draw minimum value
		//
		tmp_str = "" + minimum_waveform_d;
		big_d.drawString(tmp_str, 5, waveform_y_d + 
				 waveform_height_d - 10);
		
		// draw maximum value
		//
		tmp_str = "" + maximum_waveform_d;
		big_d.drawString(tmp_str, 5, waveform_y_d + boundary);
		
		big_d.setColor(GRAPH_COLOR);
		
		// draw the signal plot on the canvas
		//
		int x_old = pts_waveform_x_d[0]+ x_offset_d;
		int y_old = (int) (pts_waveform_y_d[0]/
				   (double)maximum_waveform_d 
				   * (waveform_height_d / 2.0 - boundary) + 
				   (waveform_y_d - blockHeight + (float)(waveform_height_d / 2) ));
		
		big_d.setColor(SIGNAL_COLOR);
	    
		for (int i = 1; i < pts_waveform_y_d.length - 2 * x_offset_d ; i++) {
		    // plot the waveform column by connecting two
		    // points ( maximum and minimum value points)
		    //
		    try {
			big_d.drawLine(x_old, y_old, 
				       pts_waveform_x_d[i] + x_offset_d, 
				       (int)(pts_waveform_y_d[i]/
					     (double)maximum_waveform_d 
					     * (waveform_height_d / 2.0 - boundary) + 
					     (waveform_y_d - blockHeight + (float)(waveform_height_d / 2) )));
			x_old = pts_waveform_x_d[i]+ x_offset_d;
			y_old = (int)(pts_waveform_y_d[i]/
				      (double)maximum_waveform_d 
				      * (waveform_height_d / 2.0 - boundary) + 
				      (waveform_y_d - blockHeight + (float)(waveform_height_d / 2) ));
		    }
		    catch (Exception e) {}
		}
	    }// end of overall mode
       	}// end of waveform component
 

	// Spectrogram component if necessary
	//
	if (spectrogram_height_d > 0) {
	    
	    // draw the title for each subpart
	    //
	    drawTitle(big_d, TEXT_COLOR, "Spectrogram Monitor", 
		      (float)x_offset_d , (float) spectrogram_y_d + ascent_d);
	    
	    // Calculate remaining size
	    //
	    float ssH = ascent_d + descent_d;
	    
	    //float remainingHeight = (float) (spectrogram_height_d - 
	    //			     (ssH * 2) - 0.5f);
	    float remainingHeight = (spectrogram_height_d - boundary - ssH);
	    float blockHeight = (remainingHeight / 10);
	    double max_spectrogram = 0.0;
	    
	    // rescale the vertical tick if it's too big
	    //
	    if (s_vertical_tick_d < maximum_spectrogram_d / 20)
		s_vertical_tick_d = maximum_spectrogram_d / 10;
	    
	    // plot spectrogram for realtime or overall
	    //
	    if (realtime_d) {
		
		big_d.setColor(GRAPH_COLOR);
		int y_step = (int)((spectrogram_height_d - boundary - ssH) / 10.0);
		int x_step = (int)((width_d - boundary) / 20.0);
		
		// draw spectrogram grid. it is special, because we want to display
		// the volume at the left side and aligned with energy
		//
		big_d.setColor(GRAPH_COLOR);
			
		// plot the dB scale
		//
		String tmp_str;
		big_d.setColor(TEXT_COLOR);
		
		if (sscale_d.equals("Hz")) {
		    tmp_str = "" + minimum_spectrogram_d +"0 Hz";
		    big_d.drawString(tmp_str, 5, spectrogram_y_d + spectrogram_height_d - 10);
		    max_spectrogram = maximum_spectrogram_d;
		    tmp_str = "" + (long)max_spectrogram + " Hz";
		    big_d.drawString(tmp_str, 5, spectrogram_y_d + 10);
		}
		else {
		    tmp_str = "" + minimum_spectrogram_d;
		    big_d.drawString(tmp_str, 5, spectrogram_y_d + spectrogram_height_d - 10);
		    max_spectrogram = maximum_spectrogram_d;
		    tmp_str = "" + (long)max_spectrogram;
		    big_d.drawString(tmp_str, 5, spectrogram_y_d+10);
		}
		
		// draw the spectrogram plot on the canvas
		//
		int graphX = x_offset_d;
		int graphY = (int) ssH+spectrogram_y_d;
		int graphW = (int)(width_d- graphX - 5);
		int graphH = (int) remainingHeight;
		
		// set the color
		//	    
		big_d.setColor(SPEC_SIGNAL_COLOR);
		
		int ptNum;
		if (read_pointer == 0) {
		ptNum = pts_received_spectrogram_d;
		}
		else if (read_pointer > 0) {
		    ptNum = width_d - x_offset_d - read_pointer + pts_received_spectrogram_d + 1;
		}
	       	int  v = 0 ;
		float max = 0;
		float min ;
		
		int circular_time_spec = width_d - x_offset_d;
		if ( circular_flag_d == 0)
		    circular_time_spec = pts_received_spectrogram_d;
		
	
		
		for (int i = read_pointer, num_times = 1; 
		     num_times < circular_time_spec;
		     num_times++,i--) {
		     if ( i == 0) {
			i = circular_time_spec ;
		    }

		     int start_bin =(int) ( minimum_frequency/(float) (sample_rate_d / fftLength));
		     int end_bin = (int)(maximum_frequency /(float) (sample_rate_d / fftLength));
		     int flen = (end_bin - start_bin);
		     //int yscale = (int)(flen / (y_step * 10)); 
		      float yscale = (flen / (spectrogram_height_d-ssH-15)) ; 

		     for (int j = 0; j < (y_step * 10); j++) {
			 
			 double fy = yscale * j;
			 int iy  = (int) fy;
			 double deltay = fy - (float)iy;    
			 //Patch2
			 			//if (iy >255)
			//  iy=255;
		
			if((y_step * 10) <= flen) {
			    v = (int)spectrogram_color_array[i][iy + start_bin];
			}
			 
			else {
			    if (iy != flen)
				v = (int)(spectrogram_color_array[i][iy + start_bin]+ deltay * (spectrogram_color_array[i][iy + start_bin + 1] - spectrogram_color_array[i][iy + start_bin]));
			    
			    else
				v = (int)spectrogram_color_array[i][iy + start_bin];
			    //System.out.println(" v" + v);
			}

			// matlab map
			//
			if (colormap_type == TI) {
			    
			    // set the index range from 0 to 255 in grayscale map
			    //
			    if( v> 115)
				v = (int)115;
			    else if(v < 0)
				v = 0 ;
			    else
				v = (int) v;
			    
			}
			if (colormap_type == MATLAB) {
			    
			    // set the index range from 0 to 255 in grayscale map
			    //
			    if(v > 63)
				v = (int)63;
			    else if(v < 0)
				v = 0 ;
			    else
				v = (int) v;
			}
			if (colormap_type == GRAYSCALE) {
			    
			    // set the index range from 0 to 255 in grayscale map
			    //
			    if(v > 255)
				v = (int)255;
			    else if(v < 0)
				v = 0 ;
			    else
				v = (int) v;
			  
			}
			
			// interpolate in the y direction if necessary
			//
			//else {
			    
			    // check whether iy value in in the range
			    //			    //
			    //if (iy < 0 || iy >=  flen || iy+1 < 0 || iy + 1 >= flen ) {
			    //System.out.println("Realtime : iy is too high or to low! value is " + iy);
			    //}
			    
			    // patch to adjust flen value
			    //
			    //if(iy == flen - 1){
			    //iy = flen - 2;
			    //}
			    
			    // get v value from spctrogram array
			    //
			    //v = (int)spectrogram_color_array[i][iy];
			    
			    //}
			
			int redColor,greenColor, blueColor;
			int rgbArray[];
			rgbArray = new int[3];
			
			// create a ColorMap object
			//
			ColorMap colorMap = new ColorMap (colormap_type);

			// rgbArray is used to store the three
			// component of RGB color
			//
			rgbArray = colorMap.getColor(v);

			// get red green blue color value from the
			// rgbArray for setting color.
			//
			redColor = rgbArray[0];
			greenColor = rgbArray[1];
			blueColor = rgbArray[2];
			
			// set color
			//
			big_d.setColor( new Color (redColor,greenColor,blueColor));
			
			//	big_d.setColor(new Color (255,255,255));
			// fill one rect of the column using the color
			// set in above.
			//	
			//big_d.fillRect(width_d - i, (int) (spectrogram_y_d - j + (y_step * 10)+ ssH), 1, 1);
			big_d.fillRect(width_d - num_times, (int) (spectrogram_y_d - j + (y_step * 10)+ ssH), 1, 1);
			//big_d.fillRect(i + x_offset_d, (int) (spectrogram_y_d - j + spectrogram_height_d - ssH), 1, 1);
			
			//	big_d.fillRect(x_offset_d + 10, (int) (25), 1, 1);
			//big_d.drawLine(i + x_offset_d, (int) (spectrogram_y_d - j + spectrogram_height_d-15), i + x_offset_d, (int) (spectrogram_y_d - j + spectrogram_height_d-16));
		     }
			 
		}
		drawRealTimeGridRows(big_d, GRID_COLOR, 11, 
				     x_step, y_step, 
				     x_offset_d, (int)(spectrogram_y_d + ssH), 
				     false, false,
				     s_super_tick_d,
				     s_major_tick_d,
				     s_minor_tick_d,
				     0);
		
		big_d.setStroke(new BasicStroke());
		
		big_d.drawLine(x_offset_d, (int)(spectrogram_y_d + ssH),x_offset_d, 
			       (int)(spectrogram_y_d + ssH + 10 *blockHeight));
		// 	if ( i == width_d - x_offset_d - 1) {
		// 			    i = 0;
		     // 			}
		
	    }
	    
	    // overall mode for spectrogram
	    //
	    else {
		
		big_d.setColor(GRAPH_COLOR);
		
		//int y_step = (int)((spectrogram_height_d - boundary - ssH) / 10.0);
		int y_step = (int)((spectrogram_height_d - boundary - ssH)/ 10.0);
		int x_step = (int)((width_d - boundary) / 20.0);
		
		// draw spectrogram grid. it is special, because we want to display
		// the volume at the left side and aligned with energy
		//
		big_d.setColor(GRAPH_COLOR);
	
		// plot the dB scale
		//
		String tmp_str;
		big_d.setColor(TEXT_COLOR);
		
		if (sscale_d.equals("Hz")) {
		    tmp_str = "" + minimum_spectrogram_d +"0 Hz";
		    big_d.drawString(tmp_str, 5, spectrogram_y_d+spectrogram_height_d - 10);
		    max_spectrogram = maximum_spectrogram_d;
		    tmp_str = "" + (long)max_spectrogram + " Hz";
		    big_d.drawString(tmp_str, 5, spectrogram_y_d + 10);
		}
		else {
		    tmp_str = "" + minimum_spectrogram_d;
		    big_d.drawString(tmp_str, 5, spectrogram_y_d + spectrogram_height_d - 10);
		    max_spectrogram = maximum_spectrogram_d;
		    tmp_str = "" + (long)max_spectrogram;
		    big_d.drawString(tmp_str, 5, spectrogram_y_d+10);
	    }
		
		// draw the energ plot on the canvas
		//
		int graphX = x_offset_d;
		int graphY = (int) ssH + spectrogram_y_d;
		int graphW = (int)(width_d- graphX - 5);
		int graphH = (int) remainingHeight;
		
		double[] c = new double[fftLength];

		// set the color
		//	    
		big_d.setColor(SPEC_SIGNAL_COLOR);
		
		// outer loop for each column
		//
		for (int i = 0; i < width_d - x_offset_d ; i++) { 
		    
		    // create and initialize variables to display
		    //
		    int v = 0;
		    double max = 0;
		    double min =spectrogram_color_array[i][0];
		    
		   		    
		    // define variables 
		    //
		    //int flen = fftLength/2;
		    //float yscale = flen / (spectrogram_height_d-ssH-15) ; 
		    //int yscale = (int)(flen / (y_step * 10)) ; 
		   
		    int start_bin =(int)((float)(minimum_frequency/sample_rate_d) * fftLength);
		    int end_bin = (int)((float)(maximum_frequency/sample_rate_d) * fftLength);
		    System.out.println("$$$$$$ " + start_bin + " " + end_bin); 
		    int flen = (int)(end_bin - start_bin);
		    // int flen = fftLength/2;
		    //int yscale = (int)(flen / (y_step * 10)); 
		    float yscale = (flen / (spectrogram_height_d-ssH-15)) ; 
		     
		    // inner loop to get color map index for plot
		    //
		    for (int j = 0; j < (y_step * 10); j++) {
			
			double fy = yscale * j;
			int iy  = (int) fy;
			double deltay = fy - (float)iy;   
			
			//if (iy >255)
			//  iy=255;
		
			if((y_step * 10) <= flen) {
			    v = (int)spectrogram_color_array[i][iy + start_bin];
			}
			 
			else {
			    if (iy != flen)
				v = (int)(spectrogram_color_array[i][iy + start_bin]+ deltay * (spectrogram_color_array[i][iy + start_bin + 1] - spectrogram_color_array[i][iy + start_bin]));
			    
			    else
				v = (int)spectrogram_color_array[i][iy + start_bin];
			    //System.out.println(" v" + v);
			}

			// matlab map
			//
			if (colormap_type == TI) {
			    
			    // set the index range from 0 to 255 in grayscale map
			    //
			    if( v> 115)
				v = (int)115;
			    else if(v < 0)
				v = 0 ;
			    else
				v = (int) v;
			    
			}
			if (colormap_type == MATLAB) {
			    
			    // set the index range from 0 to 255 in grayscale map
			    //
			    if(v > 63)
				v = (int)63;
			    else if(v < 0)
				v = 0 ;
			    else
				v = (int) v;
			}
			if (colormap_type == GRAYSCALE) {
			    
			    // set the index range from 0 to 255 in grayscale map
			    //
			    if(v > 255)
				v = (int)255;
			    else if(v < 0)
				v = 0 ;
			    else
				v = (int) v;
			  
			}
			
			// interpolate in the y direction if necessary
			//
			//else {
			    
			    // check whether iy value in in the range
			    //			    //
			    //if (iy < 0 || iy >=  flen || iy+1 < 0 || iy + 1 >= flen ) {
			    //System.out.println("Realtime : iy is too high or to low! value is " + iy);
			    //}
			    
			    // patch to adjust flen value
			    //
			    //if(iy == flen - 1){
			    //iy = flen - 2;
			    //}
			    
			    // get v value from spctrogram array
			    //
			    //v = (int)spectrogram_color_array[i][iy];
			    
			    //}
			
			int redColor,greenColor, blueColor;
			int rgbArray[];
			rgbArray = new int[3];
			
			// create a ColorMap object
			//
			ColorMap colorMap = new ColorMap (colormap_type);

			// rgbArray is used to store the three
			// component of RGB color
			//
			rgbArray = colorMap.getColor(v);

			// get red green blue color value from the
			// rgbArray for setting color.
			//
			redColor = rgbArray[0];
			greenColor = rgbArray[1];
			blueColor = rgbArray[2];
			
			// set color
			//
			big_d.setColor( new Color (redColor,greenColor,blueColor));
			
			//	big_d.setColor(new Color (255,255,255));
			// fill one rect of the column using the color
			// set in above.
			//	
			big_d.fillRect(i + x_offset_d, (int) (spectrogram_y_d - j + (y_step * 10)+ ssH), 1, 1);
			//big_d.fillRect(i + x_offset_d, (int) (spectrogram_y_d - j + spectrogram_height_d - ssH), 1, 1);
			
			//	big_d.fillRect(x_offset_d + 10, (int) (25), 1, 1);
			//big_d.drawLine(i + x_offset_d, (int) (spectrogram_y_d - j + spectrogram_height_d-15), i + x_offset_d, (int) (spectrogram_y_d - j + spectrogram_height_d-16));
		    }
		}
		
		drawOverallGridRows(big_d, GRID_COLOR, 11, 
				    x_step, y_step, 
				    x_offset_d, (int)(spectrogram_y_d + ssH), 
				    false, false,
				    s_super_tick_d,
				    s_major_tick_d,
				    s_minor_tick_d,
				    0);
		
		big_d.setStroke(new BasicStroke());
		big_d.drawLine(x_offset_d, (int)(spectrogram_y_d + ssH),x_offset_d, (int)(spectrogram_y_d + ssH + 10 * blockHeight));
	    }
	    
	}
	
	// update the display
	//
	g.drawImage(bimg_d, 0, 0, this);

	// clean up all objects waiting to be garbage collected
	//
	System.runFinalization();
    }
    

    /**
     * plot in realtime.
     *
     * @return a boolean value indicating status.
     */
    public boolean refresh() { 
	
	
	setConfiguration(energy_percentage_d,
			 waveform_percentage_d,
			 spectrogram_percentage_d);
	pts_received_energy_d = 0;
	pts_received_waveform_d = 0;
	pts_received_spectrogram_d = 0;
	
	// local variable
	//
	float start_time = (float)0.0;
	float end_time;
	
	// this is defined by the user
	//
	if (realtime_d) {
	    end_time = (float)user_seconds_d;
	    
	    // log of window duration and sampling freq
	    //
	    log_nt = (float) (20 * WM_ENERGY_LOG10_E * (float)Math.log(window_duration_d/sample_rate_d));
	}
	else {
	    end_time = (float)(1.0 / sample_rate_d) * 
		(float)overall_samples_d.length;   
	}
	
	// set the number of pixels per second
	//
	float pixels_per_sec = (float)(width_d - x_offset_d) / 
	    (end_time - start_time);
	
	// allocate memory
	//
	int data_length = (int)(window_duration_d *
				sample_rate_d) + 2;
	
	float[] data = new float[data_length];
	
	int window_count = 0;	
	
	// loop over each pixel
	//
	for (int i = 0; i < width_d - x_offset_d; i++) {
	    
	    // accum is total number of samples in our sample buffer
	    // sample rate is 8000\16000
	    // pixels_per_sec = (pixel/sec)
	    // i is the current pixel so
	    // (samples/(samples/sec)) * (pixels/sec) => total pixel of data
	    // if current pixel >= pixels of data, break
	    //
	    if (realtime_d) {
		
		if( i >= ((accum_num_samples_d/sample_rate_d) * pixels_per_sec))
		    break;
		
		// compute the time in seconds that correspond to the
		// pixel location
		// pixel_count / (pixel/sec) + sec = sec
		//
		double pixel_time = i / pixels_per_sec + start_time;
		
		// win_start/win_end 	    
		// determine the bounds of the window around the pixel location
		//
		// pixel_time = (sec) - (sec/2) = sec
		double win_start = pixel_time - (window_duration_d / 2.0);
		
		// set window start and window ending 
		//
		if (win_start < start_time) {
		    win_start = start_time;
		}
		
		double win_end = pixel_time + (window_duration_d / 2.0);
		
		if (win_end > end_time) {
		    win_end = end_time;
		}
		
		// these are actual sample count numbers
		// smp_start\end = sec * (samples/sec) = sample number
		// this sample number then indexes into the accum_buffer
		//
		int smp_start = (int)(win_start * sample_rate_d);
		int smp_end = (int)(win_end * sample_rate_d);
		
		// need to check to make sure the accum buffer has sample
		// data for this window
		// if the window start is AFTER the number of samples, then
		// we don't want this window at all
		//
		if (smp_start >= accum_num_samples_d) {
		    break;
		}
		
		if (smp_end >= accum_num_samples_d) {
		    break;
		}
		
		// If the end is greater than samples then we dont have a whole
		// window so set to the end of the sample count
		//
		if (smp_start > accum_num_samples_d) {
		    smp_start = accum_num_samples_d;
		}
		
		// reset the data
		//	    
		for (int j = 0; j < data_length; j++) {
		    data[j] = (float)0.0;
		}
		int curr_sample = 0;
	
		for (int index = smp_start; index < smp_end; index++) {
		    
		    // make sure we dont go over end of data[] array
		    //
		    if (curr_sample < data_length) {
			data[curr_sample] = accum_points_d[index];
			curr_sample ++ ;
		    }
		    
		}
	    }
	    else {
		if( i >= ((accum_num_samples_d/sample_rate_d) * pixels_per_sec))
		    break;
		
		// compute the time in seconds that correspond to the
		// pixel location
		// pixel_count / (pixel/sec) + sec = sec
		double pixel_time = i / pixels_per_sec + start_time;
		//System.out.println("pixel_time increase:" + 1/pixels_per_sec );
		// win_start\win_end 	    
		// determine the bounds of the window around the pixel location
		//
		// pixel_time = (sec) - (sec/2) = sec
		double win_start = pixel_time - (window_duration_d / 2.0);
		
		if (win_start < start_time) {
		    win_start = start_time;
		}
		
		double win_end = pixel_time + (window_duration_d / 2.0);
		
		if (win_end > end_time) {
		    win_end = end_time;
		}
		
		// these are actual sample count numbers
		// smp_start\end = sec * (samples/sec) = sample number
		// this sample number then indexes into the accum_buffer
		//
		int smp_start = (int)(win_start * sample_rate_d);
		int smp_end = (int)(win_end * sample_rate_d);
		
		// need to check to make sure the accum buffer has sample
		// data for this window
		// if the window start is AFTER the number of samples, then
		// we don't want this window at all
		//
		if (smp_start >= accum_num_samples_d) {
		    break;
		}
		
		if (smp_end >= accum_num_samples_d) {
		    break;
		}
		
		// If the end is greater than samples then we dont have a whole
		// window so set to the end of the sample count
		//
		if (smp_start > accum_num_samples_d) {
		    smp_start = accum_num_samples_d;
		}
		
		// reset the data
		//	    
	  
		for (int j = 0; j < data_length; j++) {
		    data[j] = (float)0.0;
		}
		
		// read the window of data in
		//
		int curr_sample = 0;
		
		for (int index = smp_start; index < smp_end; index++) {
		    
		    // make sure we dont go over end of data[] array
		    //
		    if (curr_sample < data_length) {
			data[curr_sample] = overall_samples_d[index];
			curr_sample ++ ;
		    }
		    
		}
	    }

	    // allocate array to store the data after energy,waveform,
	    // spectrogram calculation.
	    //
	    float realtime_energy = Energy(data);
	    float[] wave_array = WaveformCalculation(data);
	    float [] realtime_spec = SpectrogramCalculation(data);

	    // increate window account
	    //
	    window_count++;
	    
	    // plot energy
	    //
	    // set the energy maximum and minimum values
	    //
	    double max_val = WM_ENERGY_MAX_AMPLITUDE;
	    double min_val = WM_ENERGY_MIN_AMPLITUDE;
	    
	    // declare a variable for the energy value in decibels
	    //
	    double energy_log = (double)0.0;
	    double max_energy = 0.0;
	    
	    // If we are within two 'count's to the end of MAX_POINTS
	    // loop back around to the beginning
	    //
	    if (escale_d.equals("dB")) { 
		
		// check the bounds of the energy value
		//
		if (realtime_energy < WM_ENERGY_MIN_VALUE) {
		    energy_log = 10 * Math.log(WM_ENERGY_MIN_VALUE);
		}
		
		else {
		    // compute the energy in decibels
		    //
		    energy_log = 10 * WM_ENERGY_LOG10_E * Math.log(realtime_energy);
		}
		
		//energy_plot_begin_d = pts_received_energy_d;
		
		if (energy_log > max_energy) {
		    max_energy = energy_log;
		}
		
		// keep the energy value
		//
		realtime_energy_d[pts_received_energy_d] = (int)(energy_log); 
	    }
	    
	    else if (escale_d.equals("Linear")) {
		realtime_energy_d[pts_received_energy_d] = (int) realtime_energy;
	    }

	    	    
	    // plot waveform
	    //
	    // create two seperate array to store the max and min
	    // value of each calumn data.
	    //
	    realtime_waveform_min [pts_received_energy_d]= wave_array[0];
	    realtime_waveform_max [pts_received_energy_d]= wave_array[1];

	    // plot spec
	    // 
	    // set the spectrogram maximum and minimum values
	    //
	    max_val = WM_SPECTROGRAM_MAX_AMPLITUDE;
	    min_val = WM_SPECTROGRAM_MIN_AMPLITUDE;
	    
	    // find the normalizing values for the data
	    //
	    double scale_y = -1.0 / (max_val - min_val) * 
		(double)(height_d / 3 - 4);
	    
	    // declare a variable for the spectrogram value in decibels
	    //
	    float spectrogram_log = (float)0.0;

	    // declare a variable for spectrogram maximum value
	    //
	    double max_spectrogram = 0.0;
	    
	    // declare variables for plot spectrogram
	    //	  
	    float max = 0;
	    float min = 0 ;
	    int a = 0;

	   
	    if (sscale_d.equals("Hz")) {
		
		// inner loop for each grid
		//
		for ( int j = 0; j < fftLength/2; j++){


		    int log_val = (int)(20 * WM_SPECTROGRAM_LOG10_E * Math.log(realtime_spec[j]));
		    
		    //if (global_max_spectral_magnitude < log_val) {
			
		    //global_max_spectral_magnitude = log_val;
		    //System.out.println(" global_max_spectral_magnitude" + global_max_spectral_magnitude + "fftlength" +fftLength);
		    //		    }
	
		    if (log_val >= 0 && log_val <= 150) {

			pdf_array[log_val]++;
			num_points++;
		    }


	    
		    // scaling for different color map
		    //
		    // TI map	    
		    if (colormap_type == TI) {
			
			// compute the spectrogram value in decibels
			//
			//float log_value = (float)(20 * WM_SPECTROGRAM_LOG10_E * Math.log(realtime_spec[j]));
			
			
			// calculate the color map index taking into
			// all the relate factors.
			//
			float  col_map =(float) 115 * (float)(( 20 * WM_SPECTROGRAM_LOG10_E * Math.log(realtime_spec[j]))- log_nt - (min_spectral_magnitude - log_nt) )/(max_spectral_magnitude - min_spectral_magnitude);
			
			// set the color_map range from 0 to 115 in TI map
			//
			if(col_map > 115)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int)115;
			else if(col_map < 0)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = 0 ;
			else
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int) col_map;
		    }
		    
		    // GRAYSCALE map
		    //
		    if (colormap_type == GRAYSCALE) {
	
			// compute the spectrogram value in decibels
			//
			//float log_value = (float)(20 * WM_SPECTROGRAM_LOG10_E * Math.log( realtime_spec[j]));

			//calculate grayscale map index
			//
			float  col_map =(float) 255 * (float)((20 * WM_SPECTROGRAM_LOG10_E * Math.log( realtime_spec[j])) - log_nt - (min_spectral_magnitude - log_nt))/(max_spectral_magnitude - min_spectral_magnitude);

			// set the index range from 0 to 255 in grayscale map
			//
			if(col_map > 255)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int)255;
			else if(col_map < 0)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = 0 ;
			else
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int) col_map;
		    }
		    
		    // matlab map
		    //
		    if (colormap_type == MATLAB) {
			
			// compute the spectrogram value in decibels
			//
			//float log_value = (float)(20 * WM_SPECTROGRAM_LOG10_E * Math.log( realtime_spec[j]));

		
			//calculate grayscale map index
			//
			float  col_map =(float) 63 * (float)((20 
							      * WM_SPECTROGRAM_LOG10_E * 
							      Math.log( realtime_spec[j]))- 
							     log_nt - (min_spectral_magnitude 
								       - log_nt))/(max_spectral_magnitude 
										   - min_spectral_magnitude);
			
			// set the index range from 0 to 63 in matlab map
			//
			if(col_map > 63)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int)63;
			else if(col_map < 0)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = 0 ;
			else
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int) col_map;
		    }
		}
	    }
	    
	    
	    // repaint the window
	    //
	    run();
	    
	    // when the data in realtime buffer is no less than the
	    // data we need to plot in one window, we should use
	    // circular buffer.
	    //
	    if (pts_received_energy_d >= width_d - x_offset_d) {
		
		// reset the variable that controls the energy and
		// waveform plot position.
		//
		pts_received_energy_d = 0;
		
		// reset the variable that controls the spectrogram
		//  position.
		//
		pts_received_spectrogram_d = 0;
		
		// shifting the read pointer
		//
		read_pointer++;
		
		// set the circular buffer figure as one 
		circular_flag_d = 1;
		 
	    }
	    
	    // shifting the read pointer
	    //
	    if (read_pointer >= 1) {

		// keeps reading the data in the circular buffer.
		//
		pts_received_energy_d++;
		pts_received_spectrogram_d = pts_received_spectrogram_d + 1;

		// when read pointer moves to the last element of the
		// buffer index, turn back to the first one.
		//
		if ( read_pointer == width_d - x_offset_d) {
		    read_pointer = 0;
		}

		else {
		    read_pointer++;
		}
	    }
	    
	    // when the pointer back to the first index, keeps reading
	    // until get the fixed number ( the size of the circular
	    // buffer) of the data.
	    //
	    if (read_pointer == 0) {
		pts_received_energy_d++;
		pts_received_spectrogram_d = pts_received_spectrogram_d + 1;
	    }
	    
	    
	}

	// reset the resize to zero
	//
	RESIZED = 0;
	
	// exit gracefully
	//
	return true;
    }
    
    

    /**
     * plot in realtime.
     *
     * @return a boolean value indicating status.
     */
    public boolean realTimeCalPlot(float[] data_points) { 
	
	// local variable
	//
	float start_time = (float)0.0;
	
	// this is defined by the user
	//
	float end_time = (float)user_seconds_d;
	
	// log of window duration and sampling freq
	//
	log_nt = (float) (20 * WM_ENERGY_LOG10_E * (float)Math.log(window_duration_d/sample_rate_d));
	
	 float new_max_spectral_magnitude = max_spectral_magnitude + brightness_d * 100 - 50;
	 float new_min_spectral_magnitude = min_spectral_magnitude + brightness_d * 100 - 50;
	 float multiplicant = 0;
	 if (colormap_type == TI) {
	    
	     multiplicant = (float)(115 * (contrast_d + 0.5) /(new_max_spectral_magnitude - new_min_spectral_magnitude));
	 }
	 if (colormap_type == MATLAB) {
	    
	     multiplicant = (float)(63 * (contrast_d + 0.5) /(new_max_spectral_magnitude - new_min_spectral_magnitude));
	 } 
	 if (colormap_type == GRAYSCALE) {
	    
	     multiplicant = (float)(255 * (contrast_d + 0.5) /(new_max_spectral_magnitude - new_min_spectral_magnitude));
	 }

	 // set the number of pixels per second
	 //
	 float pixels_per_sec = (float)(width_d - x_offset_d) / 
	     (end_time - start_time);
	 
	 
	 // allocate memory
	 //
	 int energy_data_length = (int)(energy_window_duration_d *
					sample_rate_d) + 2;
	 
	 float[] energy_data = new float[energy_data_length];
	 
	 int spectrogram_data_length = (int)(energy_window_duration_d *
					     sample_rate_d) + 2;
	 
	 float[] spectrogram_data = new float[spectrogram_data_length];
 
	    
	 //int waveform_data_length = spectrogram_data_length;
	 //float[] waveform_data = new float[waveform_data_length];

	 // declear the variable to count the number of the window.
	 //
	 int window_count = 0;	
	 
	 // loop over each pixel
	 //
	 for (int i = 0; i < width_d - x_offset_d; i++) {
	     
	     // accum is total number of samples in our sample buffer
	     // sample rate is 8000\16000
	     // pixels_per_sec = (pixel/sec)
	     // i is the current pixel so
	     // (samples/(samples/sec)) * (pixels/sec) => total pixel of data
	     // if current pixel >= pixels of data, break
	     //
	     if( i >= ((data_points.length/sample_rate_d) * pixels_per_sec))
		 break;
	     
	     // compute the time in seconds that correspond to the
	     // pixel location
	     // pixel_count / (pixel/sec) + sec = sec
	     double pixel_time = i / pixels_per_sec + start_time;
	     double next_pixel_time = (i + 1)/ pixels_per_sec + start_time;
	     
	     // win_start\win_end 	    
	     // determine the bounds of the window around the pixel location
	     //
	     // pixel_time = (sec) - (sec/2) = sec
	     double waveform_win_start = pixel_time;
	     
	     if (waveform_win_start < start_time) {
		 waveform_win_start = start_time;
	     }
	     
	     double waveform_win_end = next_pixel_time;
	     
	     if (waveform_win_end > end_time) {
		 waveform_win_end = end_time;
	     }
	     
	     // these are actual sample count numbers
	     // smp_start\end = sec * (samples/sec) = sample number
	     // this sample number then indexes into the accum_buffer
	     //
	     int waveform_smp_start = (int)(waveform_win_start * sample_rate_d);
	     int waveform_smp_end = (int)(waveform_win_end * sample_rate_d);
	     
	     int waveform_data_length = (int)(waveform_smp_end - waveform_smp_start);
	     //float[] waveform_data = new float[spectrogram_data_length];
	     float[] waveform_data = new float[waveform_data_length];

	    // need to check to make sure the accum buffer has sample
	    // data for this window
	    // if the window start is AFTER the number of samples, then
	    // we don't want this window at all
	    //
	    if (waveform_smp_start >= data_points.length) {
		break;
	    }
	    
	    if (waveform_smp_end >= data_points.length) {
		break;
	    }
	    
	    // If the end is greater than samples then we dont have a whole
	    // window so set to the end of the sample count
	    //
	    if (waveform_smp_start > data_points.length) {
		waveform_smp_start = data_points.length;
	    }
	    
	    // reset the data
	    //	    
	    for (int j = 0; j < waveform_data_length; j++) {
	    waveform_data[j] = (float)0.0;
	    }
	    
	    // read the window of data in
	    //
	    int curr_sample = 0;
	    
	    for (int index = waveform_smp_start; index < waveform_smp_end; index++) {
	
		// make sure we dont go over end of data[] array
		//
		if (curr_sample < waveform_data_length) {
		    waveform_data[curr_sample] = 32767 * data_points[index]/waveform_height_d;
		    curr_sample ++ ;
		}
	    }

	    // win_start\win_end 	    
	    // determine the bounds of the window around the pixel location
	    //
	    // pixel_time = (sec) - (sec/2) = sec
	    double energy_win_start = pixel_time - (energy_window_duration_d / 2.0);
	    
	    // set the win_start and win_end
	    // 
	    if (energy_win_start < start_time) {
		energy_win_start = start_time;
	    }
	    
	    double energy_win_end = pixel_time + (spectrogram_window_duration_d / 2.0);
	    
	    if (energy_win_end > end_time) {
		energy_win_end = end_time;
	    }
	    
	    // these are actual sample count numbers
	    // smp_start\end = sec * (samples/sec) = sample number
	    // this sample number then indexes into the accum_buffer
	    //
	    int energy_smp_start = (int)(energy_win_start * sample_rate_d);
	    int energy_smp_end = (int)(energy_win_end * sample_rate_d);
	    
	    // need to check to make sure the accum buffer has sample
	    // data for this window
	    // if the window start is AFTER the number of samples, then
	    // we don't want this window at all
	    //
	    if (energy_smp_start >= data_points.length) {
		break;
	    }

	    if (energy_smp_end >= data_points.length) {
		break;
	    }
	    
	    // If the end is greater than samples then we dont have a whole
	    // window so set to the end of the sample count
	    //
	    if (energy_smp_start > data_points.length) {
		energy_smp_start = data_points.length;
	    }
	    
	    // reset the data
	    //	    
	    for (int j = 0; j < energy_data_length; j++) {
		energy_data[j] = (float)0.0;
	    }

	    // read the window of data in
	    //
	    curr_sample = 0;

	    for (int index = energy_smp_start; index < energy_smp_end; index++) {
		
		// make sure we dont go over end of data[] array
		//
		if (curr_sample < energy_data_length) {
		    energy_data[curr_sample] = data_points[index];
		    curr_sample ++ ;
		}
	    }


	    
	    // win_start\win_end 	    
	    // determine the bounds of the window around the pixel location
	    //
	    // pixel_time = (sec) - (sec/2) = sec
	    double spectrogram_win_start = pixel_time - (spectrogram_window_duration_d / 2.0);
	    
	    // set the win_start and win_end
	    // 
	    if (spectrogram_win_start < start_time) {
		spectrogram_win_start = start_time;
	    }
	    
	    double spectrogram_win_end = pixel_time + (spectrogram_window_duration_d / 2.0);
	    
	    if (spectrogram_win_end > end_time) {
		spectrogram_win_end = end_time;
	    }
	    
	    // these are actual sample count numbers
	    // smp_start\end = sec * (samples/sec) = sample number
	    // this sample number then indexes into the accum_buffer
	    //
	    int spectrogram_smp_start = (int)(spectrogram_win_start * sample_rate_d);
	    int spectrogram_smp_end = (int)(spectrogram_win_end * sample_rate_d);
	    
	    // need to check to make sure the accum buffer has sample
	    // data for this window
	    // if the window start is AFTER the number of samples, then
	    // we don't want this window at all
	    //
	    if (spectrogram_smp_start >= data_points.length) {
		break;
	    }

	    if (spectrogram_smp_end >= data_points.length) {
		break;
	    }
	    
	    // If the end is greater than samples then we dont have a whole
	    // window so set to the end of the sample count
	    //
	    if (spectrogram_smp_start > data_points.length) {
		spectrogram_smp_start = data_points.length;
	    }
	    
	    // reset the data
	    //	    
	    for (int j = 0; j < spectrogram_data_length; j++) {
		spectrogram_data[j] = (float)0.0;
	    }

	    // read the window of data in
	    //
	    curr_sample = 0;

	    for (int index = spectrogram_smp_start; index < spectrogram_smp_end; index++) {
		
		// make sure we dont go over end of data[] array
		//
		if (curr_sample < spectrogram_data_length) {
		    spectrogram_data[curr_sample] = data_points[index];
		    curr_sample ++ ;
		}
	    }

	    // allocate memory to store the data that after energy,
	    // waveform and spec calculation.
	    //
	    float realtime_energy = Energy(energy_data);
	    float[] wave_array = WaveformCalculation(waveform_data);
	    
	    // todo
	    //
	    for (int kk = 0; kk < wave_array.length; kk++) {
		System.out.println("wave_array " + kk + " " + wave_array[kk]);
	    } 
	    float [] realtime_spec = SpectrogramCalculation(spectrogram_data);
	    
	    window_count++;
	    
	    // plot energy
	    // set the energy maximum and minimum values
	    //
	    double max_val = WM_ENERGY_MAX_AMPLITUDE;
	    double min_val = WM_ENERGY_MIN_AMPLITUDE;
	    
	    // declare a variable for the energy value in decibels
	    //
	    double energy_log = (double)0.0;
	    double max_energy = 0.0;
	    
	    // If we are within two 'count's to the end of MAX_POINTS
	    // loop back around to the beginning
	    //
	    if (escale_d.equals("dB")) { 
		
		// check the bounds of the energy value
		//
		if (realtime_energy < WM_ENERGY_MIN_VALUE) {
		    energy_log = 10 * Math.log(WM_ENERGY_MIN_VALUE);
		}
		
		else {
		    // compute the energy in decibels
		    //
		    energy_log = 10 * WM_ENERGY_LOG10_E * Math.log(realtime_energy);
		}
		
		//energy_plot_begin_d = pts_received_energy_d;
		
		if (energy_log > max_energy) {
		    max_energy = energy_log;
		}
		
		// keep the energy value
		//
		realtime_energy_d[pts_received_energy_d] = (int)(energy_log); 
	    }
	    
	    else if (escale_d.equals("Linear")) {
		realtime_energy_d[pts_received_energy_d] = (int) realtime_energy;
	    }

	    // plot waveform
	    //
	    // store the max and min waveform value of each column
	    // into seperate array to plot.
	    //
	    realtime_waveform_min [pts_received_energy_d]= wave_array[0];
	    realtime_waveform_max [pts_received_energy_d]= wave_array[1];
	   
	    // plot spec
	    // 
	    // set the spectrogram maximum and minimum values
	    //
	    max_val = WM_SPECTROGRAM_MAX_AMPLITUDE;
	    min_val = WM_SPECTROGRAM_MIN_AMPLITUDE;
	    
	    // find the normalizing values for the data
	    //
	    double scale_y = -1.0 / (max_val - min_val) * 
		(double)(height_d / 3 - 4);
	    
	    // declare a variable for the spectrogram value in decibels
	    //
	    float spectrogram_log = (float)0.0;
	    double max_spectrogram = 0.0;
	    
	    // declear variables for sacling
	    //
	    float max = 0;
	    float min = 100 ;
	    int a = 0;
	    
	    if (sscale_d.equals("Hz")) {
		
		// inner loop for each grid
		//
		for ( int j = 0; j < fftLength/2; j++){


		    int log_val = (int)(20 * WM_SPECTROGRAM_LOG10_E * Math.log(realtime_spec[j]));
		    
		    //if (global_max_spectral_magnitude < log_val) {
			
		    //global_max_spectral_magnitude = log_val;
		    //System.out.println(" global_max_spectral_magnitude" + global_max_spectral_magnitude + "fftlength" +fftLength);
		    //		    }
	
		    if (log_val >= 0 && log_val <= 150) {

			pdf_array[log_val]++;
			num_points++;
		    }


	    
		    // scaling for different color map
		    //
		    // TI map	    
		    if (colormap_type == TI) {
			
			// compute the spectrogram value in decibels
			//
			//float log_value = (float)(20 * WM_SPECTROGRAM_LOG10_E * Math.log(realtime_spec[j]));
			
			
			// calculate the color map index taking into
			// all the relate factors.
			//
			float  col_map =(float)(( 20 * WM_SPECTROGRAM_LOG10_E * Math.log(realtime_spec[j]))- log_nt - (new_min_spectral_magnitude - log_nt)) * multiplicant;
			
			// set the color_map range from 0 to 115 in TI map
			//
			if(col_map > 115)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int)115;
			else if(col_map < 0)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = 0 ;
			else
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int) col_map;
		    }
		    
		    // GRAYSCALE map
		    //
		    if (colormap_type == GRAYSCALE) {
	
			// compute the spectrogram value in decibels
			//
			//float log_value = (float)(20 * WM_SPECTROGRAM_LOG10_E * Math.log( realtime_spec[j]));

			//calculate grayscale map index
			//
			float  col_map =(float)((20 * WM_SPECTROGRAM_LOG10_E * Math.log( realtime_spec[j])) - log_nt - (min_spectral_magnitude - log_nt)) * multiplicant;

			// set the index range from 0 to 255 in grayscale map
			//
			if(col_map > 255)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int)255;
			else if(col_map < 0)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = 0 ;
			else
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int) col_map;
		    }
		    
		    // matlab map
		    //
		    if (colormap_type == MATLAB) {
			
			// compute the spectrogram value in decibels
			//
			//float log_value = (float)(20 * WM_SPECTROGRAM_LOG10_E * Math.log( realtime_spec[j]));

		
			//calculate grayscale map index
			//
			float  col_map =(float)((20 * WM_SPECTROGRAM_LOG10_E * 
						 Math.log( realtime_spec[j]))- 
						log_nt - (min_spectral_magnitude 
							  - log_nt)) * multiplicant;
			
			// set the index range from 0 to 63 in matlab map
			//
			if(col_map > 63)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int)63;
			else if(col_map < 0)
			    spectrogram_color_array[pts_received_spectrogram_d][j] = 0 ;
			else
			    spectrogram_color_array[pts_received_spectrogram_d][j] = (int) col_map;
		    }
		}
	    }
	    
	    
	    // repaint the window
	    //
	    run();
	    
	    // when the data in realtime buffer is no less than the
	    // data we need to plot in one window, we should use
	    // circular buffer.
	    //
	    if (pts_received_energy_d >= width_d - x_offset_d) {
		
		// reset the variable that controls the energy and
		// waveform plot position.
		//
		pts_received_energy_d = 0;
		
		// reset the variable that controls the spectrogram
		//  position.
		//
		pts_received_spectrogram_d = 0;
		
		// shifting the read pointer
		//
		read_pointer++;
		
		// set the circular buffer figure as one 
		circular_flag_d = 1;
		 
	    }
	    
	    // shifting the read pointer
	    //
	    if (read_pointer >= 1) {

		// keeps reading the data in the circular buffer.
		//
		pts_received_energy_d++;
		pts_received_spectrogram_d = pts_received_spectrogram_d + 1;

		// when read pointer moves to the last element of the
		// buffer index, turn back to the first one.
		//
		if ( read_pointer == width_d - x_offset_d) {
		    read_pointer = 0;
		}

		else {
		    read_pointer++;
		}
	    }
	    
	    // when the pointer back to the first index, keeps reading
	    // until get the fixed number ( the size of the circular
	    // buffer) of the data.
	    //
	    if (read_pointer == 0) {
		pts_received_energy_d++;
		pts_received_spectrogram_d = pts_received_spectrogram_d + 1;
	    }
	    
	    
	}
	
	// exit gracefully
	//
	return true;
	
    } // end of realtime mode.
    


    // overall mode
    //
    public boolean overallCalPlot(float[] data_points) { 
	
	// local variable
	//
	float start_time = (float)0.0;
       
	float inc = 0;
	for (int i = 0; i < 151; i++) {
	    
	    pdf_array[i] = (float)(pdf_array[i]/ num_points);
	    inc += pdf_array[i];
	    System.out.println("pdf_array " + i + " " + pdf_array[i]);
	    cdf_array[i] = inc;
	    System.out.println("cdf_array " + i + " " + cdf_array[i]);
	    //if (inc >= 0.95) {
	    //System.out.println("the max val " + i);
	    //weighted_max_spectral_magnitude = i;		
	    //break;
	    //}
	}

	for (int i = 0; i < 151; i++) {
	    
	    if(cdf_array[i] <= 0.75){
		System.out.println("the min val " + i);
		weighted_min_spectral_magnitude = i;
	    }
	    if (cdf_array[i] >= 0.95) {
		System.out.println("the max val " + i);
		weighted_max_spectral_magnitude = i;		
		break;
	    }
	}


	float new_weighted_max_spectral_magnitude = weighted_max_spectral_magnitude + brightness_d * 100 - 50;
	float new_weighted_min_spectral_magnitude = weighted_min_spectral_magnitude + brightness_d * 100 - 50;
	float multiplicant = 0;
	 if (colormap_type == TI) {
	     
	     multiplicant = (float)(115 * (contrast_d + 0.5) /(new_weighted_max_spectral_magnitude - new_weighted_min_spectral_magnitude));
	 }
	 if (colormap_type == MATLAB) {
	     
	     multiplicant = (float)(63 * (contrast_d + 0.5) /(new_weighted_max_spectral_magnitude - new_weighted_min_spectral_magnitude));
	 } 
	 if (colormap_type == GRAYSCALE) {
	     
	     multiplicant = (float)(255 * (contrast_d + 0.5) /(new_weighted_max_spectral_magnitude - new_weighted_min_spectral_magnitude));
	 }
	 
	// this is defined by the user
	//
	float end_time = (float)(1.0 / sample_rate_d) * 
	    (float)data_points.length;
	
	//System.out.println("$$$data_length " + data_points.length);
	
	// set the number of pixels per second
	//
	float pixels_per_sec = (float)(width_d - x_offset_d) / 
	    (end_time - start_time);
	
	// log of window duration and sampling freq
	//
	//log_nt = (float) (20 * WM_ENERGY_LOG10_E * Math.log(window_duration_d/sample_rate_d));
	
	// allocate memory
	//
	int energy_data_length = (int)(energy_window_duration_d * sample_rate_d)+ 2;
 	float[] energy_data = new float[energy_data_length];
	int spectrogram_data_length = (int)(spectrogram_window_duration_d * sample_rate_d) + 2;
 	float[] spectrogram_data = new float[spectrogram_data_length];
	int window_count = 0;	

	// allocate memory
	//
	overall_energy_x_d = new int[width_d];
	overall_energy_y_d = new int[width_d];
	pts_waveform_x_d =  new int[2*width_d];
	pts_waveform_y_d = new int [2*width_d];
	overall_waveform = new float [2* width_d];
	
	// loop over each pixel
	//
	for (int i = 0; i < width_d - x_offset_d; i++) {
	    
	    // accum is total number of samples in our sample buffer
	    // sample rate is 8000\16000
	    // pixels_per_sec = (pixel/sec)
	    // i is the current pixel so
	    // (samples/(samples/sec)) * (pixels/sec) => total pixel of data
	    // if current pixel >= pixels of data, break
	    //
	    if( i >= ((data_points.length/sample_rate_d) * pixels_per_sec))
		break;
	    
	    // compute the time in seconds that correspond to the
	    // pixel location
	    //
	    // pixel_count / (pixel/sec) + sec = sec
	    double pixel_time = i / pixels_per_sec + start_time;
	    
	    double next_pixel_time = (i + 1)/ pixels_per_sec + start_time;
	    
	    // win_start\win_end 	    
	    // determine the bounds of the window around the pixel location
	    //
	    // pixel_time = (sec) - (sec/2) = sec
	    double waveform_win_start = pixel_time;
	    
	    if (waveform_win_start < start_time) {
		waveform_win_start = start_time;
	    }
	    
	    double waveform_win_end = next_pixel_time;
	    
	    if (waveform_win_end > end_time) {
		waveform_win_end = end_time;
	    }
	    
	    // these are actual sample count numbers
	    // smp_start\end = sec * (samples/sec) = sample number
	    // this sample number then indexes into the accum_buffer
	    //
	    int waveform_smp_start = (int)(waveform_win_start * sample_rate_d);
	    int waveform_smp_end = (int)(waveform_win_end * sample_rate_d);
	    
	    int waveform_data_length = (int)(waveform_smp_end - waveform_smp_start);
	    //float[] waveform_data = new float[spectrogram_data_length];
	    float[] waveform_data = new float[waveform_data_length];

	    // need to check to make sure the accum buffer has sample
	    // data for this window
	    // if the window start is AFTER the number of samples, then
	    // we don't want this window at all
	    //
	    if (waveform_smp_start >= data_points.length) {
		break;
	    }
	    
	    if (waveform_smp_end >= data_points.length) {
		break;
	    }
	    
	    // If the end is greater than samples then we dont have a whole
	    // window so set to the end of the sample count
	    //
	    if (waveform_smp_start > data_points.length) {
		waveform_smp_start = data_points.length;
	    }
	    
	    // reset the data
	    //	    
	    for (int j = 0; j < waveform_data_length; j++) {
		waveform_data[j] = (float)0.0;
	    }
	    
	    // read the window of data in
	    //
	    int curr_sample = 0;
	    
	    for (int index = waveform_smp_start; index < waveform_smp_end; index++) {
	
		// make sure we dont go over end of data[] array
		//
		if (curr_sample < waveform_data_length) {
		    waveform_data[curr_sample] = 32767 * data_points[index]/waveform_height_d;
		    curr_sample ++ ;
		}
	    }
	    


	    // win_start\win_end 	    
	    // determine the bounds of the window around the pixel location
	    //
	    // pixel_time = (sec) - (sec/2) = sec
	    double energy_win_start = pixel_time - (energy_window_duration_d / 2.0);

	    if (energy_win_start < start_time) {
		energy_win_start = start_time;
	    }
	    
	    double energy_win_end = pixel_time + (energy_window_duration_d / 2.0);
	    
	    if (energy_win_end > end_time) {
		energy_win_end = end_time;
	    }
	    
	    // these are actual sample count numbers
	    // smp_start\end = sec * (samples/sec) = sample number
	    // this sample number then indexes into the accum_buffer
	    //
	    int energy_smp_start = (int)(energy_win_start * sample_rate_d);
	    int energy_smp_end = (int)(energy_win_end * sample_rate_d);
	    
	    // need to check to make sure the accum buffer has sample
	    // data for this window
	    // if the window start is AFTER the number of samples, then
	    // we don't want this window at all
	    //
	    if (energy_smp_start >= data_points.length) {
		break;
	    }
	    
	    if (energy_smp_end >= data_points.length) {
		break;
	    }
	    
	    // If the end is greater than samples then we dont have a whole
	    // window so set to the end of the sample count
	    //
	    if (energy_smp_start > data_points.length) {
		energy_smp_start = data_points.length;
	    }
	    
	    // reset the data
	    //	    
	    for (int j = 0; j < energy_data_length; j++) {
		energy_data[j] = (float)0.0;
	    }

	    // read the window of data in
	    //
	    curr_sample = 0;

	    for (int index = energy_smp_start; index < energy_smp_end; index++) {
	
		// make sure we dont go over end of data[] array
		//
		if (curr_sample < energy_data_length) {
		    energy_data[curr_sample] = data_points[index];
		    curr_sample ++ ;
		}
	    }

	    // win_start\win_end 	    
	    // determine the bounds of the window around the pixel location
	    //
	    // pixel_time = (sec) - (sec/2) = sec
	    double spectrogram_win_start = pixel_time - (spectrogram_window_duration_d / 2.0);

	    if (spectrogram_win_start < start_time) {
		spectrogram_win_start = start_time;
	    }
	    
	    double spectrogram_win_end = pixel_time + (spectrogram_window_duration_d / 2.0);
	    
	    if (spectrogram_win_end > end_time) {
		spectrogram_win_end = end_time;
	    }
	    
	    // these are actual sample count numbers
	    // smp_start\end = sec * (samples/sec) = sample number
	    // this sample number then indexes into the accum_buffer
	    //
	    int spectrogram_smp_start = (int)(spectrogram_win_start * sample_rate_d);
	    int spectrogram_smp_end = (int)(spectrogram_win_end * sample_rate_d);
	    
	    // need to check to make sure the accum buffer has sample
	    // data for this window
	    // if the window start is AFTER the number of samples, then
	    // we don't want this window at all
	    //
	    if (spectrogram_smp_start >= data_points.length) {
		break;
	    }
	    
	    if (spectrogram_smp_end >= data_points.length) {
		break;
	    }
	    
	    // If the end is greater than samples then we dont have a whole
	    // window so set to the end of the sample count
	    //
	    if (spectrogram_smp_start > data_points.length) {
		spectrogram_smp_start = data_points.length;
	    }
	    
	    // reset the data
	    //	    
	    for (int j = 0; j < spectrogram_data_length; j++) {
		spectrogram_data[j] = (float)0.0;
	    }

	    // read the window of data in
	    //
	    curr_sample = 0;

	    for (int index = spectrogram_smp_start; index < spectrogram_smp_end; index++) {
	
		// make sure we dont go over end of data[] array
		//
		if (curr_sample < spectrogram_data_length) {
		    spectrogram_data[curr_sample] = data_points[index];
		    curr_sample ++ ;
		}
	    } 

	    
	    // store the value after calculation in the corresponding array
	    //
	   
	   
	    float [] overall_spec = SpectrogramCalculation(spectrogram_data);
	    float overall_energy = Energy(energy_data);
	    float[] overall_wave = WaveformCalculation(waveform_data);
	    window_count++;

	    // plot energy
	    //
	    float energy_log = (float)0.0;
	    float max_energy =(float) 0.0;
	    
	    if (escale_d.equals("dB")) {
		
		overall_energy_x_d[i] = i + x_offset_d;
		
		// check the bounds of the energy value
		//
		if ( overall_energy < WM_ENERGY_MIN_VALUE) {
		    energy_log =(float)( 10 * Math.log(WM_ENERGY_MIN_VALUE));
		}
		
		else {
		    // compute the energy in decibels
		    //
		    energy_log = (float)(10 * WM_ENERGY_LOG10_E * Math.log(overall_energy));
		}
		
		if (energy_log > max_energy) {
		    max_energy = energy_log;
		}
		
		// keep the energy value
		//
		overall_energy_y_d[i] = (int)(energy_log); 
	    }
	    
	    
	    else if (escale_d.equals("Linear")) {
		overall_energy_x_d[i] = i + x_offset_d;
		overall_energy_y_d[i] = (int)overall_energy;
	    }
	    
	    System.out.println("$EE" + "overall_energy_x_d " + i + overall_energy_x_d[i] + "overall_energy_y_d" + overall_energy_y_d[i]);
	    // store the values into the array for plotting.
	    //
	    overall_waveform[2*i] = overall_wave[0];
	    overall_waveform[2*i + 1]= overall_wave[1];
	    pts_waveform_y_d[2*i]= (int) overall_wave[0];
	    pts_waveform_y_d[2*i + 1]= (int) overall_wave[1];
	    pts_waveform_x_d[2*i] = i;
	    pts_waveform_x_d[2*i + 1] = i;
	    
	    // to make sure the size never beyond the window
	    //
	    if (pts_received_energy_d >= width_d) {
		pts_received_energy_d = 0;
	    }

	    // plot spec
	    // 
	    // set the spectrogram maximum and minimum values
	    //
	    float max_val =(float) WM_SPECTROGRAM_MAX_AMPLITUDE;
	    float min_val =(float) WM_SPECTROGRAM_MIN_AMPLITUDE;
	    
	    // find the normalizing values for the data
	    //
	    double scale_y = -1.0 / (max_val - min_val) * 
		(double)(height_d / 3 - 4);
	    
	    // declare a variable for the spectrogram value in decibels
	    //
	    float spectrogram_log = (float)0.0;
	    double max_spectrogram = 0.0;
	    
	    // If we are within two 'count's to the end of MAX_POINTS
	    // loop back around to the beginning
	    //

	    if (sscale_d.equals("Hz")) {
		
		// inner loop for each grid
		//
		for ( int j = 0; j < fftLength/2;j++){
		    
		    // scaling for different color map
		    //
		    // TI map	    		    		    
		    if (colormap_type == TI) {
			
			// calculate the color map index taking into
			// all the relate factors.
			//
			float  col_map =(float)((20 * WM_SPECTROGRAM_LOG10_E * Math.log(overall_spec[j]))- (new_weighted_min_spectral_magnitude)) * multiplicant;
			// set the color_map range from 0 to 115 in TI map
			//			  
			if(col_map > 115)
			    spectrogram_color_array[i][j] = (int)115;
			else if(col_map < 0)
			    spectrogram_color_array[i][j] = 0 ;
			else
			    spectrogram_color_array[i][j] = (int) col_map;
		    }
		    
		    // GRAYSCALE map
		    //
		     if (colormap_type == GRAYSCALE) {

			//calculate grayscale map index
			//
			float  col_map =(float)((20 * WM_SPECTROGRAM_LOG10_E * Math.log(overall_spec[j]))- (new_weighted_min_spectral_magnitude)) * multiplicant;
			
			// set the index range from 0 to 255 in grayscale map
			 //
			if(col_map > 255)
			    spectrogram_color_array[i][j] = (int)255;
			else if(col_map < 0)
			    spectrogram_color_array[i][j] = 0 ;
			else
			    spectrogram_color_array[i][j] = (int) col_map;
		     }
		     
		     
		     // matlab map
		     //
		     if (colormap_type == MATLAB) {
			 
			 //calculate grayscale map index
			 //
			 float  col_map =(float)((20 * WM_SPECTROGRAM_LOG10_E * Math.log(overall_spec[j]))- (new_weighted_min_spectral_magnitude)) * multiplicant;
			 
			 // set the index range from 0 to 255 in grayscale map
			 //
			 if(col_map > 63)
			     spectrogram_color_array[i][j] = (int)63;
			 else if(col_map < 0)
			     spectrogram_color_array[i][j] = 0 ;
			 else
			     spectrogram_color_array[i][j] = (int) col_map;
		     
		     }
		}
	    }
	}		 		     
	
	// repaint
	//
	run();
	
	// exit gracefully
	//
	return true;
    }
    
    
    /** 
     * Main driver program. Used to test this class separately.
     *
     * @param args arguments from the command line.
     */
    public static void main(String args[]) {
	
        final SpeechDisplay splot = new SpeechDisplay();

        WindowListener l = new WindowAdapter() {
		public void windowClosing(WindowEvent e) { System.exit(0); }
	    };
	
        JFrame f = new JFrame("SpeechDisplay");
	
        f.addWindowListener(l);
        f.getContentPane().add("Center", splot);
        f.pack();
        f.setVisible(true);
	
	splot.setSampleRate(8000);
	
	int counter = 0;
	
	//boolean realtime = true;
	boolean realtime = false;
	int modeCounter = 0;

	float percentage = (float)(1.0 / 3.0);

	// initilaize the graphic display
	//
	float percentage_1 = (float) 0.33;
	float percentage_2 = (float) 0.33;
	float percentage_3 = (float) 0.33;
	
	//
	splot.setConfiguration(percentage_1, percentage_2, percentage_3);
	splot.setMode(realtime);

	splot.setEScale("dB");
	splot.setSScale("Hz");

	Random generator = new Random();
	
	//	while (true) {
	    	   
	//int num_sample = 16000;
	//num_sample = generator.nextInt(50000);
	    
	//float [] float16 = new float[num_sample];
   
	//  int input_frequency1 = 100;
	//  int sample_frequency = 8000;
	    
	//  for (int k = 0; k < num_sample; k++) {
	//float16[k] = 10000 * (float)Math.sin((float)2 * Math.PI * k * input_frequency1/ sample_frequency);
		//float16[k] = (float)Math.sin((float)2 * Math.PI * k / sample_frequency);
		//float16[k] = 10000;
	//   }

	//  splot.setData(float16);
	//  byte[] audio = new byte [float16.length * 2];
	//  splot.floatToByte(audio,float16);
	    
	//  for( int j = 0; j < audio.length; j++) {
	//System.out.println("auido index " + j + " " + audio[j]);
	//  }
	    try {
		//FileOutputStream ss = new FileOutputStream("audio.raw");	
		//ss.write(audio);
	    
		FileInputStream rr = new FileInputStream(args[0]);
		byte[] file_read = new byte [ rr.available()];
		rr.read(file_read);
		float[] float_read = new float [ file_read.length/2];
		splot.byteToFloat(float_read, file_read, float_read.length);
	   
		//System.out.println("$$$$$");
		//	for( int j = 0; j < float_read.length; j++) {
		//  System.out.println("index " + j + " " + float_read[j]);
		//}
		splot.setMode(true);
		splot.setData(float_read);
		splot.setMode(false);
		splot.setData(float_read);
	    }
	    catch (Exception e) { }
	    
	    //  } // end of while
	
    }  // main method
    


  /**
     * Calculate the energy for a windowed frame data.
     *
     * @param data_a an array of sampled data.
     *
     * @return a energy value for this frame data.
     */
    public float Energy(float[] data_a) {
	
	float[] data_energy = new float[data_a.length];
	float pixel_energy = 0;
	int data_length = data_a.length;
	
	// use the desired window function for the data
	//
	for (int samp_num = 0; samp_num < data_length; samp_num++) {
	    
	    float x_in = data_a[samp_num];
	    data_energy[samp_num] = x_in * 
		(float)(WM_DEFAULT_HAMMING_COEFF - 
			(((float)1.0 - WM_DEFAULT_HAMMING_COEFF) 
			 * Math.cos(2.0 * Math.PI * 
				    (float)samp_num / 
				    (float)(data_length - 1))));
	}
	
	// compute the energy of the data
	//
	for (int samp_num = 0; samp_num < data_length; samp_num++) {
	    
	    pixel_energy += data_energy[samp_num] * data_energy[samp_num];
	    
	}		
	
	pixel_energy /= (float)data_length;
	// for test
	//pixel_energy =  pixel_energy;
	//System.out.println ( "the value of energy is: " + pixel_energy);
	return pixel_energy;

    }
    
    public boolean specHamming (float[] data_a, float coeff_Hamm, int sample_num) {
        
	int i = 0;

	// check for null data
        //
	if (data_a.length != 0) {
	   
	     if (sample_num > 1) {
    
                  for (i = 0; i < sample_num ; i++) {
			   float x_n = data_a[i];
			   float x_hamm_n = x_n * (float)(coeff_Hamm -(((float)1.0 - coeff_Hamm) * cos((2*Math.PI)
												       * (float)sample_num/(float)(sample_num - 1))));
			   data_a [i] = x_hamm_n;
		  }
		 }
	     else
		 return  false; // when sample = 1, end the function.
	     return true;
	}
        else 
	    System.out.println("There is no data can precess"+ "\n");
        return false;
     }


    /**
     * Waveform calculation in real time display mode.
     *
     * @return a boolean value indicating status.
     */
    public float[] WaveformCalculation (float[] data) {

	float[] output_array = new float [2];
	int i_cur_time = 0;
	int i_end_time = data.length;
	float sample_val = 0;
	
	int data_length = data.length;
	float data_a[] = new float[data.length];

	// use the desired window function for the data
	//
	for (int samp_num = 0; samp_num < data_length; samp_num++) {
	    
	    float x_in = data[samp_num];
	    data_a[samp_num] = x_in * 
		(float)(WM_DEFAULT_HAMMING_COEFF - 
			(((float)1.0 - WM_DEFAULT_HAMMING_COEFF) 
			 * Math.cos(2.0 * Math.PI * 
				    (float)samp_num / 
				    (float)(data_length - 1))));
	}
	
	// These two values hold the TOTAL minimum and maximum for all samples
	// found. They are initialized to the polar opposite ends to guarantee
	// that the first "max" value will be larger than the min value and
	// the first "min" is smaller than the max value.
	//
	//int min_val = (int)maximum_waveform_d;
	//System.out.println( " data.length :   " + data.length);
	//System.out.println( " i_cur_time  :   " + i_cur_time);
	//System.out.println( " i_end_time  :   " + i_end_time);
	
	float max_val = 0;
	float min_val = 0;
	
	// main loop
	//
	while (i_cur_time < i_end_time) {
	    
	    // the difference between i_cur_time and i_end_time is set to 
	    // the user defined number of seconds. But in the beginning of the 
	    // recording we are going have the speech data lesser than 
		// i_end_time - i_cur_time. So we need to check for the number of samples 
		// we have got and appropriately break from the loop 
		//
	    if( i_cur_time >= data.length)
		break;
		
		// compute the sample value
		//
		sample_val = (float)data_a[i_cur_time]; //TODO
		//System.out.println(" the sample_value is : " + sample_val);

		if (sample_val < min_val) {
		
		    min_val = sample_val;
		}
		

		if (sample_val > max_val) {
		    
		    max_val = sample_val;
		   
		}
	
		i_cur_time++;
	
	    }
	    
	    // output the critical points if necessary
	    //
	    // second part must be true if we are in this loop
	    //
	    // the lowest valued sample in this window
	    //
	    output_array[0] = min_val;
	    output_array[1] = max_val;
	    if(maximum_waveform_d < max_val){
		maximum_waveform_d = max_val;
	    }
	    //System.out.println("!!!min_val:" + min_val + "    max_val" + max_val);	    
	    //System.out.println("!!!multiplied min_val:" + output_array[0] + "    max_val" + output_array[1]);	    

	    // exit gracefully
	    //
	    return output_array;
	
    }
 
    // TODO
     /**
     * Calculate the spectrogram for a windowed frame data.
     *
     * @param data_a an array of sampled data.
     *
     * @return a column of spectrogram value for this frame data.
     */

    public float[]  SpectrogramCalculation(float[] input_a) { 

	// fft length is initialised to 2 and will be increased
	// depending on the number of samples in the window
	// make adjustment of window size for hamming and fft computation
        //
	while (fftLength < (spectrogram_window_duration_d * sample_rate_d)){
	fftLength = fftLength * 2;
	}
	
	// hamming operation
	//
	specHamming(input_a,(float)0.54, (int)(spectrogram_window_duration_d * sample_rate_d));
	
	/*
	// use the desired window function for the data
	//
	for (int samp_num = 0; samp_num < input_a.length; samp_num++) {
	
	float x_in = input_a[samp_num];
	input_a[samp_num] = x_in * 
	(float)(WM_DEFAULT_HAMMING_COEFF - 
	(((float)1.0 - WM_DEFAULT_HAMMING_COEFF) 
	* Math.cos(2.0 * Math.PI * 
	(float)samp_num / 
	(float)(input_a.length - 1))));
	}
	*/

	float[] data_spec = new float[fftLength];
	for (int i = 0; i < fftLength; i++) {
	    
	    if(i < spectrogram_window_duration_d * sample_rate_d) {
		data_spec[i] = input_a[i];
	    }
	    else {
		data_spec[i] = 0;
	    }
	    
	}
	
	Fft fft_comp = new Fft();
	
	// declare a input array
	//
	    fft_comp.rad2_init_c(fftLength);
	    
	    // compute the fft
	    //
	    float [] spec_column = fft_comp.rad2_real_cc(data_spec);
	    
	    // exit gracefully
	    //
	    return spec_column;	
	
    }

   public boolean pre_filter ( float[] input_a, float coeff_a, int sample_num){
        int i=0;

        
	// check for null data
        //
	if (input_a.length != 0)
         {
	   
             //loop over all data do filter computation 
	     //
             for (i = sample_num - 1 ; i > 0; i--)
		 {
		    float x_filt = input_a[i]-(coeff_a * input_a[ i - 1 ]);
		     input_a [i] = x_filt;
                  }
             input_a[0] =input_a[0] * (1 - coeff_a);
         return true;
         }
        else System.out.println("There is no data can precess"+ "\n");
        return false;
     }


 /** 
     * Convert float array to byte array.
     *
     * @param byteSound User provided byte array to return result in.
     * @param dbuf User provided float array to convert.
     */
    public void floatToByte(byte[] byteSound, float [] dbuf) {
        
	// check whether this will work
	//
	int bufsz = dbuf.length;
        int ib = 0;
        
	//if(format_d.isBigEndian()) {
            for(int i = 0; i < bufsz; i++) {
                int j=0;
		//while (j < getNumOfChannels()) {
		    short y = (short)Math.round(dbuf[i]);
		    byteSound[ib] = (byte)(y >> 8);
		    //if (byteSound[ib] < 0) {
		    //byteSound[ib] = byteSound[ib] + 256;
		    //}
		    ib++;
		    byteSound[ib] = (byte)(y & 0x00ff);
		    ib++;
		    j++;
		    //}
	    }
	    //} 
	    
	    /*    
	//  else {
	for(int i=0;i<bufsz;i++) {
	    int j=0;
	    //while(j < getNumOfChannels()) {
	    short y = (short)Math.round(32767 * dbuf[i]);
	    byteSound[ib] = (byte)(y & 0x00ff);
	    ib++;
	    byteSound[ib] = (byte)(y >> 8);
	    ib++;
	    j++;
	    //}
	}
	//}
	*/
}





    /** 
     * Convert byte array to float array.
     *
     * @param dbuf User provided float array to return result in.
     * @param dbuf User provided byte array to convert.
     * @param bufsz Number of float samples to write.
     */
    public void byteToFloat(float [] dbuf, byte[] bbuf, int bufsz) {
        
	//int num_channels = getNumOfChannels();
	int ib = 0;
	int j;
	//if(format_d.isBigEndian()) {
	for(int i = 0; i < bufsz; i++) {
		j = 0;
		//while (j < num_channels) {
		    short y = bbuf[ib];
                y = (short)(y << 8);
                y |= (bbuf[ib+1]&0x00ff);
                ib += 2;
                dbuf[i] = y / 32767.f;
		j++;
		//	}
	}
        //} 
	/*
	else {
            for(int i = 0; i < (bufsz/num_channels); i++) {
		j = 0;
		while (j < num_channels) {
		    short y = (short)bbuf[ib+1];
		    y = (short)(y << 8);
		    y |= (bbuf[ib]&0x00ff);
		    ib += 2;
		    dbuf[j][i] = y / 32767.f;
		    j++;
		}
	    }
	}
	*/
    }

}// end of class
