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/3D/Sound3D.h"
00027 #include "Sound/System/LampSound.h"
00028 #include "Sound/3D/SoundListener.h"
00029
00030 namespace Lamp{
00031
00032
00033
00034 Sound3D::Sound3D(DirectSoundBuffer* soundBuffer) :
00035 SoundBuffer(soundBuffer), sound3DBuffer_(NULL){
00036 if(DirectXFailed(soundBuffer->QueryInterface(
00037 DirectSound3DBufferInterfaceID, (void**)&sound3DBuffer_))){
00038 ErrorOut("Sound3D::Sound3D() 3Dバッファの取得に失敗しました。");
00039 }
00040
00041 DS3DBUFFER param;
00042 param.dwSize = sizeof(DS3DBUFFER);
00043 if(DirectXFailed(sound3DBuffer_->GetAllParameters(¶m))){
00044 ErrorOut("Sound3D::Sound3D() 3Dパラメータの取得に失敗しました。");
00045 }
00046 position_.set(param.vPosition.x, param.vPosition.x, param.vPosition.z);
00047 velocity_.set(param.vVelocity.x, param.vVelocity.x, param.vVelocity.z);
00048 coneDirection_.set(param.vConeOrientation.x,
00049 param.vConeOrientation.x, param.vConeOrientation.z);
00050 minimumDistance_ = param.flMinDistance;
00051 maximumDistance_ = param.flMaxDistance;
00052 insideConeAngle_ = Math::toRadian((float)param.dwInsideConeAngle);
00053 outsideConeAngle_ = Math::toRadian((float)param.dwOutsideConeAngle);
00054 coneOutsideVolume_ = decibelToVolume(param.lConeOutsideVolume);
00055 Assert(param.dwMode == DS3DMODE_NORMAL);
00056 if(param.dwMode == DS3DMODE_NORMAL){
00057 is3DEnabled_ = true;
00058 }else if(param.dwMode == DS3DMODE_DISABLE){
00059 is3DEnabled_ = false;
00060 }else{ Assert(false); }
00061 }
00062
00063
00064 Sound3D::~Sound3D(){
00065 SafeRelease(sound3DBuffer_);
00066 }
00067
00068
00069 void Sound3D::copySound3DData(Sound3D* destination){
00070 copySoundBufferData(destination);
00071 }
00072
00073
00074
00075
00076 void Sound3D::setPosition(const Vector3& position){
00077 if(position_ == position){ return; }
00078 if(DirectXFailed(sound3DBuffer_->SetPosition(
00079 -position.x, position.y, position.z, DS3D_DEFERRED))){
00080 ErrorOut("Sound3D::setPosition() 位置の設定に失敗しました。");
00081 }
00082 position_ = position;
00083 }
00084
00085
00086 void Sound3D::setVelocity(const Vector3& velocity){
00087 if(velocity_ == velocity){ return; }
00088 if(DirectXFailed(sound3DBuffer_->SetVelocity(
00089 -velocity.x, velocity.y, velocity.z, DS3D_DEFERRED))){
00090 ErrorOut("Sound3D::setVelocity() 速度の設定に失敗しました。");
00091 }
00092 velocity_ = velocity;
00093 }
00094
00095
00096 void Sound3D::setPositionAndVelocity(
00097 const Vector3& position, float millisecond){
00098 Assert(millisecond >= 0);
00099 if(millisecond < Math::epsilon){
00100 setVelocity(Vector3::zero);
00101 }else{
00102 Vector3 velocity = position - position_;
00103 velocity *= (1000.f / millisecond);
00104 setVelocity(velocity);
00105 }
00106 setPosition(position);
00107 }
00108
00109
00110 void Sound3D::setMinimumDistance(float minimumDistance){
00111 Assert(minimumDistance > 0.f);
00112 if(minimumDistance_ == minimumDistance){ return; }
00113 if(DirectXFailed(sound3DBuffer_->SetMinDistance(
00114 minimumDistance, DS3D_DEFERRED))){
00115 ErrorOut("Sound3D::setMinimumDistance() 最小距離の設定に失敗しました。");
00116 }
00117 minimumDistance_ = minimumDistance;
00118 }
00119
00120
00121 void Sound3D::setMaximumDistance(float maximumDistance){
00122 Assert(maximumDistance > 0.f);
00123 if(maximumDistance_ == maximumDistance){ return; }
00124 if(DirectXFailed(sound3DBuffer_->SetMaxDistance(
00125 maximumDistance, DS3D_DEFERRED))){
00126 ErrorOut("Sound3D::setMaximumDistance() "
00127 "最大距離の設定に失敗しました。");
00128 }
00129 maximumDistance_ = maximumDistance;
00130 }
00131
00132
00133 void Sound3D::setConeDirection(const Vector3& coneDirection){
00134 if(coneDirection_ == coneDirection){ return; }
00135 if(DirectXFailed(sound3DBuffer_->SetConeOrientation(
00136 -coneDirection.x, coneDirection.y, coneDirection.z, DS3D_DEFERRED))){
00137 ErrorOut("Sound3D::setConeDirection() "
00138 "コーンの向きの設定に失敗しました。");
00139 }
00140 coneDirection_ = coneDirection;
00141 }
00142
00143
00144 void Sound3D::setConeAngle(float insideConeAngle, float outsideConeAngle){
00145 if((insideConeAngle_ == insideConeAngle) &&
00146 (outsideConeAngle_ == outsideConeAngle)){ return; }
00147 Assert(insideConeAngle <= outsideConeAngle);
00148 Assert((insideConeAngle >= 0.f) && (insideConeAngle <= Math::doublePI));
00149 Assert((outsideConeAngle >= 0.f) && (outsideConeAngle <= Math::doublePI));
00150 if(DirectXFailed(sound3DBuffer_->SetConeAngles(
00151 (u_int)Math::toDegree(insideConeAngle),
00152 (u_int)Math::toDegree(outsideConeAngle), DS3D_DEFERRED))){
00153 ErrorOut("Sound3D::setConeAngle() コーン角度の設定に失敗しました。");
00154 }
00155 insideConeAngle_ = insideConeAngle;
00156 outsideConeAngle_ = outsideConeAngle;
00157 }
00158
00159
00160 void Sound3D::setConeOutsideVolume(float coneOutsideVolume){
00161 if(coneOutsideVolume_ == coneOutsideVolume){ return; }
00162 int db = volumeToDecibel(coneOutsideVolume);
00163 if(DirectXFailed(sound3DBuffer_->SetConeOutsideVolume(db, DS3D_DEFERRED))){
00164 ErrorOut("Sound3D::setConeOutsideVolume() "
00165 "コーン外側ボリュームの設定に失敗しました。");
00166 }
00167 coneOutsideVolume_ = coneOutsideVolume;
00168 }
00169
00170
00171 void Sound3D::set3DEnabled(bool enabled){
00172 if(is3DEnabled_ == enabled){ return; }
00173 u_int mode;
00174 if(enabled){ mode = DS3DMODE_NORMAL; }
00175 else{ mode = DS3DMODE_DISABLE; }
00176 if(DirectXFailed(sound3DBuffer_->SetMode(mode, DS3D_DEFERRED))){
00177 ErrorOut("Sound3D::set3DEnabled() 3Dの有効、無効設定に失敗しました。");
00178 }
00179 is3DEnabled_ = enabled;
00180 }
00181
00182
00183 void Sound3D::apply3DSettings(){
00184 LampSound::getSoundListener()->apply3DSettings();
00185 }
00186
00187
00188
00189
00190 void Sound3D::reset(Reset flags){
00191 SoundBuffer::reset(flags);
00192 if((flags & resetPosition) != 0){ setPosition(Vector3::zero); }
00193 if((flags & resetVelocity) != 0){ setVelocity(Vector3::zero); }
00194 if((flags & resetDistance) != 0){
00195 setDistance(DS3D_DEFAULTMINDISTANCE, DS3D_DEFAULTMAXDISTANCE);
00196 }
00197 if((flags & resetConeDirection) != 0){ setConeDirection(Vector3::unitZ); }
00198 if((flags & resetConeAngle) != 0){
00199 setConeAngle(Math::doublePI, Math::doublePI);
00200 }
00201 if((flags & resetConeOutsideVolume) != 0){ setConeOutsideVolume(1.f); }
00202 if((flags & reset3DEnabled) != 0){ set3DEnabled(true); }
00203 }
00204
00205
00206 String Sound3D::toString() const{
00207 String result, temp;
00208 result = SoundBuffer::toString();
00209 if(is3DEnabled_){
00210 result += "3D Enabled ";
00211 }else{
00212 result += "3D Disabled ";
00213 }
00214 temp.format("BufferSize(%7dbyte)\n", getBufferSize());
00215 result += temp;
00216 temp.format("Position ( %.1f, %.1f, %.1f )\n",
00217 position_.x, position_.y, position_.z);
00218 result += temp;
00219 temp.format("Velocity ( %.1f, %.1f, %.1f )\n",
00220 velocity_.x, velocity_.y, velocity_.z);
00221 result += temp;
00222 temp.format("Distance Min %.1f Max %.3f\n",
00223 minimumDistance_, maximumDistance_);
00224 result += temp;
00225 temp.format("ConeDirection ( %.2f, %.2f, %.2f )\n",
00226 coneDirection_.x, coneDirection_.y, coneDirection_.z);
00227 result += temp;
00228 temp.format("ConeAngle In %5.1f° Out %5.1f° OutVolume %.2f\n",
00229 Math::toDegree(insideConeAngle_), Math::toDegree(outsideConeAngle_),
00230 coneOutsideVolume_);
00231 result += temp;
00232
00233 return result;
00234 }
00235
00236 }
00237