LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

save a file into an array

Hello,

I'm a newbie in Labwindows/CVI. I'm doing a project and now I have the problem to acquire an mpeg2 file from disk for further elaborations.
I've built a GUI with a open file menu, then I used the 'FileSelectPopup' function to allow the user to select the file and to
record the file path into a variable. Then I have acquired the file and saved into an
array using the 'FileToArray' function. My problem was to know the 'Number_of_Elements' for that function
so I used the 'GetFileInfo' function that returns the dimension of the mp2 file in byte and I passed
that number * 8 to the 'FileToArray' function. Is it correct? If I try to write the array into a file
using the 'ArrayToFile' function, the file can be played correctly even if the dimension is bigger
than the original one (if I play the file, it seems that some null bits are attached at the end).
Thanks in advance
0 Kudos
Message 1 of 6
(4,062 Views)
Hello Aldart,
 
which kind of data type have you set as "datatype" input for the function "FileToArray"? If you set "unsigned char" or "char" maybe it is not necessary to multiply per 8 the file dimension you got from "GetFileInfo".
 
Hope this can help,
 
Fabio
Fabio M.
NI
Principal Engineer
0 Kudos
Message 2 of 6
(4,035 Views)
Hello Fabio!

Thank you for your reply. I want to explain better my problem. I have the path of an audio mpeg2 file and I have to read the first 32 bits (that is the header of the file) to acquire some information about the file (sampling rate, bitrate,...). I thought to insert every bit in a ceil of an array and to read then every form of the header according to its position. In a second stage I have to insert all the file into an array for further manipulations (scrambling, interleaving, OFDM modulation and so on). So I have to work on the bits of the file and I wanted to acquire them and insert into an array. This was quite easy in Matlab:

fid = fopen(filepath, 'r' ) ;
header  = fread(fid, 32, 'ubit1');     
fclose(fid);

so now header is an array of 32 double, every element is a bit of the header.  I cannot do the same thing with C and CVI because fread and fopen c-functions work on bytes and not directly on bits. Is it right or am I wrong? How can I solve it?
Thank you so much in advance.


0 Kudos
Message 3 of 6
(4,000 Views)

The minimum amount of data that a C file read/write operation can transfer is one byte. For your application to examine a 32 bit header bit by bit, I would probably use code along the following lines:

#define BIT_SET(word, bit) ((word) & 1 << (bit) ? 1: 0)
...
FILE *fp;
un
signed int header;
...
fp = fopen (filepath, "rb");
fread (&header, sizeof (unsigned int), 1, fp);  // Read 32 bits into 1 word
...
if (BIT_SET (header, 14)) {   // Test if bit 14 of the header is set
            // Do stuff for bit 14 set
} else {
            // Do stuff for bit 14 clear
}
    // etc

JR

0 Kudos
Message 4 of 6
(3,971 Views)
Hello JR,

thank you for your help! I have followed your advise and I have read the header and also all the rest of my mpeg 2 file. This is what I have obtained for the header:

1    1    1    1    1    1    1    1    0    0    1    1    1    1    1    1    0    0    1    0    0    0    0    1    0    0    1    0    0    0    1    0

The strange thing is that the header should start with a sync word of 12 '1'  and I have only 8. For example according to the standard the sampling rate should correspond to the bit in 21th and 22th position that is  '00' and I should have '01' that corrispond to 48  kHz. Same problem with the bitrate.
Where am I wrong?
Thank you so much

aldart
0 Kudos
Message 5 of 6
(3,946 Views)
It is a problem of bit identification, due to the way that the data is stored in PC memory. What appears in the header in bit position x does not appear in bit position x of the stored word! To cut a long story (about little-endian, words, fread() etc) short, consider the following bit sequence as it appears in the header:

{start of header}    0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v    {end of header}

So according to your expectations if the first 12 bits should be a '1' then bits shown as 0 to b should be set. Unfortunately, when the above sequence is read into a 32 bit word on a PC system, they are re-ordered and appear as follows:

{MS bit}    o p q r s t u v g h i j k l m n 8 9 a b c d e f 0 1 2 3 4 5 6 7    {LS bit}

and you no longer see 12 '1's in a row. When you request bit 0 (the LS bit of a word) using the macro BIT_SET (header, 0) you will actually get the value as identified at position 7 in the header. Probably not what you were expecting... To read the first bit of the header (at the position identified as 0) you need to use the macro BIT_SET (header, 7).
 
All very confusing, sometimes. As I say, it is a question of bit identification, so all you really need to do is to renumber the bits in the header according to the mapping shown above. (Something along the lines of #define BIT0 7 would work, for example - than you could use BIT_SET (header, BIT0) in your code to maintain readability.
 
JR
0 Kudos
Message 6 of 6
(3,934 Views)