<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    wangtianbao

    pcm轉wav

    PCM轉WAV只需在PCM文件前面增加WAV頭即可,WAV文件頭中包含的信息有:采樣率、采樣的位數、文件大小等。頭文件的長度占44字節。

    采樣的位數指的是描述數字信號所使用的位數。8位(8bit)代表2的8次方=256,16 位(16bit)則代表2的16次方=65536 / 1024 =64K

    采樣率是一秒鐘內對聲音信號的采樣次數

    網絡接收一個音頻的時長是20ms, 已知音頻采樣率是8kHz,采樣的位數是16bit。
    [時長]20ms * [采樣率]8kHz * [采樣的位數]16bit = 320 byte

    例如,CD碟采用16位的采樣精度,44.1KHz的采樣頻率,為雙聲道,它每秒所需要的數據量為16×44100×2÷8=176400字節。這樣算下來,比特率應該是1400多Kbps,如果采用MP3、WMA編碼格式,比特率能夠更小。


    WAV文件的基本格式
    類型內容變量名大小取值
    RIFF頭 文件標識符串 fileId 4B "RIFF"
    頭后文件長度 fileLen 4B 非負整數(=文件長度-8)
    數據類型標識符 波形文件標識符 waveId 4B "WAVE"
    格式塊 塊頭 格式塊標識符 chkId 4B "fmt"
    頭后塊長度 chkLen 4B 非負整數(=16或18)
    塊數據 格式標記 wFormatTag 2B 非負短整數(PCM=1)
    聲道數 wChannels 2B 非負短整數(=1或2)
    采樣率 dwSampleRate 4B 非負整數(單聲道采樣數/秒)
    平均字節率 dwAvgBytesRate 4B 非負整數(字節數/秒)
    數據塊對齊 wBlockAlign 2B 非負短整數(不足補零)
    采樣位數 wBitsPerSample 2B 非負短整數(PCM時才有)
    擴展域大小 wExtSize 2B 非負短整數 可選(根據chkLen=16或18判斷)
    擴展域 extraInfo extSize B 擴展信息
    數據塊 塊頭 數據塊標識符串 chkId 4B "data"
    頭后塊長度 chkLen 4B 非負整數
    塊數據 波形采樣數據 x 或 xl、xr chkLen B 左右聲道樣本交叉排列
    樣本值為整數(整字節存儲,不足位補零),整個數據塊按blockAlign對齊


    示例:
    package com.pvcp.common.utils;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;

    public class PcmToWavUtil {

        public static boolean convert(String pcmFilePath, String wavFilePath, int bitsPerSample, int samplesPerSec) {
            FileInputStream fis = null;
            FileOutputStream fos = null;
            try {
                fis = new FileInputStream(pcmFilePath);
                fos = new FileOutputStream(wavFilePath);
                // 計算長度
                int pcmSize = fis.available();// 由于音頻文件一般不會大于 Int 最大值,所以使用 available
                
    // 填入參數,比特率等等。這里用的是 16位 單聲道 8000 hz
                WavHeader header = new WavHeader();
                // 長度字段 = 內容的大小(PCMSize) + 頭部字段的大小(不包括前面4字節的標識符RIFF以及fileLength本身的4字節)
                header.fileLength = pcmSize + (44 - 8);
                header.fmtHdrLeth = 16;
                header.bitsPerSample = (short)bitsPerSample;
                header.channels = 1;
                header.formatTag = 0x0001;
                // header.samplesPerSec = 8000;
                header.samplesPerSec = samplesPerSec;
                header.blockAlign = (short) (header.channels * header.bitsPerSample / 8);
                header.avgBytesPerSec = header.blockAlign * header.samplesPerSec;
                header.dataHdrLeth = pcmSize;
                byte[] h = header.getHeader();
                assert h.length == 44;// WAV標準,頭部應該是44字節
                
    // write header
                fos.write(h, 0, h.length);
                // write data stream
                SourceUtils.write(fis, fos);
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            } finally {
                SourceUtils.close(fis, fos);
            }

        }

    }


    package com.pvcp.common.utils;

    import java.io.Closeable;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.lang.reflect.Method;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;

    public class SourceUtils {
        private static Log logging = LogFactory.getLog(SourceUtils.class);
        public static void runMethod(String methodName,Object objs){
            if(objs == null){
                return;
            }
            for(Object obj:objs){
                if(obj == null){
                    return;
                }
                try {
                    Method m = obj.getClass().getDeclaredMethod(methodName);
                    m.invoke(obj);
                } catch (Exception e) {
                    logging.error("執行["+methodName+"]方法異常!對象:"+obj+";異常:"+e.getMessage());
                }
            }
        }
        public static void write(InputStream in,OutputStream out){
            try {
                byte[] buff = new byte[1024*5];
                int len = 0;
                while((len=in.read(buff)) != -1){
                    try {
                        out.write(buff,0,len);
                        out.flush();
                    } catch (Exception e) {
                        
                    }
                }
            } catch (Exception e) {
                
            }
        }
        public static void close(Object objs){
            if(objs == null){
                return;
            }
            for(Object obj:objs){
                if(obj == null){
                    return;
                }
                try {
                    if(obj instanceof Closeable){
                        ((Closeable) obj).close();
                    }else if(obj instanceof AutoCloseable){
                        ((AutoCloseable) obj).close();
                    }else{
                        runMethod("close", obj);
                    }
                } catch (Exception e) {
                    logging.error("關閉資源異常!對象:"+obj+";異常:"+e.getMessage(), e);
                }
            }
        }
        
    }

    package com.pvcp.common.utils;

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;

    public class WavHeader {

        /**
         * 4 資源交換文件標志(RIFF)
         
    */
        public final char fileID[] = { 'R', 'I', 'F', 'F' };
        /**
         * 4 總字節數
         
    */
        public int fileLength;
        /**
         * 4 WAV文件標志(WAVE)
         
    */
        public char wavTag[] = { 'W', 'A', 'V', 'E' };
        /**
         * 4 波形格式標志(fmt ),最后一位空格
         
    */
        public char fmtHdrID[] = { 'f', 'm', 't', ' ' };
        /**
         * 4 過濾字節(一般為00000010H),若為00000012H則說明數據頭攜帶附加信息
         
    */
        public int fmtHdrLeth;
        /**
         * 2 格式種類(值為1時,表示數據為線性PCM編碼)
         
    */
        public short formatTag;
        /**
         * 2 通道數,單聲道為1,雙聲道為2
         
    */
        public short channels;
        /**
         * 4 采樣頻率
         
    */
        public int samplesPerSec;
        /**
         * 4 波形數據傳輸速率(每秒平均字節數)
         
    */
        public int avgBytesPerSec;
        /**
         * 2 DATA數據塊長度,字節
         
    */
        public short blockAlign;
        /**
         * 2 PCM位寬
         
    */
        public short bitsPerSample;
        /**
         * 4 數據標志符(data)
         
    */
        public char dataHdrID[] = { 'd', 'a', 't', 'a' };
        /**
         * 4 DATA總數據長度字節
         
    */
        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);
            }
        }

    }

    posted on 2018-05-08 10:02 王添寶 閱讀(61) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产aⅴ无码专区亚洲av| vvvv99日韩精品亚洲| 亚洲s色大片在线观看| 一级毛片在播放免费| 亚洲AV无码乱码精品国产| 亚洲欧美国产国产综合一区| 在线观看免费人成视频色9| 亚洲图片中文字幕| 69堂人成无码免费视频果冻传媒 | 无码国产精品一区二区免费I6| 亚洲综合无码一区二区| 日本免费网站视频www区| 亚洲精品影院久久久久久| 91嫩草免费国产永久入口| 激情亚洲一区国产精品| 精品无码国产污污污免费| 美女视频黄a视频全免费网站色| 亚洲国产黄在线观看| 在线看片免费人成视频播| 亚洲精品福利网泷泽萝拉| 成人男女网18免费视频| 精品免费AV一区二区三区| 国产av无码专区亚洲av果冻传媒| 男人天堂免费视频| 亚洲人成777在线播放| 日本免费一区二区三区最新| 国产福利电影一区二区三区,免费久久久久久久精| 久久夜色精品国产亚洲av| 91禁漫免费进入| 亚洲日韩中文字幕无码一区| 亚洲色偷偷狠狠综合网| 一级毛片免费观看不卡视频| 亚洲狠狠成人综合网| 久久久久国产成人精品亚洲午夜 | 亚洲人成毛片线播放| 日本一道综合久久aⅴ免费| 久久WWW免费人成—看片| 亚洲avav天堂av在线网爱情| 亚洲精品无码久久久久AV麻豆| 国产成人精品无码免费看| 亚洲熟妇丰满xxxxx|