Daiki Kato / EasyPlayback

Dependents:   GR-PEACH_Audio_WAV_PwmOut GR-Boards_Audio_WAV

Revision:
0:9956e2ed09da
Child:
1:fdd79b99ba73
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/decoder/EasyDec_WavCnv2ch.h	Mon Oct 30 07:04:30 2017 +0000
@@ -0,0 +1,299 @@
+/* mbed EasyDec_WavCnv2ch Library
+ * Copyright (C) 2017 dkato
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**************************************************************************//**
+* @file          EasyDec_WavCnv2ch.h
+* @brief         wav
+******************************************************************************/
+#ifndef __EASY_DEC_WAV_CNV_2CH_H__
+#define __EASY_DEC_WAV_CNV_2CH_H__
+
+#include "EasyDecoder.h"
+
+/** A class to communicate a EasyDec_WavCnv2ch
+ *
+ */
+class EasyDec_WavCnv2ch : public EasyDecoder {
+public:
+
+    static inline EasyDecoder* inst() { return new EasyDec_WavCnv2ch; }
+
+    /** analyze header
+     *
+     * @param p_title title tag buffer
+     * @param p_artist artist tag buffer
+     * @param p_album album tag buffer
+     * @param tag_size tag buffer size
+     * @param fp file pointer
+     * @return true = success, false = failure
+     */
+    virtual bool AnalyzeHeder(char* p_title, char* p_artist, char* p_album, uint16_t tag_size, FILE* fp) {
+        bool result = false;
+        size_t read_size;
+        uint8_t wk_read_buff[36];
+        char *data;
+        uint32_t chunk_size;
+        uint32_t sub_chunk_size;
+        uint32_t list_index_max;
+        bool list_ok = false;
+        uint32_t read_index = 0;
+        uint32_t data_index = 0;
+        uint16_t wk_len;
+
+        if (fp == NULL) {
+            return false;
+        }
+        music_data_size  = 0;
+        music_data_index = 0;
+        wav_fp = fp;
+        if (p_title != NULL) {
+            p_title[0] = '\0';
+        }
+        if (p_artist != NULL) {
+            p_artist[0] = '\0';
+        }
+        if (p_album != NULL) {
+            p_album[0] = '\0';
+        }
+
+        read_size = fread(&wk_read_buff[0], sizeof(char), 36, wav_fp);
+        if (read_size < 36) {
+            // do nothing
+        } else if (memcmp(&wk_read_buff[0], "RIFF", 4) != 0) {
+            // do nothing
+        } else if (memcmp(&wk_read_buff[8], "WAVE", 4) != 0) {
+            // do nothing
+        } else if (memcmp(&wk_read_buff[12], "fmt ", 4) != 0) {
+            // do nothing
+        } else {
+            read_index += 36;
+            channel = ((uint32_t)wk_read_buff[22] << 0) + ((uint32_t)wk_read_buff[23] << 8);
+            sampling_rate = ((uint32_t)wk_read_buff[24] << 0)
+                          + ((uint32_t)wk_read_buff[25] << 8)
+                          + ((uint32_t)wk_read_buff[26] << 16)
+                          + ((uint32_t)wk_read_buff[27] << 24);
+            block_size = ((uint32_t)wk_read_buff[34] << 0) + ((uint32_t)wk_read_buff[35] << 8);
+            while (1) {
+                read_size = fread(&wk_read_buff[0], sizeof(char), 8, wav_fp);
+                read_index += 8;
+                if (read_size < 8) {
+                    break;
+                } else {
+                    chunk_size = ((uint32_t)wk_read_buff[4] << 0)
+                               + ((uint32_t)wk_read_buff[5] << 8)
+                               + ((uint32_t)wk_read_buff[6] << 16)
+                               + ((uint32_t)wk_read_buff[7] << 24);
+                    if (memcmp(&wk_read_buff[0], "data", 4) == 0) {
+                        result = true;
+                        music_data_size = chunk_size;
+                        if (list_ok == true) {
+                            break;
+                        } else {
+                            data_index = read_index;
+                            fseek(wav_fp, chunk_size, SEEK_CUR);
+                            read_index += chunk_size;
+                        }
+                    } else if (memcmp(&wk_read_buff[0], "LIST", 4) == 0) {
+                        list_ok = true;
+                        list_index_max = read_index + chunk_size;
+                        read_size = fread(&wk_read_buff[0], sizeof(char), 4, wav_fp);
+                        read_index += 4;
+                        while (read_index < list_index_max) {
+                            read_size = fread(&wk_read_buff[0], sizeof(char), 8, wav_fp);
+                            read_index += 8;
+                            if (read_size < 8) {
+                                break;
+                            } else if (memcmp(&wk_read_buff[0], "INAM", 4) == 0) {
+                                data = p_title;
+                            } else if (memcmp(&wk_read_buff[0], "IART", 4) == 0) {
+                                data = p_artist;
+                            } else if (memcmp(&wk_read_buff[0], "IPRD", 4) == 0) {
+                                data = p_album;
+                            } else {
+                                data = NULL;
+                            }
+                            sub_chunk_size = ((uint32_t)wk_read_buff[4] << 0)
+                                           + ((uint32_t)wk_read_buff[5] << 8)
+                                           + ((uint32_t)wk_read_buff[6] << 16)
+                                           + ((uint32_t)wk_read_buff[7] << 24);
+                            if ((data != NULL) && (tag_size != 0)) {
+                                if (sub_chunk_size > (uint32_t)(tag_size - 1)) {
+                                    wk_len = (tag_size - 1);
+                                } else {
+                                    wk_len = sub_chunk_size;
+                                }
+                                read_size = fread(data, sizeof(char), wk_len, wav_fp);
+                                data[wk_len] = '\0';
+                            }
+                            if ((sub_chunk_size & 0x00000001) != 0) {
+                                sub_chunk_size += 1;
+                            }
+                            read_index += sub_chunk_size;
+                            fseek(wav_fp, read_index, SEEK_SET);
+                        }
+                        if (data_index != 0) {
+                            break;
+                        } else {
+                            fseek(wav_fp, list_index_max, SEEK_SET);
+                        }
+                    } else {
+                        fseek(wav_fp, chunk_size, SEEK_CUR);
+                        read_index += chunk_size;
+                    }
+                }
+            }
+
+            if (data_index != 0) {
+                fseek(wav_fp, data_index, SEEK_SET);
+            }
+        }
+
+        return result;
+    };
+
+    /** get next data
+     *
+     * @param buf data buffer address
+     * @param len data buffer length
+     * @return get data size
+     */
+    virtual size_t GetNextData(void *buf, size_t len) {
+        size_t ret_size;
+        size_t read_max = len;
+
+        if ((block_size < 8) || ((block_size & 0x07) != 0)) {
+            return -1;
+        }
+
+        if ((channel == 1) && (len != 0)) {
+            read_max /= 2;
+        }
+
+        if (block_size == 24) {
+            // Add padding
+            uint32_t write_index = 0;
+            uint32_t wavfile_index;
+            uint32_t read_len;
+            uint32_t pading_index = 0;
+            uint8_t * p_buf = (uint8_t *)buf;
+            size_t ret;
+
+            if ((music_data_index + read_max) > music_data_size) {
+                read_max = music_data_size - music_data_index;
+            }
+            while (write_index < (uint32_t)read_max) {
+                read_len = (read_max - write_index) * 3 / 4;
+                if (read_len > sizeof(wk_wavfile_buff)) {
+                    read_len = sizeof(wk_wavfile_buff);
+                }
+                music_data_index += read_len;
+                ret = fread(wk_wavfile_buff, sizeof(char), read_len, wav_fp);
+                if (ret < read_len) {
+                    break;
+                }
+                wavfile_index = 0;
+                while ((write_index < read_max) && (wavfile_index < read_len)) {
+                    if (pading_index == 0) {
+                        p_buf[write_index] = 0;
+                    } else {
+                        p_buf[write_index] = wk_wavfile_buff[wavfile_index];
+                        wavfile_index++;
+                    }
+                    if (pading_index < 3) {
+                        pading_index++;
+                    } else {
+                        pading_index = 0;
+                    }
+                    write_index++;
+                }
+            }
+            ret_size = write_index;
+        } else {
+            if ((music_data_index + read_max) > music_data_size) {
+                read_max = music_data_size - music_data_index;
+            }
+            music_data_index += read_max;
+
+            ret_size = fread(buf, sizeof(char), read_max, wav_fp);
+        }
+
+        if ((channel == 1) && (ret_size > 0)) {
+            int block_byte;
+            int idx_w = len - 1;
+            int idx_r = ret_size - 1;
+            int idx_r_last;
+            int j;
+
+            if (block_size == 24) {
+                block_byte = 4;
+            } else {
+                block_byte = block_size / 8;
+            }
+            while (idx_w >= 0) {
+                idx_r_last = idx_r;
+                for (j = 0; j < block_byte; j++) {
+                    ((uint8_t*)buf)[idx_w--] = ((uint8_t*)buf)[idx_r--];
+                }
+                idx_r = idx_r_last;
+                for (j = 0; j < block_byte; j++) {
+                    ((uint8_t*)buf)[idx_w--] = ((uint8_t*)buf)[idx_r--];
+                }
+            }
+            ret_size *= 2;
+        }
+
+        return ret_size;
+    };
+
+    /** get channel
+     *
+     * @return channel
+     */
+    virtual uint16_t GetChannel() {
+        if (channel == 1) {
+            return 2;
+        } else {
+            return channel;
+        }
+    };
+
+    /** get block size
+     *
+     * @return block size
+     */
+    virtual uint16_t GetBlockSize() {
+        return block_size;
+    };
+
+    /** get sampling rate
+     *
+     * @return sampling rate
+     */
+    virtual uint32_t GetSamplingRate() {
+        return sampling_rate;
+    };
+
+private:
+    FILE * wav_fp;
+    uint32_t music_data_size;
+    uint32_t music_data_index;
+    uint16_t channel;
+    uint16_t block_size;
+    uint32_t sampling_rate;
+    uint8_t wk_wavfile_buff[3072];
+};
+
+#endif