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 //------------------------------------------------------------------------------

Generated on Wed Mar 16 10:29:38 2005 for Lamp by doxygen 1.3.2