洗洗脚泡泡澡 2017-09-28 09:03 采纳率: 40.9%
浏览 1127
已结题

FTP下载过程中对V3格式文件进行转换

ftp下载文件过程中,对v3格式文件进行转换,转成wav格式,并返回给页面,下载和播放。
怎么实现。网上的本地转换代码确实可用,但是我对字节流、转码这一块不太懂,不知道有
没有大神来看看,怎么写?
下面是本地v3转wav的代码

 package cn.sh.ideal.utils;

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


    public class V3ToWav {
        private static V3ToWav v3ToWav;
        private V3ToWav(){

        }

        public static V3ToWav getInstance(){
            if(v3ToWav == null){
                v3ToWav = new V3ToWav();
            }
            return v3ToWav;
        }

        private static final int WAV_HEAD = 36;// wav文件头长度

        private static final int VF_ADPCM = 1;// 编码格式

        private static final int BIT_RATE_VB_8 = 1;// 每个样本位数

        private static final int BIT_RATE_VB_16 = 2;// 每个样本位数

        private static final int RESET_VALUE = 48;

        private static byte out_val;

        /**
         * 
         * @param inFile
         * @param outFile
         * @param voxFormat
         *            格式 取值范围:VF_ADPCM = 1, VF_MULAW = 2, VF_ALAW = 3
         * @param voxRate
         *            采样率 取值范围:VR_6K = 6000, VR_8K = 8000
         * @param bit_rate
         *            位数 取值范围:VB_8 = 1, VB_16 = 2
         * @return
         */

        public static void voxConvert(String inFile, String outFile, int voxFormat,
                int voxRate, int bit_rate) throws Exception {

            if (outFile == null) {
                outFile = inFile.substring(0, inFile.length() - 2);
                outFile = outFile + "wav";
            }

            File outF = new File(outFile);
            File inF = new File(inFile);

            long inFileSize = inF.length();
            if (voxFormat == VF_ADPCM) { // if using ADPCM input format...
                inFileSize = inFileSize * 2;
            }// change from bytes to samples

            FileOutputStream filewriter = new FileOutputStream(outF, false);
            String wavBegin = "RIFF";
            filewriter.write(wavBegin.getBytes());// WAV 文件头

            long wavLength = inFileSize * bit_rate + WAV_HEAD;
            byte[] tmpArr = new byte[4];
            longToIntBinary(wavLength, tmpArr, 0);
            filewriter.write(tmpArr);// 文件总长度

            String wavTag = "WAVEfmt ";
            filewriter.write(wavTag.getBytes());// WAV 文件标识

            int headLength = 16;
            tmpArr = new byte[4];
            longToIntBinary(headLength, tmpArr, 0);
            filewriter.write(tmpArr);// size of .WAV file header

            int wFormatTag = 1; // format tag (01 = Windows PCM)
            tmpArr = new byte[2];
            toShortBinary(wFormatTag, tmpArr, 0);
            filewriter.write(tmpArr);// format tag (01 = Windows PCM)

            int nChannels = 1; // channels (1=mono, 2=stereo)
            tmpArr = new byte[2];
            toShortBinary(nChannels, tmpArr, 0);
            filewriter.write(tmpArr);// channels (1=mono, 2=stereo)

            int nSamplesPerSec = voxRate; // samples per second
            tmpArr = new byte[4];
            longToIntBinary(nSamplesPerSec, tmpArr, 0);
            filewriter.write(tmpArr);

            int nAvgBytesPerSec = voxRate * bit_rate; // bytes per second
            // during play
            tmpArr = new byte[4];
            longToIntBinary(nAvgBytesPerSec, tmpArr, 0);
            filewriter.write(tmpArr);

            int nBlockAlign = bit_rate; // bytes per sample
            tmpArr = new byte[2];
            toShortBinary(nBlockAlign, tmpArr, 0);
            filewriter.write(tmpArr);// bytes per sample

            int wBitsPerSample = 8 * bit_rate; // bits per sample
            tmpArr = new byte[2];
            toShortBinary(wBitsPerSample, tmpArr, 0);
            filewriter.write(tmpArr);// bits per sample

            /** ******以下是数据头********* */
            String dataTag = "data";
            filewriter.write(dataTag.getBytes());// data tag

            long Datalen = inFileSize * bit_rate; // write size of .WAV data
            // portion
            tmpArr = new byte[4];
            longToIntBinary(Datalen, tmpArr, 0);
            filewriter.write(tmpArr);// 数据总长度

            //FileInputStream fileReader = new FileInputStream(inF);
            FileInputStream fileReader = new FileInputStream(inF);
            byte[] outbytebuffer = new byte[20000];
            int[] outintbuffer = new int[20000];
            switch (voxFormat) {
            case VF_ADPCM:// VF_ADPCM
            {
                short Sn = 0; // initialize the ADPCM variables
                int SS = 16; // initialize the Step
                int SSindex = 1;
                int i = 0;
                byte[] b = new byte[10000];

                int outindex;
                byte sample;// 一个采样样本

                int allBytes = fileReader.available();
                while (allBytes > 0) {
                    int thisRead = allBytes > 10000 ? 10000 : allBytes;
                    int bytes = fileReader.read(b, 0, thisRead);

                    allBytes -= thisRead;// 剩余可读的字节数
                    outindex = 0;
                    for (int index = 0; index < bytes; index++) {
                        sample = b[index];
                        byte highByte = (byte) (sample >>> 4 & 0xff);
                        byte lowByte = (byte) (sample & 0x0f);

                        /** *****开始高字节处理******** */
                        if ((highByte == 0) || (highByte == 8)) {
                            i++;
                        }
                        Object[] retVal = decode((byte) (sample >>> 4), Sn, SS,
                                SSindex);
                        Sn = ((Short) retVal[0]).shortValue();
                        SS = ((Integer) retVal[1]).intValue();
                        SSindex = ((Integer) retVal[2]).intValue();

                        int out_int;
                        if (bit_rate == BIT_RATE_VB_8) {// if 8 bits per sample...
                            out_int = Sn / 16;
                            if (out_int > 127) { // clip if above or below WAV
                                // bounds
                                out_int = 127;
                            }
                            if (out_int < -128) {
                                out_int = -128;
                            }
                            out_val = (byte) ((out_int - 128) & 0xff); // convert

                            // to
                            // .WAV format
                            outbytebuffer[outindex] = out_val; // write the output
                            // byte
                        } else {// else 16 bits per sample
                            out_int = Sn * 16; // rescale to 16 bits
                            outintbuffer[outindex] = out_int; // write the output
                            // int
                        }
                        outindex++;

                        if (i == RESET_VALUE) { // Reset ADPCM variables 48位时重置各个值
                            Sn = 0; // initialize the ADPCM variables
                            SS = 16; // initialize the Step
                            i = 0;
                        }

                        /** *******低字节处理********* */
                        if (lowByte == 0 || lowByte == 8) {
                            i++;
                        }
                        retVal = decode((byte) (sample & 0x0f), Sn, SS, SSindex);
                        Sn = ((Short) retVal[0]).shortValue();
                        SS = ((Integer) retVal[1]).intValue();
                        SSindex = ((Integer) retVal[2]).intValue();

                        if (bit_rate == BIT_RATE_VB_8) {// if 8 bits per sample...
                            out_int = Sn / 16;
                            if (out_int > 127) { // clip if above or below WAV
                                // bounds
                                out_int = 127;
                            }
                            if (out_int < -128) {
                                out_int = -128;
                            }
                            out_val = (byte) ((out_int - 128) & 0xff); // convert

                            // to
                            // .WAV format
                            outbytebuffer[outindex] = out_val; // write the output
                            // byte
                        } else {// else 16 bits per sample
                            out_int = Sn * 16; // rescale to 16 bits
                            outintbuffer[outindex] = out_int; // write the output
                            // int
                        }
                        outindex++;

                        if (i == RESET_VALUE) { // Reset ADPCM variables 48位时重置各个值
                            Sn = 0; // initialize the ADPCM variables
                            SS = 16; // initialize the Step
                            i = 0;
                        }
                    }
                    if (bit_rate == BIT_RATE_VB_8) {
                        filewriter.write(outbytebuffer);

                    } else {
                        for (int j = 0; j < outintbuffer.length; j++) {
                            byte[] arr = new byte[4];
                            longToIntBinary(outintbuffer[j], arr, 0);
                            filewriter.write(arr);

                        }
                    }
                }
                break;

            }
            default:
                break;
            }

            fileReader.close();
            filewriter.close();

        }

        /**
         * 
         * @param sample
         * @param Sn
         * @param ss
         *            引用变量
         * @param SSindex
         *            引用变量
         * @return
         */
        private static Object[] decode(byte sample, short Sn, int SS, int SSindex) {
            Object[] retArr = new Object[3];
            int[] SSadjust = new int[] { -1, -1, -1, -1, 2, 4, 6, 8 };
            // Calculated stepsizes per Dialogic Application Note 1366
            int[] SStable = new int[] { 0, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37,
                    41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
                    157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449,
                    494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411,
                    1552 };
            int Mn = 0; // calculate the linear adjustment
            if ((sample & 0x4) != 0) {
                Mn = SS;
            }
            if ((sample & 0x2) != 0) {
                Mn = Mn + (SS >>> 1);
            }// div 2
            if ((sample & 0x1) != 0) {
                Mn = Mn + (SS >>> 2);
            }// div 4

            Mn = Mn + (SS >>> 3); // div 8
            // 取Sample的符号位,即最高位
            if ((sample & 0x8) != 0) { // 最高位为1,则符号位为负
                Sn = (short) (((int) Sn - Mn) & 0xffff); // ...subtract the
                // adjustment
            } else { // 符号位为正
                Sn = (short) (((int) Sn + Mn) & 0xffff); // ...add the adjustment
            }

            if (Sn > 2047) { // adjust if sample too large...
                Sn = 2047;
            }
            if (Sn < -2048) { // ...or too small
                Sn = -2048;
            }

            // use as index into step size adjustment, adjust step size index
            SSindex = SSindex + SSadjust[sample & 0x07];

            if (SSindex < 1) { // keep SSindex within bounds...
                SSindex = 1;
            }
            if (SSindex > 49) {
                SSindex = 49;
            }

            SS = SStable[SSindex]; // get new step size from table

            retArr[0] = Sn;
            retArr[1] = SS;
            retArr[2] = SSindex;
            return retArr;
        }

        /**
         * 整型转数组
         * 
         * @param val
         * @param array
         * @param offset
         */
        private static void longToIntBinary(long val, byte[] array, int offset) {
            array[offset] = (byte) (val & 0xff);
            array[offset + 1] = (byte) (val >>> 8 & 0xff);
            array[offset + 2] = (byte) (val >>> 16 & 0xff);
            array[offset + 3] = (byte) (val >>> 24 & 0xff);
        }

        private void byteToShortBinary(byte val, byte[] array, int offset) {
            array[offset] = (byte) (val & 0xff);
            array[offset + 1] = 0x0;
        }

        /**
         * java中没有有符号类型,所以将超过0x7FFF的short类型保存为int类型。本方法提供了将有符号short类型
         * 转换保存在字节数组中,占据两个字节
         * 
         * @param val
         *            int
         * @param array
         *            byte[]
         * @param offset
         *            int
         */
        private static void toShortBinary(int val, byte[] array, int offset) {
            array[offset] = (byte) (val & 0xff);
            array[offset + 1] = (byte) (val >>> 8 & 0xff);
        }

        public static void main(String[] args) {

            String inFile  = "E:\\HK006470083.V3";
            String outFile = "E:\\test.wav";

            try {
                voxConvert(inFile, outFile, 1, 6000, 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
}

  • 写回答

1条回答

  • lcx495052184 2017-10-23 03:41
    关注

    转换完不正确啊,全是噪音

    评论

报告相同问题?

悬赏问题

  • ¥60 Java中实现如何实现张量类,并用于图像处理(不运用其他科学计算库和图像处理库))
  • ¥20 5037端口被adb自己占了
  • ¥15 python:excel数据写入多个对应word文档
  • ¥60 全一数分解素因子和素数循环节位数
  • ¥15 ffmpeg如何安装到虚拟环境
  • ¥188 寻找能做王者评分提取的
  • ¥15 matlab用simulink求解一个二阶微分方程,要求截图
  • ¥30 乘子法解约束最优化问题的matlab代码文件,最好有matlab代码文件
  • ¥15 写论文,需要数据支撑
  • ¥15 identifier of an instance of 类 was altered from xx to xx错误