zoukankan      html  css  js  c++  java
  • java 将pcm字节数组转为wav文件

    1、前言

    参考 java将pcm音频转换成wav格式

    2、关键代码

        public void pcmByteToWavFile(byte[] pcmData, String fileName) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(fileName);
                //填入参数,比特率等等。这里用的是16位 双声道 48000 hz
                WaveHeader header = new WaveHeader();
                //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
                header.fileLength = pcmData.length + (44 - 8);
                header.FmtHdrLeth = 16;
                header.BitsPerSample = 16;//比特率
                header.Channels = 2;//双通道
                header.FormatTag = 0x0001;
                header.SamplesPerSec = 48000;//采样率
                header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
                header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
                header.DataHdrLeth = pcmData.length;
                byte[] headerBytes = header.getHeader();
                assert headerBytes.length == 44; //WAV标准,头部应该是44字节
                byte[] byteResult = new byte[headerBytes.length + pcmData.length];
                System.arraycopy(headerBytes, 0, byteResult, 0, headerBytes.length);
                System.arraycopy(pcmData, 0, byteResult, headerBytes.length, pcmData.length);
                fos.write(byteResult, 0, byteResult.length);
                fos.flush();
                fos.close();
            } catch (Exception e) {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }
    

    3、代码

    package com.ruoyi.project.utils;
    
    import java.io.*;
    
    public class AudioUtil {
        private static AudioUtil Instance = new AudioUtil();
    
        public static AudioUtil getInstance() {
            return Instance;
        }
    
        public void pcmByteToWavFile(byte[] pcmData, String fileName) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(fileName);
                //填入参数,比特率等等。这里用的是16位 双声道 48000 hz
                WaveHeader header = new WaveHeader();
                //长度字段 = 内容的大小(PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
                header.fileLength = pcmData.length + (44 - 8);
                header.FmtHdrLeth = 16;
                header.BitsPerSample = 16;//比特率
                header.Channels = 2;//双通道
                header.FormatTag = 0x0001;
                header.SamplesPerSec = 48000;//采样率
                header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
                header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
                header.DataHdrLeth = pcmData.length;
                byte[] headerBytes = header.getHeader();
                assert headerBytes.length == 44; //WAV标准,头部应该是44字节
                byte[] byteResult = new byte[headerBytes.length + pcmData.length];
                System.arraycopy(headerBytes, 0, byteResult, 0, headerBytes.length);
                System.arraycopy(pcmData, 0, byteResult, headerBytes.length, pcmData.length);
                fos.write(byteResult, 0, byteResult.length);
                fos.flush();
                fos.close();
            } catch (Exception e) {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        }
    
        public class WaveHeader {
            public final char fileID[] = {'R', 'I', 'F', 'F'};
            public int fileLength;
            public char wavTag[] = {'W', 'A', 'V', 'E'};
            ;
            public char FmtHdrID[] = {'f', 'm', 't', ' '};
            public int FmtHdrLeth;
            public short FormatTag;
            public short Channels;
            public int SamplesPerSec;
            public int AvgBytesPerSec;
            public short BlockAlign;
            public short BitsPerSample;
            public char DataHdrID[] = {'d', 'a', 't', 'a'};
            public int DataHdrLeth;
    
            public byte[] getHeader() throws IOException {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                WriteChar(bos, fileID);
                WriteInt(bos, fileLength);
                WriteChar(bos, wavTag);
                WriteChar(bos, FmtHdrID);
                WriteInt(bos, FmtHdrLeth);
                WriteShort(bos, FormatTag);
                WriteShort(bos, Channels);
                WriteInt(bos, SamplesPerSec);
                WriteInt(bos, AvgBytesPerSec);
                WriteShort(bos, BlockAlign);
                WriteShort(bos, BitsPerSample);
                WriteChar(bos, DataHdrID);
                WriteInt(bos, DataHdrLeth);
                bos.flush();
                byte[] r = bos.toByteArray();
                bos.close();
                return r;
            }
    
            private void WriteShort(ByteArrayOutputStream bos, int s) throws IOException {
                byte[] mybyte = new byte[2];
                mybyte[1] = (byte) ((s << 16) >> 24);
                mybyte[0] = (byte) ((s << 24) >> 24);
                bos.write(mybyte);
            }
    
    
            private void WriteInt(ByteArrayOutputStream bos, int n) throws IOException {
                byte[] buf = new byte[4];
                buf[3] = (byte) (n >> 24);
                buf[2] = (byte) ((n << 8) >> 24);
                buf[1] = (byte) ((n << 16) >> 24);
                buf[0] = (byte) ((n << 24) >> 24);
                bos.write(buf);
            }
    
            private void WriteChar(ByteArrayOutputStream bos, char[] id) {
                for (int i = 0; i < id.length; i++) {
                    char c = id[i];
                    bos.write(c);
                }
            }
        }
    }
    
    
  • 相关阅读:
    [ USACO 2007 FEB ] Lilypad Pond (Silver)
    [ USACO 2007 FEB ] Lilypad Pond (Gold)
    [ USACO 2007 OPEN ] Dining
    [ BZOJ 2134 ] 单选错位
    「APIO2018新家」
    「WC2018即时战略」
    「学习笔记」杜教筛
    「APIO2018选圆圈」
    「学习笔记」集合幂级数
    「NOIP2018」保卫王国
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/15605435.html
Copyright © 2011-2022 走看看