From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- .../nel/sound__driver__dsound_8cpp-source.html | 895 +++++++++++++++++++++ 1 file changed, 895 insertions(+) create mode 100644 docs/doxygen/nel/sound__driver__dsound_8cpp-source.html (limited to 'docs/doxygen/nel/sound__driver__dsound_8cpp-source.html') diff --git a/docs/doxygen/nel/sound__driver__dsound_8cpp-source.html b/docs/doxygen/nel/sound__driver__dsound_8cpp-source.html new file mode 100644 index 00000000..380a238d --- /dev/null +++ b/docs/doxygen/nel/sound__driver__dsound_8cpp-source.html @@ -0,0 +1,895 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

sound_driver_dsound.cpp

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2001 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 
+00027 // The one and only INITGUID
+00028 #define INITGUID
+00029 
+00030 #include "stddsound.h"
+00031 
+00032 
+00033 #include "sound_driver_dsound.h"
+00034 #include "listener_dsound.h"
+00035 #include <math.h>
+00036 
+00037 
+00038 using namespace std;
+00039 using namespace NLMISC;
+00040 
+00041 
+00042 namespace NLSOUND {
+00043 
+00044 CSoundDriverDSound* CSoundDriverDSound::_Instance = NULL;
+00045 uint32 CSoundDriverDSound::_TimerPeriod = 100;
+00046 HINSTANCE CSoundDriverDllHandle = 0;
+00047 HWND CSoundDriverWnd = 0;
+00048 
+00049 
+00050 // ******************************************************************
+00051 // The main entry of the DLL. It's used to get a hold of the hModule handle.
+00052 
+00053 BOOL WINAPI DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+00054 {
+00055   CSoundDriverDllHandle = (HINSTANCE) hModule;
+00056   return TRUE;
+00057 }
+00058 
+00059 
+00060 // ******************************************************************
+00061 // The event handling procedure of the invisible window created below. 
+00062 
+00063 long FAR PASCAL CSoundDriverCreateWindowProc(HWND hWnd, unsigned message, WPARAM wParam, LPARAM lParam)
+00064 {
+00065     return DefWindowProc(hWnd, message, wParam, lParam);
+00066 }
+00067 
+00068 // ******************************************************************
+00069 
+00070 __declspec(dllexport) ISoundDriver *NLSOUND_createISoundDriverInstance()
+00071 {
+00072         static bool Registered = false;
+00073 
+00074         if (!Registered)
+00075         {
+00076                 // Don't ask me why we have to create a window to do sound!
+00077                 // echo <your comment> | mail support@microsoft.com -s "F#%@cking window"
+00078                 WNDCLASS myClass;
+00079                 myClass.hCursor = LoadCursor( NULL, IDC_ARROW );
+00080                 myClass.hIcon = NULL; 
+00081                 myClass.lpszMenuName = (LPSTR) NULL;
+00082                 myClass.lpszClassName = (LPSTR) "CSoundDriver";
+00083                 myClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
+00084                 myClass.hInstance = CSoundDriverDllHandle;
+00085                 myClass.style = CS_GLOBALCLASS;
+00086                 myClass.lpfnWndProc = CSoundDriverCreateWindowProc;
+00087                 myClass.cbClsExtra = 0;
+00088                 myClass.cbWndExtra = 0;
+00089 
+00090                 if (!RegisterClass(&myClass)) 
+00091                 {
+00092                         nlwarning("Failed to initialize the sound driver (RegisterClass)");
+00093                         return 0;
+00094                 }
+00095 
+00096                 Registered = true;
+00097         }
+00098 
+00099         CSoundDriverWnd = CreateWindow((LPSTR) "CSoundDriver", (LPSTR) "CSoundDriver", WS_OVERLAPPEDWINDOW,
+00100                                                                         CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, (HWND) NULL, (HMENU) NULL, 
+00101                                                                         CSoundDriverDllHandle, (LPSTR) NULL);  
+00102 
+00103         if (CSoundDriverWnd == NULL)
+00104         {
+00105                 nlwarning("Failed to initialize the sound driver (CreateWindow)");
+00106                 return 0;
+00107         }
+00108         
+00109         CSoundDriverDSound *driver = new CSoundDriverDSound();
+00110         driver->init(CSoundDriverWnd);
+00111 
+00112         return driver;
+00113 }
+00114 
+00115 // ******************************************************************
+00116 
+00117 __declspec(dllexport) uint32 NLSOUND_interfaceVersion()
+00118 {
+00119         return ISoundDriver::InterfaceVersion;
+00120 }
+00121 
+00122 // ******************************************************************
+00123 
+00124 __declspec(dllexport) void NLSOUND_outputProfile(ostream &out)
+00125 {
+00126         CSoundDriverDSound::instance()->writeProfile(out);
+00127 }
+00128 
+00129 
+00130 
+00131 
+00132 
+00133 // ******************************************************************
+00134 
+00135 CSoundDriverDSound::CSoundDriverDSound() : ISoundDriver()
+00136 {
+00137         if ( _Instance == NULL )
+00138         {
+00139                 _Instance = this;
+00140 
+00141         _DirectSound = NULL;
+00142         _PrimaryBuffer = NULL;
+00143         _SourceCount = 0;
+00144         _TimerID = NULL;
+00145 
+00146 #if NLSOUND_PROFILE
+00147         _TimerIntervalCount = 0;
+00148         _TotalTime = 0.0;
+00149         _TotalUpdateTime = 0.0;
+00150                 _UpdateCount = 0;
+00151                 _UpdateSources = 0;
+00152                 _UpdateExec = 0;
+00153 #endif
+00154 
+00155     }
+00156         else
+00157         {
+00158                 nlerror("Sound driver singleton instanciated twice");
+00159         }
+00160 }
+00161 
+00162 // ******************************************************************
+00163 
+00164 CSoundDriverDSound::~CSoundDriverDSound()
+00165 {
+00166         nldebug("Destroying DirectSound driver");
+00167 
+00168     if (_TimerID != NULL)
+00169     {
+00170         timeKillEvent(_TimerID);
+00171         timeEndPeriod(_TimerResolution); 
+00172     }
+00173 
+00174 
+00175         // Assure that the remaining sources have released all their DSBuffers 
+00176         // before closing down DirectSound
+00177         set<CSourceDSound*>::iterator iter;
+00178 
+00179         for (iter = _Sources.begin(); iter != _Sources.end(); iter++)
+00180         {
+00181                 (*iter)->release();
+00182         }
+00183 
+00184 
+00185         // Assure that the listener has released all resources before closing 
+00186         // down DirectSound
+00187         if (CListenerDSound::instance() != 0)
+00188         {
+00189                 CListenerDSound::instance()->release();
+00190         }
+00191 
+00192 
+00193     if (_PrimaryBuffer != NULL) 
+00194     {
+00195         _PrimaryBuffer->Release(); 
+00196         _PrimaryBuffer = NULL;
+00197     }
+00198 
+00199     if (_DirectSound != NULL) 
+00200     {
+00201         _DirectSound->Release(); 
+00202         _DirectSound = NULL;
+00203     }
+00204 
+00205         _Instance = 0;
+00206 }
+00207 
+00208 // ******************************************************************
+00209 
+00210 class CDeviceDescription
+00211 {
+00212 public:
+00213 
+00214     static CDeviceDescription* _List;
+00215 
+00216     CDeviceDescription(LPGUID guid, const char* descr) 
+00217     {
+00218         _Guid = guid;
+00219         _Description = strdup(descr);
+00220         _Next = _List;
+00221         _List = this;
+00222     }
+00223 
+00224     virtual ~CDeviceDescription()
+00225     {
+00226         if (_Description) 
+00227         {
+00228             free(_Description);
+00229         }
+00230         if (_Next)
+00231         {
+00232             delete _Next;
+00233         }
+00234     }
+00235 
+00236     char* _Description;
+00237     CDeviceDescription* _Next;
+00238     LPGUID _Guid;
+00239 };
+00240 
+00241 CDeviceDescription* CDeviceDescription::_List = 0;
+00242 
+00243 
+00244 BOOL CALLBACK CSoundDriverDSoundEnumCallback(LPGUID guid, LPCSTR description, PCSTR module, LPVOID context)
+00245 {
+00246     new CDeviceDescription(guid, description);
+00247     return TRUE;
+00248 }
+00249 
+00250 // ******************************************************************
+00251 
+00252 bool CSoundDriverDSound::init(HWND wnd)
+00253 {
+00254     if (FAILED(DirectSoundEnumerate(CSoundDriverDSoundEnumCallback, this)))
+00255     {
+00256         throw ESoundDriver("Failed to enumerate the DirectSound devices");
+00257     }
+00258 
+00259     // Create a DirectSound object and set the cooperative level.
+00260 
+00261     if (DirectSoundCreate(NULL, &_DirectSound, NULL) != DS_OK) 
+00262     {
+00263         throw ESoundDriver("Failed to create the DirectSound object");
+00264     }
+00265 
+00266 
+00267     if (_DirectSound->SetCooperativeLevel(wnd, DSSCL_PRIORITY) != DS_OK) 
+00268     {
+00269         throw ESoundDriver("Failed to set the cooperative level");
+00270     }
+00271 
+00272 
+00273     // Analyse the capabilities of the sound driver/device
+00274 
+00275     _Caps.dwSize = sizeof(_Caps); 
+00276 
+00277     if (_DirectSound->GetCaps(&_Caps) != DS_OK)  
+00278     {
+00279         throw ESoundDriver("Failed to query the sound device caps");
+00280     }
+00281 
+00282 
+00283     // Create primary buffer 
+00284  
+00285     DSBUFFERDESC desc;
+00286 
+00287     ZeroMemory(&desc, sizeof(DSBUFFERDESC));
+00288     desc.dwSize = sizeof(DSBUFFERDESC);
+00289 
+00290 
+00291     // First, try to allocate a 3D hardware buffer.
+00292     // If we can't get a 3D hardware buffer, use a 2D hardware buffer.
+00293     // As last option, use a 2D software buffer.
+00294 
+00295     if (countHw3DBuffers() > 0) 
+00296     {
+00297                 nldebug("Primary buffer: Allocating 3D buffer in hardware");
+00298         desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_LOCHARDWARE | DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME;
+00299     } 
+00300     else
+00301     {
+00302                 nldebug("Primary buffer: Allocating 3D buffer in software");
+00303         desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME;
+00304         desc.guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION;
+00305     }
+00306 
+00307 
+00308     if (_DirectSound->CreateSoundBuffer(&desc, &_PrimaryBuffer, NULL) != DS_OK) 
+00309     {
+00310 
+00311                 nlwarning("Primary buffer: Failed to create a buffer with 3D capabilities.");
+00312 
+00313                 ZeroMemory(&desc, sizeof(DSBUFFERDESC));
+00314                 desc.dwSize = sizeof(DSBUFFERDESC);
+00315 
+00316                 if (countHw2DBuffers() > 0) 
+00317                 {
+00318                         nldebug("Primary buffer: Allocating 2D buffer in hardware");
+00319                         desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_LOCHARDWARE | DSBCAPS_CTRLVOLUME;
+00320                 } 
+00321                 else
+00322                 {
+00323                         nldebug("Primary buffer: Allocating 2D buffer in software");
+00324                         desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLVOLUME;
+00325                 }
+00326 
+00327                 if (_DirectSound->CreateSoundBuffer(&desc, &_PrimaryBuffer, NULL) != DS_OK) 
+00328                 {
+00329                         throw ESoundDriver("Failed to create the primary buffer");
+00330                 }
+00331     }
+00332 
+00333 
+00334     // Set the format of the primary buffer
+00335 
+00336     WAVEFORMATEX format;
+00337 
+00338     format.cbSize = sizeof(WAVEFORMATEX);
+00339 
+00340     // Make sure the sound card accepts the default settings.
+00341     // For now, only the default settings are accepted. Fallback
+00342     // strategy will be handled later.
+00343 
+00344     if ((_Caps.dwMinSecondarySampleRate > 22050) && (22050 > _Caps.dwMaxSecondarySampleRate)) {
+00345         throw ESoundDriver("Unsupported sample rate range");        
+00346     }   
+00347 
+00348     if ((_Caps.dwFlags & DSCAPS_PRIMARY16BIT) == 0) {
+00349         throw ESoundDriver("Unsupported sample size [16bits]");        
+00350     }   
+00351 
+00352     format.wBitsPerSample = 16;
+00353     format.nChannels = 1;
+00354     format.nSamplesPerSec = 22050;
+00355     format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
+00356     format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
+00357     format.wFormatTag = WAVE_FORMAT_PCM;
+00358 
+00359 
+00360     if (_PrimaryBuffer->SetFormat(&format) != DS_OK) 
+00361     {
+00362         throw ESoundDriver("Failed to create set the format of the primary buffer");
+00363     }
+00364 
+00365 
+00366     uint32 numBuffers = countHw3DBuffers();
+00367         if (numBuffers == 0)
+00368         {
+00369                 numBuffers = 31;
+00370         }
+00371 
+00372         /*
+00373     _Sources = new CSourceDSound*[numBuffers];
+00374 
+00375 
+00376         for (uint i = 0; i < numBuffers; i++) 
+00377         {
+00378                 _Sources[i] = 0;
+00379         }
+00380 
+00381         try
+00382         {
+00383             for (i = 0; i < numBuffers; i++) 
+00384                 {
+00385                         _Sources[i] = new CSourceDSound(i);
+00386                         _Sources[i]->init(_DirectSound);
+00387                         _SourceCount++;
+00388                 }
+00389         }
+00390         catch (ESoundDriver& e)
+00391         {
+00392                 // Okay, here's the situation: I'm listening to WinAmp while debugging.
+00393                 // The caps told me there were 31 buffers available. In reality, there were
+00394                 // only 30 available because WinAmp was using one. Somehow DirectSound didn't
+00395                 // notice. So when creating buffer 31, an exception was thrown. 
+00396                 // If something like this happens, don't bother and go on with the buffers we've 
+00397                 // got. If no buffers are created at all, throw the exception again.
+00398 
+00399                 if (_Sources == 0)
+00400                 {
+00401                         throw e;
+00402                 }
+00403         }
+00404 
+00405 */
+00406 
+00407 
+00408     TIMECAPS tcaps;
+00409     
+00410     timeGetDevCaps(&tcaps, sizeof(TIMECAPS));
+00411     _TimerResolution = (tcaps.wPeriodMin > 10)? tcaps.wPeriodMin : 10;
+00412     timeBeginPeriod(_TimerResolution); 
+00413 
+00414 
+00415 
+00416 #if NLSOUND_PROFILE
+00417     for (uint i = 0; i < 1024; i++)
+00418     {
+00419         _TimerInterval[i] = 0;
+00420     }
+00421 
+00422     _TimerDate = CTime::getPerformanceTime();
+00423 #endif
+00424 
+00425 
+00426 
+00427 
+00428     _TimerID = timeSetEvent(_TimerPeriod, 0, &CSoundDriverDSound::TimerCallback, (DWORD)this, TIME_CALLBACK_FUNCTION | TIME_PERIODIC);
+00429 
+00430     if (_TimerID == NULL)
+00431     {
+00432         throw ESoundDriver("Failed to create the timer");
+00433     }
+00434 
+00435         
+00436 
+00437 
+00438     return true;
+00439 }
+00440 
+00441 // ******************************************************************
+00442 
+00443 uint CSoundDriverDSound::countMaxSources()
+00444 {
+00445         // Try the hardware 3d buffers first
+00446         uint n = countHw3DBuffers();
+00447         if (n > 0) 
+00448         {
+00449                 return n;
+00450         }
+00451 
+00452         // If not, try the hardware 2d buffers first
+00453         n = countHw2DBuffers();
+00454         if (n > 0)
+00455         {
+00456                 return n;
+00457         }
+00458 
+00459         // Okay, we'll use 32 software buffers
+00460         return 32;
+00461 }
+00462 
+00463 // ******************************************************************
+00464 
+00465 void CSoundDriverDSound::writeProfile(ostream& out)
+00466 {
+00467     // Write the available sound devices
+00468     CDeviceDescription* list = CDeviceDescription::_List;
+00469     while (list) {
+00470                 out << list->_Description << "\n";
+00471         list = list->_Next;
+00472     }
+00473 
+00474     out << "\n";
+00475 
+00476     // Write the buffers sizes
+00477     out << "buffer size: " << CSourceDSound::_SecondaryBufferSize << "\n";
+00478     out << "copy size: " << CSourceDSound::_UpdateCopySize << "\n";
+00479     out << "swap size: " << CSourceDSound::_SwapCopySize << "\n";
+00480     out << "\n";
+00481 
+00482     // Write the number of hardware buffers 
+00483     DSCAPS caps;
+00484     caps.dwSize = sizeof(caps); 
+00485     _DirectSound->GetCaps(&caps);  
+00486 
+00487     cout << "3d hw buffers: " << caps.dwMaxHw3DAllBuffers << "\n";
+00488         cout << "2d hw buffers: " << caps.dwMaxHwMixingAllBuffers << "\n";
+00489     out << "\n";
+00490 
+00491     // Write the number of hardware buffers 
+00492 #if NLSOUND_PROFILE
+00493     out << "update time total --- " <<  getAverageUpdateTime()<< "\n";
+00494         out << "update time source --- " << CSourceDSound::getAverageUpdateTime() << "\n";
+00495         out << "update --- t: " << CSourceDSound::getAverageCumulTime();
+00496         out << " - p: " << CSourceDSound::getAveragePosTime();
+00497         out << " - l: " << CSourceDSound::getAverageLockTime();
+00498         out << " - c: " << CSourceDSound::getAverageCopyTime();
+00499         out << " - u: " << CSourceDSound::getAverageUnlockTime() << "\n";
+00500         out << "update percentage: --- " << getUpdatePercentage() << "\n";
+00501         out << "update num sources --- " << getAverageUpdateSources() << "\n";
+00502         out << "update byte size --- " << CSourceDSound::getAverageUpdateSize() << "\n";
+00503         out << "swap time --- " << CSourceDSound::getTestAverage() << "\n";
+00504         out << "src --- " << countPlayingSources() << "\n";
+00505 #endif
+00506 }
+00507 
+00508 
+00509 void CALLBACK CSoundDriverDSound::TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+00510 {
+00511     CSoundDriverDSound* driver = (CSoundDriverDSound*) dwUser;
+00512     driver->update();
+00513 }
+00514 
+00515 // ******************************************************************
+00516 
+00517 void CSoundDriverDSound::update()
+00518 {
+00519 #if NLSOUND_PROFILE
+00520     TTicks now = CTime::getPerformanceTime();
+00521 #endif
+00522 
+00523         set<CSourceDSound*>::iterator iter;
+00524 
+00525         iter = _Sources.begin();
+00526 
+00527         if ((iter != _Sources.end()) && (*iter)->needsUpdate())
+00528         {
+00529                 while (iter != _Sources.end())
+00530                 {
+00531                         if ((*iter)->update2()) {
+00532 #if NLSOUND_PROFILE
+00533                                 _UpdateSources++;
+00534 #endif
+00535                         }
+00536                         iter++;
+00537                 }
+00538         }
+00539 
+00540 
+00541 #if NLSOUND_PROFILE
+00542     _TotalUpdateTime += 1000.0 * CTime::ticksToSecond(CTime::getPerformanceTime() - now);
+00543         _UpdateCount++;
+00544 #endif
+00545 }
+00546 
+00547 // ******************************************************************
+00548 
+00549 uint CSoundDriverDSound::countHw3DBuffers()
+00550 {
+00551     DSCAPS caps;
+00552     caps.dwSize = sizeof(caps); 
+00553 
+00554     if (_DirectSound->GetCaps(&caps) != DS_OK)  
+00555     {
+00556         throw ESoundDriver("Failed to query the sound device caps");
+00557     }
+00558 
+00559     return caps.dwFreeHw3DStreamingBuffers;
+00560 }
+00561 
+00562 // ******************************************************************
+00563 
+00564 uint CSoundDriverDSound::countHw2DBuffers()
+00565 {
+00566     DSCAPS caps;
+00567     caps.dwSize = sizeof(caps); 
+00568 
+00569     if (_DirectSound->GetCaps(&caps) != DS_OK)  
+00570     {
+00571         throw ESoundDriver("Failed to query the sound device caps");
+00572     }
+00573 
+00574     return caps.dwFreeHwMixingStreamingBuffers;
+00575 }
+00576 
+00577 // ******************************************************************
+00578 
+00579 IListener *CSoundDriverDSound::createListener()
+00580 {
+00581     LPDIRECTSOUND3DLISTENER dsoundListener;
+00582 
+00583     if (CListenerDSound::instance() != NULL) 
+00584     {
+00585         return CListenerDSound::instance();
+00586     }
+00587 
+00588     if (_PrimaryBuffer == 0) 
+00589     {
+00590         throw ESoundDriver("Corrupt driver");
+00591     }
+00592 
+00593     if (FAILED(_PrimaryBuffer->QueryInterface(IID_IDirectSound3DListener, (LPVOID *) &dsoundListener)))
+00594     {
+00595                 nlwarning("The 3D listener interface is not available.");
+00596         return new CListenerDSound(NULL);
+00597     }
+00598 
+00599     return new CListenerDSound(dsoundListener);
+00600 }
+00601 
+00602 // ******************************************************************
+00603 
+00604 IBuffer *CSoundDriverDSound::createBuffer()
+00605 {
+00606     if (_PrimaryBuffer == 0) 
+00607     {
+00608         throw ESoundDriver("Corrupt driver");
+00609     }
+00610 
+00611 
+00612     // FIXME: set buffer ID
+00613     return new CBufferDSound();   
+00614 }
+00615 
+00616 // ******************************************************************
+00617 
+00618 void CSoundDriverDSound::removeBuffer(IBuffer *buffer)
+00619 {
+00620 }
+00621 
+00622 // ******************************************************************
+00623 
+00624 bool CSoundDriverDSound::loadWavFile(IBuffer *destbuffer, const char *filename)
+00625 {
+00626         return ((CBufferDSound*) destbuffer)->loadWavFile(filename);
+00627 }
+00628 
+00629 // ******************************************************************
+00630 
+00631 ISource *CSoundDriverDSound::createSource()
+00632 {
+00633     if (_PrimaryBuffer == 0) 
+00634     {
+00635         throw ESoundDriver("Corrupt driver");
+00636     }
+00637 
+00638 
+00639         CSourceDSound* src = new CSourceDSound(0);
+00640         src->init(_DirectSound);
+00641         _Sources.insert(src);
+00642 
+00643         return src;
+00644 }
+00645 
+00646 
+00647 // ******************************************************************
+00648 
+00649 void CSoundDriverDSound::removeSource(ISource *source)
+00650 {
+00651         _Sources.erase((CSourceDSound*) source);
+00652 }
+00653 
+00654 // ******************************************************************
+00655 
+00656 void CSoundDriverDSound::commit3DChanges()
+00657 {
+00658         CListenerDSound* listener = CListenerDSound::instance();
+00659         listener->commit3DChanges();
+00660 
+00661 
+00662         const CVector &origin = listener->getPos();
+00663 
+00664         set<CSourceDSound*>::iterator iter;
+00665 
+00666         // We handle the volume of the source according to the distance
+00667         // ourselves. Call updateVolume() to, well..., update the volume
+00668         // according to, euh ..., the new distance!
+00669         for (iter = _Sources.begin(); iter != _Sources.end(); iter++)
+00670         {
+00671                 if ((*iter)->isPlaying()) 
+00672                 {
+00673                         (*iter)->updateVolume(origin);
+00674                 }
+00675         }
+00676 }
+00677 
+00678 
+00679 // ******************************************************************
+00680 
+00681 uint CSoundDriverDSound::countPlayingSources()
+00682 {
+00683     uint n = 0;
+00684         set<CSourceDSound*>::iterator iter;
+00685 
+00686         for (iter = _Sources.begin(); iter != _Sources.end(); iter++)
+00687         {
+00688                 if ((*iter)->isPlaying()) 
+00689                 {
+00690                         n++;
+00691                 }
+00692         }
+00693 
+00694     return n;
+00695 }
+00696 
+00697 
+00698 // ******************************************************************
+00699 
+00700 void CSoundDriverDSound::setGain( float gain )
+00701 {
+00702         if (_PrimaryBuffer != 0)
+00703         {
+00704                 if (gain < 0.00001f)
+00705                 {
+00706                         gain = 0.00001f;
+00707                 }
+00708 
+00709                 /* convert from linear amplitude to hundredths of decibels */
+00710                 LONG volume = (LONG)(100.0 * 20.0 * log10(gain));
+00711 
+00712                 if (volume < DSBVOLUME_MIN) 
+00713                 {
+00714                         volume = DSBVOLUME_MIN;
+00715                 }
+00716                 else if (volume > DSBVOLUME_MAX) 
+00717                 {
+00718                         volume = DSBVOLUME_MAX;
+00719                 }
+00720 
+00721                 HRESULT hr = _PrimaryBuffer->SetVolume(volume);
+00722 
+00723                 if (hr != DS_OK)
+00724                 {
+00725                         nldebug("Failed to set the volume");
+00726                 }
+00727         }
+00728 }
+00729 
+00730 // ******************************************************************
+00731 
+00732 float CSoundDriverDSound::getGain()
+00733 {
+00734         if (_PrimaryBuffer != 0)
+00735         {
+00736                 /* convert from hundredths of decibels to linear amplitude */
+00737                 LONG volume;
+00738                 HRESULT hr = _PrimaryBuffer->GetVolume(&volume);
+00739 
+00740                 if (hr != DS_OK)
+00741                 {
+00742                         nldebug("Failed to get the volume");
+00743                         return 1.0;
+00744                 }
+00745 
+00746                 return (float) pow(10, (double) volume / 20.0 / 100.0);
+00747         }
+00748 
+00749         return 1.0;
+00750 }
+00751 
+00752 
+00753 
+00754 #if NLSOUND_PROFILE
+00755 
+00756 // ******************************************************************
+00757 
+00758 uint CSoundDriverDSound::countTimerIntervals()
+00759 {
+00760     return 1024;
+00761 }
+00762 
+00763 // ******************************************************************
+00764 
+00765 uint CSoundDriverDSound::getTimerIntervals(uint index)
+00766 {           
+00767     return _TimerInterval[index];
+00768 }
+00769 
+00770 // ******************************************************************
+00771 
+00772 void CSoundDriverDSound::addTimerInterval(uint32 dt) 
+00773 {
+00774     if (_TimerIntervalCount >= 1024)
+00775     {
+00776         _TimerIntervalCount = 0;
+00777     }
+00778 
+00779     _TimerInterval[_TimerIntervalCount++] = dt;
+00780 }
+00781 
+00782 // ******************************************************************
+00783 
+00784 double CSoundDriverDSound::getCPULoad()
+00785 {
+00786     return (_TotalTime > 0.0)? 100.0 * _TotalUpdateTime / _TotalTime : 0.0;  
+00787 }
+00788 
+00789 // ******************************************************************
+00790 
+00791 void CSoundDriverDSound::printDriverInfo(FILE* fp)
+00792 {
+00793     CDeviceDescription* list = CDeviceDescription::_List;
+00794 
+00795     while (list) {
+00796         fprintf(fp, "%s\n", list->_Description);
+00797         list = list->_Next;
+00798     }
+00799 
+00800     fprintf(fp, "\n");
+00801 
+00802     fprintf(fp, "buffer size: %d\n"
+00803                                 "copy size: %d\n"
+00804                                 "swap size: %d\n", 
+00805                         CSourceDSound::_SecondaryBufferSize,
+00806                         CSourceDSound::_UpdateCopySize,
+00807                         CSourceDSound::_SwapCopySize);
+00808 
+00809     fprintf(fp, "\n");
+00810 
+00811     DSCAPS caps;
+00812     caps.dwSize = sizeof(caps); 
+00813 
+00814     if (_DirectSound->GetCaps(&caps) != DS_OK)  
+00815     {
+00816         throw ESoundDriver("Failed to query the sound device caps");
+00817     }
+00818 
+00819     
+00820     fprintf(fp, "3d hw buffers: %d\n" "2d hw buffers: %d\n\n", caps.dwMaxHw3DAllBuffers, caps.dwMaxHwMixingAllBuffers);
+00821 }
+00822 
+00823 #endif
+00824 
+00825 
+00826 } // NLSOUND
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1