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/System/SoundBuffer.h"
00027 #include "Sound/System/LampSound.h"
00028 #include "Sound/System/SoundManager.h"
00029 #include "Sound/System/SoundDefinition.h"
00030
00031 namespace Lamp{
00032
00033
00034
00035
00036
00037 SoundBuffer::SoundBuffer(DirectSoundBuffer* soundBuffer) :
00038 Sound(), soundBuffer_(soundBuffer){
00039 lock_.clear();
00040
00041 long decibelVolume;
00042 if(DirectXFailed(soundBuffer->GetVolume(&decibelVolume))){
00043 ErrorOut("SoundBuffer::SoundBuffer() ボリュームの取得に失敗しました。");
00044 }
00045 volume_ = decibelToVolume(decibelVolume);
00046 frequency_ = getBufferFrequency();
00047 fadeStartVolume_ = fadeEndVolume_ = 0.f;
00048 isFading_ = false;
00049 setPriority(priorityDefault);
00050 setOwnership(true);
00051 setLoop(false);
00052 isSuspended_ = false;
00053 }
00054
00055
00056 void SoundBuffer::initialize(
00057 u_int size, int sample, int channel, int bit, Focus focus){
00058 size_ = size;
00059 sample_ = sample;
00060 channel_ = channel;
00061 bit_ = bit;
00062 focus_ = focus;
00063 }
00064
00065
00066 SoundBuffer::~SoundBuffer(){
00067
00068 stopFade();
00069 stop();
00070 SafeRelease(soundBuffer_);
00071 }
00072
00073
00074 void SoundBuffer::copySoundBufferData(SoundBuffer* destination){
00075 destination->setName(getName());
00076 destination->initialize(
00077 getBufferSize(), getSample(), getChannel(), getBit(), getFocus());
00078 destination->setPriority(getPriority());
00079 destination->setLoop(isLoop());
00080 }
00081
00082
00083
00084
00085 bool SoundBuffer::play(){
00086
00087 isSuspended_ = false;
00088 return playBuffer();
00089 }
00090
00091
00092 void SoundBuffer::stop(){
00093 isSuspended_ = false;
00094 stopBuffer();
00095 setCursor(0);
00096 }
00097
00098
00099 void SoundBuffer::suspend(){
00100 State state = getState();
00101
00102 if(state == stateStop){ return; }
00103 isSuspended_ = true;
00104 stopBuffer();
00105 }
00106
00107
00108 bool SoundBuffer::resume(){
00109 State state = getState();
00110
00111 if(state == stateStop){ return true; }
00112
00113 bool result = playBuffer();
00114 isSuspended_ = false;
00115 return result;
00116 }
00117
00118
00119 SoundBuffer::State SoundBuffer::getState() const{
00120 u_long status;
00121 if(DirectXFailed(soundBuffer_->GetStatus(&status))){
00122 ErrorOut("SoundBuffer::getState() ステータスの取得に失敗しました。");
00123 }
00124 if((status & DSBSTATUS_BUFFERLOST) != 0){
00125
00126 if(DirectXFailed(soundBuffer_->Restore())){
00127 ErrorOut("SoundBuffer::getState() バッファのリストアに失敗しました。");
00128 }
00129 if(DirectXFailed(soundBuffer_->GetStatus(&status))){
00130 ErrorOut("SoundBuffer::getState() ステータスの取得に失敗しました。");
00131 }
00132 if((status & DSBSTATUS_BUFFERLOST) != 0){ return stateLost; }
00133 }
00134 if((status & DSBSTATUS_PLAYING) != 0){ return statePlay; }
00135 if(isSuspended_){ return stateSuspend; }
00136 return stateStop;
00137 }
00138
00139
00140 bool SoundBuffer::playBuffer(){
00141 u_int priority = (u_int)(getPriority() + 32768);
00142 u_int flag = getPlayFlag();
00143
00144 HRESULT result = soundBuffer_->Play(0, priority, flag);
00145 if(DirectXSucceeded(result)){ return true; }
00146
00147 if(result == E_OUTOFMEMORY){ Assert(false); return false; }
00148
00149 if(result != DSERR_BUFFERLOST){
00150 ErrorOut("SoundBuffer::playBuffer() バッファの再生に失敗しました。");
00151 return false;
00152 }
00153 result = soundBuffer_->Restore();
00154 if(DirectXFailed(result)){ return false; }
00155
00156 result = soundBuffer_->Play(0, priority, flag);
00157 if(DirectXSucceeded(result)){ return true; }
00158 return false;
00159 }
00160
00161
00162 void SoundBuffer::stopBuffer(){
00163 if(DirectXFailed(soundBuffer_->Stop())){
00164 ErrorOut("SoundBuffer::stopBuffer() サウンドの停止に失敗しました。");
00165 }
00166 }
00167
00168
00169
00170
00171 void SoundBuffer::setCursor(u_int cursor){
00172 Assert((cursor >= 0) && (cursor < getSize()));
00173 if(DirectXFailed(soundBuffer_->SetCurrentPosition(cursor))){
00174 ErrorOut("SoundBuffer::setCursor() 再生位置の設定に失敗しました。");
00175 }
00176 }
00177
00178
00179 u_int SoundBuffer::getCursor() const{
00180 u_long result;
00181 if(DirectXFailed(soundBuffer_->GetCurrentPosition(&result, NULL))){
00182 ErrorOut("SoundBuffer::getCursor() 再生位置の取得に失敗しました。");
00183 }
00184 return result;
00185 }
00186
00187
00188
00189
00190 void SoundBuffer::setVolume(float volume){
00191 if(volume_ == volume){ return; }
00192 int db = volumeToDecibel(volume);
00193 if(DirectXFailed(soundBuffer_->SetVolume(db))){
00194 ErrorOut("SoundBuffer::setVolume() ボリュームの設定に失敗しました。");
00195 }
00196 volume_ = volume;
00197 }
00198
00199
00200
00201
00202 void SoundBuffer::setFrequency(int frequency){
00203 if(frequency_ == frequency){ return; }
00204 Assert(frequency >= DSBFREQUENCY_MIN);
00205 Assert(frequency <= 100000);
00206 if(DirectXFailed(soundBuffer_->SetFrequency(frequency))){
00207 ErrorOut("SoundBuffer::setFrequency() 周波数の設定に失敗しました。");
00208 }
00209 frequency_ = frequency;
00210 }
00211
00212
00213 void SoundBuffer::setOriginalFrequency(){
00214 if(DirectXFailed(soundBuffer_->SetFrequency(DSBFREQUENCY_ORIGINAL))){
00215 ErrorOut("SoundBuffer::resetFrequency() 周波数の設定に失敗しました。");
00216 }
00217 frequency_ = getBufferFrequency();
00218 }
00219
00220
00221 int SoundBuffer::getBufferFrequency() const{
00222 u_long frequency;
00223 if(DirectXFailed(soundBuffer_->GetFrequency(&frequency))){
00224 ErrorOut("SoundBuffer::getBufferFrequency() "
00225 "バッファ周波数の取得に失敗しました。");
00226 }
00227 Assert(frequency >= DSBFREQUENCY_MIN);
00228 Assert(frequency <= 100000);
00229 return frequency;
00230 }
00231
00232
00233
00234
00235 void SoundBuffer::fade(float millisecond, float startVolume, float endVolume){
00236 Assert(millisecond >= 0.f);
00237 if(isFading_){
00238 LampSound::getSoundManager()->removeUpdateSound(this);
00239 isFading_ = false;
00240 }
00241 if(millisecond <= Math::epsilon){ return; }
00242 fadeStartTime_ = Timer::getTick();
00243 fadePeriod_ = millisecond;
00244 fadeStartVolume_ = startVolume;
00245 fadeEndVolume_ = endVolume;
00246 isFading_ = true;
00247 setVolume(fadeStartVolume_);
00248 play();
00249 LampSound::getSoundManager()->addUpdateSound(this);
00250 }
00251
00252
00253 bool SoundBuffer::update(){
00254 Assert(isFading());
00255 float rate = Timer::getInterval(fadeStartTime_) / fadePeriod_;
00256
00257 if(rate >= 1.f){
00258 setVolume(fadeEndVolume_);
00259 if(fadeEndVolume_ <= Math::epsilon){ stop(); }
00260 isFading_ = false;
00261 return true;
00262 }
00263 float volume =
00264 (fadeEndVolume_ - fadeStartVolume_) * rate + fadeStartVolume_;
00265 setVolume(volume);
00266 return false;
00267 }
00268
00269
00270
00271
00272 SoundBuffer::Lock& SoundBuffer::lock(){
00273 Assert(!lock_.isValid());
00274 HRESULT result = soundBuffer_->Lock(0, 0,
00275 &lock_.address0_, &lock_.size0_, NULL, NULL, DSBLOCK_ENTIREBUFFER);
00276 if(DirectXSucceeded(result)){ return lock_; }
00277
00278 lock_.clear();
00279 if(result != DSERR_BUFFERLOST){
00280 ErrorOut("SoundBuffer::lock() バッファのロックに失敗しました。");
00281 return lock_;
00282 }
00283 result = soundBuffer_->Restore();
00284 if(DirectXFailed(result)){ return lock_; }
00285
00286 result = soundBuffer_->Lock(0, 0,
00287 &lock_.address0_, &lock_.size0_, NULL, NULL, DSBLOCK_ENTIREBUFFER);
00288 if(DirectXFailed(result)){ lock_.clear(); }
00289 return lock_;
00290 }
00291
00292
00293 SoundBuffer::Lock& SoundBuffer::lock(u_int offset, u_int bytes){
00294 Assert(!lock_.isValid());
00295 HRESULT result = soundBuffer_->Lock(offset, bytes,
00296 &lock_.address0_, &lock_.size0_, &lock_.address1_, &lock_.size1_, 0);
00297 if(DirectXSucceeded(result)){ return lock_; }
00298
00299 lock_.clear();
00300 if(result != DSERR_BUFFERLOST){
00301 ErrorOut("SoundBuffer::lock() バッファのロックに失敗しました。");
00302 return lock_;
00303 }
00304 result = soundBuffer_->Restore();
00305 if(DirectXFailed(result)){ return lock_; }
00306
00307 result = soundBuffer_->Lock(0, 0,
00308 &lock_.address0_, &lock_.size0_, &lock_.address1_, &lock_.size1_, 0);
00309 if(DirectXFailed(result)){ lock_.clear(); }
00310 return lock_;
00311 }
00312
00313
00314 void SoundBuffer::unlock(){
00315
00316 if(!lock_.isValid()){ return; }
00317 if(DirectXFailed(soundBuffer_->Unlock(
00318 lock_.address0_, lock_.size0_, lock_.address1_, lock_.size1_))){
00319 ErrorOut("SoundBuffer::unlock() バッファのアンロックに失敗しました。");
00320 }
00321 lock_.clear();
00322 }
00323
00324 }
00325