Saving file problem

09 Sep 2009

I am trying to convert the Sound Recorder cookbook application to write to a local file 'out.snd' rather than the original serial usb link. I seem to be having lots of problems - even though I have commented out the write32 part of the code and attempted to use the timer to run it for just 1 second, it still crashes and leaves an empty file which I can only get at by keeping the reset button of the mbed pressed. If I dont enable the ticker interruot, I can get the first bit of text written to the file. The code is here - any help gratefully accepted:

 

/* afa 3 Sep 20009 - uses sound recorder code to write to a local file */

#include 
#include "mbed.h"

DigitalOut l1(LED1);
DigitalOut l2(LED2);
DigitalOut l3(LED3);
DigitalOut l4(LED4);
AnalogIn ain(p20);
Ticker ticker;
Timer t;
LocalFileSystem local("local");
FILE *fp;

/* Sampling routine; records a single sample */
void sample()
{
    static const float ALPHA = 0.999f;
    static float v;
    float l, s =  ain.read();
    
    /* Convert raw value to sample */
    int8_t b = (s - 0.5f) * 127.0f * 2.0f;

    /* Compute next bar graph value */
    l = abs(s - 0.5f) * 2.0;
    v = l > v ? l : v * ALPHA;

    /* Snazzy bar graph */
    l1 = v > 0.08;
    l2 = v > 0.16;
    l3 = v > 0.32;
    l4 = v > 0.62;    

    fprintf(fp, "%c", b);
}

/* Write a 32 bit value in correct byte order for SND files */
void write32(uint32_t v)
{
    uint8_t *b = (uint8_t *)&v;
    
    fprintf(fp, "%c%c%c%c", b[3], b[2], b[1], b[0]);
}



int main() 
{
   
 FILE *fp = fopen("/local/out.snd", "w");  // Open "out.snd" on the local file system for writing   
    /* Au format header: http://en.wikipedia.org/wiki/Au_file_format */
    
    fprintf(fp, ".snd");
   /* write32(24);
    write32(-1);    
    write32(2);        
    write32(8000);        
    write32(1); */
    /* Sampler */
    ticker.attach_us(&sample, 100);
    t.start(); 
    while(t.read() < 1.0) {
        wait(1);           
    }
    t.stop();
    ticker.detach();
    fclose(fp); 
    exit(1) ;
    }
    

   



09 Sep 2009

Hi Tony,

One problem I can see is you are using a global FILE variable in sample() and write32(), but you never set it up, as when you open the file you assign it to a local variable. It is basically a typo, but:

FILE *fp;  // defines a global variable called fp

void sample() {
    // [snip]
    fprintf(fp, "%c", b); // uses variable fp; no local variable called fp, so uses global
}

int main() {
    FILE *fp = fopen("/local/out.snd", "w");  // defines a local variable called fp, and opens file
}

what you really want is:

int main() {
    fp = fopen("/local/out.snd", "w");  // open file and assign to global variable
}

The other thing is a sample rate of 100us for writing every sample to flash sounds fast (FLASH writes are slow), but you'd have to do some tests to see what write rate you can sustain to flash (there were some benchmarks in the cookbook maybe).

There may be more, but this should help you get further.

Simon

09 Sep 2009

Hi Simon

Thanks for the advice - that got the filing system working. The next problem relates to the ticker and the timer - there seems to be a conflict - even if I run the ticker at 500us, the timer never times out. If I comment out the ticker call, then the timer works. I know the ticker call is working, because it is correctly writing the audio file. I put some led calls in the wait loop, and this just showed that the timer wasnt working. Code currently looks like this:

Tony

/* afa 9 Sep 20009 - uses sound recorder code to write to a local file */

#include 
#include "mbed.h"

DigitalOut l1(LED1);
DigitalOut l2(LED2);
DigitalOut l3(LED3);
DigitalOut l4(LED4);
AnalogIn ain(p20);
Ticker ticker;
Timer t;
LocalFileSystem local("local");
FILE *fp;

/* Sampling routine; records a single sample */
void sample()
{
    static const float ALPHA = 0.999f;
    static float v;
    float l, s =  ain.read();
    
    /* Convert raw value to sample */
    int8_t b = (s - 0.5f) * 127.0f * 2.0f;

    /* Compute next bar graph value */
    l = abs(s - 0.5f) * 2.0;
    v = l > v ? l : v * ALPHA;

    /* Snazzy bar graph */
   /* l1 = v > 0.08;
    l2 = v > 0.16;
    l3 = v > 0.32;
    l4 = v > 0.62;    */

    fprintf(fp, "%c", b);
}

/* Write a 32 bit value in correct byte order for SND files */
void write32(uint32_t v)
{
    uint8_t *b = (uint8_t *)&v;
    
    fprintf(fp, "%c%c%c%c", b[3], b[2], b[1], b[0]);
}



int main() 
{
   l1=1;
 fp = fopen("/local/out.snd", "w");  // Open "out.snd" on the local file system for writing   
    /* Au format header: http://en.wikipedia.org/wiki/Au_file_format */
    
    fprintf(fp, ".snd");
    write32(24);
    write32(-1);    
    write32(2);        
    write32(8000);        
    write32(1);
    /* Sampler */
    ticker.attach_us(&sample, 500);
    t.reset();
    l2=1;
    t.start(); 
    while(t.read_ms() < 5000) {
    l3=t.read_ms()/1000;
        wait(1);           
    }
    t.stop();
    ticker.detach();
    fclose(fp);
    l4=1; 
    exit(1) ;
    }
 

09 Sep 2009

Hi,

Maybe you are ticking too quickly and always in the interrupt. i.e. by the time you finish one, you have over-run and the next is invoked straight away, hence it never gets to run the non-interrupt code. Try slowing the Ticker down (or doing less in the interrupt - you are doing a lot) and see what happens.

Simon

09 Sep 2009

Hi SImon

The ticker works down to 1150us. Below that, the program never terminates. That seems to be very slow, since the original sound recorder code worked at 8KHz with the same maths into the serial port. Is this a true indication of the speed of the filing system?

 

Tony

10 Sep 2009

Writing to flash memory is much slower than reading flash (you have to erase, which takes a while), and both are much much slower than reading or writing RAM.

As you are using the LocalFileSystem, you are also going to the interface to service the reads/writes. An SD card connected to the microcontroller would probably be faster, and of course storing to internal RAM would be much faster (but limited by space).

I'd recommend writing a little benchmark (or modify the one in the cookbook) just to understand the behaviour of reading/writing flash/ram etc so you get a feel for the different speeds and trade-offs. (computer science is dominated by speed vs. capacity trade-offs!)

Simon