欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實現多個wav文件合成一個的方法示例

 更新時間:2019年05月16日 11:18:59   作者:大愛一生  
這篇文章主要介紹了Java實現多個wav文件合成一個的方法,涉及java文件流讀寫、編碼轉換、解析等相關操作技巧,需要的朋友可以參考下

本文實例講述了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節(jié)點技巧總結》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設計有所幫助。

相關文章

  • SpringSecurity+Mysql數據庫實現用戶安全登錄認證的實踐

    SpringSecurity+Mysql數據庫實現用戶安全登錄認證的實踐

    Spring Security 是一個提供身份認證、授權和防范常見攻擊的安全權限框架,本文主要介紹了SpringSecurity+Mysql數據庫實現用戶安全登錄認證的實踐,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • mybatis中一對一關系association標簽的使用

    mybatis中一對一關系association標簽的使用

    這篇文章主要介紹了mybatis中一對一關系association標簽的使用,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java快速排序QuickSort(實例)

    Java快速排序QuickSort(實例)

    下面小編就為大家?guī)硪黄狫ava快速排序QuickSort(實例)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 淺談Java實現面向對象編程java oop

    淺談Java實現面向對象編程java oop

    這篇文章主要介紹了淺談Java實現面向對象編程java oop,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • SpringBoot重啟后,第一次請求接口請求慢的問題及解決

    SpringBoot重啟后,第一次請求接口請求慢的問題及解決

    這篇文章主要介紹了SpringBoot重啟后,第一次請求接口請求慢的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring Boot Mysql 數據庫操作示例

    Spring Boot Mysql 數據庫操作示例

    本篇文章主要介紹了Spring Boot Mysql 數據庫操作示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • springboot應用中靜態(tài)資源訪問與接口請求沖突問題解決

    springboot應用中靜態(tài)資源訪問與接口請求沖突問題解決

    這篇文章主要介紹了springboot應用中靜態(tài)資源訪問與接口請求沖突,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • MyBatis實現留言板的示例代碼

    MyBatis實現留言板的示例代碼

    本文主要介紹了MyBatis實現留言板的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08
  • JDBC如何訪問MySQL數據庫,并增刪查改

    JDBC如何訪問MySQL數據庫,并增刪查改

    這篇文章主要介紹了JDBC如何訪問MySQL數據庫,幫助大家更好的理解和學習java與MySQL,感興趣的朋友可以了解下
    2020-08-08
  • Java數據結構之二叉排序樹的實現

    Java數據結構之二叉排序樹的實現

    二叉排序樹(Binary Sort Tree),又稱二叉查找樹(Binary Search Tree),亦稱二叉搜索樹。本文詳細介紹了二叉排序樹的原理,并且提供了Java代碼的完全實現。需要的可以參考一下
    2022-01-01

最新評論