6 Stimmen

Korrekte Konvertierung von 16bit PCM Wave-Daten in Float

Ich habe eine Wave-Datei in 16-Bit-PCM-Form. Ich habe die Rohdaten in einer byte[] und eine Methode zur Extraktion von Proben, und ich brauche sie im Float-Format, d. h. eine float[] um eine Fourier-Transformation durchzuführen. Hier ist mein Code, sieht das richtig aus? Ich arbeite auf Android, also javax.sound.sampled usw. ist nicht verfügbar.

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

7voto

jk. Punkte 7293

Ich hatte eine ähnliche Lösung, aber IMHO ein wenig sauberer. Leider gibt es keine gute Bibliotheksmethode, soweit mir bekannt ist: *Dies setzt voraus, dass die geraden Bytes die unteren Bytes sind.

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

3voto

Dennis C Punkte 23918

Sie können versuchen, die ByteBuffer-API zu verwenden. http://developer.Android.com/reference/java/nio/ByteBuffer.html#asFloatBuffer ()

2voto

Christian Fritz Punkte 18961

Wie von hertzsprung angedeutet, funktioniert die Antwort von jk. nur für unsigned PCM. Auf Android PCM16 ist Big-Endian signiert, so müssen Sie für die potenziell negativen Wert, kodiert in berücksichtigen Zweierkomplement . Das bedeutet, dass wir prüfen müssen, ob das High-Byte größer als 127 ist, und wenn ja, zuerst 256 davon abziehen, bevor wir es mit 256 multiplizieren.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X