Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
dsp.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup ixlib
4 * @brief DirectSound device control and shared configuration.
5 *
6 * Originally `D:\rnd\prj\ix\win95\dsp\dsp.cpp`, address range
7 * 444910-44518f.
8 */
9#include <limits.h>
10#include "ix.h"
11#include <dsound.h>
12#include <stdlib.h>
13#include <string.h>
14
15#define IX_DSP_FILE "D:\\rnd\\prj\\ix\\win95\\dsp\\dsp.cpp"
16
17unsigned short nMasterVolume = 0xffff; /* 0x0047198C */
18void *(__cdecl *pIxMalloc)(unsigned int) = malloc; /* 0x00471990 */
19void (__cdecl *pIxFree)(void *) = free; /* 0x00471994 */
20
21HANDLE hIxPlaybackThread; /* 0x00597D00 */
22HWND hPlaybackWindow; /* 0x00597D04 */
23HANDLE hAudioWakeEvent; /* 0x00597D08 */
24unsigned int dwMixerWriteOffset; /* 0x00597D0C */
25LPDIRECTSOUND pDspDevice; /* 0x00597D10 */
26unsigned int dwSoundBufferSize; /* 0x00597D14 */
27unsigned int dwDspFlags; /* 0x00597D18 */
28DWORD dwMixerThreadId; /* 0x00597D1C */
29LPDIRECTSOUNDBUFFER pMixerBuffer; /* 0x00597D20 */
30short asPanGains[512]; /* 0x00597D28 */
31unsigned int dwDspTick; /* 0x00598128 */
32LPDIRECTSOUNDBUFFER pDspPrimaryBuffer; /* 0x0059812C */
33
34/* Function start: 0x00444910 */ /* source line 62 */
35int ix_dsp_init(void)
36{
37 if ((dwDspFlags & 1) == 0) {
38 nVoiceCount = 32;
39 nStreamCount = 2;
41 InitializeCriticalSection(&csMixer);
42 hAudioWakeEvent = CreateEventA(0, TRUE, FALSE, 0);
44 hIxPlaybackThread = CreateThread(
45 0, 0x1000, ix_mixer_thread_proc, 0, 0,
47 if (hIxPlaybackThread == 0) {
48 ix_log_printf("Fatal [%s - %d]:\n", IX_DSP_FILE, 62);
49 ix_log_printf("Failed to start mixer");
50 exit(-1);
51 }
52 dwDspFlags |= 1;
53 }
54 return 0;
55}
56
57/* Function start: 0x004449CF */
59{
60 if ((dwDspFlags & 1) != 0) {
61 if ((dwDspFlags & 4) != 0) {
62 dwDspFlags &= ~4U;
63 SetEvent(hAudioWakeEvent);
64 WaitForSingleObject(hIxPlaybackThread, INFINITE);
65 }
66 if (pDspDevice != 0) {
67 pDspDevice->Release();
68 pDspDevice = 0;
69 }
70 DeleteCriticalSection(&csMixer);
71 CloseHandle(hAudioWakeEvent);
72 dwDspFlags &= 0x7ffffffe;
73 }
74}
75
76/* Function start: 0x00444A62 */
77void ix_dsp_configure(int option, void *value)
78{
79 switch (option) {
80 case 0:
81 hPlaybackWindow = (HWND)value;
82 break;
83 case 1:
84 pDspDevice = (LPDIRECTSOUND)value;
85 break;
86 case 2:
87 if ((dwDspFlags & 1) != 0)
88 SetEvent(hAudioWakeEvent);
89 break;
90 case 3:
91 if (value != 0)
92 dwDspFlags |= 0x10;
93 else
94 dwDspFlags &= ~0x10U;
95 break;
96 case 4:
97 pIxMalloc = (void *(__cdecl *)(unsigned int))value;
98 break;
99 case 5:
100 pIxFree = (void (__cdecl *)(void *))value;
101 break;
102 }
103}
104
105/* Function start: 0x00444B25 */
106BOOL CALLBACK ix_dsp_open_driver(LPGUID guid, LPSTR description,
107 LPSTR module, LPVOID context)
108{
109 HRESULT result;
110
111 if (pDspDevice != 0) {
112 pDspDevice->Release();
113 pDspDevice = 0;
114 }
115 result = DirectSoundCreate(guid, &pDspDevice, 0);
116 if (result == DS_OK) {
117 result = pDspDevice->SetCooperativeLevel(
119 (dwDspFlags & 0x10) == 0
120 ? DSSCL_WRITEPRIMARY : DSSCL_EXCLUSIVE);
121 if (result == DS_OK) {
122 ix_log_printf("sound driver: %s [%s]\n", description, module);
123 return FALSE;
124 }
125 if (pDspDevice != 0) {
126 pDspDevice->Release();
127 pDspDevice = 0;
128 }
129 }
130 return TRUE;
131}
132
133/* Function start: 0x00444BFD */
134unsigned int ix_dsp_get_tick(void)
135{
136 return dwDspTick;
137}
138
139/* Function start: 0x00444C12 */
140unsigned int ix_dsp_get_flags(void)
141{
142 return dwDspFlags;
143}
144
145/* Function start: 0x00444C27 */
146void ix_dsp_set_config_bit1(int enabled)
147{
148 if (enabled != 0)
149 dwDspFlags |= 2;
150 else
151 dwDspFlags &= ~2U;
152}
153
154/* Function start: 0x00444C54 */
155void ix_dsp_set_config_bit3(int enabled)
156{
157 if (enabled != 0)
158 dwDspFlags |= 8;
159 else
160 dwDspFlags &= ~8U;
161}
162
163/* Function start: 0x00444C81 */
165{
166 return nVoiceCount;
167}
168
169/* Function start: 0x00444C96 */ /* source line(s) 176: can't change voice count while voices are in use */
170void ix_dsp_set_voice_count(int voiceCount)
171{
172 if (nVoicesAllocated != 0 ||
173 nAllocatedStreams != 0) {
174 ix_log_printf("Warning [%s - %d]:\n", IX_DSP_FILE, 176);
175 ix_log_printf("can't change voice count while voices are in use");
176 return;
177 }
178 if (voiceCount >= 0)
179 nVoiceCount = voiceCount < 32 ? voiceCount : 32;
180 else
181 nVoiceCount = 0;
182}
183
184/* Function start: 0x00444D18 */
186{
187 return nStreamCount;
188}
189
190/* Function start: 0x00444D2D */ /* source line(s) 187: can't change stream count while voices are in use */
191void ix_dsp_set_stream_count(int streamCount)
192{
193 if (nVoicesAllocated != 0 ||
194 nAllocatedStreams != 0) {
195 ix_log_printf("Warning [%s - %d]:\n", IX_DSP_FILE, 187);
196 ix_log_printf("can't change stream count while voices are in use");
197 return;
198 }
199 if (streamCount >= 0)
200 nStreamCount = streamCount < 2 ? streamCount : 2;
201 else
202 nStreamCount = 0;
203}
204
205/* Function start: 0x00444DAF */
206unsigned short ix_dsp_get_master_volume(void)
207{
208 return nMasterVolume;
209}
210
211/* Function start: 0x00444DC5 */
213{
214 int voice;
215
216 if ((volume & 0xffff) >= 0) {
217 nMasterVolume = (unsigned short)(
218 (volume & 0xffff) < 0xffff ? (volume & 0xffff) : 0xffff);
219 } else {
220 nMasterVolume = 0;
221 }
222 for (voice = 0; voice < nVoiceCount; voice++) {
223 if ((aVoices[voice].flags & IX_VOICE_ACTIVE) != 0)
224 ix_dspv_recalc_mix(voice);
225 }
226}
227
228/* Function start: 0x00444E52 */
230{
231 short volumeStep;
232 short left;
233 short panDistance;
234 short panPosition;
235 short right;
236
237 volumeStep = 0x3ff;
238 left = 0x7fff;
239 for (panPosition = 0; panPosition < 0x40; panPosition++) {
240 panDistance = (short)(0x20 - panPosition);
241 right = (short)(panDistance * volumeStep);
242 asPanGains[panPosition * 2] = left;
243 asPanGains[panPosition * 2 + 1] = right;
244 asPanGains[0x100 + panPosition * 2] =
245 (short)(left * -1);
246 asPanGains[0x100 + panPosition * 2 + 1] =
247 (short)(right * -1);
248 }
249 right = (short)0x8001;
250 for (panPosition = 0x40; panPosition < 0x80; panPosition++) {
251 panDistance = (short)(0x60 - panPosition);
252 left = (short)(panDistance * volumeStep);
253 asPanGains[panPosition * 2] = left;
254 asPanGains[panPosition * 2 + 1] = right;
255 asPanGains[0x100 + panPosition * 2] =
256 (short)(left * -1);
257 asPanGains[0x100 + panPosition * 2 + 1] =
258 (short)(right * -1);
259 }
260}
261
262/* Function start: 0x00444F97 */
263const char *ix_dsp_result_to_text(int result)
264{
265 switch (result) {
266 case DS_OK:
267 return "The function succeeded.";
268 case DSERR_ALLOCATED:
269 return "The function failed because resources (such as a priority level) were already in use by another caller.";
270 case DSERR_ALREADYINITIALIZED:
271 return "This object is already initialized.";
272 case DSERR_BADFORMAT:
273 return "The specified wave format is not supported.";
274 case DSERR_BUFFERLOST:
275 return "The buffer memory has been lost and must be restored.";
276 case DSERR_CONTROLUNAVAIL:
277 return "The control (volume, pan, and so forth) requested by the caller is not available.";
278 case DSERR_INVALIDCALL:
279 return "This function is not valid for the current state of this object";
280 case DSERR_INVALIDPARAM:
281 return "An invalid parameter was passed to the returning function.";
282 case DSERR_NOAGGREGATION:
283 return "This object does not support aggregation.";
284 case DSERR_NODRIVER:
285 return "No sound driver is available for use.";
286 case DSERR_OUTOFMEMORY:
287 return "The DirectSound subsystem couldn't allocate sufficient memory to complete the caller's request.";
288 case DSERR_PRIOLEVELNEEDED:
289 return "The caller does not have the priority level required for the function to succeed.";
290 case E_NOINTERFACE:
291 return "The requested COM interface is not available.";
292 default:
293 return "Unknow dsound error!";
294 }
295}
296
297/* Function start: 0x00445123 */
298void *ix_dsp_alloc(unsigned int bytes)
299{
300 return pIxMalloc(bytes);
301}
302
303/* Function start: 0x00445140 */
304#pragma function(memcpy)
305void *ix_dsp_copy(void *destination, const void *source, unsigned int bytes)
306{
307 return memcpy(destination, source, bytes);
308}
309
310/* Function start: 0x00445164 */
311void ix_dsp_free(void *memory)
312{
313 pIxFree(memory);
314}
void ix_dsp_build_pan_tables(void)
Definition dsp.cpp:229
int ix_dsp_get_stream_count(void)
Definition dsp.cpp:185
HANDLE hIxPlaybackThread
Definition dsp.cpp:21
int ix_dsp_init(void)
Definition dsp.cpp:35
unsigned int dwDspTick
Definition dsp.cpp:31
short asPanGains[512]
Definition dsp.cpp:30
LPDIRECTSOUND pDspDevice
Definition dsp.cpp:25
void ix_dsp_configure(int option, void *value)
Definition dsp.cpp:77
int ix_dsp_get_voice_count(void)
Definition dsp.cpp:164
void ix_dsp_set_stream_count(int streamCount)
Definition dsp.cpp:191
unsigned int ix_dsp_get_tick(void)
Definition dsp.cpp:134
void(__cdecl *pIxFree)(void *)
void ix_dsp_shutdown(void)
Definition dsp.cpp:58
unsigned int ix_dsp_get_flags(void)
Definition dsp.cpp:140
void ix_dsp_set_config_bit3(int enabled)
Definition dsp.cpp:155
void ix_dsp_set_voice_count(int voiceCount)
Definition dsp.cpp:170
LPDIRECTSOUNDBUFFER pDspPrimaryBuffer
Definition dsp.cpp:32
unsigned int dwDspFlags
Definition dsp.cpp:27
void *__cdecl * pIxMalloc(unsigned int)
HANDLE hAudioWakeEvent
Definition dsp.cpp:23
BOOL CALLBACK ix_dsp_open_driver(LPGUID guid, LPSTR description, LPSTR module, LPVOID context)
Definition dsp.cpp:106
unsigned short nMasterVolume
Definition dsp.cpp:17
void ix_dsp_free(void *memory)
Definition dsp.cpp:311
unsigned short ix_dsp_get_master_volume(void)
Definition dsp.cpp:206
void ix_dsp_set_config_bit1(int enabled)
Definition dsp.cpp:146
LPDIRECTSOUNDBUFFER pMixerBuffer
Definition dsp.cpp:29
void * ix_dsp_copy(void *destination, const void *source, unsigned int bytes)
Definition dsp.cpp:305
#define IX_DSP_FILE
Definition dsp.cpp:15
HWND hPlaybackWindow
Definition dsp.cpp:22
unsigned int dwMixerWriteOffset
Definition dsp.cpp:24
const char * ix_dsp_result_to_text(int result)
Definition dsp.cpp:263
DWORD dwMixerThreadId
Definition dsp.cpp:28
unsigned int dwSoundBufferSize
Definition dsp.cpp:26
void * ix_dsp_alloc(unsigned int bytes)
Definition dsp.cpp:298
int nAllocatedStreams
Definition dsps.cpp:18
int nStreamCount
Definition dsps.cpp:17
int nVoicesAllocated
Definition dspv.cpp:22
CRITICAL_SECTION csMixer
Definition dspv.cpp:20
int nVoiceCount
Definition dspv.cpp:21
The library's classes and shared declarations.
IxVoice aVoices[]
Definition dspv.cpp:19
void ix_log_printf(const char *fmt,...)
Definition ixlog.cpp:32
DWORD WINAPI ix_mixer_thread_proc(void *parameter)
Definition mixer.cpp:33
unsigned short nMasterVolume
Definition dsp.cpp:17
@ IX_VOICE_ACTIVE
Definition ix.h:51
int nVoiceCount
Definition dspv.cpp:21
unsigned int flags
Definition ix.h:65
unsigned short volume
Definition ix.h:71
friend void ix_dsp_set_master_volume(unsigned short)
Definition dsp.cpp:212
friend void ix_dspv_recalc_mix(int)
Definition dspv.cpp:220