reading multi-byte number in little endian from SD - am I coding efficiently?

Hi,
I am currently refreshing my C++ skills by means of playing around with the Uno and ethernet shield.
I’d like to read a *.wav file from SD. It works, but I am not shure wether my code is efficient (==fast).

A wave file’s first 8 bytes are:
4 bytes containing “RIFF” in ascii (0x52494646)
4 bytes containing the file size, coded as little endian.
I read this information and write the file size into an unsigned long with this code snipplets:

unsigned long riff_ChunkSize;
riff_ChunkSize =  (unsigned long)waveFile.read();
riff_ChunkSize += (unsigned long)waveFile.read() << 8;
riff_ChunkSize += (unsigned long)waveFile.read() << 16;
riff_ChunkSize += (unsigned long)waveFile.read() << 24;

This works, but I have a feeling I am doing something incredibly dumb here. Is there a faster solution for this? Is all this casting and shifting really necessary?

regards,
Ben

I wouldn't think that's terribly inefficient, but the shifts could be avoided with a union:

    union {
        unsigned long ul;
        byte b[4];
    } riff_Chunksize;
    
    riff_Chunksize.b[0] = wavFile.read();
    riff_Chunksize.b[1] = wavFile.read();
    riff_Chunksize.b[2] = wavFile.read();
    riff_Chunksize.b[3] = wavFile.read();

Yes! Thank you so much, Jack, this is exactly what i was looking for! With a Union I can get rid of the casting and shifting. Direct bytewise access should be the fastest way. I have no idea how the compiler optimized my code, but yours should be fast no matter how dumb the compiler is. :) Thanks again Ben

Ben_:
Yes! Thank you so much, Jack, this is exactly what i was looking for! With a Union I can get rid of the casting and shifting. Direct bytewise access should be the fastest way. I have no idea how the compiler optimized my code, but yours should be fast no matter how dumb the compiler is. :slight_smile:
Thanks again
Ben

You bet. FYI, the GCC compiler is amazingly good with optimization. Not sure it would add a union though :wink: