美文网首页学习之鸿蒙&Android学习
安卓音频开发(三)pcm转wav

安卓音频开发(三)pcm转wav

作者: motosheep | 来源:发表于2021-06-11 15:11 被阅读0次

    pcm是原始的无损音频数据,但是在安卓手机上,播放起来并不是很方便,这里就演示如何把pcm转为wav。
    只需一个工具类即可实现,原理其实很简单,就在pcm文件的文件头,加上wav的文件头属性即可。为什么这么简单还要写,因为网上所找到的答案实在是乱七八糟,什么都有,所以特此记录,直接上代码:

    package com.north.light.libaudio.utils;
    
    import android.media.AudioFormat;
    import android.media.AudioRecord;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * Created by lzt
     * time 2021/6/9 15:42
     *
     * @author lizhengting
     * 描述:pcm格式的音频转换为wav格式的工具类
     */
    public class PcmToWavUtil {
        private int mBufferSize; //缓存的音频大小
        private int mSampleRate = 8000;// 8000|16000
        private int mChannel = AudioFormat.CHANNEL_IN_STEREO; //立体声
        private int mEncoding = AudioFormat.ENCODING_PCM_16BIT;
    
        private static class SingleHolder {
            static PcmToWavUtil mInstance = new PcmToWavUtil();
        }
    
        public static PcmToWavUtil getInstance() {
            return SingleHolder.mInstance;
        }
    
    
        public PcmToWavUtil() {
            this.mBufferSize = AudioRecord.getMinBufferSize(mSampleRate, mChannel, mEncoding);
        }
    
        /**
         * @param sampleRate sample rate、采样率
         * @param channel    channel、声道
         * @param encoding   Audio data format、音频格式
         */
        public PcmToWavUtil(int sampleRate, int channel, int encoding) {
            this.mSampleRate = sampleRate;
            this.mChannel = channel;
            this.mEncoding = encoding;
            this.mBufferSize = AudioRecord.getMinBufferSize(mSampleRate, mChannel, mEncoding);
        }
    
        /**
         * pcm文件转wav文件
         *
         * @param inFilename  源文件路径
         * @param outFilename 目标文件路径
         * @param deleteOrg   是否删除源文件
         */
        public void pcmToWav(String inFilename, String outFilename, boolean deleteOrg) {
            FileInputStream in;
            FileOutputStream out;
            long totalAudioLen;
            long totalDataLen;
            long longSampleRate = mSampleRate;
            int channels = 2;
            long byteRate = 16 * mSampleRate * channels / 8;
            byte[] data = new byte[mBufferSize];
            try {
                in = new FileInputStream(inFilename);
                out = new FileOutputStream(outFilename);
                totalAudioLen = in.getChannel().size();
                totalDataLen = totalAudioLen + 36;
    
                writeWaveFileHeader(out, totalAudioLen, totalDataLen,
                        longSampleRate, channels, byteRate);
                while (in.read(data) != -1) {
                    out.write(data);
                }
                in.close();
                out.close();
                if (deleteOrg) {
                    new File(inFilename).delete();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void pcmToWav(String inFilename, String outFilename) {
            pcmToWav(inFilename, outFilename, false);
        }
    
        /**
         * 加入wav文件头
         */
        private void writeWaveFileHeader(FileOutputStream out, long totalAudioLen,
                                         long totalDataLen, long longSampleRate, int channels, long byteRate)
                throws IOException {
            byte[] header = new byte[44];
            header[0] = 'R'; // RIFF/WAVE header
            header[1] = 'I';
            header[2] = 'F';
            header[3] = 'F';
            header[4] = (byte) (totalDataLen & 0xff);
            header[5] = (byte) ((totalDataLen >> 8) & 0xff);
            header[6] = (byte) ((totalDataLen >> 16) & 0xff);
            header[7] = (byte) ((totalDataLen >> 24) & 0xff);
            header[8] = 'W'; //WAVE
            header[9] = 'A';
            header[10] = 'V';
            header[11] = 'E';
            header[12] = 'f'; // 'fmt ' chunk
            header[13] = 'm';
            header[14] = 't';
            header[15] = ' ';
            header[16] = 16; // 4 bytes: size of 'fmt ' chunk
            header[17] = 0;
            header[18] = 0;
            header[19] = 0;
            header[20] = 1; // format = 1
            header[21] = 0;
            header[22] = (byte) channels;
            header[23] = 0;
            header[24] = (byte) (longSampleRate & 0xff);
            header[25] = (byte) ((longSampleRate >> 8) & 0xff);
            header[26] = (byte) ((longSampleRate >> 16) & 0xff);
            header[27] = (byte) ((longSampleRate >> 24) & 0xff);
            header[28] = (byte) (byteRate & 0xff);
            header[29] = (byte) ((byteRate >> 8) & 0xff);
            header[30] = (byte) ((byteRate >> 16) & 0xff);
            header[31] = (byte) ((byteRate >> 24) & 0xff);
            header[32] = (byte) (2 * 16 / 8); // block align
            header[33] = 0;
            header[34] = 16; // bits per sample
            header[35] = 0;
            header[36] = 'd'; //data
            header[37] = 'a';
            header[38] = 't';
            header[39] = 'a';
            header[40] = (byte) (totalAudioLen & 0xff);
            header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
            header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
            header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
            out.write(header, 0, 44);
        }
    }
    

    that‘s all----------------------------------------------------------------------------------

    相关文章

      网友评论

        本文标题:安卓音频开发(三)pcm转wav

        本文链接:https://www.haomeiwen.com/subject/gkhveltx.html