Daiki Kato / EasyPlaybackPWM
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EasyDec_WavCnv2ch.h Source File

EasyDec_WavCnv2ch.h

Go to the documentation of this file.
00001 /* mbed EasyDec_WavCnv2ch 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_WavCnv2ch.h
00019 * @brief         wav
00020 ******************************************************************************/
00021 #ifndef __EASY_DEC_WAV_CNV_2CH_H__
00022 #define __EASY_DEC_WAV_CNV_2CH_H__
00023 
00024 #include "EasyDecoder.h"
00025 
00026 /** A class to communicate a EasyDec_WavCnv2ch
00027  *
00028  */
00029 class EasyDec_WavCnv2ch : public EasyDecoder {
00030 public:
00031 
00032     static inline EasyDecoder* inst() { return new EasyDec_WavCnv2ch; }
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         size_t ret_size;
00175         size_t read_max = len;
00176 
00177         if ((block_size < 8) || ((block_size & 0x07) != 0)) {
00178             return -1;
00179         }
00180 
00181         if ((channel == 1) && (len != 0)) {
00182             read_max /= 2;
00183         }
00184 
00185         if (block_size == 24) {
00186             // Add padding
00187             uint32_t write_index = 0;
00188             uint32_t wavfile_index;
00189             uint32_t read_len;
00190             uint32_t pading_index = 0;
00191             uint8_t * p_buf = (uint8_t *)buf;
00192             size_t ret;
00193 
00194             if ((music_data_index + read_max) > music_data_size) {
00195                 read_max = music_data_size - music_data_index;
00196             }
00197             while (write_index < (uint32_t)read_max) {
00198                 read_len = (read_max - write_index) * 3 / 4;
00199                 if (read_len > sizeof(wk_wavfile_buff)) {
00200                     read_len = sizeof(wk_wavfile_buff);
00201                 }
00202                 music_data_index += read_len;
00203                 ret = fread(wk_wavfile_buff, sizeof(char), read_len, wav_fp);
00204                 if (ret < read_len) {
00205                     break;
00206                 }
00207                 wavfile_index = 0;
00208                 while ((write_index < read_max) && (wavfile_index < read_len)) {
00209                     if (pading_index == 0) {
00210                         p_buf[write_index] = 0;
00211                     } else {
00212                         p_buf[write_index] = wk_wavfile_buff[wavfile_index];
00213                         wavfile_index++;
00214                     }
00215                     if (pading_index < 3) {
00216                         pading_index++;
00217                     } else {
00218                         pading_index = 0;
00219                     }
00220                     write_index++;
00221                 }
00222             }
00223             ret_size = write_index;
00224         } else {
00225             if ((music_data_index + read_max) > music_data_size) {
00226                 read_max = music_data_size - music_data_index;
00227             }
00228             music_data_index += read_max;
00229 
00230             ret_size = fread(buf, sizeof(char), read_max, wav_fp);
00231         }
00232 
00233         if ((channel == 1) && (ret_size > 0)) {
00234             int block_byte;
00235             int idx_w = len - 1;
00236             int idx_r = ret_size - 1;
00237             int idx_r_last;
00238             int j;
00239 
00240             if (block_size == 24) {
00241                 block_byte = 4;
00242             } else {
00243                 block_byte = block_size / 8;
00244             }
00245             while (idx_w >= 0) {
00246                 idx_r_last = idx_r;
00247                 for (j = 0; j < block_byte; j++) {
00248                     ((uint8_t*)buf)[idx_w--] = ((uint8_t*)buf)[idx_r--];
00249                 }
00250                 idx_r = idx_r_last;
00251                 for (j = 0; j < block_byte; j++) {
00252                     ((uint8_t*)buf)[idx_w--] = ((uint8_t*)buf)[idx_r--];
00253                 }
00254             }
00255             ret_size *= 2;
00256         }
00257 
00258         return ret_size;
00259     };
00260 
00261     /** get channel
00262      *
00263      * @return channel
00264      */
00265     virtual uint16_t GetChannel() {
00266         if (channel == 1) {
00267             return 2;
00268         } else {
00269             return channel;
00270         }
00271     };
00272 
00273     /** get block size
00274      *
00275      * @return block size
00276      */
00277     virtual uint16_t GetBlockSize() {
00278         return block_size;
00279     };
00280 
00281     /** get sampling rate
00282      *
00283      * @return sampling rate
00284      */
00285     virtual uint32_t GetSamplingRate() {
00286         return sampling_rate;
00287     };
00288 
00289 private:
00290     FILE * wav_fp;
00291     uint32_t music_data_size;
00292     uint32_t music_data_index;
00293     uint16_t channel;
00294     uint16_t block_size;
00295     uint32_t sampling_rate;
00296     uint8_t wk_wavfile_buff[3072];
00297 };
00298 
00299 #endif