一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java讀取wav文件(波形文件)并繪制波形圖的方法

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

2019-12-24 13:07RobinTang JAVA教程

這篇文章主要介紹了java讀取wav文件(波形文件)并繪制波形圖的方法,涉及java操作多媒體音頻文件轉換的相關技巧,需要的朋友可以參考下

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

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// 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);
  }
  // 判斷是否創建wav讀取器成功
  public boolean isSuccess() {
    return issuccess;
  }
  // 獲取每個采樣的編碼長度,8bit或者16bit
  public int getBitPerSample(){
    return this.bitspersample;
  }
  // 獲取采樣率
  public long getSampleRate(){
    return this.samplerate;
  }
  // 獲取聲道個數,1代表單聲道 2代表立體聲
  public int getNumChannels(){
    return this.numchannels;
  }
  // 獲取數據長度,也就是一共采樣多少個
  public int getDataLen(){
    return this.len;
  }
  // 獲取數據
  // 數據是一個二維數組,[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教程而來的波形繪制面板:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 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;
    }
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 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); // 創建一個繪制波形的面板
      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,wav,波形

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久免费热线精品频 | 王小军怎么了最新消息 | ipx 在线播放 | 日韩欧一级毛片在线播无遮挡 | 荷兰艾优apiyoo | 美女张开下身让男人桶 | 97理伦| 色综合色狠狠天天综合色 | 好吊色青青青国产综合在线观看 | 久久91精品国产91久 | 青青草原在线免费 | 国产精品女同久久免费观看 | 石原莉奈被店长侵犯免费 | 91精品国产在线 | 荡女人人爱全文免费阅读 | 性色AV一区二区三区V视界影院 | 欧美成人免费tv在线播放 | 521色香蕉网在线观看免费 | 九九99在线视频 | 胸大的姑娘中文字幕视频 | 91久久福利国产成人精品 | 亚洲日本中文字幕天堂网 | 亚洲风情无码免费视频 | www国产精品| 好吊色永久免费视频大全 | 国产午夜一区二区在线观看 | 久热人人综合人人九九精品视频 | 秒播影视 午夜福利毛片 | 99久久免费国产精品热 | 国产精品久久久久a影院 | 亚洲国产欧美在线人网站 | 日本中文字幕在线视频 | 亚洲免费色图 | 美国艳星lisann成人作品 | 大陆黄色片 | 亚洲成人第一页 | 国产成人无精品久久久 | 慢慢娇淫 | 亚洲国产美女精品久久久久 | 午夜精品久久久久久久99蜜桃i | 国产乱子伦一区二区三区 |