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

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

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程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩综合一区 | 青春草在线观看精品免费视频 | 国内自拍网红在线自拍综合 | 91肥熟国产老肥熟在线 | 欧美性另类69xxxx | 亚洲男女在线 | 国产在线精品观看 | 午夜片无码区在线观看 | 久久机热免费视频 | 糖心vlog麻豆精东影业传媒 | 亚洲日日做天天做日日谢 | 美女裆部 | 4hu影院永久在线播放 | 日韩精品视频在线观看免费 | 精品国产品国语在线不卡丶 | 经典欧美gifxxoo动态图暗网 | 亚洲国产在线视频中文字 | 亚洲精品免费在线观看 | 秋葵污视频 | 精品国产免费久久久久久 | 极品丝袜乱系列在线阅读 | 好吊色永久免费视频大全 | 四虎影视国产精品婷婷 | 精品国产一区二区三区久久影院 | 亚洲精品久久久WWW游戏好玩 | 99九九成人免费视频精品 | 天天爱天天做天天爽天天躁 | 糖心视频在线观看 | 精品国产精品国产偷麻豆 | 娇妻被朋友征服中文字幕 | 国产人成77777视频网站 | 午夜爱| 美女全身体光羞羞漫画 | 男人与雌性宠物交啪啪小说 | 国产私人影院 | 丝袜爆操 | 免费尤物视频 | 国产成人精品日本亚洲网址 | 亚洲精品福利你懂 | 国产90后美女露脸在线观看 | 日本一区二区三区在线 观看网站 |