android - Java - 将 16 位 Mono PCM 原始数据转换为立体声

标签 android audio mixing audiotrack

我正在将两个 16 位 PCM 样本混合到一个短缓冲区中。

// This is our buffer for PCM audio data
mp3Buffer = new short[minBufferSize];
wavBuffer = new short[minBufferSize];
mixedBuffer = new short[minBufferSize];

我正在使用 mp3 和 wav 文件中的样本填充这些缓冲区。我发现 wav 文件将始终为单声道,而 mp3 文件将始终为立体声。

我读到,如果您“只需分配原始 PCM 数据大小两倍的缓冲区,并且对于原始缓冲区中的每个样本,将其放入新缓冲区中两次”

short[] stereoWavBuffer = new short[minBufferSize];
int k = 1;
for (int j = 0; j < minBufferSize / 2; j += 2)
{
    stereoWavBuffer[j] = wavBuffer[j];
    stereoWavBuffer[k] = wavBuffer[k];
     k += 2;

                }
                // TO DO -  Add the 2 buffers together

                for (int i = 0; i < minBufferSize; i++){
                    mixedBuffer[i] = (short)(mp3Buffer[i] + stereoWavBuffer[i]);
                }


                track.write(mixedBuffer, 0, minBufferSize); 
}

我怎样才能做到这一点?我尝试过这个,但 wav 音频现在是正常速度,但听起来像花栗鼠。

最佳答案

在我看来,你的第一个 for 循环应该是

j < minBufferSize - 1

/2 意味着您永远不会读取所有波形缓冲区或写入整个立体声缓冲区, - 即使您只读取一半波形缓冲区,因为这是单声道的所有数据,您仍然需要写入整个立体声缓冲。此外,您还需要将 J 加 1 而不是 2,以便读取每个单声道样本。

速度问题似乎是因为您应该将 j 和 k 处的 Stereowavebuffer 设置为等于 j 处的 Wavebuffer。看来您实际上只是复制了原始单声道文件的一半。然后以立体声播放(即:双倍字节率)。

我认为第一个循环应该看起来更像这样

int k = 0;
for (int j = 0; j < minBufferSize / 2; j++) //Assuming you only have half a buffer since mono???
{
    stereoWavBuffer[k] = wavBuffer[j];
    stereoWavBuffer[k+1] = wavBuffer[j];
     k += 2;
}

-已编辑以修复 iPad 打字错误!

关于android - Java - 将 16 位 Mono PCM 原始数据转换为立体声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10056280/

相关文章:

android - fragment 的多个实例正在重用同一个 Bundle

android - Ionic.io 从 Node js 服务器发送推送通知

android - APK 大小是否受到 React Native 中未使用的包的影响?

android - Android RTSP 流媒体协议(protocol)支持多少种音频编解码器?

algorithm - 元素混合算法

c++ - 在 C++ 代码中使用/混合 C?

java - 允许用户更改我的应用程序的颜色

jquery - jQuery的事件使声音

video - 渲染录制的和实时/流式音频/视频时的时间流回调

c++ - 从 C++ 对象调用 Objective-C 父对象