⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spectrumtimeanalyzer.java

📁 mp3播放功能
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package MP3;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JPanel;

import kj.dsp.KJDigitalSignalProcessingAudioDataConsumer;
import kj.dsp.KJDigitalSignalProcessor;
import kj.dsp.KJFFT;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class implements interface KJDigitalSignalProcessor in order to be registered with the 
 * KJDigitalSignalProcessingAudioDataConsumer class .The class is designed to draw peaks
 * when the player is playing a song.The code is made reference to other mp3 player. 
 * 
 * 
 */

public class SpectrumTimeAnalyzer extends JPanel implements KJDigitalSignalProcessor
{
    private static Log log = LogFactory.getLog(SpectrumTimeAnalyzer.class);
    public static final int DISPLAY_MODE_SCOPE = 0;
    public static final int DISPLAY_MODE_SPECTRUM_ANALYSER = 1;
    public static final int DISPLAY_MODE_OFF = 2;
    public static final int DEFAULT_WIDTH = 256;
    public static final int DEFAULT_HEIGHT = 128;
    public static final int DEFAULT_FPS = 50;
    public static final int DEFAULT_SPECTRUM_ANALYSER_FFT_SAMPLE_SIZE = 512;
    public static final int DEFAULT_SPECTRUM_ANALYSER_BAND_COUNT = 19;
    public static final float DEFAULT_SPECTRUM_ANALYSER_DECAY = 0.05f;
    public static final int DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY = 20;
    public static final float DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO = 0.4f;
    public static final float DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO_RANGE = 0.1f;
    public static final float MIN_SPECTRUM_ANALYSER_DECAY = 0.02f;
    public static final float MAX_SPECTRUM_ANALYSER_DECAY = 0.08f;
    public static final Color DEFAULT_SCOPE_COLOR = new Color(255, 128, 192);
    public static final float DEFAULT_VU_METER_DECAY = 0.02f;
    private Image bi;
    private int displayMode = DISPLAY_MODE_SPECTRUM_ANALYSER;
    private Color scopeColor = DEFAULT_SCOPE_COLOR;
    private Color[] spectrumAnalyserColors = getDefaultSpectrumAnalyserColors();
    private KJDigitalSignalProcessingAudioDataConsumer dsp = null;
    private boolean dspStarted = false;
    private Color peakColor = null;
    private int[] peaks = new int[DEFAULT_SPECTRUM_ANALYSER_BAND_COUNT];
    private int[] peaksDelay = new int[DEFAULT_SPECTRUM_ANALYSER_BAND_COUNT];
    private int peakDelay = DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY;
    private boolean peaksEnabled = true;
    private int barOffset = 1;
    private int width;
    private int height;
    private int height_2;
    // -- Spectrum analyser variables.
    private KJFFT fft;
    private float[] old_FFT;
    private int saFFTSampleSize;
    private int saBands;
    private float saColorScale;
    private float saMultiplier;
    private float saDecay = DEFAULT_SPECTRUM_ANALYSER_DECAY;
    private SourceDataLine m_line = null;
    // -- VU Meter
    private float oldLeft;
    private float oldRight;
    private float vuDecay = DEFAULT_VU_METER_DECAY;
    private float vuColorScale;
    // -- FPS calulations.
    private long lfu = 0;
    private int fc = 0;
    private int fps = DEFAULT_FPS;
    private boolean showFPS = false;
    
 

    //  private Runnable PAINT_SYNCHRONIZER = new AWTPaintSynchronizer();
    public SpectrumTimeAnalyzer()
    {
        setOpaque(false);
        initialize();
    }

    
    /**
	 * Method to see if the peaks can be displayed.
	 * 
	 * @return Returns whether the peaks is enabled or not.
	 */
    
    public boolean isPeaksEnabled()
    {
        return peaksEnabled;
    }

    /**
	 * Method to set peaks' state.
	 * 
	 * @param peaksEnabled
	 *               the state of peaks
	 */
    public void setPeaksEnabled(boolean peaksEnabled)
    {
        this.peaksEnabled = peaksEnabled;
    }

    /**
	 * Method to get the value of FPS.
	 * 
	 * @return Returns the FPS
	 */
    public int getFps()   
    {
        return fps;
    }

    /**
     * Method to set the value of FPS
     * 
     * @param fps
     */
    public void setFps(int fps)   //设置每秒的帧数
    {
        this.fps = fps;
    }

    /**
     * Method to start DSP when a song is playing.
     * @param line
     */
    public void startDSP(SourceDataLine line)
    {
        if (displayMode == DISPLAY_MODE_OFF) return;
        if (line != null) m_line = line;
        if (dsp == null)
        {
            dsp = new KJDigitalSignalProcessingAudioDataConsumer(2048, fps);
            dsp.add(this);
        }
        if ((dsp != null) && (m_line != null))
        {
            if (dspStarted == true)
            {
                stopDSP();
            }
            dsp.start(m_line);
            dspStarted = true;
            log.debug("DSP started");
        }
    }

    /**
     * Method to stop DSP when no song is playing.
     */
    public void stopDSP()
    {
        if (dsp != null)
        {
            dsp.stop();
            dspStarted = false;
            log.debug("DSP stopped");
        }
    }

    /**
     * Method to close DSP when there is no need to use it.
     */
    public void closeDSP()
    {
        if (dsp != null)
        {
            stopDSP();
            dsp = null;
            log.debug("DSP closed");
        }
    }

    /**
     * Menthod to setup DSP.
     * @param line
     */
    public void setupDSP(SourceDataLine line)
    {
        if (dsp != null)
        {
            int channels = line.getFormat().getChannels();
            if (channels == 1) dsp.setChannelMode(KJDigitalSignalProcessingAudioDataConsumer.CHANNEL_MODE_MONO);
            else dsp.setChannelMode(KJDigitalSignalProcessingAudioDataConsumer.CHANNEL_MODE_STEREO);
            int bits = line.getFormat().getSampleSizeInBits();
            if (bits == 8) dsp.setSampleType(KJDigitalSignalProcessingAudioDataConsumer.SAMPLE_TYPE_EIGHT_BIT);
            else dsp.setSampleType(KJDigitalSignalProcessingAudioDataConsumer.SAMPLE_TYPE_SIXTEEN_BIT);
        }
    }

    /**
     * Method to write PCM data to DSP.
     * @param pcmdata
     */
    public void writeDSP(byte[] pcmdata)
    {
        if ((dsp != null) && (dspStarted == true)) dsp.writeAudioData(pcmdata);
    }

    /**
     * Method to return DSP.
     * @return Returns DSP
     */
    public KJDigitalSignalProcessingAudioDataConsumer getDSP()
    {
        return dsp;
    }

    /**
     * Set visual colors from skin.
     * @param viscolor
     */
    public void setVisColor(String viscolor)
    {
        ArrayList visColors = new ArrayList();
        viscolor = viscolor.toLowerCase();
        ByteArrayInputStream in = new ByteArrayInputStream(viscolor.getBytes());
        BufferedReader bin = new BufferedReader(new InputStreamReader(in));
        try
        {
            String line = null;
            while ((line = bin.readLine()) != null)
            {
                visColors.add(getColor(line));
            }
            Color[] colors = new Color[visColors.size()];
            visColors.toArray(colors);
            Color[] specColors = new Color[15];
            System.arraycopy(colors, 2, specColors, 0, 15);
            List specList = Arrays.asList(specColors);
            Collections.reverse(specList);
            specColors = (Color[]) specList.toArray(specColors);
            setSpectrumAnalyserColors(specColors);
            setBackground((Color) visColors.get(0));
            if (visColors.size()>23) setPeakColor((Color) visColors.get(23));
            if (visColors.size()>18) setScopeColor((Color) visColors.get(18));
        }
        catch (IOException ex)
        {
            log.warn("Cannot parse viscolors", ex);
        }
        finally
        {
            try
            {
                if (bin != null) bin.close();
            }
            catch (IOException e)
            {
            }
        }
    }

    /**
     * Set visual peak color.
     * @param c
     */
    public void setPeakColor(Color c)
    {
        peakColor = c;
    }

    /**
     * Set peak falloff delay.
     * @param framestowait
     */
    public void setPeakDelay(int framestowait)
    {
        int min = (int) Math.round((DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO - DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO_RANGE) * fps);
        int max = (int) Math.round((DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO + DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO_RANGE) * fps);
        if ((framestowait >= min) && (framestowait <= max))
        {
            peakDelay = framestowait;
        }
        else
        {
            peakDelay = (int) Math.round(DEFAULT_SPECTRUM_ANALYSER_PEAK_DELAY_FPS_RATIO * fps);
        }
    }

    /**
     * Return peak falloff delay
     * @return int framestowait
     */
    public int getPeakDelay()
    {
        return peakDelay;
    }

    /**
     * Convert string to color.
     * @param linecolor
     * @return Returns the Color converted from string
     */
    public Color getColor(String linecolor)
    {
        Color color = Color.BLACK;
        StringTokenizer st = new StringTokenizer(linecolor, ",");
        int red = 0, green = 0, blue = 0;
        try
        {
            if (st.hasMoreTokens()) red = Integer.parseInt(st.nextToken().trim());
            if (st.hasMoreTokens()) green = Integer.parseInt(st.nextToken().trim());
            if (st.hasMoreTokens())
            {
                String blueStr = st.nextToken().trim();
                if (blueStr.length() > 3) blueStr = (blueStr.substring(0, 3)).trim();
                blue = Integer.parseInt(blueStr);
            }
            color = new Color(red, green, blue);
        }
        catch (NumberFormatException e)
        {
            log.debug("Cannot parse viscolor : "+e.getMessage());
        }
        return color;
    }

    /** 
     * Set the mathematical formula to calculate the Spectrum analyser Color Scale 
     * and the VU Meter Color Scale.
     *
     */
    private void computeColorScale()
    {
        saColorScale = ((float) spectrumAnalyserColors.length / height) * barOffset * 1.0f;
        vuColorScale = ((float) spectrumAnalyserColors.length / (width - 32)) * 2.0f;
    }

    /**
     * Set the mathematical formula to calculate the Spectrum analyser Multiplier.
     *
     */
    private void computeSAMultiplier()
    {
        saMultiplier = (saFFTSampleSize / 2) / saBands;
    }

    /**
     * Method to draw the Scope.
     * 
     * @param pGrp
     * @param pSample
     */
    private void drawScope(Graphics pGrp, float[] pSample)
    {
        pGrp.setColor(scopeColor);
        int wLas = (int) (pSample[0] * (float) height_2) + height_2;
        int wSt = 2;
        for (int a = wSt, c = 0; c < width; a += wSt, c++)
        {
            int wAs = (int) (pSample[a] * (float) height_2) + height_2;
            pGrp.drawLine(c, wLas, c + 1, wAs);
            wLas = wAs;
        }
    }

    /**
     * Method to draw the SpectrumAnalyzer.
     * 
     * @param pGrp
     * @param pSample
     * @param pFrrh
     */
    private void drawSpectrumAnalyser(Graphics pGrp, float[] pSample, float pFrrh)
    {
        float c = 0;
        float[] wFFT = fft.calculate(pSample);
        float wSadfrr = (saDecay * pFrrh);
        float wBw = ((float) width / (float) saBands);
        for (int a = 0, bd = 0; bd < saBands; a += saMultiplier, bd++)
        {
            float wFs = 0;
            // -- Average out nearest bands.
            for (int b = 0; b < saMultiplier; b++)
            {
                wFs += wFFT[a + b];
            }
            // -- Log filter.
            wFs = (wFs * (float) Math.log(bd + 2));
            if (wFs > 1.0f)
            {
                wFs = 1.0f;
            }
            // -- Compute SA decay...
            if (wFs >= (old_FFT[a] - wSadfrr))
            {
                old_FFT[a] = wFs;
            }
            else
            {
                old_FFT[a] -= wSadfrr;
                if (old_FFT[a] < 0)
                {
                    old_FFT[a] = 0;
                }
                wFs = old_FFT[a];
            }
            drawSpectrumAnalyserBar(pGrp, (int) c, height, (int) wBw - 1, (int) (wFs * height), bd);
            c += wBw;
        }
    }

    /**
     * Method to draw VU Meter 
     * 
     * @param pGrp
     * @param pLeft
     * @param pRight
     * @param pFrrh

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -