Little to Big Endian not working

Hey guys, I'm writing a parser that can read in .wav files and simply parse the header. I know it's been done before but I was hoping to implement myself and so far a lot of it is working properly, just not the sample rate or byte rate. I should be getting back 44100 for the sample rate but I get back this huge number 4294945860 and I'm trying to make sense of it.

Here is the code so far:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
     fs.read(buffer4, sizeof(header.sample_rate));

        header.sample_rate =   (buffer4[0]<<0) |
                               (buffer4[1]<<8) |
                               (buffer4[2]<<16) |
                               (buffer4[3]<<24) ;

        cout << "(25-28) Sample rate: " << header.sample_rate << endl;


        fs.read(buffer4, sizeof(header.byte_rate));

        header.byte_rate =   (buffer4[0]<<0) |
                               (buffer4[1]<<8) |
                               (buffer4[2]<<16) |
                               (buffer4[3]<<24) ;

        cout << "(29-32) Byte rate: " << header.byte_rate << endl;

This definitely works for the other parts in the header where I have to convert from little endian to big endian. I'm using unsigned int's for byte_rate and sample_rate.

Any idea?

Thanks
Last edited on
Well, you don't show all of the code, so I made some guesses. The first is that buffer4 is of type char. Seems obvious? Well, yes, but by default a char is a signed value, in the range -128 to +127. When you start left-shifting a negative value, then you may get something that wasn't intended.

I started adding various casts to my code, to get everything to line up. The casts at lines 15 to 18 didn't fix the problem. However, changing the type of the buffer to unsigned char, and adding the reinterpret_cast in the file read() seems to have done the trick.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Wave {
public:    
    unsigned long sample_rate;
    unsigned long byte_rate;
};

void Read(std::istream & fs)
{
    Wave header;
    
    unsigned char buffer4[1024];
    
    fs.read(reinterpret_cast<char *>(buffer4), sizeof(header.sample_rate));

    header.sample_rate =   (static_cast<unsigned long>(buffer4[0]) <<  0) 
                         | (static_cast<unsigned long>(buffer4[1]) <<  8)
                         | (static_cast<unsigned long>(buffer4[2]) << 16)
                         | (static_cast<unsigned long>(buffer4[3]) << 24)  ;

    std::cout << "(25-28) Sample rate: " << header.sample_rate << '\n';


    fs.read(reinterpret_cast<char*>(buffer4), sizeof(header.byte_rate));

    header.byte_rate =   (buffer4[0] <<  0) |
                         (buffer4[1] <<  8) |
                         (buffer4[2] << 16) |
                         (buffer4[3] << 24) ;

    std::cout << "(29-32) Byte rate: " << header.byte_rate << '\n';
}


Yep, switching it to an unsigned char array definitely worked. Using that reinterpret_cast<char *> for reading isn't the prettiest thing but at least i'm getting the right numbers now.

Thank you.
Topic archived. No new replies allowed.