将Android中的音频从48kHz重新采样到44.1kHz,反之亦然 - 纯Java或OpenSL ES?

时间:2016-10-14 10:58:11

标签: android audio mediacodec

我设法使用MediaCodec加入视频文件的音轨。如果两个音轨的通道数和采样率相同,则没有问题。

(由于某种原因,如果原始音轨是22050 Hz,OMX.SEC.aac.dec总是输出44100 Hz 2声道音频,如果原始音轨是24000 Hz,则输出48000 Hz 2声道音频。)

当我尝试在22050 Hz音轨后添加24000 Hz音轨时出现问题。假设我想要输出由两个所述音轨组成​​的22050 Hz音轨,我将不得不重新采样24000 Hz音轨。

我试过了:

private byte[] minorDownsamplingFrom48kTo44k(byte[] origByteArray)
{
    int origLength = origByteArray.length;
    int moddedLength = origLength * 147/160;
    int delta = origLength - moddedLength;
    byte[] resultByteArray = new byte[moddedLength];
    int arrayIndex = 0;
    for(int i = 0; i < origLength; i+=11)
    {
        for(int j = i; j < i+10; j++)
        {
            resultByteArray[arrayIndex] = origByteArray[j];
            arrayIndex++;
        }
    }
    return resultByteArray;
}

它返回一个3700字节的字节数组,编码后的正确音频...在非常响亮的混乱声音后面。

我的问题:

  1. 如何在不留下此类瑕疵的情况下正确地对音轨进行下采样?我应该使用平均值吗?
  2. 我是否应该使用使用OpenSL ES实施的重采样器来使流程更快和/或更好?

1 个答案:

答案 0 :(得分:1)

主要问题是,当你应该跳过 samples 时,你只是跳过 bytes

每个样本是16位,所以两个字节。如果音频是立体声,则每个样本有四个字节。你必须总是跳过这么多字节,否则你的样本会完全混淆。

使用相同的比例(10/11),您可以使用40/44始终跳过一个完整的四字节样本并保持样本正确。

至于为什么生成的视频以不同的速度播放,这是完全不同的。