4
votes

I am a bit confused on what I have done.. As far as I know, java and especially the DataOutputStream writes values in Big endian.

I am writing a little signal generator and have to store the files in little endian. No problem so far, just swap the bytes.

writeShort() also says "writing high byte first".

So for example decimal '2' would be stored normally as:

00 02 (big endian)
02 00 (little endian) is what I need.

So I swap the bytes:

public static short swap (short value)
{
        int b1 = value & 0xff;
        int b2 = (value >> 8) & 0xff;

        return (short) (b1 << 8 | b2 << 0);
}

and write the short:

dos.writeShort(swap(x[t]));

The hex editor shows me the file in the format it should be: 02 00

When I now try to open my generated audio file, I can't hear anything. (audacity raw data import and settings like samplerate all correct).

I removed the byte swapping, getting a file with: 00 02 which is big endian.

I opened audacity again and with the same configuration, I heard the tone. Definetely I configured little endian!

I copied the file to windows (I am working on a mac) and opened the file in Cool Edit 2000, choosing again 16khz, 16 bit unsigned pcm and little endian (16-bit LSB, MSB). I heard the tone again, choosing big endian nothing.

Where is my failure? Something confuses me as this should not work like I described..

Generating the tone:

// x(t) = A*cos (2*pi * f * t + phi)
        // 
        if(null != dos) 
        {
            double sampPeriod = 1.0/16000;
            short x[] = new short[16000]; // 16k samples for 1 second
            for(int t=0; t < x.length; t++)
            {
                double time = t * sampPeriod;
                x[t] = (short) (amplitude * Math.sin(2.0*Math.PI*frequenz*time+phase));
            }

            for(int t=0; t < x.length; t++)
            {
                try {
                    dos.writeShort(x[t]);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

Edited 2:16pm 02/04/13: I was reading around assuming something in my understanding is the failure and I found the following picture on wikipedia:

read access

See answer of the problem in the next post.

1
00 02 is not little or big endian by itself. It is 2 when interpreted as big endian and 512 when interpreted as little endian.zch
ok, this may be a discussion about how I described it and I understand what you want to say to me. But it doesn't help me at this moment.Stefan
as I was writing in my answer: This did help me :)Stefan

1 Answers

2
votes

Ok guys and everyone who is interested by following this question:

The failure has nothing to do with little or big endian. Everything I understood from LE and BE was correct. (But not the assume at the end about read access, that tricked my mind as I was searching for any explanation..)

The failure was about the amplitude of the signal.

In case the amplitude was too low - the volume itself (which generates through amplitude) was too low. So nothing could be heard. Interpreting the written big endian file as little endian made every short-sample in the file a larger one (coming back to zch's comment: 00 02 is 512 when interpreted as little endian).

This generated a higher sampling value at that time and caused me to hear a thing.

By setting generally a higher amplitude and byte-swapping correctly to little endian I could again hear a thing. So the main failure was nothing about endianess.

zch's comment made me brood over again and again, resulting in a little c++ code on windows reading the values and seeing that native LE interpretation is the same as zch said. That lead me to the amplitude point and now I have found the problem. Hope no one else does this stupid failure or will find this post and know in the future :-)