2

我有 2 个文件。曾经是一个 mp3 被解码为 pcm 到一个流中,我也有一个 wav 被读入 pcm。样本以短数据类型保存。

音频统计:44,100 个样本 * 每个样本 16 位 * 2 个通道 = 1,411,200 位/秒

我需要将 X 秒的静音应用到 mp3 pcm 数据的开头,我这样做是这样的:

private short[] mp3Buffer = null;
private short[] wavBuffer = null;
private short[] mixedBuffer = null;

double silenceSamples = (audioInfo.rate * padding) * 2;
for (int i = 0; i < minBufferSize; i++){

    if (silenceSamples > 0 ){

        mp3Buffer[i] = 0; //Add 0 to the buffer as silence

        mixedBuffer[i] = (short)((mp3Buffer[i] + stereoWavBuffer[i])/2);  
        silenceSamples = silenceSamples - 0.5;
    }
    else
        mixedBuffer[i] = (short)((mp3Buffer[i] + stereoWavBuffer[i])/2);
}

音频始终关闭。有时一两秒太快,有时一两秒太慢太慢。我不认为这是时间问题,因为我首先启动音频记录(wav),然后设置启动计时器->启动媒体播放器(已经准备好)->结束计时器并将差异设置为“填充”变量。从 wav 标头中,我也跳过了 44kb。

任何帮助将非常感激。

4

1 回答 1

1

我假设您想通过在其中一个流的开头插入填充以某种方式对齐两个音频源?这里有一些问题。

mp3Buffer[i] = 0; //Add 0 to the buffer as silence

这不是在开头添加静音,只是将数组中 offest [i] 处的条目设置为 0。下一行:

mixedBuffer[i] = (short)((mp3Buffer[i] + stereoWavBuffer[i])/2);

然后只是覆盖这个值。

如果您想以某种方式对齐流,最好的方法不是在任何一个流的开头插入静音,而是在其中一个流与另一个流的偏移处开始混合。此外,最好将它们混合成 32 位浮点数,然后标准化。就像是:

    int silenceSamples = (audioInfo.rate * padding) * 2;
            float[] mixedBuffer = new float[minBufferSize + silenceSamples]
    for (int i = 0; i < minBufferSize + silenceSamples; i++){

    if (i < silenceSamples )
    {       
        mixedBuffer[i] = (float) stereoWavBuffer[i];  
    }
    else if(i < minBufferSize)
    {
        mixedBuffer[i] = (float) (stereoWavBuffer[i] + mp3Buffer[i-silenceSamples]);
    }
    else 
    {
        mixedBuffer[i] = (float) (mp3Buffer[i-silenceSamples]);
    }

要对数据进行规范化,您需要遍历混合缓冲区并找到绝对最大值Math.abs(...),然后将数组中的所有值乘以 32,767/largestValue - 这将为您提供一个缓冲区,其中最大值适合回短而无需裁剪。然后遍历您的浮点数组,将每个值移回一个短数组。

我不确定你minBufferSize是什么 - 这需要足够大以混合所有数据。

于 2012-05-23T22:28:33.467 回答