Test of Embedded Artists LPCXpresso baseboard ethernet, SD card, audio and OLED display facilities. The program displays the day, date and time on the baseboard OLED and sounds the Big Ben chimes on the hour and quarter hour. On initial startup the program checks that the mbed clock is set and that the chime wav files can be accessed on the SD card. If not it asks to be connected to the internet to obtain the current time and to download the wav files to the SD card.

Dependencies:   EthernetNetIf NTPClient_NetServices mbed EAOLED

wavplayer.cpp

Committer:
tom_coxon
Date:
2010-08-14
Revision:
0:f61e8db0570d

File content as of revision 0:f61e8db0570d:

/*
 Library wave file player by Tom Coxon

 Based on WAVEplayer by Vlad Cazan/Stephan Rochon modified by Tom Coxon to:

 1. Run correctly on the Embedded Artists LPCXpresso baseboard.
 2. To play 8 bit sample size in addition to original 16 bit
 3. To be more fault tolerant when playing wav files.
*/

#include "wavplayer.h"

Ticker tick;

AnalogOut DACout(p18);

void WavPlayer::dac_out() {
    if (DAC_on) {
        DACout.write_u16(DAC_fifo[DAC_rptr]);
        DAC_rptr=(DAC_rptr+1) & 0xff;
    }
}

//void play_wave(char *wavname) {
void WavPlayer::play_wave(char *wavname) {
    unsigned chunk_id,chunk_size,channel;
    unsigned data,samp_int,i;
    short dac_data;
    char *slice_buf;
    short *data_sptr;
    FMT_STRUCT wav_format;
    FILE *wavfile;
    long slice,num_slices;
    DAC_wptr=0;
    DAC_rptr=0;

    size_t result;

    for (i=0;i<256;i+=2) {
        DAC_fifo[i]=0;
        DAC_fifo[i+1]=3000;
    }
    DAC_wptr=4;
    DAC_on=0;

    printf("Playing wave file '%s'\r\n",wavname);

    wavfile=fopen(wavname,"rb");
    if (!wavfile) {
        printf("Unable to open wav file '%s'\r\n",wavname);
        exit(1);
    }

    fread(&chunk_id,4,1,wavfile);
    fread(&chunk_size,4,1,wavfile);
    while (!feof(wavfile)) {
        printf("Read chunk ID 0x%x, size 0x%x\r\n",chunk_id,chunk_size);
        switch (chunk_id) {
            case 0x46464952:
                fread(&data,4,1,wavfile);
                printf("RIFF chunk\r\n");
                printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
                printf("  RIFF type 0x%x\r\n",data);
                break;
            case 0x20746d66:
                fread(&wav_format,sizeof(wav_format),1,wavfile);
                printf("FORMAT chunk\r\n");
                printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
                printf("  compression code %d\r\n",wav_format.comp_code);
                printf("  %d channels\r\n",wav_format.num_channels);
                printf("  %d samples/sec\r\n",wav_format.sample_rate);
                printf("  %d bytes/sec\r\n",wav_format.avg_Bps);
                printf("  block align %d\r\n",wav_format.block_align);
                printf("  %d bits per sample\r\n",wav_format.sig_bps);
                if (chunk_size > sizeof(wav_format))
                    fseek(wavfile,chunk_size-sizeof(wav_format),SEEK_CUR);
// create a slice buffer large enough to hold multiple slices
                slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
                if (!slice_buf) {
                    printf("Unable to malloc slice buffer");
                    exit(1);
                }
                break;
            case 0x61746164:
                slice_buf=(char *)malloc(wav_format.block_align*SLICE_BUF_SIZE);
                if (!slice_buf) {
                    printf("Unable to malloc slice buffer");
                    exit(1);
                }
                num_slices=chunk_size/wav_format.block_align;
                printf("DATA chunk\r\n");
                printf("  chunk size %d (0x%x)\r\n",chunk_size,chunk_size);
                printf("  %d slices\r\n",num_slices);
                printf("  Ideal sample interval=%d\r\n",(unsigned)(1000000.0/wav_format.sample_rate));
                samp_int=1000000/(wav_format.sample_rate);
                printf("  programmed interrupt tick interval=%d\r\n",samp_int);

// starting up ticker to write samples out -- no printfs until tick.detach is called
                tick.attach_us(this,&WavPlayer::dac_out, samp_int);
                DAC_on=1;
                for (slice=0;slice<num_slices;slice+=SLICE_BUF_SIZE) {

                    result = fread(slice_buf,wav_format.block_align*SLICE_BUF_SIZE,1,wavfile);
                    if (feof(wavfile)) {
                        printf("Oops -- not enough slices in the wave file\r\n");
                        if (result) ;//just to stop compiler complaining that we have not used result
                        break;
                    }

                    data_sptr=(short *)slice_buf;
                    for (i=0;i<SLICE_BUF_SIZE;i++) {
                        dac_data=0;

// for a stereo wave file average the two channels.
                        for (channel=0;channel<wav_format.num_channels;channel++) {
                            switch (wav_format.sig_bps) {
                                case 16:
                                    dac_data+=(  ((int)(*data_sptr++)) +32768 );
                                    break;
                                case 8:
                                    dac_data+=(  ((int)(*data_sptr++)) +32768 <<8);
                                    break;
                            }
                        }
                        DAC_fifo[DAC_wptr]=dac_data;
                        DAC_wptr=(DAC_wptr+1) & 0xff;
                        while (DAC_wptr==DAC_rptr) {
                            wait_us(10);
                        }
                    }
                }
                DAC_on=0;
                tick.detach();
                printf("Ticker detached\r\n");
                free(slice_buf);
                break;
            case 0x5453494c:
                printf("INFO chunk, size %d\r\n",chunk_size);
                fseek(wavfile,chunk_size,SEEK_CUR);
                break;
            default:
                printf("unknown chunk type 0x%x, size %d\r\n",chunk_id,chunk_size);
                data=fseek(wavfile,chunk_size,SEEK_CUR);
                break;
        }
        fread(&chunk_id,4,1,wavfile);
        fread(&chunk_size,4,1,wavfile);
    }
    printf("++++++++++++ Done with wave file ++++++++++\r\n");
    fclose(wavfile);
}