Talk Watch system using NTP timer for JBB.

Dependencies:   EthernetNetIf FatFileSystem HTTPClient_ToBeRemoved HTTPServer NTPClient_NetServices TextLCD mbed

Fork of StarBoardOrangeTest3 by Yuji Notsu

wavplayer.cpp

Committer:
y_notsu
Date:
2014-06-22
Revision:
1:8816ea8be54b
Parent:
0:ae31fe6f181c

File content as of revision 1:8816ea8be54b:

/*
 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");

                        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);
}