revised version of F746_SD_GraphicEqualizer

Dependencies:   BSP_DISCO_F746NG F746_GUI F746_SAI_IO FrequencyResponseDrawer LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed

Fork of F746_SD_GraphicEqualizer by 不韋 呂

MyClasses_Functions/SD_WavReader.cpp

Committer:
edamame22
Date:
2016-07-07
Revision:
12:87f6955b5a80
Parent:
10:fc6367c2ffcf

File content as of revision 12:87f6955b5a80:

//--------------------------------------------------------------
//  SD_WavReader class
//      SD カードの *.wav ファイルの内容を読み出す
//      以下のフォーマット以外は扱わない
//          PCM,16 ビットステレオ,標本化周波数 44.1 kHz
//
//  2016/04/19, Copyright (c) 2016 MIKAMI, Naoki
//--------------------------------------------------------------

#include "SD_WavReader.hpp"

namespace Mikami
{
    SD_WavReader::SD_WavReader(int32_t bufferSize)
        : STR_("sd"), ok_(false)
    {
        sd_ = new SDFileSystem(STR_.c_str());
        sd_->mount();
        
        buffer = new int16_t[bufferSize*2];
    }

    SD_WavReader::~SD_WavReader()
    {
        delete[] buffer;
        sd_->unmount();
        delete sd_;
    }
    
    void SD_WavReader::Open(const string fileName)
    {
        string name = (string)"/" + STR_ + "/" + fileName;
        fp_ = fopen(name.c_str(), "rb");
        if (fp_ == NULL) ErrorMsg("open error!!");
    }
    
    
    // ファイルのヘッダ (RIFFxxxxWAVEfm ) 読み込み
    //      戻り値: *.wav で,16 ビットステレオ,
    //             標本化周波数:44.1 kHz の場合 true
    bool SD_WavReader::IsWavFile()
    {
        char data[17];
        fread(data, 1, 16, fp_);
        string strRead = "";
        for (int n=0; n<4; n++) strRead += data[n];
        for (int n=8; n<16; n++) strRead += data[n];

        // "RIFF", "WAVE", "fmt " が存在することを確認
        if (strRead != "RIFFWAVEfmt ") return false;
/**{
 char dump[500]; strcpy(dump, strRead.c_str());
ren_Msg1(4, dump);
}**/
        // fmt chunck のサイズを取得
        uint32_t fmtChunkSize;
        fread(&fmtChunkSize, sizeof(uint32_t), 1, fp_);

        // PCM, Stereo, 44.1 kHz, 16 bit であることを確認
        WaveFormatEx fmtData;
        fread(&fmtData, fmtChunkSize, 1, fp_);

        if ((fmtData.wFormatTag     != 1)     ||
            (fmtData.nChannels      != 2)     ||
            (fmtData.nSamplesPerSec != 44100) ||
            (fmtData.wBitsPerSample != 16)
           )
           return false;
/**{
    char dump[500];
sprintf(dump, "wFormatTag: %d", fmtData.wFormatTag);
ren_Msg1(1, dump);
sprintf(dump, "nChannels: %d", fmtData.nChannels);
ren_Msg1(2, dump);
sprintf(dump, "nSamplesPerSec: %d", fmtData.nSamplesPerSec);
ren_Msg1(3, dump);
sprintf(dump, "wBitsPerSample: %d", fmtData.wBitsPerSample);
ren_Msg1(4, dump); 
}**/
        // data chunk を探す
        char dataId[5];
        dataId[4] = 0;
        fread(dataId, 1, 4, fp_);
/**{
    char dump[500];
sprintf(dump, "dataId: %s", dataId);
ren_Msg1(5, dump); wait(20.0f);
}**/
        if ("data" != (string)dataId)
            for (int n=0; n<1000; n++)
            {
                char oneByte;
                fread(&oneByte, 1, 1, fp_);
                for (int k=0; k<3; k++)
                    dataId[k] = dataId[k+1];
                dataId[3] = oneByte;
                if ("data" == (string)dataId) break;
                
                if (n == 999) return false;
            }

        // データサイズ (byte) を取得
        int32_t sizeByte;
        fread(&sizeByte, sizeof(int32_t), 1, fp_);
        size_ = sizeByte/4;

        ok_ = true;
        return true;
    }

    // ファイルからデータの取得
    void SD_WavReader::Read(int16_t data[], uint32_t size)
    {
        if (!ok_) ErrorMsg("Get data FAILED");
        fread(data, sizeof(int16_t), size, fp_);
    }        

    // ファイルからデータをモノラルに変換しての取得
    void SD_WavReader::ReadAndToMono(int16_t data[], uint32_t size)
    {
        if (!ok_) ErrorMsg("Get data FAILED");
        fread(buffer, sizeof(int16_t), size*2, fp_);
        for (int n=0; n<size; n++)
            data[n] = (buffer[2*n] + buffer[2*n+1])/2;
    }        
    
    // データサイズ(標本化点の数)の取得
    int32_t SD_WavReader::GetSize()
    {
        if (!ok_) ErrorMsg("Get data size FAILED");
        return size_;
    }
}