Android PCM格式转G711a率代码

 AudioRecord录音出来的是原始文件PCM文件,有时候我们可能需要给转成G711格式的才能播放,最近我的项目就是需要把PCM格式转成G711格式,然后进行上传到服务器上,来实现声音的传递。我在网上查找资料也看了许久,还是觉得这个写的不错,所以发出来给大家参考一下。


public class G711Code {
    private final static int SIGN_BIT = 0x80;
    private final static int QUANT_MASK = 0xf;
    private final static int SEG_SHIFT = 4;
    private final static int SEG_MASK = 0x70;

    static short[] seg_end = {0xFF, 0x1FF, 0x3FF, 0x7FF,0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};

    static short search(short val,short[] table,short size){

        for (short i = 0 ; i < size; i++) {
            if(val <= table[i]){
                return i;
            }
        }
        return size;
    }

    static byte linear2alaw(short pcm_val){
        short mask;
        short seg;
        char aval;
        if(pcm_val >= 0){
            mask = 0xD5;
        }else{
            mask = 0x55;
            pcm_val = (short) (-pcm_val - 1);
            if(pcm_val < 0){
                pcm_val = 32767;
            }
        }

        /* Convert the scaled magnitude to segment number. */
        seg = search(pcm_val, seg_end, (short) 8);

        /* Combine the sign, segment, and quantization bits. */

        if (seg >= 8)       /* out of range, return maximum value. */
            return (byte) (0x7F ^ mask);
        else {
            aval = (char) (seg << SEG_SHIFT);
            if (seg < 2)
                aval |= (pcm_val >> 4) & QUANT_MASK;
            else
                aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
            return (byte) (aval ^ mask);
        }
    }


    static short alaw2linear(byte a_val){
        short       t;
        short       seg;

        a_val ^= 0x55;

        t = (short) ((a_val & QUANT_MASK) << 4);
        seg = (short) ((a_val & SEG_MASK) >> SEG_SHIFT);
        switch (seg) {
            case 0:
                t += 8;
                break;
            case 1:
                t += 0x108;
                break;
            default:
                t += 0x108;
                t <<= seg - 1;
        }
        return (a_val & SIGN_BIT) != 0 ? t : (short) -t;
    }

    /**
     * pcm 转 G711 a率
     * @param pcm
     * @param code
     * @param size
     */
    public static void G711aEncoder(short[] pcm,byte[] code,int size){
        for(int i=0;i<size;i++){
            code[i]=linear2alaw(pcm[i]);
            Log.e("-------------","数据编码");
        }
    }

    /**
     * G.711 转 PCM
     * @param pcm
     * @param code
     * @param size
     */
    public static void G711aDecoder(short[] pcm,byte[] code,int size)
    {
        for(int i=0;i<size;i++){
            pcm[i]=alaw2linear(code[i]);
        }
    }

}

使用文件说明

//inG711Buffer为读取音频short类型,outG711Buffer为需要转换格式写入的byte类型,nReadBytes读取音频的长度

//调用G711编码
G711Code.G711aEncoder(inG711Buffer,outG711Buffer,nReadBytes);

猜你喜欢

转载自blog.csdn.net/as425017946/article/details/100537143