本文实例讲述了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);

}

// 判断是否创建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

for(int n=0; 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

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); // 创建一个绘制波形的面板

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程序设计有所帮助。

java wav 读取_java读取wav文件(波形文件)并绘制波形图的方法相关推荐

  1. java wav 波形_java读取wav文件(波形文件)并绘制波形图的方法

    本文实例讲述了java读取wav文件(波形文件)并绘制波形图的方法.分享给大家供大家参考.具体如下: 因为最近有不少网友询问我波形文件读写方面的问题,出于让大家更方便以及让代码能够得到更好的改进,我将 ...

  2. C#图像处理读取图像像素,根据像素数组绘制图像的方法

    前言 对图像进行处理与识别的前提,是先读取图像的像素.而每个像素有R.G.B三种颜色组成,然后对图片中大量的0~255之间的RGB灰度值进行深入分析和处理. 在C#中读取图像像素.根据像素数组绘制图像 ...

  3. java wav 切割_java切割音频文件

    工具: 一个jar包即可:jave-1.0.2.jar 可以切割wav格式的音频文件 完整工程目录 就一个jar包,一个main类 代码: package com.zit; import java.i ...

  4. java对文件读取_java开发中文件读取的方法总结

    1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内容 4.随机读取文件内容 public class ReadFromFile { /** * 以字节为单位读取文件,常用于读二进制文件 ...

  5. java fileupload 进度_Java上传文件进度条的实现方法(附demo源码下载)

    本文实例讲述了Java上传文件进度条的实现方法.分享给大家供大家参考,具体如下: 东西很简单,主要用到commons-fileupload,其中有一个progressListener的接口,该接口可以 ...

  6. java 添加等待时间_Java中线程等待特定时间的最有效方法 - java

    我知道这个问题here,但是我有一个稍微不同的问题.如果我希望自己通过各种Thread方法(而不是通过实用程序类或Quartz)手动编码某个线程在特定时间的运行,那么最有效(就开销而言)进行编码. 我 ...

  7. java xml 反射_Java 读取XML文件以及Java 的反射机制实现

    Java 读取XML文件以及Java 的反射机制实现 代码部分 import java.io.File; import javax.xml.parsers.DocumentBuilder; impor ...

  8. java classpath 遍历_Java 读取JAR文件信息

    Java 读取JAR文件信息 为什么想到读取JAR文件的信息 查看spring 资源处理,查找多个资源classpath*,会去寻找jar包中的内容,因此会出现读取jar包中的文件或者读取文件夹中的文 ...

  9. java zip 读取_java读取zip (含压缩包内的文件)

    ZIP是一种相当简单的分别压缩每个文件的存档格式.java中使用ZipFile.ZipInputStream快速读取或解压zip压缩包中的目录和文件. 完整示例:package com.weizhix ...

最新文章

  1. Apache 超详细编译参数解析
  2. 运维请注意:”非常危险“的Linux命令大全
  3. 如何用正确的方法来写出质量好的软件的75条体会
  4. 华为2014校园招聘的机试题目
  5. 天线的安装对通信效果有什么影响?
  6. Spring Cloud 入门 之 Feign 篇(三)
  7. delphi query 存储为dbf_Delphi 代码审计项目实战 1
  8. IE11不支持Selenium 2.0的解决方法
  9. Flutter之GlobalKey详解
  10. stm32f407 串口干扰采集_无线采集又添新伙伴,蓝牙无线采集来助力
  11. Fisco bcos 在多机器上搭建多个节点的区块链网络 教程
  12. 使用winpcap开发网络抓包工具
  13. 软件测试自我评价模版,软件测试简历自我评价填写样本
  14. oppo计算机锁屏快捷键,oppo一键锁屏方法【图文教程】
  15. 如何用Docker搭建自己的LANP|LNMP环境?
  16. python中content怎么用,如何将动态内容添加到html中以便用Python发送邮件
  17. 分享 编写子程序代码(把伪代码转换为真正的代码)
  18. 华氏度与摄氏度的转化(C语言)
  19. 第十五周 内部排序一(2)验证交换排序
  20. python pandas 怎么判断一天是否为工作日+计算距离特定时间之间的天数

热门文章

  1. 【Simulink】基于FCS-MPC的单相并网逆变器控制(Matlab Function)
  2. 2019年美亚杯资格赛 个人赛 writeup
  3. 【C++学习笔记】3.第一个程序与注释
  4. Mysql_复制表结构与内容到另一个新表
  5. 【数据结构】稀疏矩阵的介绍
  6. 实验 4 在分支循环结构中调用自定义函数 为了倡导居民节约用电,某省电力公司执行“阶梯电价...
  7. java 编译器版本_java虚拟机和编译器版本不一致问题
  8. 进出口贸易管理系统-概述
  9. 智能中医诊疗系统php代码,中医体质辨识与调理师-平安四众 - 中医体质辨识与调理【中医体质辨识与调理师】...
  10. linux tftp客户端安装命令,Linux系统中tftp命令使用详解