【问题标题】:Correct way to Convert 16bit PCM Wave data to float将 16 位 PCM Wave 数据转换为浮点数的正确方法
【发布时间】:2011-06-05 12:55:35
【问题描述】:

我有一个 16 位 PCM 格式的波形文件。我有byte[] 中的原始数据和一种提取样本的方法,我需要它们以浮点格式,即float[] 来进行傅里叶变换。这是我的代码,这看起来对吗?我正在使用 Android,所以 javax.sound.sampled 等不可用。

private static short getSample(byte[] buffer, int position) {
  return (short) (((buffer[position + 1] & 0xff) << 8) | (buffer[position] & 0xff));
}

...

float[] samples = new float[samplesLength];
  for (int i = 0;i<input.length/2;i+=2){
    samples[i/2] = (float)getSample(input,i) / (float)Short.MAX_VALUE;
  }

【问题讨论】:

标签: java android pcm audio-processing


【解决方案1】:

我有一个类似的解决方案,但恕我直言,更简洁一些。不幸的是,据我所知,没有好的库方法:*这假设偶数字节是低字节

private static float[] bytesToFloats(byte[] bytes) {
    float[] floats = new float[bytes.length / 2];
    for(int i=0; i < bytes.length; i+=2) {
        floats[i/2] = bytes[i] | (bytes[i+1] << 8);
    }
    return floats;
}

【讨论】:

  • 这仅适用于未签名的 PCM,对吧?否则,您需要从每对字节中的第二个中屏蔽符号位。
  • @hertzsprung : 你能解释一下在签名 PCM 的情况下该怎么做吗?
【解决方案2】:

【讨论】:

    【解决方案3】:

    正如 hertzsprung 所指出的,jk 的答案。仅适用于未签名的 PCM。在 Android 上,PCM16 是大端签名的,因此您需要考虑潜在的负值,编码为 two's complement。这意味着我们需要检查高字节是否大于 127,如果是,则先从中减去 256,然后再乘以 256。

    private static float[] bytesToFloats(byte[] bytes) {
        float[] floats = new float[bytes.length / 2];
        for(int i=0; i < bytes.length; i+=2) {
            floats[i/2] = bytes[i] | (bytes[i+1] < 128 ? (bytes[i+1] << 8) : ((bytes[i+1] - 256) << 8));
        }
        return floats;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-08
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多