Click to See Complete Forum and Search --> : F read type problem


conor20
December 14th, 2006, 05:18 AM
Hello,

I am trying to read in values from a wav file. Each sample is 16 bits long (eg equivalent to a short int).

I want to run a FFT routine on the values then which takes a double array.

When I try to read in the values from the wav file with fread straight to the double array (with the code)

fread(sound_buffer, 2, 512, WavFile);

it puts two samples into each element of the double array sound_buffer as (presumably) each element is 32 bits and each sample is only 16 bits long.
This means that the values in the double array are useless.

I have it working by first f reading the values into a short int array then copying them into a double array but this is hugely ineffecient as it's going to be called a few hundred times a second.

Does anyone know how to use fread to copy one short int to every double element in the array?

Thanks a million,
Conor.

AlbertGM
December 14th, 2006, 10:15 AM
What's sound_buffer? Double array like:double sound_buffer[size];Why?
Anyway, if you have an int you can put it into two shorts. Watch this:
#include <cstdio>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[]){

unsigned int i32BitsData = 0xAABBCCDD;

unsigned short i16BitsDataH = 0; // Hi 2 Bytes
unsigned short i16BitsDataL = 0; // Low 2 Bytes


i16BitsDataH = (unsigned short) ((short*)(&i32BitsData))[1];
i16BitsDataL = (unsigned short) ((short*)(&i32BitsData))[0];

printf("All: %X, Hi Part = %X, Low Part = %X\n", i32BitsData, (unsigned short)i16BitsDataH, (unsigned short)i16BitsDataL);

return 0;
}

Albert.

SuperKoko
December 14th, 2006, 10:20 AM
I have it working by first f reading the values into a short int array then copying them into a double array but this is hugely ineffecient as it's going to be called a few hundred times a second.


The conversion need to be done only once!
The final result is that each short int of the file will be converted once to double.
That process is probably negligible compared to the FFT itself.


Does anyone know how to use fread to copy one short int to every double element in the array?

In no way would it be faster than if you write it yourself.
There is no magical short->double convertor placed between the RAM and the CPU.
You'll have to use the FPU itself. It's as fast as it can be.

SuperKoko
December 14th, 2006, 10:23 AM
AlbertGM : FFT requires floating point values. The OP was saying that fread'ing directly raw "short int" data into a double array doesn't make sense and that he needs a mean to convert each short int to double in an efficient way.
BTW: your code is broken and has undefined behavior.

AlbertGM
December 14th, 2006, 10:33 AM
BTW: your code is broken and has undefined behavior.Sorry, but what means BTW?
The code works and prints:All: AABBCCDD, Hi Part = AABB, Low Part = CCDDWhy you say it has an undefined behavior?

MrViggy
December 14th, 2006, 05:31 PM
By The Way.

You're assuming that a short is half the size of an int. There are compilers that do not make that "assumption", and you're code will fail on those. The standard only says:
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
Theoritically, all integers on a particular machine/compiler could be only 1 byte!

Viggy

AlbertGM
December 15th, 2006, 03:02 AM
That's true. I assume you are working over amb 32bits-machine. But that's what I undestood in the first post. Maybe I undestood wrong.
Thanks for correcting me.

Albert.

SuperKoko
December 15th, 2006, 05:46 AM
Sorry, but what means BTW?

By The Way

If the problem is not only about sizes of integers, but aliasing.
The standard clearly forbids that you fetch a value with a type incompatible with the type stored in memory.

For example, with GCC, it's easy to write a program where writing a "long" in memory and reading it with an int pointer doesn't work (the int read is not the long written). And that, on a platform where sizeof(int)==sizeof(long) and int and long have the exact same representations.

Approximatively the same piece of code can prove that char* and const char* mustn't be aliased, even though they've the same representations.


15If a program attempts to access the stored value of an object through
an lvalue of other than one of the following types the behavior is
undefined25):
_________________________
25) The intent of this list is to specify those circumstances in which
an object may or may not be aliased.

--the dynamic type of the object,

--a cv-qualified version of the dynamic type of the object,

--a type that is the signed or unsigned type corresponding to the
dynamic type of the object,

--a type that is the signed or unsigned type corresponding to a cv-
qualified version of the dynamic type of the object,

--an aggregate or union type that includes one of the aforementioned
types among its members (including, recursively, a member of a sub-
aggregate or contained union),

--a type that is a (possibly cv-qualified) base class type of the
dynamic type of the object,

--a char or unsigned char type.