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

OggVorbisReader.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  * OggVorbisリーダ実装
00022  * @author Junpee
00023  */
00024 
00025 #include "LampBasic.h"
00026 #include "Sound/Reader/OggVorbisReader.h"
00027 #include "vorbis/vorbisfile.h"
00028 
00029 namespace Lamp{
00030 
00031 //------------------------------------------------------------------------------
00032 // OggVorbisリーダ実装クラス
00033 //------------------------------------------------------------------------------
00034 /**
00035  * OggVorbisリーダ実装クラス
00036  */
00037 class OggVorbisReaderImpl{
00038 public:
00039     /**
00040      * コンストラクタ
00041      * @param filePath ファイルパス
00042      */
00043     OggVorbisReaderImpl(const FilePath& filePath) : filePath_(filePath),
00044         file_(NULL), cursor_(0), pcmScale_(0),
00045         size_(0), sample_(0), channel_(0), bit_(0),
00046         oggVorbisinitialized_(false), initialized_(false){
00047         ::memset(&oggVorbis_, 0, sizeof(OggVorbis_File));
00048     }
00049 
00050     /**
00051      * デストラクタ
00052      */
00053     virtual ~OggVorbisReaderImpl(){
00054         int result;
00055         if(file_ != NULL){
00056             if(oggVorbisinitialized_){
00057                 result = ov_clear(&oggVorbis_);
00058                 Assert(result == 0);
00059             }else{
00060                 result = fclose(file_);
00061                 Assert(result == 0);
00062             }
00063         }
00064     }
00065 
00066     //--------------------------------------------------------------------------
00067     /**
00068      * サイズの取得
00069      * @return サイズ
00070      */
00071     virtual u_int getSize() const{
00072         Assert(initialized_);
00073         return size_;
00074     }
00075 
00076     /**
00077      * サンプル数の取得
00078      * @return サンプル数
00079      */
00080     virtual int getSample() const{
00081         Assert(initialized_);
00082         return sample_;
00083     }
00084 
00085     /**
00086      * チャンネル数の取得
00087      * @return チャンネル数
00088      */
00089     virtual int getChannel() const{
00090         Assert(initialized_);
00091         return channel_;
00092     }
00093 
00094     /**
00095      * ビット数の取得
00096      * @return ビット数
00097      */
00098     virtual int getBit() const{
00099         Assert(initialized_);
00100         return bit_;
00101     }
00102 
00103     /**
00104      * コメントの取得
00105      * @return コメント
00106      */
00107     virtual const String& getComment(){
00108         Assert(initialized_);
00109         return comment_;
00110     }
00111 
00112     //--------------------------------------------------------------------------
00113     /**
00114      * 位置の設定
00115      * @param cursor 設定する位置
00116      */
00117     virtual void setCursor(u_int cursor){
00118         Assert((cursor % pcmScale_) == 0);
00119         if(ov_pcm_seek(&oggVorbis_, cursor / pcmScale_) != 0){
00120             ErrorOut("OggVorbisReader::setCursor() 位置の設定に失敗しました。");
00121         }
00122         cursor_ = cursor;
00123     }
00124 
00125     /**
00126      * 位置の取得
00127      * @return 位置
00128      */
00129     virtual u_int getCursor(){ return cursor_; }
00130 
00131     //--------------------------------------------------------------------------
00132     /**
00133      * ヘッダ読み込み
00134      * @return 成功すればtrue
00135      */
00136     virtual bool readHeader(){
00137         if(!filePath_.existFile()){ return false; }
00138         file_ = fopen(filePath_.getPath().getBytes(), "rb");
00139         if(file_ == NULL){ return false; }
00140         // OggVorbisを開く
00141         ::memset(&oggVorbis_, 0, sizeof(OggVorbis_File));
00142         int result = ov_open(file_, &oggVorbis_, NULL, 0);
00143         // 必要そうならエラーコードの識別入れる
00144         if(result < 0){ return false; }
00145         oggVorbisinitialized_ = true;
00146         // シーク可能か
00147         if(ov_seekable(&oggVorbis_) == 0){ return false; }
00148         // 情報の取得
00149         vorbis_info* info = ov_info(&oggVorbis_, -1);
00150         if(info == NULL){ return false; }
00151         sample_ = info->rate;
00152         Assert((sample_ >= DSBFREQUENCY_MIN) && (sample_ <= 100000));
00153         channel_ = info->channels;
00154         Assert((channel_ == 1) || (channel_ == 2));
00155         // 16bit整数フォーマットを指定
00156         bit_ = 16;
00157         Assert((bit_ == 8) || (bit_ == 16));
00158         pcmScale_ = 2 * channel_;
00159         // サイズ取得
00160         __int64 size = ov_pcm_total(&oggVorbis_, -1);
00161         if(size < 0){ return false; }
00162         size *= pcmScale_;
00163         if(size > Limit::uIntMax){ return false; }
00164         size_ = (u_int)size;
00165         // コメントの読み込み
00166         vorbis_comment* commnets = ov_comment(&oggVorbis_,-1);
00167         int commentCount = commnets->comments;
00168         for(int i = 0; i < commentCount; i++){
00169             String comment = commnets->user_comments[i];
00170             if(comment.startsWith("COMMENT=")){
00171                 comment_ = comment.getSubstring(8);
00172             }
00173         }
00174         setCursor(0);
00175         initialized_ = true;
00176         return true;
00177     }
00178 
00179     //--------------------------------------------------------------------------
00180     /**
00181      * 読み込み
00182      * @param buffer 読み込みバッファ
00183      * @param size 読み込みサイズ
00184      * @return 読み込んだサイズ。終端なら0、失敗すれば-1
00185      */
00186     virtual int read(void* buffer, u_int size){
00187         char* readBuffer = (char*)buffer;
00188         int readSize = 0;
00189         while(true){
00190             // リトルエンディアン、16bit整数フォーマット、符号付
00191             int result = ov_read(&oggVorbis_,
00192                 (readBuffer + readSize), (size - readSize), 0, 2, 1, NULL);
00193             if(result < 0){ return -1; }
00194             readSize += result;
00195             cursor_ += result;
00196             if((size == readSize) || (result == 0)){ break; }
00197         }
00198         Assert(size == readSize);
00199         return readSize;
00200     }
00201 
00202 private:
00203     //--------------------------------------------------------------------------
00204     // ファイルパス
00205     FilePath filePath_;
00206     // ファイル
00207     FILE* file_;
00208     // OggVorbis
00209     OggVorbis_File oggVorbis_;
00210     // コメント
00211     String comment_;
00212     // 読み込み位置
00213     u_int cursor_;
00214     // PCMスケール
00215     u_int pcmScale_;
00216 
00217     // サイズ
00218     u_int size_;
00219     // サンプル数
00220     int sample_;
00221     // チャンネル数
00222     int channel_;
00223     // ビット数
00224     int bit_;
00225     // OggVorbis初期化済みフラグ
00226     bool oggVorbisinitialized_;
00227     // 初期化済みフラグ
00228     bool initialized_;
00229 
00230 };
00231 //------------------------------------------------------------------------------
00232 // OggVorbisReader
00233 //------------------------------------------------------------------------------
00234 // コンストラクタ
00235 OggVorbisReader::OggVorbisReader(const FilePath& filePath){
00236     implement_ = new OggVorbisReaderImpl(filePath);
00237 }
00238 //------------------------------------------------------------------------------
00239 // デストラクタ
00240 OggVorbisReader::~OggVorbisReader(){
00241     SafeDelete(implement_);
00242 }
00243 //------------------------------------------------------------------------------
00244 // サイズの取得
00245 u_int OggVorbisReader::getSize() const{ return implement_->getSize(); }
00246 //------------------------------------------------------------------------------
00247 // サンプル数の取得
00248 int OggVorbisReader::getSample() const{ return implement_->getSample(); }
00249 //------------------------------------------------------------------------------
00250 // チャンネル数の取得
00251 int OggVorbisReader::getChannel() const{ return implement_->getChannel(); }
00252 //------------------------------------------------------------------------------
00253 // ビット数の取得
00254 int OggVorbisReader::getBit() const{ return implement_->getBit(); }
00255 //------------------------------------------------------------------------------
00256 // コメントの取得
00257 const String& OggVorbisReader::getComment(){ return implement_->getComment(); }
00258 //------------------------------------------------------------------------------
00259 // 位置の設定
00260 void OggVorbisReader::setCursor(u_int cursor){
00261     implement_->setCursor(cursor);
00262 }
00263 //------------------------------------------------------------------------------
00264 // 位置の取得
00265 u_int OggVorbisReader::getCursor(){ return implement_->getCursor(); }
00266 //------------------------------------------------------------------------------
00267 // ヘッダ読み込み
00268 bool OggVorbisReader::readHeader(){ return implement_->readHeader(); }
00269 //------------------------------------------------------------------------------
00270 // 読み込み
00271 int OggVorbisReader::read(void* buffer, u_int size){
00272     return implement_->read(buffer, size);
00273 }
00274 //------------------------------------------------------------------------------
00275 } // End of namespace Lamp
00276 //------------------------------------------------------------------------------

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