Wing Commander
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
sample.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup ixlib
4 * @brief Sample objects: AIFF, WAV and raw loading.
5 *
6 * Originally `D:\Rnd\prj\ix\src\sound\sample.cpp`, address range
7 * 4486b0-4492c5, the last ix code before the import thunks and the CRT.
8 */
9#include "ix.h"
10#include <math.h>
11#include <dos.h>
12
13#define IX_SAMPLE_FILE "D:\\Rnd\\prj\\ix\\src\\sound\\sample.cpp"
14
15#define IX_SWAP_WORD(value) \
16 (short)((((value) & 0x00ff) << 8) | \
17 (((value) >> 8) & 0x00ff))
18
19#define IX_SWAP_DWORD(value) \
20 ((((unsigned int)(value) & 0x0000ff00) << 8) | \
21 (((unsigned int)(value) >> 8) & 0x0000ff00) | \
22 ((unsigned int)(value) << 24) | \
23 ((unsigned int)(value) >> 24))
24
25#define IX_UNSIGNED_TO_DOUBLE(value) \
26 ((double)(long)((value) - 2147483647L - 1) + 2147483648.0)
27
29 unsigned int id;
30 unsigned int size;
31};
32
34 short channels;
35 unsigned int sampleFrames;
37 unsigned char sampleRate[10];
38};
39
41 short id;
42 unsigned int position;
43 unsigned char nameLength;
44};
45
47 unsigned short format;
48 unsigned short channels;
50 unsigned int bytesPerSecond;
51 unsigned short blockAlignment;
52 unsigned short bitsPerSample;
53};
54
55/* Function start: 0x004486B0 */
57{
58 flags = 0;
59 buffer = 0;
60 next = pSamples;
61 previous = 0;
62 if (pSamples != 0)
63 pSamples->previous = this;
64 pSamples = this;
65}
66
67/* Function start: 0x0044870F */
69{
70 if (buffer != 0) {
72 buffer = 0;
73 }
74 if (this == pSamples)
75 pSamples = next;
76 if (next != 0)
78 if (previous != 0)
80}
81
82/* Function start: 0x0044879C */ /* source line(s) 166;169;170;193;195;197: sample already ready! | FORM id not found! | AIFF id not found! | Unsupported number of ch */
83int IxSample::ix_sample_load_aiff(void *data, int bytes)
84{
85 unsigned char *file = (unsigned char *)data;
86
87 if ((flags & IX_SAMPLE_READY) != 0) {
88 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 166);
89 ix_log_printf("sample already ready!");
90 return -1;
91 }
93 if (*(unsigned int *)file != *(unsigned int *)"FORM") {
94 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 169);
95 ix_log_printf("FORM id not found!");
96 return -1;
97 }
98 if (*(unsigned int *)(file + 8) != *(unsigned int *)"AIFF") {
99 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 170);
100 ix_log_printf("AIFF id not found!");
101 return -1;
102 }
103 {
104 unsigned char *end;
105 IxSampleChunk *chunk;
106
107 end = (unsigned char *)data + bytes;
108 chunk = (IxSampleChunk *)((unsigned char *)data + 12);
109 while ((unsigned char *)chunk < end) {
110 chunk->size = IX_SWAP_DWORD(chunk->size);
111 switch (chunk->id) {
112 case 0x4d4d4f43: {
113 int sampleRate;
114 IxAiffCommonChunk *common;
115
116 common = (IxAiffCommonChunk *)(chunk + 1);
117 common->channels = (short)(
118 (((unsigned int)common->channels << 8) & 0xff00) |
119 ((common->channels >> 8) & 0xff));
120 common->sampleFrames = IX_SWAP_DWORD(common->sampleFrames);
121 common->bitsPerSample = (short)(
122 ((common->bitsPerSample & 0xff00) >> 8) |
123 ((common->bitsPerSample & 0xff) << 8));
124 sampleRate = (int)ix_sample_convert_from_ieee_extended(common->sampleRate);
125 rateNumerator = 1;
127 if (common->channels != 1 && common->channels != 2) {
128 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 193);
129 ix_log_printf("Unsupported number of channels in AIFF!");
130 return -1;
131 }
132 if (sampleRate < 4000 || sampleRate > 44100) {
133 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 195);
134 ix_log_printf("Unsupported AIFF sample rate!");
135 return -1;
136 }
137 if (common->bitsPerSample != 8 && common->bitsPerSample != 16) {
138 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 197);
139 ix_log_printf("Unsupported AIFF bits per sample!");
140 return -1;
141 }
143 channels = common->channels;
144 frequency = sampleRate;
145 loopStart = 0;
146 loopEnd = (unsigned int)-1;
148 bytesPerFrame = ((int)bitsPerSample / 8) * (int)channels;
149 break;
150 }
151
152 case 0x4b52414d: {
153 IxAiffMarker *marker;
154
155 marker = (IxAiffMarker *)(chunk + 1);
156 marker = (IxAiffMarker *)((unsigned char *)marker + 2);
158 marker = (IxAiffMarker *)((unsigned char *)marker +
159 marker->nameLength + sizeof(IxAiffMarker));
160 while (((unsigned int)marker & 1) != 0)
161 marker = (IxAiffMarker *)((unsigned char *)marker + 1);
162 loopEnd = IX_SWAP_DWORD(marker->position);
164 break;
165 }
166
167 case 0x444e5353: {
168 int samplesRemaining;
169 unsigned short *samples;
170
171 buffer = (unsigned char *)ix_dsp_alloc(chunk->size);
172 sampleCount = chunk->size / bytesPerFrame;
173 if (loopEnd == (unsigned int)-1)
175 if (bitsPerSample == 16) {
176 samples = (unsigned short *)(chunk + 1);
177 samplesRemaining = sampleCount * channels;
178 while (samplesRemaining--) {
179 *samples = IX_SWAP_WORD(*samples);
180 samples++;
181 }
182 }
183 ix_dsp_copy(buffer, chunk + 1, chunk->size);
184 break;
185 }
186 default:
187 break;
188 }
189 chunk = (IxSampleChunk *)((unsigned char *)chunk +
190 chunk->size + sizeof(IxSampleChunk));
191 }
192 }
195 return 0;
196}
197
198/* Function start: 0x00448C8B */ /* 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 *file = (unsigned char *)data;
202
203 if ((flags & IX_SAMPLE_READY) != 0) {
204 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 261);
205 ix_log_printf("sample already ready!");
206 return -1;
207 }
209 if (*(unsigned int *)file != *(unsigned int *)"RIFF") {
210 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 264);
211 ix_log_printf("RIFF id not found!");
212 return -1;
213 }
214 if (*(unsigned int *)(file + 8) != *(unsigned int *)"WAVE") {
215 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 265);
216 ix_log_printf("WAVE id not found!");
217 return -1;
218 }
219 {
220 unsigned char *end;
221 IxSampleChunk *chunk;
222
223 end = (unsigned char *)data + bytes;
224 chunk = (IxSampleChunk *)((unsigned char *)data + 12);
225 while ((unsigned char *)chunk < end) {
226 switch (chunk->id) {
227 case 0x20746d66: {
228 IxWaveFormat *format;
229
230 format = (IxWaveFormat *)(chunk + 1);
231 if (format->channels != 1 && format->channels != 2) {
232 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 279);
233 ix_log_printf("Unsupported number of channels in WAV!");
234 return -1;
235 }
236 if (format->format != 1) {
237 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 281);
238 ix_log_printf("Unsupported WAV format!");
239 return -1;
240 }
241 if (format->frequency < 4000 || format->frequency > 44100) {
242 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 283);
243 ix_log_printf("Unsupported WAV sample rate!");
244 return -1;
245 }
246 if (format->bitsPerSample != 8 && format->bitsPerSample != 16) {
247 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 285);
248 ix_log_printf("Unsupported WAV bits per sample!");
249 return -1;
250 }
252 channels = format->channels;
253 frequency = format->frequency;
254 loopStart = 0;
255 loopEnd = (unsigned int)-1;
257 bytesPerFrame = ((int)bitsPerSample / 8) * (int)channels;
258 rateNumerator = 1;
260 break;
261 }
262
263 case 0x61746164: {
264 int samplesRemaining;
265 signed char *samples;
266
267 buffer = (unsigned char *)ix_dsp_alloc(chunk->size);
268 sampleCount = chunk->size / bytesPerFrame;
270 if (bitsPerSample == 8) {
271 samples = (signed char *)(chunk + 1);
272 samplesRemaining = bytesPerFrame * sampleCount;
273 while (samplesRemaining--) {
274 *samples = (signed char)(*samples - 0x80);
275 samples++;
276 }
277 }
278 ix_dsp_copy(buffer, chunk + 1, chunk->size);
279 break;
280 }
281 default:
282 break;
283 }
284 chunk = (IxSampleChunk *)((unsigned char *)chunk +
285 chunk->size + sizeof(IxSampleChunk));
286 }
287 }
290 return 0;
291}
292
293/* Function start: 0x00449044 */ /* source line(s) 333: sample already ready! */
294int IxSample::ix_sample_load_raw(void *data, int bytes, int newFrequency,
295 int newBitsPerSample, int newChannels)
296{
297 if ((flags & IX_SAMPLE_READY) != 0) {
298 ix_log_printf("Warning [%s - %d]:\n", IX_SAMPLE_FILE, 333);
299 ix_log_printf("sample already ready!");
300 return -1;
301 }
303 buffer = (unsigned char *)ix_dsp_alloc(bytes);
304 ix_dsp_copy(buffer, data, bytes);
305 bitsPerSample = newBitsPerSample;
306 channels = newChannels;
307 frequency = newFrequency;
308 loopStart = 0;
309 bytesPerFrame = ((int)bitsPerSample / 8) * (int)channels;
310 loopEnd = bytes / (int)bytesPerFrame;
312 rateNumerator = 1;
316 return 0;
317}
318
319/* Function start: 0x0044914C */
321{
322 /* Separate component scopes preserve the original /Od stack slots. */
323 unsigned long lowMantissa;
324 {
325 int exponent;
326 {
327 double value;
328 unsigned long highMantissa;
329 unsigned char *source;
330
331 source = bytes;
332 exponent = ((source[0] & 0x7f) << 8) | (source[1] & 0xff);
333 highMantissa = ((unsigned long)(source[2] & 0xFF) << 24) |
334 ((unsigned long)(source[3] & 0xFF) << 16) |
335 ((unsigned long)(source[4] & 0xFF) << 8) |
336 ((unsigned long)(source[5] & 0xFF));
337 lowMantissa = ((unsigned long)(source[6] & 0xFF) << 24) |
338 ((unsigned long)(source[7] & 0xFF) << 16) |
339 ((unsigned long)(source[8] & 0xFF) << 8) |
340 ((unsigned long)(source[9] & 0xFF));
341 if (exponent == 0 && highMantissa == 0 && lowMantissa == 0) {
342 value = 0;
343 } else if (exponent == 0x7fff) {
344 value = HUGE_VAL;
345 } else {
346 exponent -= 16383;
347 value = ldexp(IX_UNSIGNED_TO_DOUBLE(highMantissa),
348 exponent -= 31);
349 value += ldexp(IX_UNSIGNED_TO_DOUBLE(lowMantissa),
350 exponent -= 32);
351 }
352 if ((source[0] & 0x80) != 0)
353 return (long)-value;
354 else
355 return (long)value;
356 }
357 }
358}
The library's classes and shared declarations.
IxSample * pSamples
Definition system.cpp:16
@ IX_SAMPLE_READY
Definition ix.h:133
@ IX_SAMPLE_LOOPING
Definition ix.h:134
@ IX_SAMPLE_LOADING
Definition ix.h:135
void ix_log_printf(const char *fmt,...)
Definition ixlog.cpp:32
void ix_dsp_free(void *memory)
Definition dsp.cpp:311
void * ix_dsp_copy(void *destination, const void *source, unsigned int bytes)
Definition dsp.cpp:305
void * ix_dsp_alloc(unsigned int bytes)
Definition dsp.cpp:298
#define IX_SWAP_WORD(value)
Definition sample.cpp:15
#define IX_SAMPLE_FILE
Definition sample.cpp:13
#define IX_SWAP_DWORD(value)
Definition sample.cpp:19
#define IX_UNSIGNED_TO_DOUBLE(value)
Definition sample.cpp:25
short bitsPerSample
Definition sample.cpp:36
unsigned char sampleRate[10]
Definition sample.cpp:37
unsigned int sampleFrames
Definition sample.cpp:35
unsigned char nameLength
Definition sample.cpp:43
unsigned int position
Definition sample.cpp:42
unsigned int size
Definition sample.cpp:30
unsigned int id
Definition sample.cpp:29
unsigned int flags
Definition wc1base.h:55
unsigned char * buffer
Definition ix.h:110
unsigned int frequency
Definition ix.h:117
int ix_sample_load_wav(void *data, int bytes)
Definition sample.cpp:199
unsigned int sampleCount
Definition ix.h:111
IxSample * next
Definition ix.h:121
int ix_sample_load_raw(void *data, int bytes, int frequency, int bitsPerSample, int channels)
Definition sample.cpp:294
unsigned int bitsPerSample
Definition ix.h:112
void ix_sample_construct(void)
Definition sample.cpp:56
unsigned int channels
Definition ix.h:113
unsigned int loopStart
Definition ix.h:118
unsigned int loopEnd
Definition ix.h:119
unsigned int rateNumerator
Definition ix.h:115
unsigned int rateDenominator
Definition ix.h:116
long ix_sample_convert_from_ieee_extended(unsigned char *bytes)
Definition sample.cpp:320
IxSample * previous
Definition ix.h:120
unsigned int bytesPerFrame
Definition ix.h:114
void ix_sample_destruct(void)
Definition sample.cpp:68
int ix_sample_load_aiff(void *data, int bytes)
Definition sample.cpp:83
unsigned int bytesPerSecond
Definition sample.cpp:50
unsigned short bitsPerSample
Definition sample.cpp:52
unsigned short format
Definition sample.cpp:47
unsigned short blockAlignment
Definition sample.cpp:51
unsigned short channels
Definition sample.cpp:48
int frequency
Definition sample.cpp:49