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

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

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

    wangtianbao

    pcm轉(zhuǎn)wav

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

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

    采樣率是一秒鐘內(nèi)對(duì)聲音信號(hào)的采樣次數(shù)

    網(wǎng)絡(luò)接收一個(gè)音頻的時(shí)長是20ms, 已知音頻采樣率是8kHz,采樣的位數(shù)是16bit。
    [時(shí)長]20ms * [采樣率]8kHz * [采樣的位數(shù)]16bit = 320 byte

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


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


    示例:
    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);
                // 計(jì)算長度
                int pcmSize = fis.available();// 由于音頻文件一般不會(huì)大于 Int 最大值,所以使用 available
                
    // 填入?yún)?shù),比特率等等。這里用的是 16位 單聲道 8000 hz
                WavHeader header = new WavHeader();
                // 長度字段 = 內(nèi)容的大小(PCMSize) + 頭部字段的大小(不包括前面4字節(jié)的標(biāo)識(shí)符RIFF以及fileLength本身的4字節(jié))
                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標(biāo)準(zhǔn),頭部應(yīng)該是44字節(jié)
                
    // 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("執(zhí)行["+methodName+"]方法異常!對(duì)象:"+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("關(guān)閉資源異常!對(duì)象:"+obj+";異常:"+e.getMessage(), e);
                }
            }
        }
        
    }

    package com.pvcp.common.utils;

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

    public class WavHeader {

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


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲卡一卡2卡三卡4麻豆| 国产亚洲精品自在线观看| 国产精品亚洲四区在线观看| 国产精品久久永久免费| 亚洲精品国产电影午夜| 日本免费xxxx| 亚洲性色AV日韩在线观看 | 日韩免费高清大片在线| 亚洲av丰满熟妇在线播放| 香蕉免费在线视频| 久久精品夜色国产亚洲av| 免费无码黄网站在线看| 亚洲AV无码国产精品色午友在线 | 麻豆国产精品免费视频| 亚洲午夜成激人情在线影院| 免费中文熟妇在线影片| 国产精品亚洲一区二区三区在线观看| 免费日本黄色网址| a在线观看免费视频| 亚洲麻豆精品果冻传媒| 毛片a级毛片免费播放100| 视频一区在线免费观看| 亚洲av最新在线网址| 黄色片在线免费观看 | 久久久久久成人毛片免费看| 亚洲制服丝袜一区二区三区| 国产在线观看免费完整版中文版| 一级毛片a女人刺激视频免费| 亚洲国产精品久久| 在线免费观看a级片| 国产精品小视频免费无限app| 亚洲黄色免费网站| 国产无遮挡又黄又爽免费视频| 久久久久久国产a免费观看不卡| 久久精品亚洲精品国产色婷| 国产精品深夜福利免费观看| 女人体1963午夜免费视频| 亚洲成a人无码亚洲成av无码| 亚洲国产精品无码久久一线| 成人毛片18女人毛片免费视频未| 中文字幕在线观看免费|