2011-01-06 10 views
3

Ich habe ein Problem. In Java muss ich Proben aus einer WAV-Datei lesen. Das Dateiformat ist: wav, PCM_SIGNED, signed int von 2bytes = 16Bits, Little Endian ... Das Objekt liest die Audio-Samples in BYTES und ich muss diese zwei Bytes in einem doppelten Wert konvertieren. Ich habe versucht, diese Formel zu verwenden, aber es ist nicht ganz richtig:Konvertiert signed int (2 Bytes, 16 Bits) im Doppelformat. Mit Java

mono = (double)((audioBytes[k] & 0xFF) | (audioBytes[k + 1] << 8)); 

die Ergebnisse mit Matlab merke ich immer wieder Unterschiede zwischen den realen Wert in Matlab und konvertiert ein in Java Vergleich. Kann mir bitte jemand helfen? Vielen Dank, Dave

+2

Haben Sie ein Beispiel für eine kurze Bytefolge, was ist Ihre erwartete Ausgabe und was ist Ihre tatsächliche Ausgabe? –

+0

Wenn audioBytes [k] ein Byte ist, audioBytes [k] & 0xFF == audioBytes [k], so ist die Maske nutzlos. –

+0

Wenn audioBytes [k] == -1, audioBytes [k] & 0xFF == 255 (nachdem ich das Ergebnis trotzdem an System.out.println übergeben habe). –

Antwort

2

Sie uns nicht genügend Informationen gegeben haben (Change-Indizes wenig/big zu tauschen) zu wissen, warum Sie unterschiedliche Ergebnisse in Matlab sind immer und Java. Normalerweise skalieren Sie die Daten des Kurzkanals [-32768..32767] zu einem Double im Bereich [-1..1], wie es aussieht, als würden Sie versuchen. Ihr Java-Ergebnis: -3.0517578125E-5 ist korrekt für den kurzen Wert -1: -1/32768. Ich weiß nicht, warum dein Matlab-Ergebnis anders ist. Sie haben uns nicht gezeigt, wie Sie zu Ihren Matlab-Ergebnissen kommen.

Wenn Sie eine große Sequenz von Bytes haben (was ich vermute, dass Sie tun), und Sie nicht über BIG-ENDIAN vs LITTLE-ENDIAN oder Verschieben von Bits und Bytes sorgen wollen, lassen Sie sich von java kümmern für Sie:

import java.nio.*; 
... 
ByteBuffer buf = ByteBuffer.wrap(audioBytes); 
buf.order(ByteOrder.LITTLE_ENDIAN); 

while (buf.remaining() >= 2) { 
    short s = buf.getShort(); 
    double mono = (double) s; 
    double mono_norm = mono/32768.0; 
    ... 
} 

ByteBuffer.getShort() die nächsten zwei Bytes des Puffers liest, kümmert sich um die Little-Endian-Bestellung, wandelt die Bytes in einer kurzen und positioniert sich für die nächste getXXX() -Aufruf.

+0

Ich denke, diese Methode ist die beste. – Davide

+0

Aber ich verstehe immer noch nicht, warum Matlab gibt mir andere Ergebnisse ... – Davide

+0

Es hängt wirklich davon ab, was Sie in MATLAB tun. Welche Code/Befehle laufen Sie ? –

-1

Können Sie nur Most_significant Byte * 256 + Least_significant_byte und dann zu verdoppeln?

+0

erläuterten Ergebnis. Das hätte ich mir nicht gedacht, weil die Bytewerte in Java zwischen -128 und 127 liegen. –

+0

Das funktioniert nicht. .. :( – Davide

0

Dies ist der richtige Weg:

double sampleValue = (double)((bytes[0]<<8) | (bytes[1]&0x00FF));