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

📄 samplinggraph.java

📁 接上一个程序 播放器可以实现波形的显示 还可以改变采样点个数和算法
💻 JAVA
字号:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import javax.sound.sampled.*;
import java.awt.geom.Line2D;
import java.util.Vector;




class SamplingGraph extends JPanel implements ComponentListener,Runnable
{
	private Thread thread;
	private String path=(System.getProperty("user.dir"));
	private AudioInputStream wavStream;
	private AudioFormat wavFormat;
	private Vector lines=new Vector();
	private double duration, seconds;
	private byte[] audioBytes;
	private int frames_per_pixel;
	private int[] audioData;
	
	public SamplingGraph()
	{
		setBackground(Color.black);
		//这个监听用来实现当该Panel大小改变时,重绘波形的功能
		addComponentListener(this);
	}
	
	public void componentResized(ComponentEvent e)
	{
		createWaveForm(audioBytes);
	}
	public void componentMoved(ComponentEvent e){}
	public void componentShown(ComponentEvent e){}
	public void componentHidden(ComponentEvent e){}
	
	public void getAudioInputStream(AudioInputStream wavStream)
	{
		if(wavStream==null)
		{
			this.wavStream=null;
			wavFormat=null;
			return;
		}
		this.wavStream=wavStream;
		wavFormat=wavStream.getFormat();	
	
	}
	
	public int[] getAudioData()
	{
		return audioData;
	}
	
	public void incSize()
	{
		Dimension d=getSize();
		int w=d.width;
		int h=d.height;
		
		int newW=w*2;
		
		d=new Dimension(newW,h);
		setPreferredSize(d);
		setSize(d);
		repaint();
	}
	
	public void decSize()
	{
		Dimension d=getSize();
		int w=d.width;
		int h=d.height;
		
		int newW=(int)w/2;
		int newH=(int)h/2;
		
		d=new Dimension(newW,newH);
		setPreferredSize(d);
		setSize(d);
		repaint();
		
	}
	
    public void createWaveForm(byte[] audioBytes) 
    {
       	if(wavStream==null) 
       	{
       		repaint();
       		return;
       	}
       	wavFormat = wavStream.getFormat();
     	
     	//lines里保存着每次根据采样点值画的连续曲线
     	//所以要先清空,以便以后载入新的连续曲线
     	lines.removeAllElements();
        
        
        //将波形文件中的每个采样点的值导入audioBytes里
        if (audioBytes == null) 
        {
            try 
            {
                audioBytes = new byte[
                    (int) (wavStream.getFrameLength() 
                        * wavFormat.getFrameSize())];
                    wavStream.read(audioBytes);
            } 
            catch (Exception ex)
            { 
                return; 
            }
        }
        
        this.audioBytes=audioBytes;

        Dimension d = getSize();
        int w = d.width;		//panel的宽
        int h = d.height; 		//panel的高
        int[] audioData = null;
        
        //如果采样点是16Bit的
        if (wavFormat.getSampleSizeInBits() == 16) 
        {
             int nlengthInSamples = audioBytes.length / 2;
             audioData = new int[nlengthInSamples];
             
             //bigEndian:
             //Indicates whether the audio data is stored in big-endian 
             //or little-endian order.
             //似乎是用来判断wav是从MSB开始记录还是从LSB开始记录 
             
             if (wavFormat.isBigEndian()) 
             {
                for (int i = 0; i < nlengthInSamples; i++)                 
                {
                     /* First byte is MSB (high order) */
                     int MSB = (int) audioBytes[2*i];
                     /* Second byte is LSB (low order) */
                     int LSB = (int) audioBytes[2*i+1];
                     audioData[i] = MSB << 8 | (255 & LSB);
                 }
             } 
             else 
             {
                 for (int i = 0; i < nlengthInSamples; i++) 
                 {
                     /* First byte is LSB (low order) */
                     int LSB = (int) audioBytes[2*i];
                     /* Second byte is MSB (high order) */
                     int MSB = (int) audioBytes[2*i+1];
                     audioData[i] = MSB << 8 | (255 & LSB);
                 }
             }
         } 
         //如果采样点是8Bit的
         else if (wavFormat.getSampleSizeInBits() == 8) 
         {
             int nlengthInSamples = audioBytes.length;
             audioData = new int[nlengthInSamples];
             if (wavFormat.getEncoding().toString().startsWith("PCM_SIGN")) 
             {
                 for (int i = 0; i < audioBytes.length; i++) 
                 {
                         audioData[i] = audioBytes[i];
                 }
             } 
             else 
             {
                 for (int i = 0; i < audioBytes.length; i++) 
                 {
                     audioData[i] = audioBytes[i] - 128;
                 }
             }
         }
         
         this.audioData=audioData;
                    
        //设置帧/每象素值,默认情况下使所有的帧恰好满窗口显示
        frames_per_pixel = (audioBytes.length / wavFormat.getFrameSize())/w;
        
        byte my_byte = 0;
        double y_last = 0,x_last=0;
        //声道
        int numChannels = wavFormat.getChannels();
        
        //以下为将采样点画出曲线的核心算法
        for (double x = 0; x < w && audioData != null; x++) 
        {
            int idx=frames_per_pixel*numChannels*(int)x;
                        
            int temp=audioData[idx];
            
            //奇数次循环取最大值,偶数次循环取最小值
            for(int i=idx;i<idx+frames_per_pixel*numChannels;i++)
            {
            	if((int)x%2==0)
            	{            		
            		if(temp>audioData[i])
            		{
            			temp=audioData[i];
            		}

            	}
            	else
            	{
            		if(temp<audioData[i])
            		{
            			temp=audioData[i];
            		}
            	}

            }
                                    
            if (wavFormat.getSampleSizeInBits() == 8) 
            {

            	my_byte=(byte)temp;
                //my_byte = (byte) audioData[idx];
            } 
            else
            {
            	my_byte=(byte)(128*temp/32768);
                //my_byte = (byte) (128 * audioData[idx] / 32768 );
            }
            //以抽样值确定所画线中Y点坐标值。
            double y_new = (double) (h * (128 - my_byte) / 256);
            //将画好的一段段线加入到lines这个容器里
            lines.add(new Line2D.Double(x_last, y_last, x, y_new));
            y_last = y_new;
            x_last = x;
        }

        repaint();
    }
    
    public void paint(Graphics g) 
    {
        Dimension d = getSize();
        int w = d.width;
        int h = d.height;
        
        Graphics2D g2 = (Graphics2D) g;
        g2.setBackground(getBackground());
        g2.clearRect(0, 0, w, h);

		for(int i=0;i<10;i++)
		{
			Shape l=new Line2D.Float(w/10*i,0,w/10*i,h);
			g2.setColor(Color.red);
			g2.draw(l);
		}
		        
		//画十字格
		for(int i=0;i<10;i++)
		{
			Shape l=new Line2D.Float(w/10*i,0,w/10*i,h);
			g2.setColor(Color.GRAY);
			g2.draw(l);
			l=new Line2D.Float(0,h/10*i,w,h/10*i);
			g2.draw(l);
		}

		Shape l=new Line2D.Float(0,h/2,w,h/2);
	    if(wavStream == null)
        {
        	g2.setColor(Color.red);
        	g2.draw(l);
        }

        if (wavStream != null) 
        {
            // .. render sampling graph ..
            g2.setColor(Color.red);
            g2.draw(l);
            g2.setColor(Color.CYAN);
            for (int i = 1; i < lines.size(); i++) 
            {
                g2.draw((Line2D) lines.get(i));
            }
        }
    }

    public void start() 
    {
        thread = new Thread(this);
        thread.setName("SamplingGraph");
        thread.start();
    }

    public void stop() 
    {
        if (thread != null) 
        {
            thread.interrupt();
        }
        thread = null;
    }

    public void run() 
    {
        while (thread != null) 
        {
            try { thread.sleep(100); } catch (Exception e) { break; }

            repaint();
        }

	}


	//用来进行测试的语句
	public static void main(String agrs[])
	{
		JFrame frm=new JFrame();
		JButton testBtn=new JButton("test");
	
				
		SamplingGraph test=new SamplingGraph();
		
		frm.getContentPane().add(test,BorderLayout.CENTER);
//			new JScrollPane(test,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS),
//			BorderLayout.CENTER);
		frm.getContentPane().add(testBtn,BorderLayout.SOUTH);
		frm.setSize(400,400);
		frm.setVisible(true);
		
				
		//窗口打开后在屏幕中央显示
 		int ScreenWidth=frm.getToolkit().getScreenSize().width;
		int ScreenHeight=frm.getToolkit().getScreenSize().height;
		frm.setLocation((ScreenWidth-frm.getWidth())/2,(ScreenHeight-frm.getHeight())/2);
		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);		
		
		test.load();
		test.createWaveForm(null);
	
		//test.decSize();
	
	}
	
	public void load()
	{
			//载入wave文件
	
			//======读取.wav文件=======
	 		JFileChooser chooser = new JFileChooser(path);
	 		chooser.setDialogTitle("载入wav文件");
	 			
	 		//设定打开文件类型为*.wav
			ExampleFileFilter filter = new ExampleFileFilter();
	    	filter.addExtension("wav");
	    	filter.setDescription("wave波形文件");
	    	chooser.setFileFilter(filter);	
		 		
		 	int result=chooser.showOpenDialog(null);    		
	    	if(result==JFileChooser.CANCEL_OPTION) return;
	    	
	    	File wavFile=chooser.getSelectedFile();
	    	
	    	try
	    	{
	    		wavStream=AudioSystem.getAudioInputStream(wavFile);
	    		AudioFormat wavFormat=wavStream.getFormat();
	    		
	            /**
                 * we can't yet open the device for ALAW/ULAW playback,
                 * convert ALAW/ULAW to PCM
                 */
                if ((wavFormat.getEncoding() == AudioFormat.Encoding.ULAW) ||
                    (wavFormat.getEncoding() == AudioFormat.Encoding.ALAW)) 
                {
                    AudioFormat tmp = new AudioFormat(
                                              AudioFormat.Encoding.PCM_SIGNED, 
                                              wavFormat.getSampleRate(),
                                              wavFormat.getSampleSizeInBits() * 2,
                                              wavFormat.getChannels(),
                                              wavFormat.getFrameSize() * 2,
                                              wavFormat.getFrameRate(),
                                              true);
                    wavStream = AudioSystem.getAudioInputStream(tmp, wavStream);
                    wavFormat = tmp;
                }
			}catch(Exception e){}
	}
	
}

⌨️ 快捷键说明

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