![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
music main
Fork of AppBoard_Waveplayer by
WaveFileReader.h@11:e48cb1e38995, 2015-04-14 (annotated)
- Committer:
- niv17
- Date:
- Tue Apr 14 03:46:33 2015 +0000
- Revision:
- 11:e48cb1e38995
Version that needs to be fixed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
niv17 | 11:e48cb1e38995 | 1 | /* Read the wavefile */ |
niv17 | 11:e48cb1e38995 | 2 | |
niv17 | 11:e48cb1e38995 | 3 | typedef struct uFMT_STRUCT { |
niv17 | 11:e48cb1e38995 | 4 | short comp_code; |
niv17 | 11:e48cb1e38995 | 5 | short num_channels; |
niv17 | 11:e48cb1e38995 | 6 | unsigned sample_rate; |
niv17 | 11:e48cb1e38995 | 7 | unsigned avg_Bps; |
niv17 | 11:e48cb1e38995 | 8 | short block_align; |
niv17 | 11:e48cb1e38995 | 9 | short sig_bps; |
niv17 | 11:e48cb1e38995 | 10 | } FMT_STRUCT; |
niv17 | 11:e48cb1e38995 | 11 | |
niv17 | 11:e48cb1e38995 | 12 | class WaveFileReader { |
niv17 | 11:e48cb1e38995 | 13 | |
niv17 | 11:e48cb1e38995 | 14 | private: |
niv17 | 11:e48cb1e38995 | 15 | FILE * wavefile; |
niv17 | 11:e48cb1e38995 | 16 | bool isRepeat; |
niv17 | 11:e48cb1e38995 | 17 | unsigned dataChunkSize; |
niv17 | 11:e48cb1e38995 | 18 | long int startofdata; |
niv17 | 11:e48cb1e38995 | 19 | void readHeader(); |
niv17 | 11:e48cb1e38995 | 20 | FMT_STRUCT wav_format; |
niv17 | 11:e48cb1e38995 | 21 | |
niv17 | 11:e48cb1e38995 | 22 | public: |
niv17 | 11:e48cb1e38995 | 23 | WaveFileReader( FILE *, bool); |
niv17 | 11:e48cb1e38995 | 24 | float readSamplePeriod(); |
niv17 | 11:e48cb1e38995 | 25 | size_t read(unsigned short *buf, size_t size); |
niv17 | 11:e48cb1e38995 | 26 | }; |
niv17 | 11:e48cb1e38995 | 27 | |
niv17 | 11:e48cb1e38995 | 28 | WaveFileReader::WaveFileReader(FILE *wavefile, bool isRepeat){ |
niv17 | 11:e48cb1e38995 | 29 | this->wavefile = wavefile; |
niv17 | 11:e48cb1e38995 | 30 | this->isRepeat = isRepeat; |
niv17 | 11:e48cb1e38995 | 31 | readHeader(); |
niv17 | 11:e48cb1e38995 | 32 | } |
niv17 | 11:e48cb1e38995 | 33 | |
niv17 | 11:e48cb1e38995 | 34 | float WaveFileReader::readSamplePeriod(){ |
niv17 | 11:e48cb1e38995 | 35 | return 1000000/(wav_format.sample_rate); |
niv17 | 11:e48cb1e38995 | 36 | } |
niv17 | 11:e48cb1e38995 | 37 | |
niv17 | 11:e48cb1e38995 | 38 | void WaveFileReader::readHeader(){ |
niv17 | 11:e48cb1e38995 | 39 | unsigned chunk_id, data, chunk_size; |
niv17 | 11:e48cb1e38995 | 40 | fread(&chunk_id,4,1,wavefile); |
niv17 | 11:e48cb1e38995 | 41 | fread(&chunk_size,4,1,wavefile); |
niv17 | 11:e48cb1e38995 | 42 | |
niv17 | 11:e48cb1e38995 | 43 | while (!feof(wavefile)){ |
niv17 | 11:e48cb1e38995 | 44 | switch (chunk_id) { |
niv17 | 11:e48cb1e38995 | 45 | case 0x46464952: |
niv17 | 11:e48cb1e38995 | 46 | fread(&data,4,1,wavefile); |
niv17 | 11:e48cb1e38995 | 47 | break; |
niv17 | 11:e48cb1e38995 | 48 | case 0x20746d66: |
niv17 | 11:e48cb1e38995 | 49 | fread(&wav_format,sizeof(wav_format),1,wavefile); |
niv17 | 11:e48cb1e38995 | 50 | if (chunk_size > sizeof(wav_format)) |
niv17 | 11:e48cb1e38995 | 51 | fseek(wavefile,chunk_size-sizeof(wav_format),SEEK_CUR); |
niv17 | 11:e48cb1e38995 | 52 | break; |
niv17 | 11:e48cb1e38995 | 53 | case 0x5453494c: |
niv17 | 11:e48cb1e38995 | 54 | fseek(wavefile,chunk_size,SEEK_CUR); |
niv17 | 11:e48cb1e38995 | 55 | break; |
niv17 | 11:e48cb1e38995 | 56 | case 0x61746164: |
niv17 | 11:e48cb1e38995 | 57 | startofdata = ftell(wavefile); |
niv17 | 11:e48cb1e38995 | 58 | dataChunkSize = chunk_size; |
niv17 | 11:e48cb1e38995 | 59 | fseek(wavefile,chunk_size,SEEK_CUR); |
niv17 | 11:e48cb1e38995 | 60 | break; |
niv17 | 11:e48cb1e38995 | 61 | default: |
niv17 | 11:e48cb1e38995 | 62 | data=fseek(wavefile,chunk_size,SEEK_CUR); |
niv17 | 11:e48cb1e38995 | 63 | break; |
niv17 | 11:e48cb1e38995 | 64 | } |
niv17 | 11:e48cb1e38995 | 65 | fread(&chunk_id,4,1,wavefile); |
niv17 | 11:e48cb1e38995 | 66 | fread(&chunk_size,4,1,wavefile); |
niv17 | 11:e48cb1e38995 | 67 | } |
niv17 | 11:e48cb1e38995 | 68 | fseek(wavefile,startofdata,SEEK_SET); |
niv17 | 11:e48cb1e38995 | 69 | } |
niv17 | 11:e48cb1e38995 | 70 | |
niv17 | 11:e48cb1e38995 | 71 | size_t WaveFileReader::read(unsigned short *DAC_fifo, size_t size){ |
niv17 | 11:e48cb1e38995 | 72 | unsigned channel; |
niv17 | 11:e48cb1e38995 | 73 | short unsigned dac_data; |
niv17 | 11:e48cb1e38995 | 74 | long long slice_value; |
niv17 | 11:e48cb1e38995 | 75 | char *slice_buf; |
niv17 | 11:e48cb1e38995 | 76 | short *data_sptr; |
niv17 | 11:e48cb1e38995 | 77 | unsigned char *data_bptr; |
niv17 | 11:e48cb1e38995 | 78 | int *data_wptr; |
niv17 | 11:e48cb1e38995 | 79 | |
niv17 | 11:e48cb1e38995 | 80 | slice_buf=(char *)malloc(wav_format.block_align); |
niv17 | 11:e48cb1e38995 | 81 | if (!slice_buf) { |
niv17 | 11:e48cb1e38995 | 82 | printf("Unable to malloc slice buffer"); |
niv17 | 11:e48cb1e38995 | 83 | exit(1); |
niv17 | 11:e48cb1e38995 | 84 | } |
niv17 | 11:e48cb1e38995 | 85 | |
niv17 | 11:e48cb1e38995 | 86 | for (size_t i=0; i<size; i++){ |
niv17 | 11:e48cb1e38995 | 87 | fread(slice_buf,wav_format.block_align,1,wavefile); |
niv17 | 11:e48cb1e38995 | 88 | if (feof(wavefile)) { |
niv17 | 11:e48cb1e38995 | 89 | if(isRepeat){ |
niv17 | 11:e48cb1e38995 | 90 | fseek(wavefile,startofdata,SEEK_SET); |
niv17 | 11:e48cb1e38995 | 91 | printf("Reached end of file, reapeat is on"); |
niv17 | 11:e48cb1e38995 | 92 | }else{ |
niv17 | 11:e48cb1e38995 | 93 | printf("Reached end of file, reapeat is off"); |
niv17 | 11:e48cb1e38995 | 94 | return i; |
niv17 | 11:e48cb1e38995 | 95 | } |
niv17 | 11:e48cb1e38995 | 96 | } |
niv17 | 11:e48cb1e38995 | 97 | data_sptr=(short *)slice_buf; // 16 bit samples |
niv17 | 11:e48cb1e38995 | 98 | data_bptr=(unsigned char *)slice_buf; // 8 bit samples |
niv17 | 11:e48cb1e38995 | 99 | data_wptr=(int *)slice_buf; // 32 bit samples |
niv17 | 11:e48cb1e38995 | 100 | slice_value=0; |
niv17 | 11:e48cb1e38995 | 101 | for (channel=0;channel<wav_format.num_channels;channel++) { |
niv17 | 11:e48cb1e38995 | 102 | switch (wav_format.sig_bps) { |
niv17 | 11:e48cb1e38995 | 103 | case 16: |
niv17 | 11:e48cb1e38995 | 104 | slice_value+=data_sptr[channel]; |
niv17 | 11:e48cb1e38995 | 105 | break; |
niv17 | 11:e48cb1e38995 | 106 | case 32: |
niv17 | 11:e48cb1e38995 | 107 | slice_value+=data_wptr[channel]; |
niv17 | 11:e48cb1e38995 | 108 | break; |
niv17 | 11:e48cb1e38995 | 109 | case 8: |
niv17 | 11:e48cb1e38995 | 110 | slice_value+=data_bptr[channel]; |
niv17 | 11:e48cb1e38995 | 111 | break; |
niv17 | 11:e48cb1e38995 | 112 | } |
niv17 | 11:e48cb1e38995 | 113 | } |
niv17 | 11:e48cb1e38995 | 114 | slice_value/=wav_format.num_channels; |
niv17 | 11:e48cb1e38995 | 115 | switch (wav_format.sig_bps) { |
niv17 | 11:e48cb1e38995 | 116 | case 8: |
niv17 | 11:e48cb1e38995 | 117 | slice_value<<=8; |
niv17 | 11:e48cb1e38995 | 118 | break; |
niv17 | 11:e48cb1e38995 | 119 | case 16: |
niv17 | 11:e48cb1e38995 | 120 | slice_value+=32768; |
niv17 | 11:e48cb1e38995 | 121 | break; |
niv17 | 11:e48cb1e38995 | 122 | case 32: |
niv17 | 11:e48cb1e38995 | 123 | slice_value>>=16; |
niv17 | 11:e48cb1e38995 | 124 | slice_value+=32768; |
niv17 | 11:e48cb1e38995 | 125 | break; |
niv17 | 11:e48cb1e38995 | 126 | } |
niv17 | 11:e48cb1e38995 | 127 | dac_data=(short unsigned)slice_value; |
niv17 | 11:e48cb1e38995 | 128 | DAC_fifo[i]=dac_data; |
niv17 | 11:e48cb1e38995 | 129 | } |
niv17 | 11:e48cb1e38995 | 130 | free(slice_buf); |
niv17 | 11:e48cb1e38995 | 131 | return size; |
niv17 | 11:e48cb1e38995 | 132 | } |