安卓AMR录音文件音量放大

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

import io.kvh.media.amr.AmrDecoder;
import io.kvh.media.amr.AmrEncoder;

public class AmrUtil {
    private static final int[] amrEncodeMode = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200}; // amr 编码方式
    private static final int AMR_FRAME_COUNT_PER_SECOND = 50;
    private static int mMode = 0;

    public static void change(String inPath, String outPath) {
        File inFile = new File(inPath);
        File outFile = new File(outPath);
        if (!inFile.exists()) {
            return;
        }
        try {
            outFile.deleteOnExit();
            outFile.createNewFile();

            FileInputStream in = new FileInputStream(inFile);
            FileOutputStream out = new FileOutputStream(outFile);

            byte[] amrhead = new byte[6];// amr head 6 bytes

            in.read(amrhead);
            out.write(amrhead);

            byte[] amrframehead = new byte[1];// amr frame head 1 bytes
            in.read(amrframehead);
            out.write(amrframehead);

            int frameSize = caclAMRFrameSize(amrframehead[0]);
            byte[] amrframecontent = new byte[frameSize - 1];// amr frame content frameSize - 1 bytes
            in.read(amrframecontent);
            out.write(amrframecontent);

            byte[] amrframe = new byte[frameSize];// amr frame frameSize bytes
            short[] pcmframe = new short[160];// pcm frame 160 shorts

            long state = AmrDecoder.init();
            AmrEncoder.init(0);

            while (in.read(amrframe) != -1) {
                AmrDecoder.decode(state, amrframe, pcmframe);
                int pcmval;
                for (int i = 0; i < pcmframe.length; i++) {
                    // 音量调节
                    pcmval = pcmframe[i] * 3;
                    if (pcmval < 32767 && pcmval > -32768) {
                        pcmframe[i] = (short) pcmval;
                    } else if (pcmval > 32767) {
                        pcmframe[i] = 32767;
                    } else if (pcmval < -32768) {
                        pcmframe[i] = -32768;
                    }
                }
                AmrEncoder.encode(mMode, pcmframe, amrframe);
                out.write(amrframe);
            }
            in.close();
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 根据帧头计算当前帧大小
    private static int caclAMRFrameSize(byte frameHeader) {
        int mode;
        int temp1 = 0;
        int temp2 = 0;
        int frameSize;
        temp1 = frameHeader; // 编码方式编号 = 帧头的3-6位 temp1 &= 0x78; // 0111-1000 temp1 >>= 3;

        mMode = temp1;
        mode = amrEncodeMode[temp1];

        // 计算amr音频数据帧大小
        // 原理: amr 一帧对应20ms,那么一秒有50帧的音频数据
        temp2 = myround((double) (((double) mode / (double) AMR_FRAME_COUNT_PER_SECOND) / (double) 8));
        frameSize = myround((double) temp2 + 0.5);
        return frameSize;
    }

    private static int myround(double x) {
        return ((int) (x + 0.5));
    }
}

参考链接:

AMR文件格式分析

opencore-amr-android


注:

更新了import,需要依赖opencore-amr-android才行哦!

implementation 'io.kvh:amr:1.1.1'

《安卓AMR录音文件音量放大》上有1条评论

  1. 今天才看到某个朋友两周前发来的邮件,询问我是否有import代码。
    虽然这位朋友可能不需要了吧,不过还是更新了下文章,希望能帮助到有需要的朋友。

发表评论