Wing Commander II
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
sample.cpp
Go to the documentation of this file.
1/*
2 * ix / D:\Rnd\prj\ix\src\sound\sample.cpp
3 *
4 * Retail address range: 0x0046B130 - 0x0046BD4F (6 functions)
5 * Object boundaries follow retail padding and alignment; diagnostic paths
6 * identify the source subsystem (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#define IX_SAMPLE_CPP
12#include "ix.h"
13#include <math.h>
14
15#define IX_SAMPLE_FILE "D:\\Rnd\\prj\\ix\\src\\sound\\sample.cpp"
16
17#define IX_SWAP_WORD(value) \
18 (short)((((value) & 0x00ff) << 8) | \
19 (((value) >> 8) & 0x00ff))
20
21#define IX_SWAP_DWORD(value) \
22 ((((unsigned int)(value) & 0x0000ff00) << 8) | \
23 (((unsigned int)(value) >> 8) & 0x0000ff00) | \
24 ((unsigned int)(value) << 24) | \
25 ((unsigned int)(value) >> 24))
26
27#define IX_UNSIGNED_TO_DOUBLE(value) \
28 ((double)(long)((value) - 2147483647L - 1) + 2147483648.0)
29
31 unsigned int id;
32 unsigned int size;
33};
34
36 short channels;
37 unsigned int sampleFrames;
39 unsigned char sampleRate[10];
40};
41
43 short id;
44 unsigned int position;
45 unsigned char nameLength;
46};
47
49 unsigned short format;
50 unsigned short channels;
52 unsigned int bytesPerSecond;
53 unsigned short blockAlignment;
54 unsigned short bitsPerSample;
55};
56
57/* Function start: 0x46B130 */
59{
60 flags = 0;
61 buffer = 0;
63 previous = 0;
64 if (g_7_pSampleList != 0)
66 g_7_pSampleList = this;
67}
68
69/* Function start: 0x46B18F */
71{
72 if (buffer != 0) {
74 buffer = 0;
75 }
76 if (this == g_7_pSampleList)
78 if (next != 0)
80 if (previous != 0)
82}
83
84/* Function start: 0x46B21C */ /* source line(s) 166;169;170;193;195;197: sample already ready! | FORM id not found! | AIFF id not found! | Unsupported number of ch */
85int IxSample::ix_sample_load_aiff(void *data, int bytes)
86{
87 unsigned char *end;
88 IxSampleChunk *chunk;
89
90 unsigned char *form;
91 form = (unsigned char *)data;
92 if ((flags & IX_SAMPLE_READY) != 0) {
93 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 166);
94 ix_log_printf("sample already ready!");
95 return -1;
96 }
98 if (*(unsigned int *)form != *(unsigned int *)"FORM") {
99 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 169);
100 ix_log_printf("FORM id not found!");
101 return -1;
102 }
103 if (*(unsigned int *)(form + 8) != *(unsigned int *)"AIFF") {
104 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 170);
105 ix_log_printf("AIFF id not found!");
106 return -1;
107 }
108 end = (unsigned char *)data + bytes;
109 chunk = (IxSampleChunk *)((unsigned char *)data + 12);
110 while ((unsigned char *)chunk < end) {
111 chunk->size = IX_SWAP_DWORD(chunk->size);
112 switch (chunk->id) {
113 case 0x4d4d4f43: {
114 int sampleRate;
115 IxAiffCommonChunk *common;
116
117 common = (IxAiffCommonChunk *)(chunk + 1);
118 common->channels = (short)(
119 (((unsigned int)common->channels << 8) & 0xff00) |
120 ((common->channels >> 8) & 0xff));
121 common->sampleFrames = IX_SWAP_DWORD(common->sampleFrames);
122 common->bitsPerSample = (short)(
123 ((common->bitsPerSample & 0xff00) >> 8) |
124 ((common->bitsPerSample & 0xff) << 8));
125 sampleRate = (int)ix_sample_convert_from_ieee_extended(common->sampleRate);
126 rateNumerator = 1;
128 if (common->channels != 1 && common->channels != 2) {
129 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 193);
130 ix_log_printf("Unsupported number of channels in AIFF!");
131 return -1;
132 }
133 if (sampleRate < 4000 || sampleRate > 44100) {
134 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 195);
135 ix_log_printf("Unsupported AIFF sample rate!");
136 return -1;
137 }
138 if (common->bitsPerSample != 8 && common->bitsPerSample != 16) {
139 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 197);
140 ix_log_printf("Unsupported AIFF bits per sample!");
141 return -1;
142 }
144 channels = common->channels;
145 frequency = sampleRate;
146 loopStart = 0;
147 loopEnd = (unsigned int)-1;
149 bytesPerFrame = ((int)bitsPerSample / 8) * (int)channels;
150 break;
151 }
152
153 case 0x4b52414d: {
154 IxAiffMarker *marker;
155
156 marker = (IxAiffMarker *)(chunk + 1);
157 marker = (IxAiffMarker *)((unsigned char *)marker + 2);
159 marker = (IxAiffMarker *)((unsigned char *)marker +
160 marker->nameLength + sizeof(IxAiffMarker));
161 while (((unsigned int)marker & 1) != 0)
162 marker = (IxAiffMarker *)((unsigned char *)marker + 1);
163 loopEnd = IX_SWAP_DWORD(marker->position);
165 break;
166 }
167
168 case 0x444e5353: {
169 int samplesRemaining;
170 unsigned short *samples;
171
172 buffer = (unsigned char *)ix_dsp_alloc(chunk->size);
173 sampleCount = chunk->size / bytesPerFrame;
174 if (loopEnd == (unsigned int)-1)
176 if (bitsPerSample == 16) {
177 samples = (unsigned short *)(chunk + 1);
178 samplesRemaining = sampleCount * channels;
179 while (samplesRemaining--) {
180 *samples = IX_SWAP_WORD(*samples);
181 samples++;
182 }
183 }
184 ix_dsp_copy(buffer, chunk + 1, chunk->size);
185 break;
186 }
187 default:
188 break;
189 }
190 chunk = (IxSampleChunk *)((unsigned char *)chunk +
191 chunk->size + sizeof(IxSampleChunk));
192 }
195 return 0;
196}
197
198/* Function start: 0x46B70B */ /* source line(s) 261;264;265;279;281;283;285: sample already ready! | RIFF id not found! | WAVE id not found! | Unsupported number of ch */
199int IxSample::ix_sample_load_wav(void *data, int bytes)
200{
201 unsigned char *end;
202 IxSampleChunk *chunk;
203
204 unsigned char *riff;
205 riff = (unsigned char *)data;
206 if ((flags & IX_SAMPLE_READY) != 0) {
207 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 261);
208 ix_log_printf("sample already ready!");
209 return -1;
210 }
212 if (*(unsigned int *)riff != *(unsigned int *)"RIFF") {
213 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 264);
214 ix_log_printf("RIFF id not found!");
215 return -1;
216 }
217 if (*(unsigned int *)(riff + 8) != *(unsigned int *)"WAVE") {
218 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 265);
219 ix_log_printf("WAVE id not found!");
220 return -1;
221 }
222 end = (unsigned char *)data + bytes;
223 chunk = (IxSampleChunk *)((unsigned char *)data + 12);
224 while ((unsigned char *)chunk < end) {
225 switch (chunk->id) {
226 case 0x20746d66: {
227 IxWaveFormat *format;
228
229 format = (IxWaveFormat *)(chunk + 1);
230 if (format->channels != 1 && format->channels != 2) {
231 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 279);
232 ix_log_printf("Unsupported number of channels in WAV!");
233 return -1;
234 }
235 if (format->format != 1) {
236 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 281);
237 ix_log_printf("Unsupported WAV format!");
238 return -1;
239 }
240 if (format->frequency < 4000 || format->frequency > 44100) {
241 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 283);
242 ix_log_printf("Unsupported WAV sample rate!");
243 return -1;
244 }
245 if (format->bitsPerSample != 8 && format->bitsPerSample != 16) {
246 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 285);
247 ix_log_printf("Unsupported WAV bits per sample!");
248 return -1;
249 }
251 channels = format->channels;
252 frequency = format->frequency;
253 loopStart = 0;
254 loopEnd = (unsigned int)-1;
256 bytesPerFrame = ((int)bitsPerSample / 8) * (int)channels;
257 rateNumerator = 1;
259 break;
260 }
261
262 case 0x61746164: {
263 int samplesRemaining;
264 signed char *samples;
265
266 buffer = (unsigned char *)ix_dsp_alloc(chunk->size);
267 sampleCount = chunk->size / bytesPerFrame;
269 if (bitsPerSample == 8) {
270 samples = (signed char *)(chunk + 1);
271 samplesRemaining = bytesPerFrame * sampleCount;
272 while (samplesRemaining--) {
273 *samples = (signed char)(*samples - 0x80);
274 samples++;
275 }
276 }
277 ix_dsp_copy(buffer, chunk + 1, chunk->size);
278 break;
279 }
280 default:
281 break;
282 }
283 chunk = (IxSampleChunk *)((unsigned char *)chunk +
284 chunk->size + sizeof(IxSampleChunk));
285 }
288 return 0;
289}
290
291/* Function start: 0x46BAC4 */ /* source line(s) 333: sample already ready! */
292int IxSample::ix_sample_load_raw(void *data, int bytes, int newFrequency,
293 int newBitsPerSample, int newChannels)
294{
295 if ((flags & IX_SAMPLE_READY) != 0) {
296 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 333);
297 ix_log_printf("sample already ready!");
298 return -1;
299 }
301 buffer = (unsigned char *)ix_dsp_alloc(bytes);
302 ix_dsp_copy(buffer, data, bytes);
303 bitsPerSample = newBitsPerSample;
304 channels = newChannels;
305 frequency = newFrequency;
306 loopStart = 0;
307 bytesPerFrame = ((int)bitsPerSample / 8) * (int)channels;
308 loopEnd = bytes / (int)bytesPerFrame;
310 rateNumerator = 1;
314 return 0;
315}
316
317/* Function start: 0x46BBCC */
319{
320 unsigned long loMant;
321 int expon;
322 double f;
323 unsigned long hiMant;
324 unsigned char *src;
325
326 src = bytes;
327 expon = ((src[0] & 0x7f) << 8) | (src[1] & 0xff);
328 hiMant = ((unsigned long)(src[2] & 0xff) << 24) |
329 ((unsigned long)(src[3] & 0xff) << 16) |
330 ((unsigned long)(src[4] & 0xff) << 8) |
331 ((unsigned long)(src[5] & 0xff));
332 loMant = ((unsigned long)(src[6] & 0xff) << 24) |
333 ((unsigned long)(src[7] & 0xff) << 16) |
334 ((unsigned long)(src[8] & 0xff) << 8) |
335 ((unsigned long)(src[9] & 0xff));
336 if (expon == 0 && hiMant == 0 && loMant == 0) {
337 f = 0;
338 } else if (expon == 0x7fff) {
339 f = HUGE_VAL;
340 } else {
341 expon -= 16383;
342 f = ldexp(IX_UNSIGNED_TO_DOUBLE(hiMant), expon -= 31);
343 f += ldexp(IX_UNSIGNED_TO_DOUBLE(loMant), expon -= 32);
344 }
345 if ((src[0] & 0x80) != 0)
346 return (long)-f;
347 else
348 return (long)f;
349}
Audio classes, DirectSound interfaces and shared ix state.
IxSample * g_7_pSampleList
Definition system.cpp:16
@ IX_SAMPLE_READY
Definition ix.h:94
@ IX_SAMPLE_LOOPING
Definition ix.h:95
@ IX_SAMPLE_LOADING
Definition ix.h:96
void ix_log_printf(const char *fmt,...)
Definition stream.cpp:164
void ix_dsp_free(void *memory)
Definition dsp.cpp:318
void * ix_dsp_copy(void *destination, const void *source, unsigned int bytes)
Definition dsp.cpp:312
void * ix_dsp_alloc(unsigned int bytes)
Definition dsp.cpp:305
#define IX_SWAP_WORD(value)
Definition sample.cpp:17
#define IX_SAMPLE_FILE
Definition sample.cpp:15
#define IX_SWAP_DWORD(value)
Definition sample.cpp:21
#define IX_UNSIGNED_TO_DOUBLE(value)
Definition sample.cpp:27
short bitsPerSample
Definition sample.cpp:38
unsigned char sampleRate[10]
Definition sample.cpp:39
unsigned int sampleFrames
Definition sample.cpp:37
unsigned char nameLength
Definition sample.cpp:45
unsigned int position
Definition sample.cpp:44
unsigned int size
Definition sample.cpp:32
unsigned int id
Definition sample.cpp:31
unsigned int flags
Definition game.h:128
unsigned char * buffer
Definition ix.h:71
unsigned int frequency
Definition ix.h:78
int ix_sample_load_wav(void *data, int bytes)
Definition sample.cpp:199
unsigned int sampleCount
Definition ix.h:72
IxSample * next
Definition ix.h:82
int ix_sample_load_raw(void *data, int bytes, int frequency, int bitsPerSample, int channels)
Definition sample.cpp:292
unsigned int bitsPerSample
Definition ix.h:73
void ix_sample_construct(void)
Definition sample.cpp:58
unsigned int channels
Definition ix.h:74
unsigned int loopStart
Definition ix.h:79
unsigned int loopEnd
Definition ix.h:80
unsigned int rateNumerator
Definition ix.h:76
unsigned int rateDenominator
Definition ix.h:77
long ix_sample_convert_from_ieee_extended(unsigned char *bytes)
Definition sample.cpp:318
IxSample * previous
Definition ix.h:81
unsigned int bytesPerFrame
Definition ix.h:75
void ix_sample_destruct(void)
Definition sample.cpp:70
int ix_sample_load_aiff(void *data, int bytes)
Definition sample.cpp:85
unsigned int bytesPerSecond
Definition sample.cpp:52
unsigned short bitsPerSample
Definition sample.cpp:54
unsigned short format
Definition sample.cpp:49
unsigned short blockAlignment
Definition sample.cpp:53
unsigned short channels
Definition sample.cpp:50
int frequency
Definition sample.cpp:51