Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# WaveReader.cpp

Go to the documentation of this file.

    00001 //------------------------------------------------------------------------------
    00002 // Lamp : Open source game middleware
    00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
    00004 //
    00005 // This library is free software; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public
    00007 // License as published by the Free Software Foundation; either
    00008 // version 2.1 of the License, or (at your option) any later version.
    00009 //
    00010 // This library is distributed in the hope that it will be useful,
    00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this library; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00018 //------------------------------------------------------------------------------
    00019
    00020 /** @file
    00021  * Waveリーダ実装
    00022  * @author Junpee
    00023  */
    00024
    00025 #include "LampBasic.h"
    00026 #include "Sound/Reader/WaveReader.h"
    00027
    00028 namespace Lamp{
    00029
    00030 //------------------------------------------------------------------------------
    00031 // コンストラクタ
    00032 WaveReader::WaveReader(const FilePath& filePath) : SoundReader(),
    00033     filePath_(filePath), handle_(NULL), dataOffset_(-1), cursor_(0),
    00034     size_(0), sample_(0), channel_(0), bit_(0), initialized_(false){
    00035 }
    00036 //------------------------------------------------------------------------------
    00037 // デストラクタ
    00038 WaveReader::~WaveReader(){
    00039     // ファイルを閉じる
    00040     if(handle_ != NULL){
    00041         mmioClose(handle_, 0);
    00042         handle_ = NULL;
    00043     }
    00044 }
    00045 //------------------------------------------------------------------------------
    00046 // 位置の設定
    00047 void WaveReader::setCursor(u_int cursor){
    00048     Assert(cursor_ <= size_);
    00049     if(mmioSeek(handle_, (dataOffset_ + cursor), SEEK_SET) == -1){
    00050         ErrorOut("WaveReader::setCursor() 位置の設定に失敗しました。");
    00051     }
    00052     cursor_ = cursor;
    00053 }
    00054 //------------------------------------------------------------------------------
    00055 // ヘッダ読み込み
    00056 bool WaveReader::readHeader(){
    00057     // ファイルを開く
    00058     handle_ = mmioOpen((LPSTR)filePath_.getPath().getBytes(), NULL,
    00059         (MMIO_ALLOCBUF | MMIO_READ));
    00060     if(handle_ == NULL){ return false; }
    00061     // RIFFチャンクへの進入
    00062     if(mmioDescend(handle_, &riffChunk_, NULL, 0) != MMSYSERR_NOERROR){
    00063         return false;
    00064     }
    00065     if(riffChunk_.ckid != FOURCC_RIFF){ return false; }
    00066     if(riffChunk_.fccType != mmioFOURCC('W', 'A', 'V', 'E')){ return false; }
    00067
    00068     // コメントチャンク
    00069     // まともにWaveファイルのコメントを編集できるソフトが無い、、、
    00070     // mmioFOURCC('L', 'I', 'S', 'T');
    00071     // mmioFOURCC('I', 'C', 'M', 'T');
    00072
    00073     // フォーマットチャンクを開く
    00074     MMCKINFO formatChunk_;
    00075     formatChunk_.ckid = mmioFOURCC('f', 'm', 't', ' ');
    00076     if(mmioDescend(handle_, &formatChunk_, &riffChunk_, MMIO_FINDCHUNK ) !=
    00077         MMSYSERR_NOERROR){ return false; }
    00078     // PCMWaveFormat読み込み
    00079     if(formatChunk_.cksize < sizeof(PCMWAVEFORMAT)){ return false; }
    00080     PCMWAVEFORMAT pcmWaveFormat;
    00081     if(mmioRead(handle_, (HPSTR)&pcmWaveFormat, sizeof(PCMWAVEFORMAT)) !=
    00082         sizeof(PCMWAVEFORMAT)){ return false; }
    00083     // フォーマット情報の読み込み
    00084     WAVEFORMAT& waveFormat = pcmWaveFormat.wf;
    00085     sample_ = waveFormat.nSamplesPerSec;
    00086     Assert((sample_ >= DSBFREQUENCY_MIN) && (sample_ <= 100000));
    00087     channel_ = waveFormat.nChannels;
    00088     Assert((channel_ == 1) || (channel_ == 2));
    00089     bit_ = pcmWaveFormat.wBitsPerSample;
    00090     Assert((bit_ == 8) || (bit_ == 16));
    00091     // フォーマットチャンクから離脱
    00092     if(mmioAscend(handle_, &formatChunk_, 0) != 0){ return false; }
    00093     // データチャンクへの進入
    00094     if(mmioSeek(handle_, riffChunk_.dwDataOffset + sizeof(FOURCC),
    00095         SEEK_SET) == -1){ return false; }
    00096     dataChunk_.ckid = mmioFOURCC('d', 'a', 't', 'a');
    00097     if(mmioDescend(handle_, &dataChunk_, &riffChunk_, MMIO_FINDCHUNK) != 0){
    00098         return false;
    00099     }
    00100     // データ情報取得
    00101     size_ = dataChunk_.cksize;
    00102     dataOffset_ = mmioSeek(handle_, 0, SEEK_CUR);
    00103     if(dataOffset_ == -1){ return false; }
    00104     cursor_ = 0;
    00105     initialized_ = true;
    00106     return true;
    00107 }
    00108 //------------------------------------------------------------------------------
    00109 // 読み込み
    00110 int WaveReader::read(void* buffer, u_int size){
    00111     // mmioAdvance()の利点が不明だったのでmmioRead()で実装
    00112     char* readBuffer = (char*)buffer;
    00113     int readSize = 0;
    00114     while(true){
    00115         int result = mmioRead(handle_,
    00116             (readBuffer + readSize), (size - readSize));
    00117         if(result == -1){ return -1; }
    00118         readSize += result;
    00119         cursor_ += result;
    00120         if((size == readSize) || (result == 0)){ break; }
    00121     }
    00122     return readSize;
    00123 }
    00124 //------------------------------------------------------------------------------
    00125 } // End of namespace Lamp
    00126 //------------------------------------------------------------------------------