Wing Commander II
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
mixer.cpp
Go to the documentation of this file.
1/*
2 * ix / D:\rnd\prj\ix\win95\dsp\mixer.cpp
3 *
4 * Original address range: 0x00445F60 - 0x004467C4 (4 functions)
5 * Range is exact: recovered from this module's own assert __FILE__ anchors in
6 * the shipped debug build (see docs/ORDER.md).
7 *
8 * Implement in ADDRESS ORDER -- MSVC emits functions in source order, so the
9 * list below is the original source order of this file.
10 */
11#include "ix.h"
12#include <dsound.h>
13#include <stdlib.h>
14#include <string.h>
15
16#pragma function(memset)
17
18#define IX_MIXER_FILE "D:\\rnd\\prj\\ix\\win95\\dsp\\mixer.cpp"
19
20extern HANDLE g_hMixerTask; /* 0x005c4ec0 */
21extern HWND g_4_hDspWnd; /* 0x005c4ec4 */
22extern HANDLE g_2_hMixerRouseEvent; /* 0x005c4ec8 */
23extern unsigned int g_dwMixerScratchSize; /* 0x005c4ed4 */
24extern unsigned int g_3_dwMixWriteOffset; /* 0x005c4ecc */
25extern LPDIRECTSOUND g_1_pDirectSound; /* 0x005c4ed0 */
26extern unsigned int g_5_dwSoundOptions; /* 0x005c4ed8 */
27extern LPDIRECTSOUNDBUFFER g_1_pPrimarySoundBuffer; /* 0x005c52ec */
28extern unsigned int g_6_dwDsoundTick; /* 0x005c52e8 */
29extern LPDIRECTSOUNDBUFFER g_pMixerBuffer; /* 0x005c4ee0 */
30
31BOOL CALLBACK ix_dsp_open_driver(LPGUID guid, LPSTR description,
32 LPSTR module, LPVOID context);
33
34/* Function start: 0x48B7C0 */ /* source lines 46, 50, 60, 63, 81, 84, 96 */
35DWORD WINAPI ix_mixer_thread_proc(void *parameter)
36{
37 DSCAPS dsCaps;
38 PCMWAVEFORMAT format;
39 DSBUFFERDESC description;
40 HRESULT result;
41 DSBCAPS bufCaps;
42
44 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
45 DirectSoundEnumerateA(ix_dsp_open_driver, 0);
46 if ((g_5_dwSoundOptions & 0x10) == 0 &&
47 g_1_pDirectSound == 0) {
48 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 46);
49 ix_log_printf("Failed to find write primary driver, using secondary buffer");
50 g_5_dwSoundOptions |= 0x10;
51 DirectSoundEnumerateA(ix_dsp_open_driver, 0);
52 }
53 if (g_1_pDirectSound == 0) {
54 ix_log_printf("Fatal [%s - %d]:\n", IX_MIXER_FILE, 50);
55 ix_log_printf("Failed to init directsound");
56 exit(-1);
57 }
58
59 memset(&dsCaps, 0, 0x60);
60 dsCaps.dwSize = 0x60;
61 g_1_pDirectSound->GetCaps(&dsCaps);
62 if ((g_5_dwSoundOptions & 0x10) == 0 &&
63 (dsCaps.dwFlags &
64 (DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO)) !=
65 (DSCAPS_PRIMARY16BIT | DSCAPS_PRIMARYSTEREO)) {
66 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 60);
67 ix_log_printf("sound driver doesn't support our primary buffer format, using secondary buffer");
68 g_5_dwSoundOptions |= 0x10;
69 DirectSoundEnumerateA(ix_dsp_open_driver, 0);
70 if (g_1_pDirectSound == 0) {
71 ix_log_printf("Fatal [%s - %d]:\n", IX_MIXER_FILE, 63);
72 ix_log_printf("Failed to init directsound");
73 exit(-1);
74 }
75 }
76
77 memset(&format, 0, 0x10);
78 format.wf.wFormatTag = WAVE_FORMAT_PCM;
79 format.wf.nChannels = 2;
80 format.wf.nSamplesPerSec = 22050;
81 format.wf.nBlockAlign = 4;
82 format.wf.nAvgBytesPerSec = 88200;
83 format.wBitsPerSample = 16;
84
85 memset(&description, 0, 0x14);
86 description.dwSize = 0x14;
87 description.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
88 result = g_1_pDirectSound->CreateSoundBuffer(
89 &description, &g_1_pPrimarySoundBuffer, 0);
90 if (result != DS_OK) {
91 ix_log_printf("Fatal [%s - %d]:\n", IX_MIXER_FILE, 81);
92 ix_log_printf("Failed to create primary buffer");
93 exit(-1);
94 }
95
96 result = g_1_pPrimarySoundBuffer->SetFormat(
97 (LPWAVEFORMATEX)&format);
98 if (result != DS_OK) {
99 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 84);
100 ix_log_printf("Failed to SetFormat, %s",
101 ix_dsp_result_to_text(result));
102 }
103 if ((g_5_dwSoundOptions & 0x10) != 0) {
104 memset(&description, 0, 0x14);
105 description.dwSize = 0x14;
106 description.dwFlags = DSBCAPS_CTRLVOLUME;
107 description.dwBufferBytes = 0x8000;
108 description.lpwfxFormat = (LPWAVEFORMATEX)&format;
109 result = g_1_pDirectSound->CreateSoundBuffer(
110 &description, &g_pMixerBuffer, 0);
111 if (result != DS_OK) {
112 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 96);
113 ix_log_printf("Failed to CreateSoundBuffer, %s",
114 ix_dsp_result_to_text(result));
115 return (DWORD)-1;
116 }
117 g_dwMixerScratchSize = 0x8000;
118 ix_log_printf("secondary buffer, size = %d\n",
120 } else {
121 memset(&bufCaps, 0, 0x14);
122 bufCaps.dwSize = 0x14;
123 g_1_pPrimarySoundBuffer->GetCaps(&bufCaps);
125 g_dwMixerScratchSize = bufCaps.dwBufferBytes;
126 ix_log_printf("primary buffer, size = %d\n",
128 }
129
130 g_1_pPrimarySoundBuffer->SetVolume(
131 10000 - (g_nMasterVolume * 10000) / 0xffff);
132 while ((g_5_dwSoundOptions & 4) != 0) {
134 if ((g_5_dwSoundOptions & 4) != 0) {
135 WaitForSingleObject(g_2_hMixerRouseEvent, 1000);
136 ResetEvent(g_2_hMixerRouseEvent);
137 g_pMixerBuffer->Restore();
138 }
139 }
140
143 } else if (g_1_pPrimarySoundBuffer != 0) {
144 g_1_pPrimarySoundBuffer->Release();
146 }
147 if (g_pMixerBuffer != 0) {
148 g_pMixerBuffer->Release();
149 g_pMixerBuffer = 0;
150 }
151 if (g_1_pDirectSound != 0) {
152 g_1_pDirectSound->Release();
154 }
155 return 0;
156}
157
158/* Function start: 0x48BC5C */ /* source line(s) 150;157;161;176;186;196: Failed to Lock, %s | Failed to Unlock, %s | Failed to Play, %s | Failed to get current pos */
160{
161 DWORD delay;
162 DWORD initialBytes;
163 HRESULT hr;
164 void *initialBuffer;
165
166 delay = 0x42;
167 hr = g_pMixerBuffer->Lock(
168 0, 0x2df0, &initialBuffer, &initialBytes, 0, 0, 0);
169 if (hr != DS_OK) {
170 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 150);
171 ix_log_printf("Failed to Lock, %s", ix_dsp_result_to_text(hr));
172 return -1;
173 }
174 EnterCriticalSection(&g_7_csMixer);
175 ix_dspv_mix(initialBuffer, initialBytes);
176 LeaveCriticalSection(&g_7_csMixer);
177 hr = g_pMixerBuffer->Unlock(initialBuffer, initialBytes, 0, 0);
178 if (hr != DS_OK) {
179 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 157);
180 ix_log_printf("Failed to Unlock, %s", ix_dsp_result_to_text(hr));
181 return -1;
182 }
183 hr = g_pMixerBuffer->Play(0, 0, DSBPLAY_LOOPING);
184 if (hr != DS_OK) {
185 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 161);
186 ix_log_printf("Failed to Play, %s", ix_dsp_result_to_text(hr));
187 return -1;
188 }
189
190 g_3_dwMixWriteOffset = 0x2df0;
191 while ((g_5_dwSoundOptions & 4) != 0) {
192 DWORD writePosition;
193 HRESULT hr;
194 DWORD bufferHeadLen;
195 int bufferedBytes;
196 void *bufferTail;
197 DWORD lockBytes;
198 void *bufferHead;
199 DWORD playCursor;
200 DWORD bufferTailLen;
201
202 Sleep(delay);
204 hr = g_pMixerBuffer->GetCurrentPosition(
205 &playCursor, &writePosition);
206 if (hr != DS_OK) {
207 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 176);
208 ix_log_printf("Failed to get current position, %s",
210 return -1;
211 }
212 if (playCursor > g_3_dwMixWriteOffset)
213 playCursor -= g_dwMixerScratchSize;
214 bufferedBytes = g_3_dwMixWriteOffset - playCursor;
215 delay = (unsigned int)(bufferedBytes * 0x42) / 0x16f8;
216
217 lockBytes = 0x16f8;
218 hr = g_pMixerBuffer->Lock(
219 g_3_dwMixWriteOffset, lockBytes,
220 &bufferHead, &bufferHeadLen, &bufferTail, &bufferTailLen, 0);
221 if (hr != DS_OK) {
222 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 186);
223 ix_log_printf("Failed to Lock, %s", ix_dsp_result_to_text(hr));
224 return -1;
225 }
226 EnterCriticalSection(&g_7_csMixer);
227 ix_dspv_mix(bufferHead, bufferHeadLen);
228 if (bufferTail != 0)
229 ix_dspv_mix(bufferTail, bufferTailLen);
230 LeaveCriticalSection(&g_7_csMixer);
231 hr = g_pMixerBuffer->Unlock(
232 bufferHead, bufferHeadLen, bufferTail, bufferTailLen);
233 if (hr != DS_OK) {
234 ix_log_printf("Warning [%s - %d]:\n", IX_MIXER_FILE, 196);
235 ix_log_printf("Failed to Unlock, %s", ix_dsp_result_to_text(hr));
236 return -1;
237 }
238 g_3_dwMixWriteOffset += bufferHeadLen;
239 if (bufferTail != 0) {
240 g_3_dwMixWriteOffset = bufferTailLen;
241 } else {
244 }
245 }
246 return 0;
247}
unsigned short g_nMasterVolume
Definition dsp.cpp:35
unsigned int g_6_dwDsoundTick
Definition dsp.cpp:27
HWND g_4_hDspWnd
Definition dsp.cpp:19
HANDLE g_hMixerTask
Definition dsp.cpp:18
LPDIRECTSOUND g_1_pDirectSound
Definition dsp.cpp:22
LPDIRECTSOUNDBUFFER g_1_pPrimarySoundBuffer
Definition dsp.cpp:28
BOOL CALLBACK ix_dsp_open_driver(LPGUID guid, LPSTR description, LPSTR module, LPVOID context)
Definition dsp.cpp:111
LPDIRECTSOUNDBUFFER g_pMixerBuffer
Definition dsp.cpp:26
unsigned int g_5_dwSoundOptions
Definition dsp.cpp:24
const char * ix_dsp_result_to_text(int result)
Definition dsp.cpp:270
HANDLE g_2_hMixerRouseEvent
Definition dsp.cpp:20
unsigned int g_dwMixerScratchSize
Definition dsp.cpp:23
unsigned int g_3_dwMixWriteOffset
Definition dsp.cpp:21
CRITICAL_SECTION g_7_csMixer
Definition dspv.cpp:20
Audio classes, DirectSound interfaces and shared ix state.
int ix_mixer_service(void)
Definition mixer.cpp:159
void ix_log_printf(const char *fmt,...)
Definition stream.cpp:164
void ix_dspv_mix(void *outputBuffer, unsigned int outputBytes)
DWORD WINAPI ix_mixer_thread_proc(void *parameter)
Definition mixer.cpp:35
#define IX_MIXER_FILE
Definition mixer.cpp:18