Daiki Kato / EasyPlaybackPWM
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EasyDec_Wav.h Source File

EasyDec_Wav.h

Go to the documentation of this file.
00001 /* mbed EasyDec_Wav Library
00002  * Copyright (C) 2017 dkato
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 /**************************************************************************//**
00018 * @file          EasyDec_Wav.h
00019 * @brief         wav
00020 ******************************************************************************/
00021 #ifndef __EASY_DECODER_WAV_H__
00022 #define __EASY_DECODER_WAV_H__
00023 
00024 #include "EasyDecoder.h"
00025 
00026 /** A class to communicate a EasyDec_Wav
00027  *
00028  */
00029 class EasyDec_Wav : public EasyDecoder {
00030 public:
00031 
00032     static inline EasyDecoder* inst() { return new EasyDec_Wav; }
00033 
00034     /** analyze header
00035      *
00036      * @param p_title title tag buffer
00037      * @param p_artist artist tag buffer
00038      * @param p_album album tag buffer
00039      * @param tag_size tag buffer size
00040      * @param fp file pointer
00041      * @return true = success, false = failure
00042      */
00043     virtual bool AnalyzeHeder(char* p_title, char* p_artist, char* p_album, uint16_t tag_size, FILE* fp) {
00044         bool result = false;
00045         size_t read_size;
00046         uint8_t wk_read_buff[36];
00047         char *data;
00048         uint32_t chunk_size;
00049         uint32_t sub_chunk_size;
00050         uint32_t list_index_max;
00051         bool list_ok = false;
00052         uint32_t read_index = 0;
00053         uint32_t data_index = 0;
00054         uint16_t wk_len;
00055 
00056         if (fp == NULL) {
00057             return false;
00058         }
00059         music_data_size  = 0;
00060         music_data_index = 0;
00061         wav_fp = fp;
00062         if (p_title != NULL) {
00063             p_title[0] = '\0';
00064         }
00065         if (p_artist != NULL) {
00066             p_artist[0] = '\0';
00067         }
00068         if (p_album != NULL) {
00069             p_album[0] = '\0';
00070         }
00071 
00072         read_size = fread(&wk_read_buff[0], sizeof(char), 36, wav_fp);
00073         if (read_size < 36) {
00074             // do nothing
00075         } else if (memcmp(&wk_read_buff[0], "RIFF", 4) != 0) {
00076             // do nothing
00077         } else if (memcmp(&wk_read_buff[8], "WAVE", 4) != 0) {
00078             // do nothing
00079         } else if (memcmp(&wk_read_buff[12], "fmt ", 4) != 0) {
00080             // do nothing
00081         } else {
00082             read_index += 36;
00083             channel = ((uint32_t)wk_read_buff[22] << 0) + ((uint32_t)wk_read_buff[23] << 8);
00084             sampling_rate = ((uint32_t)wk_read_buff[24] << 0)
00085                           + ((uint32_t)wk_read_buff[25] << 8)
00086                           + ((uint32_t)wk_read_buff[26] << 16)
00087                           + ((uint32_t)wk_read_buff[27] << 24);
00088             block_size = ((uint32_t)wk_read_buff[34] << 0) + ((uint32_t)wk_read_buff[35] << 8);
00089             while (1) {
00090                 read_size = fread(&wk_read_buff[0], sizeof(char), 8, wav_fp);
00091                 read_index += 8;
00092                 if (read_size < 8) {
00093                     break;
00094                 } else {
00095                     chunk_size = ((uint32_t)wk_read_buff[4] << 0)
00096                                + ((uint32_t)wk_read_buff[5] << 8)
00097                                + ((uint32_t)wk_read_buff[6] << 16)
00098                                + ((uint32_t)wk_read_buff[7] << 24);
00099                     if (memcmp(&wk_read_buff[0], "data", 4) == 0) {
00100                         result = true;
00101                         music_data_size = chunk_size;
00102                         if (list_ok == true) {
00103                             break;
00104                         } else {
00105                             data_index = read_index;
00106                             fseek(wav_fp, chunk_size, SEEK_CUR);
00107                             read_index += chunk_size;
00108                         }
00109                     } else if (memcmp(&wk_read_buff[0], "LIST", 4) == 0) {
00110                         list_ok = true;
00111                         list_index_max = read_index + chunk_size;
00112                         read_size = fread(&wk_read_buff[0], sizeof(char), 4, wav_fp);
00113                         read_index += 4;
00114                         while (read_index < list_index_max) {
00115                             read_size = fread(&wk_read_buff[0], sizeof(char), 8, wav_fp);
00116                             read_index += 8;
00117                             if (read_size < 8) {
00118                                 break;
00119                             } else if (memcmp(&wk_read_buff[0], "INAM", 4) == 0) {
00120                                 data = p_title;
00121                             } else if (memcmp(&wk_read_buff[0], "IART", 4) == 0) {
00122                                 data = p_artist;
00123                             } else if (memcmp(&wk_read_buff[0], "IPRD", 4) == 0) {
00124                                 data = p_album;
00125                             } else {
00126                                 data = NULL;
00127                             }
00128                             sub_chunk_size = ((uint32_t)wk_read_buff[4] << 0)
00129                                            + ((uint32_t)wk_read_buff[5] << 8)
00130                                            + ((uint32_t)wk_read_buff[6] << 16)
00131                                            + ((uint32_t)wk_read_buff[7] << 24);
00132                             if ((data != NULL) && (tag_size != 0)) {
00133                                 if (sub_chunk_size > (uint32_t)(tag_size - 1)) {
00134                                     wk_len = (tag_size - 1);
00135                                 } else {
00136                                     wk_len = sub_chunk_size;
00137                                 }
00138                                 read_size = fread(data, sizeof(char), wk_len, wav_fp);
00139                                 data[wk_len] = '\0';
00140                             }
00141                             if ((sub_chunk_size & 0x00000001) != 0) {
00142                                 sub_chunk_size += 1;
00143                             }
00144                             read_index += sub_chunk_size;
00145                             fseek(wav_fp, read_index, SEEK_SET);
00146                         }
00147                         if (data_index != 0) {
00148                             break;
00149                         } else {
00150                             fseek(wav_fp, list_index_max, SEEK_SET);
00151                         }
00152                     } else {
00153                         fseek(wav_fp, chunk_size, SEEK_CUR);
00154                         read_index += chunk_size;
00155                     }
00156                 }
00157             }
00158 
00159             if (data_index != 0) {
00160                 fseek(wav_fp, data_index, SEEK_SET);
00161             }
00162         }
00163 
00164         return result;
00165     };
00166 
00167     /** get next data
00168      *
00169      * @param buf data buffer address
00170      * @param len data buffer length
00171      * @return get data size
00172      */
00173     virtual size_t GetNextData(void *buf, size_t len) {
00174         if (block_size == 24) {
00175             // Add padding
00176             uint32_t write_index = 0;
00177             uint32_t wavfile_index;
00178             uint32_t read_len;
00179             uint32_t pading_index = 0;
00180             uint8_t * p_buf = (uint8_t *)buf;
00181             size_t ret;
00182 
00183             if ((music_data_index + len) > music_data_size) {
00184                 len = music_data_size - music_data_index;
00185             }
00186             while (write_index < (uint32_t)len) {
00187                 read_len = (len - write_index) * 3 / 4;
00188                 if (read_len > sizeof(wk_wavfile_buff)) {
00189                     read_len = sizeof(wk_wavfile_buff);
00190                 }
00191                 music_data_index += read_len;
00192                 ret = fread(wk_wavfile_buff, sizeof(char), read_len, wav_fp);
00193                 if (ret < read_len) {
00194                     break;
00195                 }
00196                 wavfile_index = 0;
00197                 while ((write_index < len) && (wavfile_index < read_len)) {
00198                     if (pading_index == 0) {
00199                         p_buf[write_index] = 0;
00200                     } else {
00201                         p_buf[write_index] = wk_wavfile_buff[wavfile_index];
00202                         wavfile_index++;
00203                     }
00204                     if (pading_index < 3) {
00205                         pading_index++;
00206                     } else {
00207                         pading_index = 0;
00208                     }
00209                     write_index++;
00210                 }
00211             }
00212 
00213             return write_index;
00214         } else {
00215             if ((music_data_index + len) > music_data_size) {
00216                 len = music_data_size - music_data_index;
00217             }
00218             music_data_index += len;
00219 
00220             return fread(buf, sizeof(char), len, wav_fp);
00221         }
00222     };
00223 
00224     /** get channel
00225      *
00226      * @return channel
00227      */
00228     virtual uint16_t GetChannel() {
00229         return channel;
00230     };
00231 
00232     /** get block size
00233      *
00234      * @return block size
00235      */
00236     virtual uint16_t GetBlockSize() {
00237         return block_size;
00238     };
00239 
00240     /** get sampling rate
00241      *
00242      * @return sampling rate
00243      */
00244     virtual uint32_t GetSamplingRate() {
00245         return sampling_rate;
00246     };
00247 
00248 private:
00249     FILE * wav_fp;
00250     uint32_t music_data_size;
00251     uint32_t music_data_index;
00252     uint16_t channel;
00253     uint16_t block_size;
00254     uint32_t sampling_rate;
00255     uint8_t wk_wavfile_buff[3072];
00256 };
00257 
00258 #endif