Правильный способ преобразования 16-битных данных PCM PCM для плавания

StackOverflow https://stackoverflow.com/questions/4630221

Вопрос

У меня есть волновой файл в 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;
  }
Это было полезно?

Решение

У меня было подобное решение, но ИМХО немного чище. К сожалению, нет хорошего метода библиотеки, насколько я знаю: * Это предполагает, что даже байты - это нижние байты

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;
}

Другие советы

Вы можете попробовать использовать API BYTEBUFFER.http://developer.android.com/reference/java/nio/bytebuffer.html#asfloatbuffer.()

Как указано hertzsprung Ответ JK. работает только для PCM беззнаков. На Android PCM16 подписан Big-Endian, поэтому вам нужно учитывать потенциально отрицательное значение, закодированное в Два дополнения. Отказ Это означает, что нам нужно проверить, превышает ли высокий байт более 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;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top