Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
dsps.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup ixlib
4 * @brief Sample stream control.
5 *
6 * Originally `D:\rnd\prj\ix\win95\dsp\dsps.cpp`, address range
7 * 445190-445f5f: compiler-generated initializers, then ten stream-control
8 * functions. Built /Od /Oi like the rest of ix.
9 *
10 * A stream is a ring buffer fed by the streamer thread and played through a
11 * voice slot allocated after the regular voices: voice[voice_count + index].
12 */
13#include <signal.h>
14#include "ix.h"
15#include <stdlib.h>
16
17int nStreamCount; /* 0x00598130 */
18int nAllocatedStreams; /* 0x00598134 */
19IxStream streams[2]; /* 0x00598138 */
20
21/* Function start: 0x4451B5 */ /* source lines 26, 27, 28, 32 */
22void ix_dsps_alloc(int stream, unsigned int size, int freq, int bps, int channels)
23{
24 IxVoice *v;
25
26 if (stream < 0 || stream >= nStreamCount) {
27 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 26);
28 ix_log_printf("invalid stream index");
29 exit(-1);
30 }
31 if ((streams[stream].flags & IX_STREAM_ALLOCATED) != 0) {
32 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 27);
33 ix_log_printf("stream already allocated!");
34 exit(-1);
35 }
36 if ((streams[stream].flags & IX_STREAM_PLAYING) != 0) {
37 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 28);
38 ix_log_printf("stream still playing!");
39 exit(-1);
40 }
41 streams[stream].buffer = new unsigned char[size];
42 if (streams[stream].buffer == 0) {
43 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 32);
44 ix_log_printf("failed to allocate stream buffer");
45 exit(-1);
46 }
47 streams[stream].size = size;
48 streams[stream].writePos = 0;
49 streams[stream].playPos = streams[stream].writePos;
50 streams[stream].pending = streams[stream].playPos;
51 InitializeCriticalSection(&streams[stream].cs);
52
53 v = &aVoices[nVoiceCount + stream];
54 v->flags = IX_VOICE_FLAG4 | 1;
55 if (bps == 16) {
57 } else {
58 /* Eight-bit samples use the default format flags. */
59 }
60 if (channels == 2) {
62 } else {
63 /* Mono samples use the default format flags. */
64 }
65 v->cursor = streams[stream].buffer;
66 v->start = v->cursor;
67 v->end = v->cursor + size;
68 v->volume = 0x7fff;
69 v->leftGain = v->volume;
70 v->rightGain = v->volume;
71 v->leftGainHi = (unsigned short)v->volume >> 8;
72 v->rightGainHi = (unsigned short)v->volume >> 8;
73 v->field_10 = 0;
74 v->rate = (freq << 8) / IX_MIXER_BASE_RATE;
77}
78
79/* Function start: 0x44546B */ /* source lines 62, 63 */
80void ix_dsps_free(int stream)
81{
82 if (stream < 0 || stream >= nStreamCount) {
83 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 62);
84 ix_log_printf("invalid stream index");
85 exit(-1);
86 }
87 if ((streams[stream].flags & IX_STREAM_ALLOCATED) == 0) {
88 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 63);
89 ix_log_printf("stream is not allocated!");
90 exit(-1);
91 }
92 if ((streams[stream].flags & IX_STREAM_PLAYING) != 0)
93 ix_dsps_stop(stream);
94 DeleteCriticalSection(&streams[stream].cs);
95 delete[] streams[stream].buffer;
100/* Function start: 0x445582 */ /* source lines 77, 78, 79 */
101void ix_dsps_prepare(int stream)
102{
103 if (stream < 0 || stream >= nStreamCount) {
104 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 77);
105 ix_log_printf("invalid stream index");
106 exit(-1);
107 }
108 if ((streams[stream].flags & IX_STREAM_ALLOCATED) == 0) {
109 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 78);
110 ix_log_printf("stream is not ready!");
111 exit(-1);
112 }
113 if ((streams[stream].flags & IX_STREAM_PLAYING) != 0) {
114 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 79);
115 ix_log_printf("stream is playing!");
116 exit(-1);
117 }
118 streams[stream].playPos = 0;
119 streams[stream].pending = streams[stream].playPos;
120 streams[stream].writePos = streams[stream].pending;
121 aVoices[nVoiceCount + stream].cursor =
122 streams[stream].buffer;
123}
124
125/* Function start: 0x4456D8 */ /* source lines 87, 88, 89 */
126void ix_dsps_play(int stream)
127{
128 IxVoice *v;
129
130 if (stream < 0 || stream >= nStreamCount) {
131 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 87);
132 ix_log_printf("invalid stream index");
133 exit(-1);
134 }
135 if ((streams[stream].flags & IX_STREAM_ALLOCATED) == 0) {
136 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 88);
137 ix_log_printf("stream is not ready!");
138 exit(-1);
139 }
140 if ((streams[stream].flags & IX_STREAM_PLAYING) != 0) {
141 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 89);
142 ix_log_printf("stream is already playing!");
143 exit(-1);
144 }
145 v = &aVoices[nVoiceCount + stream];
146 v->cursor = streams[stream].playPos
147 + streams[stream].buffer;
150}
151
152/* Function start: 0x445808 */ /* source lines 99, 100, 101 */
153void ix_dsps_stop(int stream)
154{
155 if (stream < 0 || stream >= nStreamCount) {
156 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 99);
157 ix_log_printf("invalid stream index");
158 exit(-1);
159 }
160 if ((streams[stream].flags & IX_STREAM_ALLOCATED) == 0) {
161 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 100);
162 ix_log_printf("stream is not ready!");
163 exit(-1);
164 }
165 if ((streams[stream].flags & IX_STREAM_PLAYING) == 0) {
166 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 101);
167 ix_log_printf("stream isnt playing!");
168 exit(-1);
169 }
172}
173
174/* Function start: 0x445906 */ /* source lines 109, 110 */
175void ix_dsps_set_volume(int stream, unsigned short vol)
176{
177 IxVoice *v;
178
179 if (stream < 0 || stream >= nStreamCount) {
180 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 109);
181 ix_log_printf("invalid stream index");
182 exit(-1);
183 }
184 if ((streams[stream].flags & IX_STREAM_ALLOCATED) == 0) {
185 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 110);
186 ix_log_printf("stream is not ready!");
187 exit(-1);
188 }
189 v = &aVoices[nVoiceCount + stream];
190 v->volume =
191 (unsigned short)(((int)(vol & 0xffff) * 0x7fff) / 0xffff);
192 v->leftGain = v->volume;
193 v->rightGain = v->volume;
194 v->leftGainHi = (unsigned short)v->volume >> 8;
195 v->rightGainHi = (unsigned short)v->volume >> 8;
196}
197
198/* Function start: 0x445A0B */ /* source line 122 */
199unsigned int ix_dsps_get_flags(int stream)
200{
201 if (stream < 0 || stream >= nStreamCount) {
202 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 122);
203 ix_log_printf("invalid stream index");
204 exit(-1);
205 }
206 return streams[stream].flags;
207}
208
209/* Function start: 0x445A6F */ /* source lines 128, 129 */
210int ix_dsps_get_buffer_free(int streamIndex)
211{
212 if (streamIndex < 0 || streamIndex >= nStreamCount) {
213 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 128);
214 ix_log_printf("invalid stream index");
215 exit(-1);
216 }
217 if ((streams[streamIndex].flags & IX_STREAM_ALLOCATED) == 0) {
218 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 129);
219 ix_log_printf("stream is not ready!");
220 exit(-1);
221 }
222 unsigned int consumedBytes = 0;
223 EnterCriticalSection(&streams[streamIndex].cs);
224 unsigned int bufferPosition =
225 aVoices[nVoiceCount + streamIndex].cursor - streams[streamIndex].buffer;
226 if (streams[streamIndex].pending < 0) {
227 streams[streamIndex].pending = 0;
228 streams[streamIndex].playPos = bufferPosition;
229 LeaveCriticalSection(&streams[streamIndex].cs);
230 return streams[streamIndex].size;
231 }
232 if (streams[streamIndex].playPos < bufferPosition) {
233 consumedBytes = bufferPosition - streams[streamIndex].playPos;
234 streams[streamIndex].pending -= consumedBytes;
235 } else if (streams[streamIndex].playPos != bufferPosition) {
236 consumedBytes = (streams[streamIndex].size
237 - streams[streamIndex].playPos) + bufferPosition;
238 streams[streamIndex].pending -= consumedBytes;
239 }
240 streams[streamIndex].playPos = bufferPosition;
241 LeaveCriticalSection(&streams[streamIndex].cs);
242 return streams[streamIndex].size - streams[streamIndex].pending;
243}
244
245/* Function start: 0x00445CDB */ /* source lines 169, 172, 173 */
246void ix_dsps_lock(int stream, unsigned int requestedBytes,
247 unsigned char **buffer, unsigned int *lockedBytes)
248{
249 IxStream *s;
250
251 if (stream < 0 || stream >= nStreamCount) {
252 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 169);
253 ix_log_printf("invalid stream index");
254 exit(-1);
256 s = &streams[stream];
257 if ((streams[stream].flags & IX_STREAM_ALLOCATED) == 0) {
258 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 172);
259 ix_log_printf("stream is not ready!");
260 exit(-1);
261 }
262 if ((streams[stream].flags & IX_STREAM_LOCKED) != 0) {
263 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 173);
264 ix_log_printf("stream is already locked!");
265 exit(-1);
266 }
267 s->lockPtr = s->buffer + s->writePos;
268 if (s->writePos + requestedBytes > s->size)
269 requestedBytes = s->size - s->writePos;
270 s->lockLen = requestedBytes;
271 *buffer = s->lockPtr;
272 *lockedBytes = s->lockLen;
273 streams[stream].flags |= IX_STREAM_LOCKED;
274}
275
276/* Function start: 0x00445E3C */ /* source lines 188, 191, 192 */
277void ix_dsps_unlock(int stream)
278{
279 IxStream *s;
280
281 if (stream < 0 || stream >= nStreamCount) {
282 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 188);
283 ix_log_printf("invalid stream index");
284 exit(-1);
285 }
286 s = &streams[stream];
287 if ((s->flags & IX_STREAM_ALLOCATED) == 0) {
288 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 191);
289 ix_log_printf("stream is not ready!");
290 exit(-1);
291 }
292 if ((s->flags & IX_STREAM_LOCKED) == 0) {
293 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPS_FILE, 192);
294 ix_log_printf("stream isn't locked!");
295 exit(-1);
296 }
297 s->writePos += s->lockLen;
298 if (s->writePos >= s->size)
299 s->writePos = s->writePos - s->size;
300 s->pending += s->lockLen;
302}
IxStream streams[2]
Definition dsps.cpp:19
int nAllocatedStreams
Definition dsps.cpp:18
int nStreamCount
Definition dsps.cpp:17
The library's classes and shared declarations.
IxStream streams[]
Definition dsps.cpp:19
int nAllocatedStreams
Definition dsps.cpp:18
IxVoice aVoices[]
Definition dspv.cpp:19
#define IX_DSPS_FILE
Definition ix.h:265
void ix_log_printf(const char *fmt,...)
Definition ixlog.cpp:32
@ IX_STREAM_LOCKED
Definition ix.h:230
@ IX_STREAM_ALLOCATED
Definition ix.h:228
@ IX_STREAM_PLAYING
Definition ix.h:229
#define IX_MIXER_BASE_RATE
Definition ix.h:200
@ IX_VOICE_STEREO
Definition ix.h:54
@ IX_VOICE_FLAG4
Definition ix.h:52
@ IX_VOICE_16BIT
Definition ix.h:53
@ IX_VOICE_ACTIVE
Definition ix.h:51
int nStreamCount
Definition dsps.cpp:17
int nVoiceCount
Definition dspv.cpp:21
Definition ix.h:233
friend void ix_dsps_unlock(int)
Definition dsps.cpp:277
int lockLen
Definition ix.h:242
unsigned int playPos
Definition ix.h:239
friend unsigned int ix_dsps_get_flags(int)
Definition dsps.cpp:199
int pending
Definition ix.h:240
unsigned char * buffer
Definition ix.h:236
friend void ix_dsps_free(int)
Definition dsps.cpp:80
unsigned char * lockPtr
Definition ix.h:241
unsigned int writePos
Definition ix.h:238
friend void ix_dsps_stop(int)
Definition dsps.cpp:153
unsigned int flags
Definition ix.h:235
unsigned int size
Definition ix.h:237
friend void ix_dsps_lock(int, unsigned int, unsigned char **, unsigned int *)
Definition dsps.cpp:246
CRITICAL_SECTION cs
Definition ix.h:243
Definition ix.h:63
unsigned char * start
Definition ix.h:67
friend void ix_dsps_prepare(int)
Definition dsps.cpp:101
short rate
Definition ix.h:70
friend int ix_dsps_get_buffer_free(int)
Definition dsps.cpp:210
unsigned char * cursor
Definition ix.h:66
short leftGain
Definition ix.h:74
unsigned char * end
Definition ix.h:68
short field_10
Definition ix.h:69
friend void ix_dsps_stop(int)
Definition dsps.cpp:153
unsigned char rightGainHi
Definition ix.h:73
friend void ix_dsps_play(int)
Definition dsps.cpp:126
short rightGain
Definition ix.h:75
friend void ix_dsps_alloc(int, unsigned int, int, int, int)
Definition dsps.cpp:22
unsigned int flags
Definition ix.h:65
unsigned char leftGainHi
Definition ix.h:72
unsigned short volume
Definition ix.h:71
friend void ix_dsps_set_volume(int, unsigned short)
Definition dsps.cpp:175