Page 1 of 1

NXC: strange behaviour storing numbers to a file

Posted: 11 Feb 2011, 18:30
by HaWe
I have a problem storing 512 value to a file:

1st question:
if I have 512 ints to store then my declarated file size for CreateFile() should be 512*2 plus a little more for eof() etc, or am I wrong?


2nd question:
my array length is 512
although my counter should count from 0...512 writing all array values to a file it keeps on counting up to several millions or so and doesn't stop when 512 has been reached -
what's wrong with my code?

Code: Select all


#define MaxRecLen 512

int  SoundRecord[MaxRecLen];             // detection: 0...MaxRecLen


//**************************************************************************
// File I/O
//**************************************************************************

string sFileName = "FILE001.dat";

void SoundSave() {

  unsigned int nFileSize = 16+(MaxRecLen*2); // nFileSize = number_of_integers*2 plus a little more
  byte fHandle, i;
  int IOresult, counter=0;
  int ibuf;
  
  ClearScreen();
  TextOut( 0,48, "SpeechRecogn "+version);
  PlayTones(Buzz);

  DeleteFile(sFileName);
  IOresult = CreateFile(sFileName, nFileSize, fHandle);
  if (IOresult == LDR_SUCCESS) {
    ClearScreen();
    for (i=0; i<512; i++)   {
        counter+=1;
        ibuf= SoundRecord[i];
        printf1( 0, 24, "counter =%5d", counter);
        printf1( 0, 16, "loudness=%5d", ibuf);

        WriteLn(fHandle, ibuf);
    }
    CloseFile(fHandle);
    PlayTones(ChordUp);
  }
  else
  PlayTones(sdError);
  
  while(!btnhit());
  ClearScreen();
}



// task main() {

// *SNIP*

// SoundSave();

// *SNIP*

}

Re: NXC: strange behaviour storing numbers to a file

Posted: 11 Feb 2011, 19:16
by spillerrec
1) No, it shouldn't be needed as far as I know.

2) The problem is the for loop. The i variable is byte, so each time it reaches 255 it resets to 0 and therefore never becomes higher than 512 so that the loop can end.

Re: NXC: strange behaviour storing numbers to a file

Posted: 11 Feb 2011, 22:05
by HaWe
1) how should the filesize be used correctly when creating a file?
2) oh no, sure, thx, I must have been blind :oops:

Re: NXC: strange behaviour storing numbers to a file

Posted: 11 Feb 2011, 22:51
by spillerrec
It should just be 512*2. I haven't heard or experienced the need to make room for some extra bytes that are beyond your control. It should fail to write anything after the size limit is reached, so it shouldn't be too difficult to detect if all data is saved properly if you upload it to your computer.
Notice though that if you upload it to your computer and want to read the stored data, multi-byte types (like int and float) are stored in little-endian byte order.

You should be able to save the whole array in one operation, but I need to confirm is this is doable with the high-level API too first.
EDIT: Yeah, it does work, you should be able to just do something like:

Code: Select all

Write( fHandle, SoundRecord );
You use WriteLn() in your program, you should be aware that this function adds two bytes to the file after each write, a carriage return and a line feed, which is most likely not what you want.

Re: NXC: strange behaviour storing numbers to a file

Posted: 12 Feb 2011, 08:47
by HaWe
You use WriteLn() in your program, you should be aware that this function adds two bytes to the file after each write, a carriage return and a line feed, which is most likely not what you want.
well, I want to process my data by Excel or a C program (Fourier Transformation) on my PC; actually the best way I've been thinking of had been to seperate the numbers by a ";" but I didn't know how to do this and I'm not quite sure if my "writeln processed data " will work with Excel - I'll have to see how to make the data Excel-compatible. There es an Excel export function in RoboLab (as Ive been told) but I couldn't find something in NXC so far.

Re: NXC: strange behaviour storing numbers to a file

Posted: 12 Feb 2011, 11:09
by spillerrec
ARGH, accidently hit alt followed by X while writing closing my browser...

My Danish version of Excel 2010 supports tabulator separated files. Like this: (\t is a tab)

Code: Select all

203\t49
2165\492
924\t84
Which will create a 2x3 table. The newline characters I used was CRLF, I don't know which other are supported.
However you need to write the numbers in text format, so you need to convert each number. The problem here is that you might not know the final size of the file as it depends on how large the numbers are. One way to deal with it is to store the data into an array as you can just do

Code: Select all

ArrayBuild( array, array, newdata );
to add stuff and automatically make it larger as needed. Then you would just have to pass the array size as the filesize. The downside would be that the file can't be larger than your currently available ram.

Re: NXC: strange behaviour storing numbers to a file

Posted: 12 Feb 2011, 11:29
by HaWe
So I assume I can also use my number-by-number-method?

with FormatNum to convert nums to string and then added "\t" or ";"
(depends on what my Excel and/or my ANSI C program need)?

And as my numbers max have 3 digits, it will probably 3+2 or 3+1 byte per number, so file size will be max 5*512 (CMIIW)?

Re: NXC: strange behaviour storing numbers to a file

Posted: 12 Feb 2011, 14:06
by HaWe
got it working, thanks for your help!

Code: Select all

void SoundSave() {

  unsigned int nFileSize = (MaxRecLen*4); //3 byte for number (text) plus 1 (";") each
  byte fHandle;
  int IOresult, counter=0;
  int ibuf, i;
  string s;
  
  PlayTones(Buzz);

  DeleteFile(sFileName);
  IOresult = CreateFile(sFileName, nFileSize, fHandle);

  if (IOresult == LDR_SUCCESS) {
    ClearScreen();
    for (i=0; i<MaxRecLen; i++)   {
        counter+=1;
        ibuf= SoundRecord[i];

        printf1( 0, 24, "counter =%5d", counter);
        printf1( 0, 16, "loudness=%5d", ibuf);

        s=NumToStr(ibuf);
        s=s + ";" ;
        fputs(s, fHandle);
    }
    CloseFile(fHandle);
    PlayTones(ChordUp);
  }
  else
  PlayTones(sdError);

}