Isle
Loading...
Searching...
No Matches
mxsoundmanager.cpp
Go to the documentation of this file.
1#include "mxsoundmanager.h"
2
3#include "mxautolock.h"
4#include "mxdsaction.h"
5#include "mxmisc.h"
6#include "mxomni.h"
7#include "mxpresenter.h"
8#include "mxticklemanager.h"
9#include "mxticklethread.h"
10#include "mxwavepresenter.h"
11
13
14// GLOBAL LEGO1 0x10101420
15MxS32 g_volumeAttenuation[100] = {-6643, -5643, -5058, -4643, -4321, -4058, -3836, -3643, -3473, -3321, -3184, -3058,
16 -2943, -2836, -2736, -2643, -2556, -2473, -2395, -2321, -2251, -2184, -2120, -2058,
17 -2000, -1943, -1888, -1836, -1785, -1736, -1689, -1643, -1599, -1556, -1514, -1473,
18 -1434, -1395, -1358, -1321, -1286, -1251, -1217, -1184, -1152, -1120, -1089, -1058,
19 -1029, -1000, -971, -943, -915, -888, -862, -836, -810, -785, -761, -736,
20 -713, -689, -666, -643, -621, -599, -577, -556, -535, -514, -494, -473,
21 -454, -434, -415, -395, -377, -358, -340, -321, -304, -286, -268, -251,
22 -234, -217, -200, -184, -168, -152, -136, -120, -104, -89, -74, -58,
23 -43, -29, -14, 0};
24
25// FUNCTION: LEGO1 0x100ae740
27{
28 Init();
29}
30
31// FUNCTION: LEGO1 0x100ae7d0
33{
35}
36
37// FUNCTION: LEGO1 0x100ae830
39{
42}
43
44// FUNCTION: LEGO1 0x100ae840
45void MxSoundManager::Destroy(MxBool p_fromDestructor)
46{
47 if (m_thread) {
49 delete m_thread;
50 }
51 else {
53 }
54
56
57 if (m_dsBuffer) {
58 m_dsBuffer->Release();
59 }
60
61 Init();
63
64 if (!p_fromDestructor) {
66 }
67}
68
69// FUNCTION: LEGO1 0x100ae8b0
70// FUNCTION: BETA10 0x10132e94
71MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread)
72{
73 MxResult status = FAILURE;
74 MxBool locked = FALSE;
75
77 goto done;
78 }
79
81 locked = TRUE;
82
84 goto done;
85 }
86
87 if (m_directSound->SetCooperativeLevel(MxOmni::GetInstance()->GetWindowHandle(), DSSCL_PRIORITY) != DS_OK) {
88 goto done;
89 }
90
91 DSBUFFERDESC desc;
92 memset(&desc, 0, sizeof(desc));
93 desc.dwSize = sizeof(desc);
94
95 if (MxOmni::IsSound3D()) {
97 }
98 else {
100 }
101
102 if (m_directSound->CreateSoundBuffer(&desc, &m_dsBuffer, NULL) != DS_OK) {
103 if (!MxOmni::IsSound3D()) {
104 goto done;
105 }
106
109
110 if (m_directSound->CreateSoundBuffer(&desc, &m_dsBuffer, NULL) != DS_OK) {
111 goto done;
112 }
113 }
114
115 WAVEFORMATEX format;
116
117 format.wFormatTag = WAVE_FORMAT_PCM;
118
119 if (MxOmni::IsSound3D()) {
120 format.nChannels = 2;
121 }
122 else {
123 format.nChannels = 1;
124 }
125
126 format.nSamplesPerSec = 11025; // KHz
127 format.wBitsPerSample = 16;
128 format.nBlockAlign = format.nChannels * 2;
129 format.nAvgBytesPerSec = format.nBlockAlign * 11025;
130 format.cbSize = 0;
131
132 status = m_dsBuffer->SetFormat(&format);
133
134 if (p_createThread) {
135 m_thread = new MxTickleThread(this, p_frequencyMS);
136
137 if (!m_thread || m_thread->Start(0, 0) != SUCCESS) {
138 goto done;
139 }
140 }
141 else {
142 TickleManager()->RegisterClient(this, p_frequencyMS);
143 }
144
145 status = SUCCESS;
146
147done:
148 if (status != SUCCESS) {
149 Destroy();
150 }
151
152 if (locked) {
154 }
155 return status;
156}
157
158// FUNCTION: LEGO1 0x100aeab0
160{
161 Destroy(FALSE);
162}
163
164// FUNCTION: LEGO1 0x100aeac0
166{
168
170
171 MxPresenter* presenter;
173
174 while (cursor.Next(presenter)) {
175 ((MxAudioPresenter*) presenter)->SetVolume(((MxAudioPresenter*) presenter)->GetVolume());
176 }
177
179}
180
181// FUNCTION: LEGO1 0x100aebd0
183{
185
186 MxPresenter* presenter;
188
189 while (cursor.Next(presenter)) {
190 if (presenter->GetAction()->GetAtomId().GetInternal() == p_atomId.GetInternal() &&
191 presenter->GetAction()->GetObjectId() == p_objectId) {
192 return presenter;
193 }
194 }
195
196 return NULL;
197}
198
199// FUNCTION: LEGO1 0x100aecf0
201{
202 // The unit for p_volume is percent, rounded to integer.
203 // Convert to DSOUND attenuation units: -10000 (silent) to 0 (loudest).
204 if (p_volume == 0) {
205 return DSBVOLUME_MIN;
206 }
207
208 return g_volumeAttenuation[p_volume - 1];
209}
210
211// FUNCTION: LEGO1 0x100aed10
213{
215
216 MxPresenter* presenter;
218
219 while (cursor.Next(presenter)) {
220 if (presenter->IsA("MxWavePresenter")) {
221 ((MxWavePresenter*) presenter)->Pause();
222 }
223 }
224}
225
226// FUNCTION: LEGO1 0x100aee10
228{
230
231 MxPresenter* presenter;
233
234 while (cursor.Next(presenter)) {
235 if (presenter->IsA("MxWavePresenter")) {
236 ((MxWavePresenter*) presenter)->Resume();
237 }
238 }
239}
[AI] Atomized (unique) string identifier, managed by reference counting.
Definition: mxatom.h:124
const char * GetInternal() const
[AI] Returns a pointer to the internal string, or nullptr if not set.
Definition: mxatom.h:194
MxResult Create() override
[AI] Initializes audio subsystem resources and registers an instance for global audio management.
virtual MxS32 GetVolume()
[AI] Gets the current global audio volume.
virtual void SetVolume(MxS32 p_volume)
[AI] Sets the current global audio volume.
void Destroy() override
[AI] Tears down the audio subsystem instance and unregisters it from global management.
[AI] Presents (plays/streams) audio (WAV, MID, etc.) as part of the Omni engine's media handler syste...
void Enter()
[AI] Acquires/gains entry to the critical section or mutex, blocking if not available.
void Leave()
[AI] Releases/leaves the critical section or mutex.
const MxAtomId & GetAtomId()
[AI] Returns a const-reference to the object's atom identifier.
Definition: mxdsobject.h:133
MxU32 GetObjectId()
[AI] Returns the object id numeric value.
Definition: mxdsobject.h:130
MxBool Next()
[AI]
MxPresenterList * m_presenters
[AI] Pointer to list of currently registered (active) presenters.
MxCriticalSection m_criticalSection
[AI] Critical section object used for guarding access to the presenter list and internal members for ...
MxThread * m_thread
[AI] Optional pointer to a worker thread used for media dispatch/IO (if multi-threaded operation is u...
static MxOmni * GetInstance()
[AI] Returns the singleton instance of the MxOmni subsystem coordinator.
Definition: mxomni.cpp:289
static MxBool IsSound3D()
[AI] Returns current state of 3D sound configuration.
Definition: mxomni.cpp:387
static void SetSound3D(MxBool p_use3dSound)
[AI] Enables or disables use of 3D sound processing.
Definition: mxomni.cpp:393
HWND GetWindowHandle() const
[AI] Gets the window handle (HWND) associated with the engine (ownership not transferred).
Definition: mxomni.h:192
[AI] Cursor/iterator for traversing an MxPresenterList.
[AI] Abstract base class for all presenter types in the LEGO Island engine, responsible for managing ...
Definition: mxpresenter.h:20
MxBool IsA(const char *p_name) const override
[AI] Determines if this object is of (or inherits) the specified named class.
Definition: mxpresenter.h:141
MxDSAction * GetAction() const
[AI] Returns the current action being presented.
Definition: mxpresenter.h:175
[AI] Manages DirectSound-based sound playback, implementing volume, resource, and device management.
LPDIRECTSOUND m_directSound
[AI] Pointer to main DirectSound interface. Needed for all DirectSound operations.
void Init()
[AI] Internal initialization routine for member variables and DirectSound pointers.
MxSoundManager()
[AI] Constructs a new MxSoundManager instance.
MxS32 GetAttenuation(MxU32 p_volume)
[AI] Maps a percentage volume (1-100) to a DirectSound-specific attenuation value.
virtual void Pause()
[AI] Pauses all currently playing wave presenters.
MxPresenter * FUN_100aebd0(const MxAtomId &p_atomId, MxU32 p_objectId)
[AI] Finds a presenter matching a specific atom ID and object ID.
void Destroy() override
[AI] Releases sound resources and unregisters from tickle system.
void SetVolume(MxS32 p_volume) override
[AI] Sets the global audio output volume for all managed sound presenters.
LPDIRECTSOUNDBUFFER m_dsBuffer
[AI] Primary DirectSound buffer interface for setting output format/volume.
virtual void Resume()
[AI] Resumes all previously paused wave presenters.
~MxSoundManager() override
[AI] Destructor for MxSoundManager.
void Terminate()
[AI] Signals the thread to terminate.
Definition: mxthread.cpp:50
MxResult Start(MxS32 p_stackSize, MxS32 p_flag)
[AI] Starts the thread with a given stack size and creation flags.
Definition: mxthread.cpp:28
virtual void UnregisterClient(MxCore *p_client)
[AI] Unregisters (marks for destruction) a previously registered client.
virtual void RegisterClient(MxCore *p_client, MxTime p_interval)
[AI] Registers an MxCore object to receive periodic tickles.
MxTickleThread periodically calls Tickle() on a target MxCore object in a separate thread.
[AI] Presenter for streaming and managing PCM waveform audio via DirectSound buffer.
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:808
HRESULT WINAPI DirectSoundCreate(LPGUID, LPDIRECTSOUND *, LPUNKNOWN)
#define DSSCL_PRIORITY
Definition: dsound.h:769
#define DS_OK
Definition: dsound.h:690
#define DSBVOLUME_MIN
Definition: dsound.h:851
#define DSBCAPS_CTRL3D
Definition: dsound.h:805
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:801
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
Definition: legotypes.h:34
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
#define AUTOLOCK(CS)
[AI] Macro for automatic locking using the MxAutoLock class. This macro instantiates an MxAutoLock ob...
Definition: mxautolock.h:5
MxTickleManager * TickleManager()
[AI] Provides access to the global tickle manager.
Definition: mxmisc.cpp:25
MxS32 g_volumeAttenuation[100]
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned int MxU32
[AI]
Definition: mxtypes.h:32
DWORD dwSize
Definition: dsound.h:97
DWORD dwFlags
Definition: dsound.h:98