Java实现多个wav文件合成一个的方法示例
本文实例讲述了Java实现多个wav文件合成一个的方法。分享给大家供大家参考,具体如下:
前面一篇介绍了java切割wav音频文件的方法,这里再给出合并多个wav音频文件的方法。
packagecom.cmos.nomsapp.utils.wavmeger;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.RandomAccessFile;
importjava.nio.ByteBuffer;
importjava.nio.ByteOrder;
importjava.util.ArrayList;
importjava.util.List;
/**
*获取wav头文件然后合并成单个wav
*@authorzcf
*@date2017-10-17
*/
publicclassWavMergeUtil{
/**
*meger多个wav
*@paraminputs多个wav
*@paramoutput要生成的wav
*@throwsIOException
*/
publicstaticvoidmergeWav(File[]inputs,Stringoutput)throwsIOException{
if(inputs.length<1){
return;
}
try(FileInputStreamfis=newFileInputStream(inputs[0]);
FileOutputStreamfos=newFileOutputStream(newFile(output))){
byte[]buffer=newbyte[1024*4];
inttotal=0;
intcount;
while((count=fis.read(buffer))>-1){
fos.write(buffer,0,count);
total+=count;
}
fis.close();
for(inti=1;i-1){
fos.write(buffer,0,count);
total+=count;
}
}
}
fos.flush();
fos.close();
FileInputStreamfisHo=newFileInputStream(newFile(output));
HeaderoutputHeader=resolveHeader(fisHo);
outputHeader.dataInputStream.close();
try(RandomAccessFileres=newRandomAccessFile(output,"rw")){
res.seek(4);
byte[]fileLen=intToByteArray(total+outputHeader.dataOffset-8);
res.write(fileLen,0,4);
res.seek(outputHeader.dataSizeOffset);
byte[]dataLen=intToByteArray(total);
res.write(dataLen,0,4);
}
}
}
/**
*解析头部,并获得文件指针指向数据开始位置的InputStreram,记得使用后需要关闭
*/
privatestaticHeaderresolveHeader(FileInputStreamfis)throwsIOException{
byte[]byte4=newbyte[4];
byte[]buffer=newbyte[2048];
intreadCount=0;
Headerheader=newHeader();
fis.read(byte4);//RIFF
fis.read(byte4);
readCount+=8;
header.fileSizeOffset=4;
header.fileSize=byteArrayToInt(byte4);
fis.read(byte4);//WAVE
fis.read(byte4);//fmt
fis.read(byte4);
readCount+=12;
intfmtLen=byteArrayToInt(byte4);
fis.read(buffer,0,fmtLen);
readCount+=fmtLen;
fis.read(byte4);//dataorfact
readCount+=4;
if(isFmt(byte4,0)){//包含fmt段
fis.read(byte4);
intfactLen=byteArrayToInt(byte4);
fis.read(buffer,0,factLen);
fis.read(byte4);//data
readCount+=8+factLen;
}
fis.read(byte4);//datasize
intdataLen=byteArrayToInt(byte4);
header.dataSize=dataLen;
header.dataSizeOffset=readCount;
readCount+=4;
header.dataOffset=readCount;
header.dataInputStream=fis;
returnheader;
}
privatestaticbooleanisRiff(byte[]bytes,intstart){
if(bytes[start+0]=='R'&&bytes[start+1]=='I'&&bytes[start+2]=='F'&&bytes[start+3]=='F'){
returntrue;
}else{
returnfalse;
}
}
privatestaticbooleanisFmt(byte[]bytes,intstart){
if(bytes[start+0]=='f'&&bytes[start+1]=='m'&&bytes[start+2]=='t'&&bytes[start+3]==''){
returntrue;
}else{
returnfalse;
}
}
privatestaticbooleanisData(byte[]bytes,intstart){
if(bytes[start+0]=='d'&&bytes[start+1]=='a'&&bytes[start+2]=='t'&&bytes[start+3]=='a'){
returntrue;
}else{
returnfalse;
}
}
/**
*将int转化为byte[]
*/
privatestaticbyte[]intToByteArray(intdata){
returnByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(data).array();
}
/**
*将short转化为byte[]
*/
privatestaticbyte[]shortToByteArray(shortdata){
returnByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(data).array();
}
/**
*将byte[]转化为short
*/
privatestaticshortbyteArrayToShort(byte[]b){
returnByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
/**
*将byte[]转化为int
*/
privatestaticintbyteArrayToInt(byte[]b){
returnByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getInt();
}
/**
*头部部分信息
*/
staticclassHeader{
publicintfileSize;
publicintfileSizeOffset;
publicintdataSize;
publicintdataSizeOffset;
publicintdataOffset;
publicFileInputStreamdataInputStream;
}
}
更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。