Android音视频处理之音频混音

作者: 郑旭泽 | 来源:发表于2016-12-16 16:42 被阅读1553次
    数字音频基本概念

    在实现功能之前,我们先来了解一下数字音频的有关属性:

    采样频率(Sample Rate):每秒采集声音的数量,它用赫兹(Hz)来表示。(采样率越高越靠近原声音的波形)
    采样精度(Bit Depth):指记录声音的动态范围,它以位(Bit)为单位。(声音的幅度差)
    声音通道(Channel):声道数。比如左声道右声道。

    采样量化后的音频最终是一串数字,声音的大小(幅度)会体现在这个每个数字数值大小上;而声音的高低(频率)和声音的音色(Timbre)都和时间维度有关,会体现在数字之间的差异上。

    音频的编码与解码

    自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。本篇文章介绍的混音就是对PCM数据做处理。

    相对自然界的信号,任何数字音频编码方案都是有损的,因为无法完全还原。在计算机应用中,能够达到最高保真水平的就是PCM编码,平时常见的WAV文件就是在PCM数据前加上一个44字节的RIFF头部组成的。

    音频信号在时域和频域上具有相关性,也即存在数据冗余,音频编码的实质是减少音频中的冗余。

    那么,解码的目的就是让编码后的数据恢复成PCM源数据。

    AAC,Mp3 --> Decoder --> Audio PCM Data

    常见的音频编码格式有以下这些:

    public static final String MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
    public static final String MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
    public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
    public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
    public static final String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
    public static final String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
    public static final String MIMETYPE_AUDIO_OPUS = "audio/opus";
    public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
    public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
    public static final String MIMETYPE_AUDIO_RAW = "audio/raw";
    public static final String MIMETYPE_AUDIO_FLAC = "audio/flac";
    public static final String MIMETYPE_AUDIO_MSGSM = "audio/gsm";
    public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3";
    public static final String MIMETYPE_AUDIO_EAC3 = "audio/eac3";
    
    音频的混音

    音频混音的原理: 量化的语音信号的叠加等价于空气中声波的叠加。

    反应到音频数据上,也就是把同一个声道的数值进行简单的相加,但是这样同时会产生一个问题,那就是相加的结果可能会溢出,当然为了解决这个问题已经有很多方案了,在这里我们采用简单的平均算法。

    下面的演示程序适用于音频文件采样率、通道数、采样精度一样的情况:

    /**
     * 混合音频,使用平均算法
     *
     * @param mixedBytes 输出混合后的数据到该byte数组
     * @param shorts1    需要混合的short数组1
     * @param shorts2    需要混合的short数组2
     */
    private void mixRawAudioBytes(byte[] mixedBytes, short[] shorts1, short[] shorts2) {
        for (int i = 0; i < shorts2.length; i++) {
            shorts1[i] = (short) ((shorts2[i] + shorts1[i]) / 2);
        }
    
        for (int i = 0; i < shorts1.length; i++) {
            mixedBytes[i * 2] = (byte) (shorts1[i] & 0x00FF);
            mixedBytes[i * 2 + 1] = (byte) ((shorts1[i] & 0xFF00) >> 8);
        }
    }
    

    相关文章

      网友评论

      • Darcy叶国忠:你这几篇文字借鉴地有点厉害啊~ 请注明出处!!!

      本文标题:Android音视频处理之音频混音

      本文链接:https://www.haomeiwen.com/subject/nginmttx.html