zoukankan      html  css  js  c++  java
  • Java实现合成多个wav音频文件

    参考地址    http://blog.sina.com.cn/s/blog_13c6397540102wxyn.html

    package test;
    /**
    * @author yanwenbin
    * @version 创建时间:2018年11月1日 下午12:03:34
    * 合成wav文件
    */

    import java.io.File;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;

    import java.io.InputStream;

    import java.io.OutputStream;

    import java.io.RandomAccessFile;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;

    public class WAVTest {
    private int headlength1 = 0;
    private int headlength2 = 0;

    /*
    * 16进制字节数组转换成int
    */
    public static int byteArrayToInt(byte[] b) {
    return b[3] & 0xFF | (b[2] & 0xFF) << 8 | (b[1] & 0xFF) << 16 | (b[0] & 0xFF) << 24;
    }

    /**
    * int转换成16进制字节数组
    */
    public static byte[] intToByteArray(int a) {
    return new byte[] { (byte) ((a >> 24) & 0xFF), (byte) ((a >> 16) & 0xFF), (byte) ((a >> 8) & 0xFF),
    (byte) (a & 0xFF) };
    }

    /**
    * 字节数组的转换 0x00 00 27 56在内存中的位置是56 27 00 00 所以要反过来
    */
    public static byte[] byteToByte(byte[] a) {
    if (a.length == 4) {
    byte[] b = new byte[4];
    b[0] = a[3];
    b[1] = a[2];
    b[2] = a[1];
    b[3] = a[0];
    return b;
    }
    return null;
    }

    /**
    * 将两个wav合成一个新的wav
    */
    public void addWav(String filepath1, String filepath2, String filepath3) throws IOException {
    File file1 = new File(filepath1);
    System.out.println("1.wav:" + -file1.length());
    File file2 = new File(filepath2);
    System.out.println("2.wav:" + file2.length());
    File file3 = new File(filepath3);
    if (!file3.exists()) {
    file3.createNewFile();
    }
    InputStream is1 = new FileInputStream(file1);
    InputStream is2 = new FileInputStream(file2);
    OutputStream os = new FileOutputStream(file3);// 追加
    byte[] tempbuffer = new byte[1024];
    int nRed = 0;
    while ((nRed = is1.read(tempbuffer)) != -1)// 将1.wav全部内容复制到3.wav
    {
    os.write(tempbuffer, 0, nRed);
    os.flush();
    }

    is1.close();
    is2.skip(44);// 跳过2.wav的文件头
    while ((nRed = is2.read(tempbuffer)) != -1)// 将2.wav全部内容追加复制到3.wav结尾处
    {
    os.write(tempbuffer, 0, nRed);
    os.flush();
    }
    is2.close();
    os.close();
    // 到此完成了1.wav和2.wav合并成3.wav,但是此时播放3.wav,会发现大小虽然是1.wav和2.wav的和
    // 但是音频内容仍然只是第一个音频的内容,所以还要更改3.wav的文件头

    }

    /**
    * 更改addWav.wav.wav的文件头
    */
    public void updateFileHead(String filepath3, boolean ifUpdate) throws IOException {
    RandomAccessFile raf = new RandomAccessFile(filepath3, "rw");
    long filelength = raf.length();
    System.out.println(filepath3 + filelength);
    // 打开一个文件通道
    FileChannel channel = raf.getChannel();
    // 映射文件中的某一部分数据以读写模式到内存中
    MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 44);// 文件头长度
    byte[] b = new byte[4];
    b[0] = buffer.get(4);
    b[1] = buffer.get(5);
    b[2] = buffer.get(6);
    b[3] = buffer.get(7);
    int length1 = WAVTest.byteArrayToInt(WAVTest.byteToByte(b));
    System.out.println(length1);// 显示data+44-8

    byte[] b1 = new byte[4];
    b1[0] = buffer.get(40);
    b1[1] = buffer.get(41);
    b1[2] = buffer.get(42);
    b1[3] = buffer.get(43);
    int length2 = WAVTest.byteArrayToInt(WAVTest.byteToByte(b1));
    System.out.println(length2);
    if (ifUpdate)// 修改头部文件
    {
    byte[] head1 = this.byteToByte(this.intToByteArray(headlength1));
    byte[] head2 = this.byteToByte(this.intToByteArray(headlength2));
    // 进行修改操作
    buffer.put(4, head1[0]);
    buffer.put(5, head1[1]);
    buffer.put(6, head1[2]);
    buffer.put(7, head1[3]);
    buffer.put(40, head2[0]);
    buffer.put(41, head2[1]);
    buffer.put(42, head2[2]);
    buffer.put(43, head2[3]);

    buffer.force();// 强制输出,在buffer中的改动生效到文件
    System.out.println("文件头修改成功");
    /**************************************** 进行查询,看修改是否生效 ***************/

    b = new byte[4];
    b[0] = buffer.get(4);
    b[1] = buffer.get(5);
    b[2] = buffer.get(6);
    b[3] = buffer.get(7);
    length1 = WAVTest.byteArrayToInt(WAVTest.byteToByte(b));
    System.out.println(length1);// 显示data+44-8
    b1 = new byte[4];

    b1[0] = buffer.get(40);
    b1[1] = buffer.get(41);
    b1[2] = buffer.get(42);
    b1[3] = buffer.get(43);
    length2 = WAVTest.byteArrayToInt(WAVTest.byteToByte(b1));
    System.out.println(length2);

    } else {
    this.headlength1 = this.headlength1 + length1;
    this.headlength2 = this.headlength2 + length2;

    }

    buffer.clear();
    channel.close();
    raf.close();

    }

    public static void main(String[] args) throws IOException {
    String filepath1 = "C:\Users\Administrator\Desktop\audio\5-son1.wav";// 源文件1.wav
    String filepath2 = "C:\Users\Administrator\Desktop\audio\5-son.wav";// 源文件2.wav
    String filepath3 = "C:/Users/Administrator/Desktop/audio/son1-son.wav";// 合成文件addwav.wav
    WAVTest wavTest = new WAVTest();
    wavTest.addWav(filepath1, filepath2, filepath3);// data合成
    wavTest.updateFileHead(filepath1, false);
    wavTest.updateFileHead(filepath2, false);
    wavTest.updateFileHead(filepath3, true);//头部合成

    }

    }

  • 相关阅读:
    35美元的树莓派电脑 黑客就偷走了NASA的火星数据
    博客样式保留
    某社交网站XSS小计
    c# WhereIf 扩展
    SQL、Linq、lamda表达式 同一功能不同写法
    tomcat org.apache.coyote.http11.HeadersTooLargeException: 尝试将更多数据写入响应标头,而不是缓冲区中有可用空间。 增加连接器上的maxHttpHeaderSize或将更少的数据写入响应头。
    Maven Dependency Scopes
    为什么mysql中不应该使用utf8编码
    springmvc dispacher中的url-pattern的/和/*区别
    在jsp中java代码中警告Cannot resolve method "XX"
  • 原文地址:https://www.cnblogs.com/ywb2018/p/9889167.html
Copyright © 2011-2022 走看看