Platform_Win32_Sound_SoundStream_DSound.cpp
Go to the documentation of this file.00001 //*** Platform_Win32_Sound_SoundStream_DSound.cpp *** 00002 00003 #include "Platform_Win32_Sound_SoundStream_DSound.h" 00004 #include "Platform_Win32_Sound.h" 00005 #include "Platform_OS.h" 00006 00007 //#define WIN32_LEAN_AND_MEAN 00008 #define VC_EXTRALEAN 00009 00010 // DirectX version 3 is enough for sound 00011 #define DIRECTSOUND_VERSION 0x0300 00012 #include <dsound.h> 00013 #include <math.h> 00014 00015 #define ErrMsg(expression,message) if (!(expression)) Platform::GetPlatform_OS()->OutputDebugText(message); 00016 00017 //*** Constructor *** 00018 00019 Platform_Win32_Sound_SoundStream_DSound::Platform_Win32_Sound_SoundStream_DSound(IDirectSound* directSound, int channels, int frequency, int bitsPerSample, int size): 00020 soundBuffer_(0), 00021 channels_(channels), 00022 frequency_(frequency), 00023 bitsPerSample_(bitsPerSample), 00024 size_(size), 00025 volume_(1.0f) 00026 { 00027 // Set up wave format structure. 00028 WAVEFORMATEX format; 00029 memset(&format, 0, sizeof(WAVEFORMATEX)); 00030 format.wFormatTag=WAVE_FORMAT_PCM; 00031 format.nChannels=(WORD)channels; 00032 format.nSamplesPerSec=(DWORD)frequency; 00033 format.nBlockAlign=(WORD)((channels*bitsPerSample)/8); 00034 format.nAvgBytesPerSec=(DWORD)(frequency * format.nBlockAlign); 00035 format.wBitsPerSample=(WORD)bitsPerSample; 00036 format.cbSize=0; 00037 00038 // Set up DSBUFFERDESC structure. 00039 DSBUFFERDESC dsbdesc; 00040 memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // Zero it out. 00041 dsbdesc.dwSize=sizeof(DSBUFFERDESC); 00042 00043 // Need default controls (pan, volume, frequency). 00044 dsbdesc.dwFlags=DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; 00045 00046 dsbdesc.dwBufferBytes=size; 00047 dsbdesc.lpwfxFormat=&format; 00048 00049 // Create buffer. 00050 HRESULT hr; 00051 hr=directSound->CreateSoundBuffer(&dsbdesc, &soundBuffer_, NULL); 00052 ErrMsg(SUCCEEDED(hr),"Couldn't create sound buffer\n"); 00053 } 00054 00055 00056 //*** Destructor *** 00057 00058 Platform_Win32_Sound_SoundStream_DSound::~Platform_Win32_Sound_SoundStream_DSound() 00059 { 00060 if (soundBuffer_) 00061 { 00062 soundBuffer_->Release(); 00063 } 00064 } 00065 00066 00067 void Platform_Win32_Sound_SoundStream_DSound::Play() 00068 { 00069 if (soundBuffer_) 00070 { 00071 soundBuffer_->Play(0,0,DSBPLAY_LOOPING); 00072 } 00073 } 00074 00075 00076 //*** Stop *** 00077 00078 void Platform_Win32_Sound_SoundStream_DSound::Stop() 00079 { 00080 if (soundBuffer_) 00081 { 00082 soundBuffer_->Stop(); 00083 } 00084 } 00085 00086 00087 //*** GetPosition *** 00088 00089 int Platform_Win32_Sound_SoundStream_DSound::GetPosition() 00090 { 00091 DWORD position=0; 00092 if (soundBuffer_) 00093 { 00094 soundBuffer_->GetCurrentPosition(&position,0); 00095 } 00096 return (int)position; 00097 } 00098 00099 00100 //*** SetPosition *** 00101 00102 void Platform_Win32_Sound_SoundStream_DSound::SetPosition(int position) 00103 { 00104 if (soundBuffer_) 00105 { 00106 soundBuffer_->SetCurrentPosition(position); 00107 } 00108 } 00109 00110 00111 //*** CopySoundToBuffer *** 00112 00113 void Platform_Win32_Sound_SoundStream_DSound::CopySoundToBuffer(int bufferOffset, const void* soundData, int bytesToCopy) 00114 { 00115 if (!soundBuffer_) 00116 { 00117 return; 00118 } 00119 00120 // Check the range of the bytesToCopy parameter 00121 ErrMsg((bufferOffset+bytesToCopy)<=size_,"Sound buffer out of range\n"); 00122 00123 // Obtain memory address of write block. This will be in two parts 00124 // if the block wraps around. 00125 LPVOID lpvPtr1; 00126 DWORD dwBytes1; 00127 LPVOID lpvPtr2; 00128 DWORD dwBytes2; 00129 HRESULT hr = soundBuffer_->Lock(bufferOffset, bytesToCopy, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); 00130 00131 // If DSERR_BUFFERLOST is returned, restore and retry lock. 00132 if (hr==DSERR_BUFFERLOST) 00133 { 00134 soundBuffer_->Restore(); 00135 hr = soundBuffer_->Lock(bufferOffset, bytesToCopy, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); 00136 } 00137 ErrMsg(SUCCEEDED(hr),"Couldn't lock sound buffer\n"); 00138 00139 // Write to pointers. 00140 CopyMemory(lpvPtr1, soundData, dwBytes1); 00141 if(lpvPtr2) 00142 { 00143 CopyMemory(lpvPtr2, static_cast<const char*>(soundData)+dwBytes1, dwBytes2); 00144 } 00145 00146 // Release the data back to DirectSound. 00147 hr=soundBuffer_->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); 00148 ErrMsg(SUCCEEDED(hr),"Couldn't unlock sound buffer\n"); 00149 } 00150 00151 00152 //*** ClearBuffer *** 00153 00154 void Platform_Win32_Sound_SoundStream_DSound::ClearBuffer(int bufferOffset, int bytesToClear) 00155 { 00156 if (!soundBuffer_) 00157 { 00158 } 00159 // Check the range of the bytesToClear parameter 00160 ErrMsg((bufferOffset+bytesToClear)<=size_,"Sound buffer out of range\n"); 00161 00162 // Obtain memory address of write block. This will be in two parts 00163 // if the block wraps around. 00164 LPVOID lpvPtr1; 00165 DWORD dwBytes1; 00166 LPVOID lpvPtr2; 00167 DWORD dwBytes2; 00168 HRESULT hr = soundBuffer_->Lock(bufferOffset, bytesToClear, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); 00169 00170 // If DSERR_BUFFERLOST is returned, restore and retry lock. 00171 if (hr==DSERR_BUFFERLOST) 00172 { 00173 soundBuffer_->Restore(); 00174 hr = soundBuffer_->Lock(bufferOffset, bytesToClear, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); 00175 } 00176 ErrMsg(SUCCEEDED(hr),"Couldn't lock sound buffer\n"); 00177 00178 // Write to pointers. 00179 FillMemory(lpvPtr1, dwBytes1,0); 00180 if(lpvPtr2) 00181 { 00182 FillMemory(lpvPtr2, dwBytes2, 0); 00183 } 00184 00185 // Release the data back to DirectSound. 00186 hr=soundBuffer_->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); 00187 ErrMsg(SUCCEEDED(hr),"Couldn't unlock sound buffer\n"); 00188 } 00189 00190 00191 //*** GetChannels *** 00192 00193 int Platform_Win32_Sound_SoundStream_DSound::GetChannels() 00194 { 00195 return channels_; 00196 } 00197 00198 00199 //*** GetFrequency *** 00200 00201 int Platform_Win32_Sound_SoundStream_DSound::GetFrequency() 00202 { 00203 return frequency_; 00204 } 00205 00206 00207 //*** GetBitsPerSample *** 00208 00209 int Platform_Win32_Sound_SoundStream_DSound::GetBitsPerSample() 00210 { 00211 return bitsPerSample_; 00212 } 00213 00214 00215 //*** GetSize *** 00216 00217 int Platform_Win32_Sound_SoundStream_DSound::GetSize() 00218 { 00219 return size_; 00220 } 00221 00222 00223 //*** ConvertLinearLevelToDirectSoundLevel *** 00224 00225 int Platform_Win32_Sound_SoundStream_DSound::ConvertLinearLevelToDirectSoundLevel(float level) 00226 { 00227 if (level<0.0001f) 00228 { 00229 return -DSBVOLUME_MIN; 00230 } 00231 return (int)(2000.0f*log10f(level)); 00232 } 00233 00234 00235 00236 00237 //*** SetVolume *** 00238 00239 void Platform_Win32_Sound_SoundStream_DSound::SetVolume(float level) 00240 { 00241 volume_=level; 00242 if (soundBuffer_) 00243 { 00244 LONG value=ConvertLinearLevelToDirectSoundLevel(level); 00245 soundBuffer_->SetVolume(value); 00246 } 00247 } 00248 00249 00250 //*** GetVolume *** 00251 00252 float Platform_Win32_Sound_SoundStream_DSound::GetVolume() 00253 { 00254 return volume_; 00255 }
Reproduction/republishing of any material on this site without permission is strictly prohibited.
