PHung Tung / MyClasses_Functions
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SD_WavReader.cpp Source File

SD_WavReader.cpp

00001 //--------------------------------------------------------------
00002 //  SD_WavReader class
00003 //      SD カードの *.wav ファイルの内容を読み出す
00004 //      以下のフォーマット以外は扱わない
00005 //          PCM,16 ビットステレオ,標本化周波数 44.1 kHz
00006 //
00007 //  2016/06/17, Copyright (c) 2016 MIKAMI, Naoki
00008 //--------------------------------------------------------------
00009 
00010 #include "SD_WavReader.hpp"
00011 
00012 namespace Mikami
00013 {
00014     SD_WavReader::SD_WavReader(int32_t bufferSize)
00015         : STR_("sd"), ok_(false)
00016     {
00017         sd_ = new SDFileSystem(STR_.c_str());
00018         sd_->mount();      
00019         buffer.SetSize(bufferSize*2);
00020     }
00021 
00022     SD_WavReader::~SD_WavReader()
00023     {
00024         sd_->unmount();
00025         delete sd_;
00026     }
00027     
00028     void SD_WavReader::Open(const string fileName)
00029     {
00030         string name = (string)"/" + STR_ + "/" + fileName;
00031         fp_ = fopen(name.c_str(), "rb");
00032         if (fp_ == NULL) ErrorMsg("Khong the mo!!");
00033     }
00034     
00035     
00036     // ファイルのヘッダ (RIFFxxxxWAVEfm ) 読み込み
00037     //      戻り値: *.wav で,16 ビットステレオ,
00038     //             標本化周波数:44.1 kHz の場合 true
00039     bool SD_WavReader::IsWavFile()
00040     {
00041         char data[17];
00042         fread(data, 1, 16, fp_);
00043         string strRead = "";
00044         for (int n=0; n<4; n++) strRead += data[n];
00045         for (int n=8; n<16; n++) strRead += data[n];
00046 
00047         // "RIFF", "WAVE", "fmt " が存在することを確認
00048         if (strRead != "RIFFWAVEfmt ") return false;
00049 
00050         // fmt chunck のサイズを取得
00051         uint32_t fmtChunkSize;
00052         fread(&fmtChunkSize, sizeof(uint32_t), 1, fp_);
00053 
00054         // PCM, Stereo, 44.1 kHz, 16 bit であることを確認
00055         WaveFormatEx fmtData;
00056         fread(&fmtData, fmtChunkSize, 1, fp_);
00057         if ((fmtData.wFormatTag     != 1)     ||
00058             (fmtData.nChannels      != 2)     ||
00059             (fmtData.nSamplesPerSec != 44100) ||
00060             (fmtData.wBitsPerSample != 16)    
00061            ) return false;
00062 
00063         // data chunk を探す
00064         char dataId[5];
00065         dataId[4] = 0;
00066         fread(dataId, 1, 4, fp_);
00067         if ("data" != (string)dataId)
00068             for (int n=0; n<100; n++)
00069             {
00070                 char oneByte;
00071                 fread(&oneByte, 1, 1, fp_);
00072                 for (int k=0; k<3; k++)
00073                     dataId[k] = dataId[k+1];
00074                 dataId[3] = oneByte;
00075                 if ("data" == (string)dataId) break;
00076                 
00077                 if (n == 99) return false;
00078             }
00079 
00080         // データサイズ (byte) を取得
00081         int32_t sizeByte;
00082         fread(&sizeByte, sizeof(int32_t), 1, fp_);
00083         size_ = sizeByte/4;
00084 
00085         ok_ = true;
00086         return true;
00087     }
00088 
00089     // ファイルからステレオデータの取得
00090     void SD_WavReader::ReadStereo(Array<int16_t>& dataL,
00091                                   Array<int16_t>& dataR)
00092     {
00093         if (!ok_) ErrorMsg("Lay du lieu that bai");
00094         uint32_t size = dataL.Length();
00095         fread(buffer, sizeof(int16_t), size*2, fp_);       
00096         for (int n=0; n<size; n++)
00097         {
00098             dataL[n] = buffer[2*n];
00099             dataR[n] = buffer[2*n+1];
00100         }
00101     }
00102 
00103     // ファイルからデータをモノラルに変換しての取得
00104     void SD_WavReader::ReadAndToMono(Array<int16_t>& data)
00105     {
00106         if (!ok_) ErrorMsg("Lay du lieu that bai");
00107         uint32_t size = data.Length();
00108         fread(buffer, sizeof(int16_t), size*2, fp_);
00109         for (int n=0; n<size; n++)
00110             data[n] = (buffer[2*n] + buffer[2*n+1])/2;
00111     }        
00112     
00113     // データサイズ(標本化点の数)の取得
00114     int32_t SD_WavReader::GetSize()
00115     {
00116         if (!ok_) ErrorMsg("Loi dung luong du lieu");
00117         return size_;
00118     }
00119 }