Java实现多个wav文件合成一个的方法示例

本文实例讲述了Java实现多个wav文件合成一个的方法。分享给大家供大家参考,具体如下:

前面一篇介绍了java切割wav音频文件的方法,这里再给出合并多个wav音频文件的方法。

package com.cmos.nomsapp.utils.wavmeger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
/**
 * 获取wav头文件然后合并成单个wav
 * @author zcf
 * @date 2017-10-17
 */
public class WavMergeUtil {
  /**
   * meger多个wav
   * @param inputs 多个wav
   * @param output 要生成的wav
   * @throws IOException
   */
  public static void mergeWav(File[] inputs, String output) throws IOException {
    if (inputs.length < 1) {
      return;
    }
    try(FileInputStream fis = new FileInputStream(inputs[0]);
      FileOutputStream fos = new FileOutputStream(new File(output))){
      byte[] buffer = new byte[1024 * 4];
      int total = 0;
      int count;
      while ((count = fis.read(buffer)) > -1) {
        fos.write(buffer, 0, count);
        total += count;
      }
      fis.close();
      for (int i = 1; i < inputs.length; i++) {
        File file = inputs[i];
        try(FileInputStream fisH = new FileInputStream(file)){
          Header header = resolveHeader(fisH);
          FileInputStream dataInputStream = header.dataInputStream;
          while ((count = dataInputStream.read(buffer)) > -1) {
            fos.write(buffer, 0, count);
            total += count;
          }
        }
      }
      fos.flush();
      fos.close();
      FileInputStream fisHo = new FileInputStream(new File(output));
      Header outputHeader = resolveHeader(fisHo);
      outputHeader.dataInputStream.close();
      try(RandomAccessFile res = new RandomAccessFile(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,记得使用后需要关闭
   */
  private static Header resolveHeader(FileInputStream fis) throws IOException {
      byte[] byte4 = new byte[4];
      byte[] buffer = new byte[2048];
      int readCount = 0;
      Header header = new Header();
      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;
      int fmtLen = byteArrayToInt(byte4);
      fis.read(buffer, 0, fmtLen);
      readCount += fmtLen;
      fis.read(byte4);// data or fact
      readCount += 4;
      if (isFmt(byte4, 0)) {// 包含fmt段
        fis.read(byte4);
        int factLen = byteArrayToInt(byte4);
        fis.read(buffer, 0, factLen);
        fis.read(byte4);// data
        readCount += 8 + factLen;
      }
      fis.read(byte4);// data size
      int dataLen = byteArrayToInt(byte4);
      header.dataSize = dataLen;
      header.dataSizeOffset = readCount;
      readCount += 4;
      header.dataOffset = readCount;
      header.dataInputStream = fis;
      return header;
  }
  private static boolean isRiff(byte[] bytes, int start) {
    if (bytes[start + 0] == 'R' && bytes[start + 1] == 'I' && bytes[start + 2] == 'F' && bytes[start + 3] == 'F') {
      return true;
    } else {
      return false;
    }
  }
  private static boolean isFmt(byte[] bytes, int start) {
    if (bytes[start + 0] == 'f' && bytes[start + 1] == 'm' && bytes[start + 2] == 't' && bytes[start + 3] == ' ') {
      return true;
    } else {
      return false;
    }
  }
  private static boolean isData(byte[] bytes, int start) {
    if (bytes[start + 0] == 'd' && bytes[start + 1] == 'a' && bytes[start + 2] == 't' && bytes[start + 3] == 'a') {
      return true;
    } else {
      return false;
    }
  }
  /**
   * 将int转化为byte[]
   */
  private static byte[] intToByteArray(int data) {
    return ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(data).array();
  }
  /**
   * 将short转化为byte[]
   */
  private static byte[] shortToByteArray(short data) {
    return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(data).array();
  }
  /**
   * 将byte[]转化为short
   */
  private static short byteArrayToShort(byte[] b) {
    return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getShort();
  }
  /**
   * 将byte[]转化为int
   */
  private static int byteArrayToInt(byte[] b) {
    return ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getInt();
  }
  /**
   * 头部部分信息
   */
  static class Header {
    public int fileSize;
    public int fileSizeOffset;
    public int dataSize;
    public int dataSizeOffset;
    public int dataOffset;
    public FileInputStream dataInputStream;
  }
}

更多关于java算法相关内容感兴趣的读者可查看本站专题:《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • java音频播放示例分享(java如何播放音频)

    这是一份精简后的代码,能够支持的格式十分有限. 复制代码 代码如下: package com.hongyuan.test; import java.io.File;import java.io.IOException; import javax.sound.sampled.AudioFormat;import javax.sound.sampled.AudioInputStream;import javax.sound.sampled.AudioSystem;import javax.sound

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

    本文实例讲述了java读取wav文件(波形文件)并绘制波形图的方法.分享给大家供大家参考.具体如下: 因为最近有不少网友询问我波形文件读写方面的问题,出于让大家更方便以及让代码能够得到更好的改进,我将这部分(波形文件的读写)代码开源在GitHub上面. 地址为https://github.com/sintrb/WaveAccess/,最新的代码.例子.文档都在那上面,我会在我时间精力允许的前提下对该项目进行维护,同时也希望对这方面有兴趣的网友能够加入到该开源项目上. 以下内容基本都过期了,你可以

  • java实现大文件分割与合并的实例代码

    复制代码 代码如下: package com.test; import java.io.BufferedReader;  import java.io.BufferedWriter;  import java.io.FileNotFoundException;  import java.io.FileReader;  import java.io.FileWriter;  import java.io.IOException;  import java.util.Collections;  im

  • 代码分析JAVA中PCM人声音频变声处理

    项目中需要用到对PCM人声音频数据进行变声处理.苦苦挣扎了一周终于找到了纯Java实现的一套框架--TarsosDSP.功能非常强大!可以实时音频处理!当然我只用到了对文件处理.实际上逻辑是一样的 TarsosDSP的GitHub地址:https://github.com/JorenSix/TarsosDSP 将它整合至自己的项目工程. 具体Java工具类代码: /** * 变声 * @param rawPcmInputStream 原始PCM数据输入流 * @param speedFactor

  • java 实现切割文件和合并文件的功能

    java 实现切割文件和合并文件的功能 一.切割文件代码如下: 需求:将一个媒体文件切割成多个碎片(每个碎片的大小为1M),并添加配置说明文件 1.创建(指定)一个文件夹,用于保存切割出来的碎片           2.创建源文件对象,并传入一个输入流对象           3.创建一个缓冲区为1M           4.创建一个输入流对象并将源文件对象传入,创建一个输出流对象引用           5.每个缓冲区获取到碎片时,使用输出对应流对象写入到一个新的文件           6.

  • Java实现大文件的切割与合并操作示例

    本文实例讲述了Java实现大文件的切割与合并操作.分享给大家供大家参考,具体如下: 这里实现对大文件的切割与合并. 按指定个数切(如把一个文件切成10份)或按指定大小切(如每份最大不超过10M),这两种方式都可以. 在这里我只是给大家写下我自己的一点简单的代码: package io2; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io

  • java实现切割wav音频文件的方法详解【附外部jar包下载】

    本文实例讲述了java实现切割wav音频文件的方法.分享给大家供大家参考,具体如下: import it.sauronsoftware.jave.Encoder; import it.sauronsoftware.jave.MultimediaInfo; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import j

  • Java使用IO流实现音频的剪切和拼接

    需求: 使用IO流将指定目录下的若干个音频文件的高潮部分,进行剪切,并重新拼接成一首新的音频文件 思路(以两首歌为例): 第一首歌有一个输入流对象bis1.第二首歌有一个输入流对象bis2,他们公用一条输出流对象bos(在选择构造方法的时候选择含有布尔类型参数的那个),待第一首歌剪切完成后,在此基础上追加第二首歌的"高潮部分". 实现代码: import java.io.BufferedInputStream; import java.io.BufferedOutputStream;

  • java实现音频文件播放功能

    本文实例为大家分享了java实现音频文件的播放功能的具体代码,供大家参考,具体内容如下 实现思路 1.首先获取音频文件的地址,然后通过IO流读取音频文件,加缓冲区,实现Player类的对象. 2.Player类主要用于播放器的初始化,以及通过它来实现一些音视频文件的播放,这个类需要手动去网上下载,然后添加路径到我们Eclipse的library中. 3.Player类有两种方法比较常用,play()方法和close()方法,前者用于启动音频文件,后者用于退出音频文件的播放,这两个方法我们在使用的

  • 使用javax.sound实现简单音频播放

    本文实例为大家分享了javax.sound实现简单音频播放的具体代码,供大家参考,具体内容如下 /** * @see * @author Al_assad yulinying_1994@outlook.com * @date 2016年11月17日 下午6:27:59 * @version V1.0 * Description: 简易音频播放器(只支持AU,RA,WAV) * 在不使用JMF的情况下快速实现音频播放 * */ import javax.sound.sampled.*; impor

  • 实例解析使用Java实现基本的音频播放器的编写要点

    Java音频播放,因为必须依赖到本地环境,所以JAVA在音频处理方面优势不大,或者说打从Java体系开发时就没太多的考虑音频播放因素,要知道最早的Java 1.1版本中,没有后来的javax.sound包,音频只能通过Applet包调取-- 遗憾的是,在图形程序开发中,我们的程序却又难免要使用到背景音乐.效果音等配合图像操作,哎,这实在是Sun大神给我们开的一个不打不小的玩笑.万幸后来Sun大神开眼,提供了javax.sound包,才解救我们于水深火热当中~ 但是继之而来的问题是,在javax.

随机推荐