这篇文章主要介绍了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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。