【发布时间】:2015-11-14 16:24:18
【问题描述】:
我知道网上有很多资源解释如何解交织 PCM 数据。在我目前的项目过程中,我看过其中的大多数......但我没有音频处理方面的背景,我很难找到关于这种常见形式究竟如何的详细解释的音频被存储。
我知道我的音频将有两个通道,因此样本将以 [left][right][left][right] 格式存储... 我不明白这到底是什么意思。我还读到每个样本都以 [left MSB][left LSB][right MSB][right LSB] 格式存储。这是否意味着每个 16 位整数实际上编码了两个 8 位帧,或者每个 16 位整数是其自己的帧,用于左声道或右声道?
谢谢大家。任何帮助表示赞赏。
编辑:如果您选择给出示例,请参考以下内容。
方法上下文
具体来说,我要做的是将交错的 short[] 转换为两个 float[],每个代表左声道或右声道。我将在 Java 中实现它。
public static float[][] deinterleaveAudioData(short[] interleavedData) {
//initialize the channel arrays
float[] left = new float[interleavedData.length / 2];
float[] right = new float[interleavedData.length / 2];
//iterate through the buffer
for (int i = 0; i < interleavedData.length; i++) {
//THIS IS WHERE I DON'T KNOW WHAT TO DO
}
//return the separated left and right channels
return new float[][]{left, right};
}
我当前的实现
我已尝试播放由此产生的音频。非常接近,接近到可以听懂一首歌的歌词,但显然仍然不是正确的方法。
public static float[][] deinterleaveAudioData(short[] interleavedData) {
//initialize the channel arrays
float[] left = new float[interleavedData.length / 2];
float[] right = new float[interleavedData.length / 2];
//iterate through the buffer
for (int i = 0; i < left.length; i++) {
left[i] = (float) interleavedData[2 * i];
right[i] = (float) interleavedData[2 * i + 1];
}
//return the separated left and right channels
return new float[][]{left, right};
}
格式
如果有人想了解有关音频格式的更多信息,以下就是我所拥有的一切。
- 格式为 PCM 2 通道交错大端线性 int16
- 采样率为 44100
- 每个 short[] 缓冲区的短裤数量为 2048
- 每个 short[] 缓冲区的帧数为 1024
- 每个数据包的帧数为 1
【问题讨论】:
-
您的实现看起来应该几乎完全正确 - 当您说您可以理解单词时,即使它们听起来是错误的,也可以确认这一点。您使用的输出格式的详细信息是什么?我的猜测是,short-to-float 转换需要缩放和/或偏移 - 使用 float 指定范围 [-32768, 32767] 会有点奇怪。
-
你是如何获得这个
short[]数组的?如果样本已经在两个字节整数中,则字节顺序无关紧要。来源是签名还是未签名?预期输出在什么范围内? -
@Sbodd 是的,阅读我认为缩放可能是问题的答案。我现在正在实施一个规范化的流程。
-
@Banthar 这个短数组来自Spotify Android SDK。这就是为什么我只能访问这些小块的原因——因为我只有流媒体的权限。短裤已签名,并且它们的预期范围包括(基于我在调试器中看到的)几乎整个 -32768 到 32768 的短裤范围。
标签: java audio pcm audioformat interleave