最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java讀取wav文件(波形文件)并繪制波形圖的方法

 更新時間:2015年06月26日 10:04:20   作者:RobinTang  
這篇文章主要介紹了java讀取wav文件(波形文件)并繪制波形圖的方法,涉及java操作多媒體音頻文件轉換的相關技巧,需要的朋友可以參考下

本文實例講述了java讀取wav文件(波形文件)并繪制波形圖的方法。分享給大家供大家參考。具體如下:

因為最近有不少網友詢問我波形文件讀寫方面的問題,出于讓大家更方便以及讓代碼能夠得到更好的改進,我將這部分(波形文件的讀寫)代碼開源在GitHub上面。

地址為https://github.com/sintrb/WaveAccess/,最新的代碼、例子、文檔都在那上面,我會在我時間精力允許的前提下對該項目進行維護,同時也希望對這方面有興趣的網友能夠加入到該開源項目上。

以下內容基本都過期了,你可以直接去GitHub上面閱讀、下載該項目。

因項目需要讀取.wav文件(波形文件)并繪制波形圖,因此簡單的做了這方面的封裝。

其實主要是對wav文件讀取的封裝,下面是一個wav文件讀取器的封裝:

// filename: WaveFileReader.java 
// RobinTang 
// 2012-08-23 
import java.io.*; 
public class WaveFileReader { 
  private String filename = null; 
  private int[][] data = null; 
  private int len = 0; 
  private String chunkdescriptor = null; 
  static private int lenchunkdescriptor = 4; 
  private long chunksize = 0; 
  static private int lenchunksize = 4; 
  private String waveflag = null; 
  static private int lenwaveflag = 4; 
  private String fmtubchunk = null; 
  static private int lenfmtubchunk = 4; 
  private long subchunk1size = 0; 
  static private int lensubchunk1size = 4; 
  private int audioformat = 0; 
  static private int lenaudioformat = 2; 
  private int numchannels = 0; 
  static private int lennumchannels = 2; 
  private long samplerate = 0; 
  static private int lensamplerate = 2; 
  private long byterate = 0; 
  static private int lenbyterate = 4; 
  private int blockalign = 0; 
  static private int lenblockling = 2; 
  private int bitspersample = 0; 
  static private int lenbitspersample = 2; 
  private String datasubchunk = null; 
  static private int lendatasubchunk = 4; 
  private long subchunk2size = 0; 
  static private int lensubchunk2size = 4; 
  private FileInputStream fis = null; 
  private BufferedInputStream bis = null; 
  private boolean issuccess = false; 
  public WaveFileReader(String filename) { 
    this.initReader(filename); 
  } 
  // 判斷是否創(chuàng)建wav讀取器成功 
  public boolean isSuccess() { 
    return issuccess; 
  } 
  // 獲取每個采樣的編碼長度,8bit或者16bit 
  public int getBitPerSample(){ 
    return this.bitspersample; 
  } 
  // 獲取采樣率 
  public long getSampleRate(){ 
    return this.samplerate; 
  } 
  // 獲取聲道個數(shù),1代表單聲道 2代表立體聲 
  public int getNumChannels(){ 
    return this.numchannels; 
  } 
  // 獲取數(shù)據(jù)長度,也就是一共采樣多少個 
  public int getDataLen(){ 
    return this.len; 
  } 
  // 獲取數(shù)據(jù) 
  // 數(shù)據(jù)是一個二維數(shù)組,[n][m]代表第n個聲道的第m個采樣值 
  public int[][] getData(){ 
    return this.data; 
  } 
  private void initReader(String filename){ 
    this.filename = filename; 
    try { 
      fis = new FileInputStream(this.filename); 
      bis = new BufferedInputStream(fis); 
      this.chunkdescriptor = readString(lenchunkdescriptor); 
      if(!chunkdescriptor.endsWith("RIFF")) 
        throw new IllegalArgumentException("RIFF miss, " + filename + " is not a wave file."); 
      this.chunksize = readLong(); 
      this.waveflag = readString(lenwaveflag); 
      if(!waveflag.endsWith("WAVE")) 
        throw new IllegalArgumentException("WAVE miss, " + filename + " is not a wave file."); 
      this.fmtubchunk = readString(lenfmtubchunk); 
      if(!fmtubchunk.endsWith("fmt ")) 
        throw new IllegalArgumentException("fmt miss, " + filename + " is not a wave file."); 
      this.subchunk1size = readLong(); 
      this.audioformat = readInt(); 
      this.numchannels = readInt(); 
      this.samplerate = readLong(); 
      this.byterate = readLong(); 
      this.blockalign = readInt(); 
      this.bitspersample = readInt(); 
      this.datasubchunk = readString(lendatasubchunk); 
      if(!datasubchunk.endsWith("data")) 
        throw new IllegalArgumentException("data miss, " + filename + " is not a wave file."); 
      this.subchunk2size = readLong(); 
      this.len = (int)(this.subchunk2size/(this.bitspersample/8)/this.numchannels); 
      this.data = new int[this.numchannels][this.len]; 
       
      for(int i=0; i<this.len; ++i){ 
        for(int n=0; n<this.numchannels; ++n){ 
          if(this.bitspersample == 8){ 
            this.data[n][i] = bis.read(); 
          } 
          else if(this.bitspersample == 16){ 
            this.data[n][i] = this.readInt(); 
          } 
        } 
      } 
      issuccess = true; 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    finally{ 
      try{ 
      if(bis != null) 
        bis.close(); 
      if(fis != null) 
        fis.close(); 
      } 
      catch(Exception e1){ 
        e1.printStackTrace(); 
      } 
    } 
  } 
  private String readString(int len){ 
    byte[] buf = new byte[len]; 
    try { 
      if(bis.read(buf)!=len) 
        throw new IOException("no more data!!!"); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
    return new String(buf); 
  } 
  private int readInt(){ 
    byte[] buf = new byte[2]; 
    int res = 0; 
    try { 
      if(bis.read(buf)!=2) 
        throw new IOException("no more data!!!"); 
      res = (buf[0]&0x000000FF) | (((int)buf[1])<<8); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
    return res; 
  } 
  private long readLong(){ 
    long res = 0; 
    try { 
      long[] l = new long[4]; 
      for(int i=0; i<4; ++i){ 
        l[i] = bis.read(); 
        if(l[i]==-1){ 
          throw new IOException("no more data!!!"); 
        } 
      } 
      res = l[0] | (l[1]<<8) | (l[2]<<16) | (l[3]<<24); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
    return res; 
  } 
  private byte[] readBytes(int len){ 
    byte[] buf = new byte[len]; 
    try { 
      if(bis.read(buf)!=len) 
        throw new IOException("no more data!!!"); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } 
    return buf; 
  } 
} 

為了繪制波形,因此做了一個從JPanel教程而來的波形繪制面板:

// filename: DrawPanel.java 
// RobinTang 
// 2012-08-23 
import java.awt.Color; 
import java.awt.Graphics; 
import javax.swing.JPanel; 
@SuppressWarnings("serial") 
public class DrawPanel extends JPanel { 
  private int[] data = null; 
  public DrawPanel(int[] data) { 
    this.data = data; 
  } 
  @Override 
  protected void paintComponent(Graphics g) { 
    int ww = getWidth(); 
    int hh = getHeight(); 
    g.setColor(Color.WHITE); 
    g.fillRect(0, 0, ww, hh); 
    int len = data.length; 
    int step = len/ww; 
    if(step==0) 
      step = 1; 
    int prex = 0, prey = 0; //上一個坐標 
    int x = 0, y = 0; 
    g.setColor(Color.RED); 
    double k = hh/2.0/32768.0; 
    for(int i=0; i<ww; ++i){ 
      x = i; 
      // 下面是個三點取出并繪制 
      // 實際中應該按照采樣率來設置間隔 
      y = hh-(int)(data[i*3]*k+hh/2); 
      System.out.print(y); 
      System.out.print(" "); 
      if(i!=0){ 
        g.drawLine(x, y, prex, prey); 
      } 
      prex = x; 
      prey = y; 
    } 
  } 
} 

有了這些之后就可以調用繪制了,簡單的:

// WaveFileReadDemo.java 
// RobinTang 
// 2012-08-23 
import javax.swing.JFrame; 
public class WaveFileReadDemo { 
  /** 
   * @param args 
   */ 
  public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    String filename = "file.wav"; 
    JFrame frame = new JFrame(); 
    WaveFileReader reader = new WaveFileReader(filename); 
    if(reader.isSuccess()){ 
      int[] data = reader.getData()[0]; //獲取第一聲道 
      DrawPanel drawPanel = new DrawPanel(data); // 創(chuàng)建一個繪制波形的面板 
      frame.add(drawPanel); 
      frame.setTitle(filename); 
      frame.setSize(800, 400); 
      frame.setLocationRelativeTo(null); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setVisible(true); 
    } 
    else{ 
      System.err.println(filename + "不是一個正常的wav文件"); 
    } 
  } 
} 

工程的源代碼可以在我的百度網盤上找到,直接到開源JAVA

放上效果圖一張:

希望本文所述對大家的java程序設計有所幫助。

相關文章

  • Spring運行時手動注入bean的方法實例

    Spring運行時手動注入bean的方法實例

    spring給我們提供了IOC服務,讓我們可以用注解的方式,方便的使用bean的相互引用,下面這篇文章主要給大家介紹了關于Spring運行時手動注入bean的相關資料,需要的朋友可以參考下
    2022-05-05
  • springboot清除字符串前后空格與防xss攻擊方法

    springboot清除字符串前后空格與防xss攻擊方法

    這篇文章主要介紹了springboot清除字符串前后空格與防xss攻擊方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Mybatis如何傳入多個參數(shù)的實現(xiàn)代碼

    Mybatis如何傳入多個參數(shù)的實現(xiàn)代碼

    這篇文章主要介紹了Mybatis如何傳入多個參數(shù)的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • 詳解java中static關鍵詞的作用

    詳解java中static關鍵詞的作用

    這篇文章主要介紹了java中static關鍵詞的作用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Java注釋代碼執(zhí)行方法解析

    Java注釋代碼執(zhí)行方法解析

    這篇文章主要介紹了Java注釋代碼執(zhí)行方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java中的隨機數(shù)Random

    Java中的隨機數(shù)Random

    這篇文章主要介紹了Java中的隨機數(shù)Random,關于隨機數(shù)的介紹不設置隨機數(shù)種子,你每次隨機抽樣得到的數(shù)據(jù)都是不一樣的。設置了隨機數(shù)種子,能夠確保每次抽樣的結果一樣,下面來了解具體的詳細內容介紹吧
    2022-03-03
  • 詳解IDEA中SpringBoot整合Servlet三大組件的過程

    詳解IDEA中SpringBoot整合Servlet三大組件的過程

    這篇文章主要介紹了詳解IDEA中SpringBoot整合Servlet三大組件的過程,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot使用Mybatis&Mybatis-plus文件映射配置方法

    SpringBoot使用Mybatis&Mybatis-plus文件映射配置方法

    這篇文章主要介紹了SpringBoot使用Mybatis&Mybatis-plus文件映射配置方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • Spring Boot 整合 JWT的方法

    Spring Boot 整合 JWT的方法

    這篇文章主要介紹了Spring Boot 整合 JWT的方法,文中實例代碼非常詳細,幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • 全面理解java中的異常處理機制

    全面理解java中的異常處理機制

    下面小編就為大家?guī)硪黄胬斫鈐ava中的異常處理機制。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06

最新評論

朝阳县| 安吉县| 太白县| 鄱阳县| 荥经县| 淮安市| 云龙县| 肥乡县| 太仆寺旗| 沙坪坝区| 托克托县| 承德县| 依安县| 墨竹工卡县| 夏津县| 搜索| 阳山县| 岳普湖县| 天柱县| 聂荣县| 镶黄旗| 措美县| 海丰县| 虞城县| 武夷山市| 红河县| 苍山县| 高密市| 义乌市| 琼结县| 临沭县| 台北县| 波密县| 金乡县| 集安市| 精河县| 绍兴县| 平南县| 五常市| 清流县| 岗巴县|