Java Byte-Array zu Integer-Array

Loopo

Admiral
Registriert
Juli 2002
Beiträge
7.617
Ich schreibe eine Java-ME-Anwendung. Ich nehme dabei einen Audio-Stream auf, das Byte-Array erhalte ich wie folgt:
Code:
ByteArrayOutputStream output;

...

byte[] recordedSoundArray = output.toByteArray();
Die Daten liegen darin als 2 Bytes im Format Little Endian. Jetzt will ich aus diesen 2 Bytes einen Integer (bzw. Short) im Format Big Endian erstellen.

PS: Die Werte sind vorzeichenbehaftet!
 
Zuletzt bearbeitet:
Danke, ich glaube das war's. Hier der komplette Code.
Code:
    public static int[] convertShort(byte[] data) {
        int outSize = data.length/2;
        int[] out = new int[outSize];

        ByteArrayInputStream bis = new ByteArrayInputStream(data);
        DataInputStream in = new DataInputStream(bis);
        int i = 0;
        try {
            while(true) {
                // convert little endian to big endian
                byte a = in.readByte();
                byte b = in.readByte();
                out[i] = (short)((b << 8) | (a & 0xff));
                //out[i] = in.readShort(); // <-- falls Array bereits in Big Endian
                i++;
            }
        } catch (EOFException ex) {
            // do nothing, end of stream is reached
        } catch (IOException ex) {
           ex.printStackTrace();
        }

        return out;
    }

Reads two input bytes and returns a short value. Let a be the first byte read and b be the second byte. The value returned is:

(short)((a << 8) | (b & 0xff))
Ist das Vorzeichen immer in a? Egal welche Bytereihenfolge?
 
Zuletzt bearbeitet:
Loopo schrieb:
Ist das Vorzeichen immer in a? Egal welche Bytereihenfolge?

In Java werden vorzeichenbehaftete Zahlen im Zweierkomplement dargestellt. Daher ist das Vorzeichen immer im höchstwertigen Bit.
Insofern ist von der Bytereihenfolge abhängig in welchem Byte das Vorzeichen steht.
 
ice-breaker schrieb:
wenn ich mich gerade nicht täusche, müssten die Bits aber auch noch gespiegelt werden.
Das weiß ich eben nicht. :rolleyes:

DjNDB schrieb:
In Java werden vorzeichenbehaftete Zahlen im Zweierkomplement dargestellt. Daher ist das Vorzeichen immer im höchstwertigen Bit.
Insofern ist von der Bytereihenfolge abhängig in welchem Byte das Vorzeichen steht.
Also immer in a im obigen Beispiel. :p
 
Da ein Audiostream unter Java ME aufgenommen wird nehme ich an, dass RecordControl verwendet wird?

Kannst du da nicht bei Manager.createPlayer im Media Encoding String die gewünschte Endianness angeben und dir das ganze ersparen?

ice-breaker schrieb:
wenn ich mich gerade nicht täusche, müssten die Bits aber auch noch gespiegelt werden.

Ich ging davon aus, dass die 2 Bytes bereits einen zerlegten Short repräsentieren ("2 Bytes im Format Little Endian").
 
Nur bedingt, weil der Emulator nur Little Endian kann. Das Handy kann beides, aber zum Testen verwende ich den Emulator. Deshalb ist eine Lösung, die mit Little Endian zurecht kommt vorzuziehen.

So nehme ich auf:
Code:
Player p = Manager.createPlayer("capture://audio?encoding=pcm&rate=16000&bits=16&channels=1&signed=signed&endian=little");
p.realize();
RecordControl rc = (RecordControl)p.getControl("RecordControl");
ByteArrayOutputStream output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
p.start();
Thread.currentThread().sleep(2000);
rc.commit();
byte[] recordedSoundArray = output.toByteArray();
p.close();
Ich weiß nur, dass das Ergebniss in recordedSoundArray 2 Bytes groß ist. Nach dem Encoding-String müsste es in Little Endian gespeichert sein. Wie die Bitreihenfolge nun selbst ist, weiß ich nicht. Ich weiß auch nicht, wie ich Testdaten da statt den Mikrofondaten reinsenden könnte...

PS: wenn alles nichts hilft, muss ich mir ein Canvas basteln und das Wave reinzeichen und schauen, ob es richtig aussieht...
 
Zuletzt bearbeitet:
Loopo schrieb:
Nur bedingt, weil der Emulator nur Little Endian kann. Das Handy kann beides, aber zum Testen verwende ich den Emulator. Deshalb ist eine Lösung, die mit Little Endian zurecht kommt vorzuziehen.

Okay, die hast du jetzt ja.

Prüfst du die System Property "audio.encodings" um ein für das jeweilige Gerät geeignetes Format zu wählen?

Wenn du dort "little endian, 16 bit, signed" wählst, dann sollte das im Byte Array auch so drin stehen.
Daher wüsste ich nicht was man da noch an den Bits ändern sollte?
 
Zurück
Oben