00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
00070
00071
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
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
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 }
00126