Edited version of the wave player class that uses the MODDMA library to handle transfers to the DAC.
Dependents: WavePlayer_MODDMA wave_player_DMA_mbed
wave_player.cpp@1:11a670498598, 2016-03-16 (annotated)
- Committer:
- ebradley6
- Date:
- Wed Mar 16 19:58:55 2016 +0000
- Revision:
- 1:11a670498598
- Parent:
- 0:286582877314
Updated comments.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ebradley6 | 0:286582877314 | 1 | //----------------------------------------------------------------------------- |
ebradley6 | 0:286582877314 | 2 | // a sample mbed library to play back wave files using MODDMA |
ebradley6 | 0:286582877314 | 3 | // Based on the wave_player library by Steve Ravet and the |
ebradley6 | 0:286582877314 | 4 | // MODDMA library by Andy Kirkham. |
ebradley6 | 0:286582877314 | 5 | // |
ebradley6 | 0:286582877314 | 6 | // The wave_player library is located here: |
ebradley6 | 0:286582877314 | 7 | // https://developer.mbed.org/users/sravet/code/wave_player/ |
ebradley6 | 0:286582877314 | 8 | // |
ebradley6 | 0:286582877314 | 9 | // The MODDMA library is located here: |
ebradley6 | 0:286582877314 | 10 | // https://developer.mbed.org/users/AjK/code/MODDMA/ |
ebradley6 | 0:286582877314 | 11 | // A wiki page and example are located here: |
ebradley6 | 0:286582877314 | 12 | // https://developer.mbed.org/cookbook/MODDMA |
ebradley6 | 0:286582877314 | 13 | // |
ebradley6 | 0:286582877314 | 14 | // explanation of wave file format. |
ebradley6 | 0:286582877314 | 15 | // https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ |
ebradley6 | 0:286582877314 | 16 | |
ebradley6 | 0:286582877314 | 17 | // if VERBOSE is uncommented then the wave player will enter a verbose |
ebradley6 | 0:286582877314 | 18 | // mode that displays all data values as it reads them from the file |
ebradley6 | 0:286582877314 | 19 | // and writes them to the DAC. Very slow and unusable output on the DAC, |
ebradley6 | 0:286582877314 | 20 | // but useful for debugging wave files that don't work. |
ebradley6 | 0:286582877314 | 21 | //#define VERBOSE |
ebradley6 | 0:286582877314 | 22 | |
ebradley6 | 0:286582877314 | 23 | |
ebradley6 | 0:286582877314 | 24 | #include <mbed.h> |
ebradley6 | 0:286582877314 | 25 | #include <stdio.h> |
ebradley6 | 0:286582877314 | 26 | #include <wave_player.h> |
ebradley6 | 0:286582877314 | 27 | |
ebradley6 | 0:286582877314 | 28 | //----------------------------------------------------------------------------- |
ebradley6 | 0:286582877314 | 29 | // constructor -- accepts an mbed pin to use for AnalogOut. Only p18 will work |
ebradley6 | 0:286582877314 | 30 | wave_player::wave_player(AnalogOut *_dac) |
ebradley6 | 0:286582877314 | 31 | { |
ebradley6 | 0:286582877314 | 32 | wave_DAC=_dac; |
ebradley6 | 0:286582877314 | 33 | wave_DAC->write_u16(32768); //DAC is 0-3.3V, so idles at ~1.6V |
ebradley6 | 0:286582877314 | 34 | verbosity=0; |
ebradley6 | 0:286582877314 | 35 | } |
ebradley6 | 0:286582877314 | 36 | |
ebradley6 | 0:286582877314 | 37 | //----------------------------------------------------------------------------- |
ebradley6 | 0:286582877314 | 38 | // if verbosity is set then wave player enters a mode where the wave file |
ebradley6 | 0:286582877314 | 39 | // is decoded and displayed to the screen, including sample values put into |
ebradley6 | 0:286582877314 | 40 | // the DAC FIFO, and values read out of the DAC FIFO by the ISR. The DAC output |
ebradley6 | 0:286582877314 | 41 | // itself is so slow as to be unusable, but this might be handy for debugging |
ebradley6 | 0:286582877314 | 42 | // wave files that don't play |
ebradley6 | 0:286582877314 | 43 | //----------------------------------------------------------------------------- |
ebradley6 | 0:286582877314 | 44 | void wave_player::set_verbosity(int v) |
ebradley6 | 0:286582877314 | 45 | { |
ebradley6 | 0:286582877314 | 46 | verbosity=v; |
ebradley6 | 0:286582877314 | 47 | } |
ebradley6 | 0:286582877314 | 48 | |
ebradley6 | 0:286582877314 | 49 | //----------------------------------------------------------------------------- |
ebradley6 | 0:286582877314 | 50 | // player function. Takes a pointer to an opened wave file. The file needs |
ebradley6 | 0:286582877314 | 51 | // to be stored in a filesystem with enough bandwidth to feed the wave data. |
ebradley6 | 0:286582877314 | 52 | // LocalFileSystem isn't, but the SDcard is, at least for 22kHz files. The |
ebradley6 | 0:286582877314 | 53 | // SDcard filesystem can be hotrodded by increasing the SPI frequency it uses |
ebradley6 | 0:286582877314 | 54 | // internally. |
ebradley6 | 0:286582877314 | 55 | //----------------------------------------------------------------------------- |
ebradley6 | 0:286582877314 | 56 | void wave_player::play(FILE *wavefile) |
ebradley6 | 0:286582877314 | 57 | { |
ebradley6 | 0:286582877314 | 58 | unsigned chunk_id,chunk_size,channel; |
ebradley6 | 0:286582877314 | 59 | unsigned data,i; |
ebradley6 | 0:286582877314 | 60 | unsigned j,k; |
ebradley6 | 0:286582877314 | 61 | int dac_cntval; |
ebradley6 | 0:286582877314 | 62 | bool buf0_flag; |
ebradley6 | 0:286582877314 | 63 | long long slice_value; |
ebradley6 | 0:286582877314 | 64 | char *slice_buf; |
ebradley6 | 0:286582877314 | 65 | short *data_sptr; |
ebradley6 | 0:286582877314 | 66 | unsigned char *data_bptr; |
ebradley6 | 0:286582877314 | 67 | int *data_wptr; |
ebradley6 | 0:286582877314 | 68 | FMT_STRUCT wav_format; |
ebradley6 | 0:286582877314 | 69 | long num_slices; |
ebradley6 | 0:286582877314 | 70 | |
ebradley6 | 0:286582877314 | 71 | for(i=0; i<BUF_SIZE; i++){ |
ebradley6 | 0:286582877314 | 72 | DAC_buf0[i]=0; |
ebradley6 | 0:286582877314 | 73 | DAC_buf1[i]=0; |
ebradley6 | 0:286582877314 | 74 | } |
ebradley6 | 0:286582877314 | 75 | |
ebradley6 | 0:286582877314 | 76 | DAC_on=0; |
ebradley6 | 0:286582877314 | 77 | |
ebradley6 | 0:286582877314 | 78 | int time=0; |
ebradley6 | 0:286582877314 | 79 | |
ebradley6 | 0:286582877314 | 80 | fread(&chunk_id,4,1,wavefile); |
ebradley6 | 0:286582877314 | 81 | fread(&chunk_size,4,1,wavefile); |
ebradley6 | 0:286582877314 | 82 | |
ebradley6 | 0:286582877314 | 83 | while (!feof(wavefile)) { |
ebradley6 | 0:286582877314 | 84 | if (verbosity) |
ebradley6 | 0:286582877314 | 85 | printf("Read chunk ID 0x%x, size 0x%x\n",chunk_id,chunk_size); |
ebradley6 | 0:286582877314 | 86 | switch (chunk_id) { |
ebradley6 | 0:286582877314 | 87 | case 0x46464952: |
ebradley6 | 0:286582877314 | 88 | fread(&data,4,1,wavefile); |
ebradley6 | 0:286582877314 | 89 | if (verbosity) { |
ebradley6 | 0:286582877314 | 90 | printf("RIFF chunk\n"); |
ebradley6 | 0:286582877314 | 91 | printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size); |
ebradley6 | 0:286582877314 | 92 | printf(" RIFF type 0x%x\n",data); |
ebradley6 | 0:286582877314 | 93 | } |
ebradley6 | 0:286582877314 | 94 | break; |
ebradley6 | 0:286582877314 | 95 | case 0x20746d66: |
ebradley6 | 0:286582877314 | 96 | fread(&wav_format,sizeof(wav_format),1,wavefile); |
ebradley6 | 0:286582877314 | 97 | if (verbosity) { |
ebradley6 | 0:286582877314 | 98 | printf("FORMAT chunk\n"); |
ebradley6 | 0:286582877314 | 99 | printf(" chunk size %d (0x%x)\n",chunk_size,chunk_size); |
ebradley6 | 0:286582877314 | 100 | printf(" compression code %d\n",wav_format.comp_code); |
ebradley6 | 0:286582877314 | 101 | printf(" %d channels\n",wav_format.num_channels); |
ebradley6 | 0:286582877314 | 102 | printf(" %d samples/sec\n",wav_format.sample_rate); |
ebradley6 | 0:286582877314 | 103 | printf(" %d bytes/sec\n",wav_format.avg_Bps); |
ebradley6 | 0:286582877314 | 104 | printf(" block align %d\n",wav_format.block_align); |
ebradley6 | 0:286582877314 | 105 | printf(" %d bits per sample\n",wav_format.sig_bps); |
ebradley6 | 0:286582877314 | 106 | } |
ebradley6 | 0:286582877314 | 107 | if (chunk_size > sizeof(wav_format)) |
ebradley6 | 0:286582877314 | 108 | fseek(wavefile,chunk_size-sizeof(wav_format),SEEK_CUR); |
ebradley6 | 0:286582877314 | 109 | break; |
ebradley6 | 0:286582877314 | 110 | case 0x61746164: |
ebradley6 | 1:11a670498598 | 111 | // Data chunk which contains the audio samples to send to the DAC |
ebradley6 | 1:11a670498598 | 112 | |
ebradley6 | 0:286582877314 | 113 | // allocate a buffer big enough to hold a slice |
ebradley6 | 0:286582877314 | 114 | slice_buf=(char *)malloc(wav_format.block_align); |
ebradley6 | 0:286582877314 | 115 | if (!slice_buf) { |
ebradley6 | 0:286582877314 | 116 | printf("Unable to malloc slice buffer"); |
ebradley6 | 0:286582877314 | 117 | exit(1); |
ebradley6 | 0:286582877314 | 118 | } |
ebradley6 | 0:286582877314 | 119 | num_slices=chunk_size/wav_format.block_align; |
ebradley6 | 0:286582877314 | 120 | |
ebradley6 | 0:286582877314 | 121 | // Calculating the transfer frequency: |
ebradley6 | 0:286582877314 | 122 | // By default, the Mbed library sets the PCLK_DAC clock value |
ebradley6 | 0:286582877314 | 123 | // to 24MHz. |
ebradley6 | 0:286582877314 | 124 | |
ebradley6 | 0:286582877314 | 125 | dac_cntval=(24000000/wav_format.sample_rate); |
ebradley6 | 0:286582877314 | 126 | |
ebradley6 | 0:286582877314 | 127 | if (verbosity) { |
ebradley6 | 0:286582877314 | 128 | printf("DATA chunk\n\r"); |
ebradley6 | 0:286582877314 | 129 | printf(" chunk size %d (0x%x)\n\r",chunk_size,chunk_size); |
ebradley6 | 0:286582877314 | 130 | printf(" %d slices\n\r",num_slices); |
ebradley6 | 0:286582877314 | 131 | printf(" sample rate is %d\r\n", wav_format.sample_rate); |
ebradley6 | 0:286582877314 | 132 | printf(" Ideal sample interval=%d\n\r",(unsigned)(1000000.0/wav_format.sample_rate)); |
ebradley6 | 0:286582877314 | 133 | printf(" programmed interrupt tick interval=%d\n\r",dac_cntval); |
ebradley6 | 0:286582877314 | 134 | } |
ebradley6 | 0:286582877314 | 135 | |
ebradley6 | 0:286582877314 | 136 | // Prepare the GPDMA system for buffer0. |
ebradley6 | 0:286582877314 | 137 | conf0 = new MODDMA_Config; |
ebradley6 | 0:286582877314 | 138 | conf0 |
ebradley6 | 0:286582877314 | 139 | ->channelNum ( MODDMA::Channel_0 ) |
ebradley6 | 0:286582877314 | 140 | ->srcMemAddr ( (uint32_t) &DAC_buf0 ) |
ebradley6 | 0:286582877314 | 141 | ->dstMemAddr ( MODDMA::DAC ) |
ebradley6 | 0:286582877314 | 142 | ->transferSize ( BUF_SIZE ) |
ebradley6 | 0:286582877314 | 143 | ->transferType ( MODDMA::m2p ) |
ebradley6 | 0:286582877314 | 144 | ->dstConn ( MODDMA::DAC ) |
ebradley6 | 0:286582877314 | 145 | ->attach_tc ( this,&wave_player::TC0_callback ) |
ebradley6 | 0:286582877314 | 146 | ->attach_err ( this,&wave_player::ERR0_callback ) |
ebradley6 | 0:286582877314 | 147 | ; // config end |
ebradley6 | 0:286582877314 | 148 | |
ebradley6 | 0:286582877314 | 149 | // Prepare the GPDMA system for buffer1. |
ebradley6 | 0:286582877314 | 150 | conf1 = new MODDMA_Config; |
ebradley6 | 0:286582877314 | 151 | conf1 |
ebradley6 | 0:286582877314 | 152 | ->channelNum ( MODDMA::Channel_1 ) |
ebradley6 | 0:286582877314 | 153 | ->srcMemAddr ( (uint32_t) &DAC_buf1 ) |
ebradley6 | 0:286582877314 | 154 | ->dstMemAddr ( MODDMA::DAC ) |
ebradley6 | 0:286582877314 | 155 | ->transferSize ( BUF_SIZE ) |
ebradley6 | 0:286582877314 | 156 | ->transferType ( MODDMA::m2p ) |
ebradley6 | 0:286582877314 | 157 | ->dstConn ( MODDMA::DAC ) |
ebradley6 | 0:286582877314 | 158 | ->attach_tc ( this,&wave_player::TC1_callback ) |
ebradley6 | 0:286582877314 | 159 | ->attach_err ( this,&wave_player::ERR1_callback ) |
ebradley6 | 0:286582877314 | 160 | ; // config end |
ebradley6 | 0:286582877314 | 161 | |
ebradley6 | 1:11a670498598 | 162 | // Set the DAC to the audio sample rate |
ebradley6 | 0:286582877314 | 163 | LPC_DAC->DACCNTVAL = dac_cntval; |
ebradley6 | 0:286582877314 | 164 | |
ebradley6 | 0:286582877314 | 165 | // Begin (enable DMA and counter). Note, don't enable |
ebradley6 | 0:286582877314 | 166 | // DBLBUF_ENA as we are using DMA double buffering. |
ebradley6 | 0:286582877314 | 167 | LPC_DAC->DACCTRL |= (3UL << 2); |
ebradley6 | 0:286582877314 | 168 | |
ebradley6 | 0:286582877314 | 169 | DAC_on=1; |
ebradley6 | 0:286582877314 | 170 | |
ebradley6 | 0:286582877314 | 171 | // start reading slices, which contain one sample each for however many channels |
ebradley6 | 0:286582877314 | 172 | // are in the wave file. one channel=mono, two channels=stereo, etc. Since |
ebradley6 | 0:286582877314 | 173 | // mbed only has a single AnalogOut, all of the channels present are averaged |
ebradley6 | 0:286582877314 | 174 | // to produce a single sample value. This summing and averaging happens in |
ebradley6 | 0:286582877314 | 175 | // a variable of type signed long long, to make sure that the data doesn't |
ebradley6 | 0:286582877314 | 176 | // overflow regardless of sample size (8 bits, 16 bits, 32 bits). |
ebradley6 | 0:286582877314 | 177 | // |
ebradley6 | 0:286582877314 | 178 | // note that from what I can find that 8 bit wave files use unsigned data, |
ebradley6 | 0:286582877314 | 179 | // while 16 and 32 bit wave files use signed data |
ebradley6 | 0:286582877314 | 180 | // |
ebradley6 | 0:286582877314 | 181 | |
ebradley6 | 1:11a670498598 | 182 | // Fill buffer 0 first |
ebradley6 | 0:286582877314 | 183 | buf0_flag=1; |
ebradley6 | 0:286582877314 | 184 | |
ebradley6 | 0:286582877314 | 185 | // Separate slices into sections of BUF_SIZE samples |
ebradley6 | 0:286582877314 | 186 | for (j=0; j<((num_slices/BUF_SIZE)+1); j++) |
ebradley6 | 0:286582877314 | 187 | { |
ebradley6 | 0:286582877314 | 188 | for(k=0; k<BUF_SIZE; k++) |
ebradley6 | 0:286582877314 | 189 | { |
ebradley6 | 0:286582877314 | 190 | // The last buffer will likely not be exactly BUF_SIZE, |
ebradley6 | 0:286582877314 | 191 | // so fill the remaining spots with 0 |
ebradley6 | 0:286582877314 | 192 | if((j*BUF_SIZE+k)>num_slices){ |
ebradley6 | 0:286582877314 | 193 | if(buf0_flag) |
ebradley6 | 0:286582877314 | 194 | DAC_buf0[k]=0; |
ebradley6 | 0:286582877314 | 195 | else |
ebradley6 | 0:286582877314 | 196 | DAC_buf1[k]=0; |
ebradley6 | 0:286582877314 | 197 | } |
ebradley6 | 0:286582877314 | 198 | else{ |
ebradley6 | 1:11a670498598 | 199 | // Read audio samples from sd card |
ebradley6 | 0:286582877314 | 200 | fread(slice_buf,wav_format.block_align,1,wavefile); |
ebradley6 | 0:286582877314 | 201 | if (feof(wavefile)) { |
ebradley6 | 0:286582877314 | 202 | printf("Oops -- not enough slices in the wave file\n"); |
ebradley6 | 0:286582877314 | 203 | exit(1); |
ebradley6 | 0:286582877314 | 204 | } |
ebradley6 | 0:286582877314 | 205 | data_sptr=(short *)slice_buf; // 16 bit samples |
ebradley6 | 0:286582877314 | 206 | data_bptr=(unsigned char *)slice_buf; // 8 bit samples |
ebradley6 | 0:286582877314 | 207 | data_wptr=(int *)slice_buf; // 32 bit samples |
ebradley6 | 0:286582877314 | 208 | slice_value=0; |
ebradley6 | 0:286582877314 | 209 | for (channel=0;channel<wav_format.num_channels;channel++) { |
ebradley6 | 0:286582877314 | 210 | switch (wav_format.sig_bps) { |
ebradley6 | 0:286582877314 | 211 | case 16: |
ebradley6 | 0:286582877314 | 212 | if (verbosity) |
ebradley6 | 0:286582877314 | 213 | printf("16 bit channel %d data=%d ",channel,data_sptr[channel]); |
ebradley6 | 0:286582877314 | 214 | slice_value+=data_sptr[channel]; |
ebradley6 | 0:286582877314 | 215 | break; |
ebradley6 | 0:286582877314 | 216 | case 32: |
ebradley6 | 0:286582877314 | 217 | if (verbosity) |
ebradley6 | 0:286582877314 | 218 | printf("32 bit channel %d data=%d ",channel,data_wptr[channel]); |
ebradley6 | 0:286582877314 | 219 | slice_value+=data_wptr[channel]; |
ebradley6 | 0:286582877314 | 220 | break; |
ebradley6 | 0:286582877314 | 221 | case 8: |
ebradley6 | 0:286582877314 | 222 | if (verbosity) |
ebradley6 | 0:286582877314 | 223 | printf("8 bit channel %d data=%d ",channel,(int)data_bptr[channel]); |
ebradley6 | 0:286582877314 | 224 | slice_value+=data_bptr[channel]; |
ebradley6 | 0:286582877314 | 225 | break; |
ebradley6 | 0:286582877314 | 226 | } |
ebradley6 | 0:286582877314 | 227 | } |
ebradley6 | 0:286582877314 | 228 | slice_value/=wav_format.num_channels; |
ebradley6 | 0:286582877314 | 229 | |
ebradley6 | 0:286582877314 | 230 | // slice_value is now averaged. Next it needs to be scaled to an unsigned 16 bit value |
ebradley6 | 0:286582877314 | 231 | // with DC offset so it can be written to the DAC. |
ebradley6 | 0:286582877314 | 232 | switch (wav_format.sig_bps) { |
ebradley6 | 0:286582877314 | 233 | case 8: slice_value<<=8; |
ebradley6 | 0:286582877314 | 234 | break; |
ebradley6 | 0:286582877314 | 235 | case 16: slice_value+=32768; |
ebradley6 | 0:286582877314 | 236 | break; |
ebradley6 | 0:286582877314 | 237 | case 32: slice_value>>=16; |
ebradley6 | 0:286582877314 | 238 | slice_value+=32768; |
ebradley6 | 0:286582877314 | 239 | break; |
ebradley6 | 0:286582877314 | 240 | } |
ebradley6 | 0:286582877314 | 241 | |
ebradley6 | 0:286582877314 | 242 | if (verbosity) |
ebradley6 | 0:286582877314 | 243 | printf("sample %d slice_value %d\n",(j*BUF_SIZE+k),(int)slice_value); |
ebradley6 | 0:286582877314 | 244 | if(buf0_flag) |
ebradley6 | 0:286582877314 | 245 | DAC_buf0[k]=(uint32_t)slice_value; |
ebradley6 | 0:286582877314 | 246 | else |
ebradley6 | 0:286582877314 | 247 | DAC_buf1[k]=(uint32_t)slice_value; |
ebradley6 | 0:286582877314 | 248 | } |
ebradley6 | 0:286582877314 | 249 | } |
ebradley6 | 0:286582877314 | 250 | |
ebradley6 | 0:286582877314 | 251 | // Except for the first buffer, wait until the previous DMA transfer is |
ebradley6 | 0:286582877314 | 252 | // complete before switching buffers |
ebradley6 | 0:286582877314 | 253 | if(j>0) |
ebradley6 | 0:286582877314 | 254 | { |
ebradley6 | 0:286582877314 | 255 | while((dma0_fin_flag==0)&(dma1_fin_flag==0)&(time<500000000)){ |
ebradley6 | 0:286582877314 | 256 | wait_us(1); |
ebradley6 | 0:286582877314 | 257 | time++; |
ebradley6 | 0:286582877314 | 258 | } |
ebradley6 | 0:286582877314 | 259 | } |
ebradley6 | 0:286582877314 | 260 | |
ebradley6 | 0:286582877314 | 261 | if (time>499999999) |
ebradley6 | 0:286582877314 | 262 | { |
ebradley6 | 0:286582877314 | 263 | printf("timeout, %d of %d\r\n", (j*BUF_SIZE), num_slices); |
ebradley6 | 0:286582877314 | 264 | exit(1); |
ebradley6 | 0:286582877314 | 265 | } |
ebradley6 | 0:286582877314 | 266 | |
ebradley6 | 0:286582877314 | 267 | time=0; |
ebradley6 | 0:286582877314 | 268 | dma0_fin_flag=0; |
ebradley6 | 0:286582877314 | 269 | dma1_fin_flag=0; |
ebradley6 | 0:286582877314 | 270 | |
ebradley6 | 0:286582877314 | 271 | // If finished filling buffer 0, set flag to fill buffer 1 |
ebradley6 | 0:286582877314 | 272 | // and start the DMA transfer for buffer 0 |
ebradley6 | 0:286582877314 | 273 | if(buf0_flag==1) |
ebradley6 | 0:286582877314 | 274 | { |
ebradley6 | 0:286582877314 | 275 | buf0_flag=0; |
ebradley6 | 0:286582877314 | 276 | dma.Setup(conf0); |
ebradley6 | 0:286582877314 | 277 | dma.Enable( conf0 ); |
ebradley6 | 0:286582877314 | 278 | } |
ebradley6 | 0:286582877314 | 279 | else // Similarly for buffer 1 |
ebradley6 | 0:286582877314 | 280 | { |
ebradley6 | 0:286582877314 | 281 | buf0_flag=1; |
ebradley6 | 0:286582877314 | 282 | dma.Setup(conf1); |
ebradley6 | 0:286582877314 | 283 | dma.Enable( conf1 ); |
ebradley6 | 0:286582877314 | 284 | } |
ebradley6 | 0:286582877314 | 285 | |
ebradley6 | 0:286582877314 | 286 | } |
ebradley6 | 0:286582877314 | 287 | DAC_on=0; |
ebradley6 | 0:286582877314 | 288 | delete conf0; |
ebradley6 | 0:286582877314 | 289 | delete conf1; |
ebradley6 | 0:286582877314 | 290 | free(slice_buf); |
ebradley6 | 0:286582877314 | 291 | break; |
ebradley6 | 0:286582877314 | 292 | case 0x5453494c: |
ebradley6 | 0:286582877314 | 293 | if (verbosity) |
ebradley6 | 0:286582877314 | 294 | printf("INFO chunk, size %d\n",chunk_size); |
ebradley6 | 0:286582877314 | 295 | fseek(wavefile,chunk_size,SEEK_CUR); |
ebradley6 | 0:286582877314 | 296 | break; |
ebradley6 | 0:286582877314 | 297 | default: |
ebradley6 | 0:286582877314 | 298 | printf("unknown chunk type 0x%x, size %d\n",chunk_id,chunk_size); |
ebradley6 | 0:286582877314 | 299 | data=fseek(wavefile,chunk_size,SEEK_CUR); |
ebradley6 | 0:286582877314 | 300 | break; |
ebradley6 | 0:286582877314 | 301 | } |
ebradley6 | 0:286582877314 | 302 | fread(&chunk_id,4,1,wavefile); |
ebradley6 | 0:286582877314 | 303 | fread(&chunk_size,4,1,wavefile); |
ebradley6 | 0:286582877314 | 304 | } |
ebradley6 | 0:286582877314 | 305 | } |
ebradley6 | 0:286582877314 | 306 | |
ebradley6 | 1:11a670498598 | 307 | // Configuration callback on TC; runs when the DMA has finished transferring buffer 0 to the DAC |
ebradley6 | 0:286582877314 | 308 | void wave_player::TC0_callback(void) { |
ebradley6 | 0:286582877314 | 309 | |
ebradley6 | 0:286582877314 | 310 | // Get configuration pointer. |
ebradley6 | 0:286582877314 | 311 | MODDMA_Config *config = dma.getConfig(); |
ebradley6 | 0:286582877314 | 312 | |
ebradley6 | 1:11a670498598 | 313 | // Only run once |
ebradley6 | 0:286582877314 | 314 | dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); |
ebradley6 | 0:286582877314 | 315 | |
ebradley6 | 0:286582877314 | 316 | // Finish the DMA cycle by shutting down the channel. |
ebradley6 | 0:286582877314 | 317 | dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); |
ebradley6 | 0:286582877314 | 318 | |
ebradley6 | 0:286582877314 | 319 | // Clear DMA IRQ flags. |
ebradley6 | 0:286582877314 | 320 | if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); |
ebradley6 | 0:286582877314 | 321 | |
ebradley6 | 0:286582877314 | 322 | // Indicate that buffer 0 has finished transferring |
ebradley6 | 0:286582877314 | 323 | dma0_fin_flag=1; |
ebradley6 | 0:286582877314 | 324 | } |
ebradley6 | 0:286582877314 | 325 | |
ebradley6 | 0:286582877314 | 326 | // Configuration callback on Error |
ebradley6 | 0:286582877314 | 327 | void wave_player::ERR0_callback(void) { |
ebradley6 | 0:286582877314 | 328 | error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); |
ebradley6 | 0:286582877314 | 329 | } |
ebradley6 | 0:286582877314 | 330 | |
ebradley6 | 1:11a670498598 | 331 | // Configuration callback on TC; runs when the DMA has finished transferring buffer 1 to the DAC |
ebradley6 | 0:286582877314 | 332 | void wave_player::TC1_callback(void) { |
ebradley6 | 0:286582877314 | 333 | |
ebradley6 | 0:286582877314 | 334 | // Get configuration pointer. |
ebradley6 | 0:286582877314 | 335 | MODDMA_Config *config = dma.getConfig(); |
ebradley6 | 0:286582877314 | 336 | |
ebradley6 | 1:11a670498598 | 337 | // Only run once |
ebradley6 | 0:286582877314 | 338 | dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); |
ebradley6 | 0:286582877314 | 339 | |
ebradley6 | 0:286582877314 | 340 | // Finish the DMA cycle by shutting down the channel. |
ebradley6 | 0:286582877314 | 341 | dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); |
ebradley6 | 0:286582877314 | 342 | |
ebradley6 | 0:286582877314 | 343 | // Clear DMA IRQ flags. |
ebradley6 | 0:286582877314 | 344 | if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); |
ebradley6 | 0:286582877314 | 345 | |
ebradley6 | 0:286582877314 | 346 | // Indicate that buffer 1 has finished transferring |
ebradley6 | 0:286582877314 | 347 | dma1_fin_flag=1; |
ebradley6 | 0:286582877314 | 348 | } |
ebradley6 | 0:286582877314 | 349 | |
ebradley6 | 0:286582877314 | 350 | // Configuration callback on Error |
ebradley6 | 0:286582877314 | 351 | void wave_player::ERR1_callback(void) { |
ebradley6 | 0:286582877314 | 352 | error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); |
ebradley6 | 0:286582877314 | 353 | } |