Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
dspv.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup ixlib
4 * @brief Voice control.
5 *
6 * Originally `D:\rnd\prj\ix\win95\dsp\dspv.cpp`, address range
7 * 4467a0-446f73: compiler-generated initializers, then the voice-control
8 * functions. The separately assembled sample mixer, dspmix.asm, follows.
9 *
10 * Built /Od like the rest of ix: a full EBP frame, EBX, ESI and EDI saved
11 * whether used or not, and one shared epilogue.
12 */
13#include <signal.h>
14#include "ix.h"
15#include <stdlib.h>
16#include <string.h>
17#include <assert.h>
18
19IxVoice aVoices[34]; /* 0x005981A8 */
20CRITICAL_SECTION csMixer; /* 0x005985E8 */
21int nVoiceCount; /* 0x00598600 */
22int nVoicesAllocated; /* 0x00598604 */
23
24/* Function start: 0x4467C5 */ /* source line 23 */
25void ix_dspv_set_active(int voice)
26{
27 if (voice < 0 || voice >= nVoiceCount) {
28 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 23);
29 ix_log_printf("%d Invalid voice index!", voice);
30 exit(-1);
31 }
33}
34
35/* Function start: 0x446829 */ /* source line 29 */
36void ix_dspv_clear_active(int voice)
37{
38 if (voice < 0 || voice >= nVoiceCount) {
39 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 29);
40 ix_log_printf("%d Invalid voice index!", voice);
41 exit(-1);
42 }
44}
45
46/* Function start: 0x44688E */ /* source line 35 */
47void ix_dspv_clear_flag4(int voice)
48{
49 if (voice < 0 || voice >= nVoiceCount) {
50 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 35);
51 ix_log_printf("%d Invalid voice index!", voice);
52 exit(-1);
53 }
55}
56
57/* Function start: 0x4468F2 */ /* source line 41 */
58unsigned int ix_dspv_get_flags(int voice)
59{
60 if (voice < 0 || voice >= nVoiceCount) {
61 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 41);
62 ix_log_printf("%d Invalid voice index!", voice);
63 exit(-1);
64 }
65 return aVoices[voice].flags;
66}
67
68/* Function start: 0x446956 */
69/* No bounds check in the original -- callers are internal. */
70void ix_dspv_set_flag4(int voice, int on)
71{
72 if (on != 0)
74 else
76}
77
78/* Function start: 0x44698F */ /* source line 55 */
79void ix_dspv_set_buffer(int voice, unsigned char *p, int len)
81 if (voice < 0 || voice >= nVoiceCount) {
82 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 55);
83 ix_log_printf("%d Invalid voice index!", voice);
84 exit(-1);
85 }
86 IxVoice *v = &aVoices[voice];
88 EnterCriticalSection(&csMixer);
89 v->cursor = p;
90 v->start = p;
91 v->end = p + len;
92 LeaveCriticalSection(&csMixer);
93}
94
95/* Function start: 0x446A2B */ /* source line 69 */
97{
98 if (voice < 0 || voice >= nVoiceCount) {
99 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 69);
100 ix_log_printf("%d Invalid voice index!", voice);
101 exit(-1);
102 }
103 IxVoice *v = &aVoices[voice];
104
105 return (int)((unsigned long)v->cursor - (unsigned long)v->start);
106}
107
108/* Function start: 0x446AA0 */ /* source line 77 */
109void ix_dspv_set_position(int voice, int off)
110{
111 if (voice < 0 || voice >= nVoiceCount) {
112 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 77);
113 ix_log_printf("%d Invalid voice index!", voice);
114 exit(-1);
115 }
116 IxVoice *v = &aVoices[voice];
117
118 v->cursor = v->start + off;
119}
120
121/* Function start: 0x446B18 */ /* source line 85 */
122void ix_dspv_set_volume(int voice, short vol)
123{
124 if (voice < 0 || voice >= nVoiceCount) {
125 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 85);
126 ix_log_printf("%d Invalid voice index!", voice);
127 exit(-1);
128 }
129 aVoices[voice].volume = vol;
130 ix_dspv_recalc_mix(voice);
131}
132
133/* Function start: 0x446B8C */ /* source line 93 */
134void ix_dspv_set_pan(int voice, unsigned short angle)
135{
136 short pos;
137 {
138 IxVoice *state;
139 {
140 short delta;
141 {
142 short step;
143
144 if (voice < 0 || nVoiceCount <= voice) {
145 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 93);
146 ix_log_printf("%d Invalid voice index!", voice);
147 exit(-1);
148 }
149 state = &aVoices[voice];
150 step = (short)((unsigned short)angle >> 9);
151 delta = step - state->panAngle;
152 if (delta > 0x40)
153 delta = delta - 0x80;
154 if (delta < -0x40)
155 delta = delta + 0x80;
156 pos = state->panPos + delta;
157 if (pos < 0)
158 pos = pos + 0x100;
159 if (pos >= 0x100)
160 pos = pos - 0x100;
161 state->panAngle = step;
162 state->panPos = pos;
163 ix_dspv_recalc_mix(voice);
164 }
165 }
166 }
167}
168
169/* Function start: 0x446CB1 */ /* source line 131 */
170void ix_dspv_set_frequency(int voice, unsigned int hz)
171{
172 if (voice < 0 || nVoiceCount <= voice) {
173 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 131);
174 ix_log_printf("%d Invalid voice index!", voice);
175 exit(-1);
176 }
177 aVoices[voice].rate =
178 (short)(((int)(hz & 0xffff) << 8) / IX_MIXER_BASE_RATE);
179}
180
181/* Function start: 0x446D2C */ /* source lines 137, 138 */
182void ix_dspv_set_bits_per_sample(int voice, int bps)
183{
184 if (voice < 0 || voice >= nVoiceCount) {
185 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 137);
186 ix_log_printf("%d Invalid voice index!", voice);
187 exit(-1);
188 }
189 if (bps != 8 && bps != 16) {
190 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 138);
191 ix_log_printf("%d is an unsupported bps!", bps);
192 exit(-1);
193 }
194 if (bps == 16)
195 aVoices[voice].flags |= IX_VOICE_16BIT;
196 else
197 aVoices[voice].flags &= ~IX_VOICE_16BIT;
198}
199
200/* Function start: 0x446DF5 */ /* source lines 148, 149 */
201void ix_dspv_set_channels(int voice, int channels)
202{
203 if (voice < 0 || voice >= nVoiceCount) {
204 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 148);
205 ix_log_printf("%d Invalid voice index!", voice);
206 exit(-1);
207 }
208 if (channels != 1 && channels != 2) {
209 ix_log_printf("Fatal [%s - %d]:\n", IX_DSPV_FILE, 149);
210 ix_log_printf("%d is an unsupported number of channels!", channels);
211 exit(-1);
212 }
213 if (channels == 2)
214 aVoices[voice].flags |= IX_VOICE_STEREO;
215 else
217}
218
219/* Function start: 0x446EBF */
220void ix_dspv_recalc_mix(int voice)
221{
222 IxVoice *voiceState;
223 short panPosition;
224 int scaledVolume;
225
226 voiceState = &aVoices[voice];
227 panPosition = voiceState->panPos;
228 scaledVolume = ((unsigned int)voiceState->volume
229 * (unsigned int)nMasterVolume) / 0xffff;
230 EnterCriticalSection(&csMixer);
231 voiceState->leftGain =
232 (short)((int)asPanGains[panPosition * 2] * scaledVolume >> 0x10);
233 voiceState->rightGain =
234 (short)((int)asPanGains[panPosition * 2 + 1] * scaledVolume >> 0x10);
235 voiceState->leftGainHi = (unsigned char)(voiceState->leftGain >> 8);
236 voiceState->rightGainHi = (unsigned char)(voiceState->rightGain >> 8);
237 LeaveCriticalSection(&csMixer);
238}
239
240/* Portable counterpart of the assembled sample mixer in dspmix.asm. */
int nVoicesAllocated
Definition dspv.cpp:22
CRITICAL_SECTION csMixer
Definition dspv.cpp:20
int nVoiceCount
Definition dspv.cpp:21
IxVoice aVoices[34]
Definition dspv.cpp:19
The library's classes and shared declarations.
short asPanGains[]
Definition dsp.cpp:30
IxVoice aVoices[]
Definition dspv.cpp:19
void ix_log_printf(const char *fmt,...)
Definition ixlog.cpp:32
CRITICAL_SECTION csMixer
Definition dspv.cpp:20
#define IX_MIXER_BASE_RATE
Definition ix.h:200
#define IX_DSPV_FILE
Definition ix.h:205
unsigned short nMasterVolume
Definition dsp.cpp:17
@ 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 nVoiceCount
Definition dspv.cpp:21
Definition ix.h:63
unsigned char * start
Definition ix.h:67
friend void ix_dspv_set_channels(int, int)
Definition dspv.cpp:201
friend void ix_dspv_set_buffer(int, unsigned char *, int)
Definition dspv.cpp:79
short rate
Definition ix.h:70
short panPos
Definition ix.h:77
friend unsigned int ix_dspv_get_flags(int)
Definition dspv.cpp:58
friend void ix_dspv_set_active(int)
Definition dspv.cpp:25
friend void ix_dspv_set_volume(int, short)
Definition dspv.cpp:122
friend void ix_dspv_set_flag4(int, int)
Definition dspv.cpp:70
friend void ix_dspv_set_bits_per_sample(int, int)
Definition dspv.cpp:182
friend void ix_dspv_set_position(int, int)
Definition dspv.cpp:109
friend void ix_dspv_set_pan(int, unsigned short)
Definition dspv.cpp:134
friend int ix_dspv_get_position(int)
Definition dspv.cpp:96
unsigned char * cursor
Definition ix.h:66
short leftGain
Definition ix.h:74
unsigned char * end
Definition ix.h:68
unsigned char rightGainHi
Definition ix.h:73
short panAngle
Definition ix.h:76
friend void ix_dspv_clear_flag4(int)
Definition dspv.cpp:47
short rightGain
Definition ix.h:75
friend void ix_dspv_set_frequency(int, unsigned int)
Definition dspv.cpp:170
unsigned int flags
Definition ix.h:65
unsigned char leftGainHi
Definition ix.h:72
unsigned short volume
Definition ix.h:71
friend void ix_dspv_clear_active(int)
Definition dspv.cpp:36
friend void ix_dspv_recalc_mix(int)
Definition dspv.cpp:220