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

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

这篇文章主要介绍了Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)读取声音资源文件文件(波形文件)并绘制波形图的方法,涉及Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)操作多媒体音频文件转换的相关技巧,需要的朋友可以参考下

本文实例讲述了Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)读取声音资源文件文件(波形文件)并绘制波形图的方法。分享给大家供大家参考。具体如下:

因为最近有不少网友询问我波形文件读写方面的问题,出于让大家更方便以及让代码能够得到更好的改进,我将这部分(波形文件的读写)代码开源在开源代码库上面。

地址为https://github.com/sintrb/WaveAccess/,最新的代码、例子、文档都在那上面,我会在我时间精力允许的前提下对该项目进行维护,同时也希望对这方面有兴趣的网友能够加入到该开源项目上。

以下内容基本都过期了,你可以直接去开源代码库上面阅读、下载该项目。

因项目需要读取。声音资源文件文件(波形文件)并绘制波形图,因此简单的做了这方面的封装。

其实主要是对声音资源文件文件读取的封装,下面是一个声音资源文件文件读取器的封装:

//文件名:WaveFileReader.java

//罗宾唐

//2012-08-23

导入Java。io。*;

公共类WaveFileReader {

私有字符串文件名=空

private int[][]data=null;

private int len=0;

私有字符串chunkdescriptor=null

静态私有int lenchunkdescriptor=4;

private long chunksize=0;

静态私有int lenchunksize=4;

私有字符串waveflag=null

静态私有int lenwaveflag=4;

私有字符串fmtubchunk=null

静态私有int lenfmtubcunk=4;

私有long子块1大小=0;

静态私有int lens ubchunk 1 size=4;

private int音频格式=0;

static private int lenaudioformat=2;

private int num channels=0;

静态私有int lennumchannels=2;

私有长采样率=0;

静态私有int lensamplerate=2;

私有长字节率=0;

静态私有int lenbyrate=4;

private int块align=0;

静态私有int len blocking=2;

private int bits样本=0;

静态私有int lenbitspersample=2;

私有字符串datasubchunk=null

静态私有int lendatasubchunk=4;

私有长子块2大小=0;

静态私有int lens ubchunk 2 size=4;

私有FileInputStream fis=null

private BufferedInputStream bis=null;

私有布尔型issuccess=false

公共波形文件阅读器(字符串文件名){

this.initReader(文件名);

}

//判断是否创建声音资源文件读取器成功

公共布尔值是access(){

返回发布成功

}

//获取每个采样的编码长度,8位或者16位

public int getBitPerSample(){

返回这个。bits样本;

}

//获取采样率

public long getSampleRate(){

返回this.samplerate

}

//获取声道个数,1代表单声道2代表立体声

public int getNumChannels(){

返回this.numchannels

}

//获取数据长度,也就是一共采样多少个

public int getDataLen(){

返回这个,伦

}

//获取数据

//数据是一个二维数组,[n][m]代表第n个声道的第m个采样值

public int[][] getData(){

返回这.数据

}

私有void initReader(字符串文件名){

this.filename=文件名;

尝试{

fis=新文件输入流(this。文件名);

bis=新缓冲区输入流(fis);

这个。chunk descriptor=readString(lenchunkdescriptor);

如果(!chunkdescriptor.endsWith('RIFF '))

抛出新的IllegalArgumentException(' RIFF miss,' filename '不是波形文件。);

这个。chunk size=read long();

这个。wave flag=read string(lenwaveflag);

如果(!waveflag.endsWith('WAVE '))

抛出新的IllegalArgumentException('波未命中,'文件名'不是波形文件。);

这个。fmtubcunk=读取字符串(lenfmtubcunk);

如果(!fmtubbchunk。结尾为(' fmt '))

抛出新的IllegalArgumentException(' fmt miss,' filename '不是波形文件。);

这个。子块1大小=read long();

这个。音频格式=readInt();

这个。numchannels=readInt();

这个。采样率=read long();

这个。字节率=read long();

这个。block align=readInt();

这个。bits sample=readInt();

这个。datasubchunk=读取字符串(lendatasubchunk);

如果(!datasubchunk.endsWith('data '))

抛出新的IllegalArgumentException('数据丢失,'文件名'不是波形文件。);

这个。子块2大小=read long();

这个。len=(int)(这个。子块2大小/(this。比特采样/8)/这个。通道数);

这个。data=new int[this。numchannels][这个。len];

for(int I=0;ithis.leni){

for(int n=0;nthis.numchannelsn){

如果(这个。比特采样==8){

这个。数据之二。read();

}

else if(这个。bits sample==16){

这个。数据[n][I]=这个。readint();

}

}

}

issuccess=true

} catch(异常e) {

e。printstacktrace();

}

最后{

尝试{

如果(bis!=空)

之二。close();

如果(fis!=空)

fis。close();

}

捕捉(异常e1){

E1。printstacktrace();

}

}

}

私有字符串readString(int len){

字节[]缓冲区=新字节[len];

尝试{

if(bis.read(buf)!=len)

抛出新的IOException('没有更多的数据!');

} catch (IOException e) {

e。printstacktrace();

}

返回新字符串(buf);

}

private int readInt(){

字节[]缓冲区=新字节[2];

int RES=0;

尝试{

if(bis.read(buf)!=2)

抛出新的IOException('没有更多的数据!');

RES=(buf[0]0x 000000 ff)|(((int)buf[1])8);

} catch (IOException e) {

e。printstacktrace();

}

返回表示留数

}

private long readLong(){

long RES=0;

尝试{

long[]l=new long[4];

for(int I=0;i4;i){

l[I]=之二。read();

if(l[i]==-1){

抛出新的IOException('没有更多的数据!');

}

}

RES=l[0]|(l[1]8)|(l[2]16)|(l[3]24);

} catch (IOException e) {

e。printstacktrace();

}

返回表示留数

}

私有字节[]读取字节(整数){

字节[]缓冲区=新字节[len];

尝试{

if(bis.read(buf)!=len)

抛出新的IOException('没有更多的数据!');

} catch (IOException e) {

e。printstacktrace();

}

返回buf

}

}

为了绘制波形,因此做了一个从JPanel教程而来的波形绘制面板:

//文件名:DrawPanel.java

//罗宾唐

//2012-08-23

导入Java。awt。颜色;

导入Java。awt。图形;

导入javax。挥棒。jpanel

@SuppressWarnings('serial ')

公共类抽屉面板扩展JPanel {

private int[]data=null;

公共画板(int[] data) {

this.data=数据

}

@覆盖

受保护的空白油漆组件(图形g) {

int ww=getWidth();

int hh=getHeight();

g.setColor(颜色。白色);

g.fillRect(0,0,ww,hh);

int len=data .长度

int step=len/ww;

如果(步长==0)

step=1;

int prex=0,prey=0;//上一个坐标

int x=0,y=0;

g.setColor(颜色。红色);

双k=hh/2.0/32768.0;

for(int I=0;iwwi){

x=I;

//下面是个三点取出并绘制

//实际中应该按照采样率来设置间隔

y=hh-(int)(data[I * 3]* k hh/2);

系统。出去。打印(y);

系统。出去。打印(" ");

如果(我!=0){

g.drawLine(x,y,prex,prey);

}

prex=x;

猎物=y;

}

}

}

有了这些之后就可以调用绘制了,简单的:

//WaveFileReadDemo.java

//罗宾唐

//2012-08-23

导入javax。挥棒。jframe

公共类WaveFileReadDemo {

/**

* @param args

*/

公共静态void main(String[] args) {

//TODO自动生成的方法存根

字符串filename=' file.wav

JFrame frame=new JFrame();

WaveFileReader阅读器=新的波形文件阅读器(文件名);

if(reader.isSuccess()){

int[]data=reader。获取数据()[0];//获取第一声道

绘制面板绘制面板=新绘制面板(数据);//创建一个绘制波形的面板

框架。添加(绘制面板);

frame.setTitle(文件名);

frame.setSize(800,400);

框架。setlocationrelativeto(null);

框架。setdefaultcloseoperation(JFrame .EXIT _ ON _ CLOSE);

框架。设置可见(真);

}

否则{

System.err.println(文件名'不是一个正常的声音资源文件文件');

}

}

}

工程的源代码可以在我的百度网盘上找到,直接到开源Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)

放上效果图一张:

希望本文所述对大家的Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)程序设计有所帮助。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: