Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /*************************************************************************** |
2 | * |
||
3 | * Copyright (c) Microsoft Corporation. All rights reserved. |
||
4 | * |
||
5 | * File: xact3wb.h |
||
6 | * Content: XACT 3 wave bank definitions. |
||
7 | * |
||
8 | ****************************************************************************/ |
||
9 | |||
10 | #ifndef __XACT3WB_H__ |
||
11 | #define __XACT3WB_H__ |
||
12 | |||
13 | #ifdef _XBOX |
||
14 | # include <xtl.h> |
||
15 | #else |
||
16 | # include <math.h> |
||
17 | #endif |
||
18 | |||
19 | #include <audiodefs.h> |
||
20 | #include <xma2defs.h> |
||
21 | |||
22 | #pragma warning(push) |
||
23 | #pragma warning(disable:4201) |
||
24 | #pragma warning(disable:4214) // nonstandard extension used : bit field types other than int |
||
25 | |||
26 | #pragma pack(push, 1) |
||
27 | #if !defined(_X86_) |
||
28 | #define XACTUNALIGNED __unaligned |
||
29 | #else |
||
30 | #define XACTUNALIGNED |
||
31 | #endif |
||
32 | |||
33 | #ifdef _M_PPCBE |
||
34 | #pragma bitfield_order(push, lsb_to_msb) |
||
35 | #endif |
||
36 | |||
37 | #define WAVEBANK_HEADER_SIGNATURE 'DNBW' // WaveBank RIFF chunk signature |
||
38 | #define WAVEBANK_HEADER_VERSION 44 // Current wavebank file version |
||
39 | |||
40 | #define WAVEBANK_BANKNAME_LENGTH 64 // Wave bank friendly name length, in characters |
||
41 | #define WAVEBANK_ENTRYNAME_LENGTH 64 // Wave bank entry friendly name length, in characters |
||
42 | |||
43 | #define WAVEBANK_MAX_DATA_SEGMENT_SIZE 0xFFFFFFFF // Maximum wave bank data segment size, in bytes |
||
44 | #define WAVEBANK_MAX_COMPACT_DATA_SEGMENT_SIZE 0x001FFFFF // Maximum compact wave bank data segment size, in bytes |
||
45 | |||
46 | typedef DWORD WAVEBANKOFFSET; |
||
47 | |||
48 | // |
||
49 | // Bank flags |
||
50 | // |
||
51 | |||
52 | #define WAVEBANK_TYPE_BUFFER 0x00000000 // In-memory buffer |
||
53 | #define WAVEBANK_TYPE_STREAMING 0x00000001 // Streaming |
||
54 | #define WAVEBANK_TYPE_MASK 0x00000001 |
||
55 | |||
56 | #define WAVEBANK_FLAGS_ENTRYNAMES 0x00010000 // Bank includes entry names |
||
57 | #define WAVEBANK_FLAGS_COMPACT 0x00020000 // Bank uses compact format |
||
58 | #define WAVEBANK_FLAGS_SYNC_DISABLED 0x00040000 // Bank is disabled for audition sync |
||
59 | #define WAVEBANK_FLAGS_SEEKTABLES 0x00080000 // Bank includes seek tables. |
||
60 | #define WAVEBANK_FLAGS_MASK 0x000F0000 |
||
61 | |||
62 | // |
||
63 | // Entry flags |
||
64 | // |
||
65 | |||
66 | #define WAVEBANKENTRY_FLAGS_READAHEAD 0x00000001 // Enable stream read-ahead |
||
67 | #define WAVEBANKENTRY_FLAGS_LOOPCACHE 0x00000002 // One or more looping sounds use this wave |
||
68 | #define WAVEBANKENTRY_FLAGS_REMOVELOOPTAIL 0x00000004 // Remove data after the end of the loop region |
||
69 | #define WAVEBANKENTRY_FLAGS_IGNORELOOP 0x00000008 // Used internally when the loop region can't be used |
||
70 | #define WAVEBANKENTRY_FLAGS_MASK 0x00000008 |
||
71 | |||
72 | // |
||
73 | // Entry wave format identifiers |
||
74 | // |
||
75 | |||
76 | #define WAVEBANKMINIFORMAT_TAG_PCM 0x0 // PCM data |
||
77 | #define WAVEBANKMINIFORMAT_TAG_XMA 0x1 // XMA data |
||
78 | #define WAVEBANKMINIFORMAT_TAG_ADPCM 0x2 // ADPCM data |
||
79 | #define WAVEBANKMINIFORMAT_TAG_WMA 0x3 // WMA data |
||
80 | |||
81 | #define WAVEBANKMINIFORMAT_BITDEPTH_8 0x0 // 8-bit data (PCM only) |
||
82 | #define WAVEBANKMINIFORMAT_BITDEPTH_16 0x1 // 16-bit data (PCM only) |
||
83 | |||
84 | // |
||
85 | // Arbitrary fixed sizes |
||
86 | // |
||
87 | #define WAVEBANKENTRY_XMASTREAMS_MAX 3 // enough for 5.1 channel audio |
||
88 | #define WAVEBANKENTRY_XMACHANNELS_MAX 6 // enough for 5.1 channel audio (cf. XAUDIOCHANNEL_SOURCEMAX) |
||
89 | |||
90 | // |
||
91 | // DVD data sizes |
||
92 | // |
||
93 | |||
94 | #define WAVEBANK_DVD_SECTOR_SIZE 2048 |
||
95 | #define WAVEBANK_DVD_BLOCK_SIZE (WAVEBANK_DVD_SECTOR_SIZE * 16) |
||
96 | |||
97 | // |
||
98 | // Bank alignment presets |
||
99 | // |
||
100 | |||
101 | #define WAVEBANK_ALIGNMENT_MIN 4 // Minimum alignment |
||
102 | #define WAVEBANK_ALIGNMENT_DVD WAVEBANK_DVD_SECTOR_SIZE // DVD-optimized alignment |
||
103 | |||
104 | // |
||
105 | // Wave bank segment identifiers |
||
106 | // |
||
107 | |||
108 | typedef enum WAVEBANKSEGIDX |
||
109 | { |
||
110 | WAVEBANK_SEGIDX_BANKDATA = 0, // Bank data |
||
111 | WAVEBANK_SEGIDX_ENTRYMETADATA, // Entry meta-data |
||
112 | WAVEBANK_SEGIDX_SEEKTABLES, // Storage for seek tables for the encoded waves. |
||
113 | WAVEBANK_SEGIDX_ENTRYNAMES, // Entry friendly names |
||
114 | WAVEBANK_SEGIDX_ENTRYWAVEDATA, // Entry wave data |
||
115 | WAVEBANK_SEGIDX_COUNT |
||
116 | } WAVEBANKSEGIDX, *LPWAVEBANKSEGIDX; |
||
117 | |||
118 | typedef const WAVEBANKSEGIDX *LPCWAVEBANKSEGIDX; |
||
119 | |||
120 | // |
||
121 | // Endianness |
||
122 | // |
||
123 | |||
124 | #ifdef __cplusplus |
||
125 | |||
126 | namespace XACTWaveBank |
||
127 | { |
||
128 | __inline void SwapBytes(XACTUNALIGNED DWORD &dw) |
||
129 | { |
||
130 | |||
131 | #ifdef _X86_ |
||
132 | |||
133 | __asm |
||
134 | { |
||
135 | mov edi, dw |
||
136 | mov eax, [edi] |
||
137 | bswap eax |
||
138 | mov [edi], eax |
||
139 | } |
||
140 | |||
141 | #else // _X86_ |
||
142 | |||
143 | dw = _byteswap_ulong(dw); |
||
144 | |||
145 | #endif // _X86_ |
||
146 | |||
147 | } |
||
148 | |||
149 | __inline void SwapBytes(XACTUNALIGNED WORD &w) |
||
150 | { |
||
151 | |||
152 | #ifdef _X86_ |
||
153 | |||
154 | __asm |
||
155 | { |
||
156 | mov edi, w |
||
157 | mov ax, [edi] |
||
158 | xchg ah, al |
||
159 | mov [edi], ax |
||
160 | } |
||
161 | |||
162 | #else // _X86_ |
||
163 | |||
164 | w = _byteswap_ushort(w); |
||
165 | |||
166 | #endif // _X86_ |
||
167 | |||
168 | } |
||
169 | |||
170 | } |
||
171 | |||
172 | #endif // __cplusplus |
||
173 | |||
174 | // |
||
175 | // Wave bank region in bytes. |
||
176 | // |
||
177 | |||
178 | typedef struct WAVEBANKREGION |
||
179 | { |
||
180 | DWORD dwOffset; // Region offset, in bytes. |
||
181 | DWORD dwLength; // Region length, in bytes. |
||
182 | |||
183 | #ifdef __cplusplus |
||
184 | |||
185 | void SwapBytes(void) |
||
186 | { |
||
187 | XACTWaveBank::SwapBytes(dwOffset); |
||
188 | XACTWaveBank::SwapBytes(dwLength); |
||
189 | } |
||
190 | |||
191 | #endif // __cplusplus |
||
192 | |||
193 | } WAVEBANKREGION, *LPWAVEBANKREGION; |
||
194 | |||
195 | typedef const WAVEBANKREGION *LPCWAVEBANKREGION; |
||
196 | |||
197 | |||
198 | // |
||
199 | // Wave bank region in samples. |
||
200 | // |
||
201 | |||
202 | typedef struct WAVEBANKSAMPLEREGION |
||
203 | { |
||
204 | DWORD dwStartSample; // Start sample for the region. |
||
205 | DWORD dwTotalSamples; // Region length in samples. |
||
206 | |||
207 | #ifdef __cplusplus |
||
208 | |||
209 | void SwapBytes(void) |
||
210 | { |
||
211 | XACTWaveBank::SwapBytes(dwStartSample); |
||
212 | XACTWaveBank::SwapBytes(dwTotalSamples); |
||
213 | } |
||
214 | |||
215 | #endif // __cplusplus |
||
216 | |||
217 | } WAVEBANKSAMPLEREGION, *LPWAVEBANKSAMPLEREGION; |
||
218 | |||
219 | typedef const WAVEBANKSAMPLEREGION *LPCWAVEBANKSAMPLEREGION; |
||
220 | |||
221 | |||
222 | // |
||
223 | // Wave bank file header |
||
224 | // |
||
225 | |||
226 | typedef struct WAVEBANKHEADER |
||
227 | { |
||
228 | DWORD dwSignature; // File signature |
||
229 | DWORD dwVersion; // Version of the tool that created the file |
||
230 | DWORD dwHeaderVersion; // Version of the file format |
||
231 | WAVEBANKREGION Segments[WAVEBANK_SEGIDX_COUNT]; // Segment lookup table |
||
232 | |||
233 | #ifdef __cplusplus |
||
234 | |||
235 | void SwapBytes(void) |
||
236 | { |
||
237 | XACTWaveBank::SwapBytes(dwSignature); |
||
238 | XACTWaveBank::SwapBytes(dwVersion); |
||
239 | XACTWaveBank::SwapBytes(dwHeaderVersion); |
||
240 | |||
241 | for(int i = 0; i < WAVEBANK_SEGIDX_COUNT; i++) |
||
242 | { |
||
243 | Segments[i].SwapBytes(); |
||
244 | } |
||
245 | } |
||
246 | |||
247 | #endif // __cplusplus |
||
248 | |||
249 | } WAVEBANKHEADER, *LPWAVEBANKHEADER; |
||
250 | |||
251 | typedef const WAVEBANKHEADER *LPCWAVEBANKHEADER; |
||
252 | |||
253 | // |
||
254 | // Table for converting WMA Average Bytes per Second values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field |
||
255 | // NOTE: There can be a max of 8 values in the table. |
||
256 | // |
||
257 | |||
258 | #define MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES 7 |
||
259 | |||
260 | static const DWORD aWMAAvgBytesPerSec[] = |
||
261 | { |
||
262 | 12000, |
||
263 | 24000, |
||
264 | 4000, |
||
265 | 6000, |
||
266 | 8000, |
||
267 | 20000, |
||
268 | 2500 |
||
269 | }; |
||
270 | // bitrate = entry * 8 |
||
271 | |||
272 | // |
||
273 | // Table for converting WMA Block Align values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field |
||
274 | // NOTE: There can be a max of 32 values in the table. |
||
275 | // |
||
276 | |||
277 | #define MAX_WMA_BLOCK_ALIGN_ENTRIES 17 |
||
278 | |||
279 | static const DWORD aWMABlockAlign[] = |
||
280 | { |
||
281 | 929, |
||
282 | 1487, |
||
283 | 1280, |
||
284 | 2230, |
||
285 | 8917, |
||
286 | 8192, |
||
287 | 4459, |
||
288 | 5945, |
||
289 | 2304, |
||
290 | 1536, |
||
291 | 1485, |
||
292 | 1008, |
||
293 | 2731, |
||
294 | 4096, |
||
295 | 6827, |
||
296 | 5462, |
||
297 | 1280 |
||
298 | }; |
||
299 | |||
300 | struct WAVEBANKENTRY; |
||
301 | |||
302 | // |
||
303 | // Entry compressed data format |
||
304 | // |
||
305 | |||
306 | typedef union WAVEBANKMINIWAVEFORMAT |
||
307 | { |
||
308 | struct |
||
309 | { |
||
310 | DWORD wFormatTag : 2; // Format tag |
||
311 | DWORD nChannels : 3; // Channel count (1 - 6) |
||
312 | DWORD nSamplesPerSec : 18; // Sampling rate |
||
313 | DWORD wBlockAlign : 8; // Block alignment. For WMA, lower 6 bits block alignment index, upper 2 bits bytes-per-second index. |
||
314 | DWORD wBitsPerSample : 1; // Bits per sample (8 vs. 16, PCM only); WMAudio2/WMAudio3 (for WMA) |
||
315 | }; |
||
316 | |||
317 | DWORD dwValue; |
||
318 | |||
319 | #ifdef __cplusplus |
||
320 | |||
321 | void SwapBytes(void) |
||
322 | { |
||
323 | XACTWaveBank::SwapBytes(dwValue); |
||
324 | } |
||
325 | |||
326 | WORD BitsPerSample() const |
||
327 | { |
||
328 | if (wFormatTag == WAVEBANKMINIFORMAT_TAG_XMA) |
||
329 | return XMA_OUTPUT_SAMPLE_BITS; // First, because most common on Xbox 360 |
||
330 | if (wFormatTag == WAVEBANKMINIFORMAT_TAG_WMA) |
||
331 | return 16; |
||
332 | if (wFormatTag == WAVEBANKMINIFORMAT_TAG_ADPCM) |
||
333 | return 4; // MSADPCM_BITS_PER_SAMPLE == 4 |
||
334 | |||
335 | // wFormatTag must be WAVEBANKMINIFORMAT_TAG_PCM (2 bits can only represent 4 different values) |
||
336 | return (wBitsPerSample == WAVEBANKMINIFORMAT_BITDEPTH_16) ? 16 : 8; |
||
337 | } |
||
338 | |||
339 | #define ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET 22 |
||
340 | DWORD BlockAlign() const |
||
341 | { |
||
342 | DWORD dwReturn = 0; |
||
343 | |||
344 | switch (wFormatTag) |
||
345 | { |
||
346 | case WAVEBANKMINIFORMAT_TAG_PCM: |
||
347 | dwReturn = wBlockAlign; |
||
348 | break; |
||
349 | |||
350 | case WAVEBANKMINIFORMAT_TAG_XMA: |
||
351 | dwReturn = nChannels * XMA_OUTPUT_SAMPLE_BITS / 8; |
||
352 | break; |
||
353 | |||
354 | case WAVEBANKMINIFORMAT_TAG_ADPCM: |
||
355 | dwReturn = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels; |
||
356 | break; |
||
357 | |||
358 | case WAVEBANKMINIFORMAT_TAG_WMA: |
||
359 | { |
||
360 | DWORD dwBlockAlignIndex = wBlockAlign & 0x1F; |
||
361 | if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES) |
||
362 | dwReturn = aWMABlockAlign[dwBlockAlignIndex]; |
||
363 | } |
||
364 | break; |
||
365 | } |
||
366 | |||
367 | return dwReturn; |
||
368 | } |
||
369 | |||
370 | DWORD AvgBytesPerSec() const |
||
371 | { |
||
372 | DWORD dwReturn = 0; |
||
373 | |||
374 | switch (wFormatTag) |
||
375 | { |
||
376 | case WAVEBANKMINIFORMAT_TAG_PCM: |
||
377 | case WAVEBANKMINIFORMAT_TAG_XMA: |
||
378 | dwReturn = nSamplesPerSec * wBlockAlign; |
||
379 | break; |
||
380 | |||
381 | case WAVEBANKMINIFORMAT_TAG_ADPCM: |
||
382 | { |
||
383 | DWORD blockAlign = BlockAlign(); |
||
384 | DWORD samplesPerAdpcmBlock = AdpcmSamplesPerBlock(); |
||
385 | dwReturn = blockAlign * nSamplesPerSec / samplesPerAdpcmBlock; |
||
386 | } |
||
387 | break; |
||
388 | |||
389 | case WAVEBANKMINIFORMAT_TAG_WMA: |
||
390 | { |
||
391 | DWORD dwBytesPerSecIndex = wBlockAlign >> 5; |
||
392 | if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES) |
||
393 | dwReturn = aWMAAvgBytesPerSec[dwBytesPerSecIndex]; |
||
394 | } |
||
395 | break; |
||
396 | } |
||
397 | |||
398 | return dwReturn; |
||
399 | } |
||
400 | |||
401 | DWORD EncodeWMABlockAlign(DWORD dwBlockAlign, DWORD dwAvgBytesPerSec) const |
||
402 | { |
||
403 | DWORD dwReturn = 0; |
||
404 | DWORD dwBlockAlignIndex = 0; |
||
405 | DWORD dwBytesPerSecIndex = 0; |
||
406 | |||
407 | for (; dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES && dwBlockAlign != aWMABlockAlign[dwBlockAlignIndex]; dwBlockAlignIndex++); |
||
408 | |||
409 | if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES) |
||
410 | { |
||
411 | for (; dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES && dwAvgBytesPerSec != aWMAAvgBytesPerSec[dwBytesPerSecIndex]; dwBytesPerSecIndex++); |
||
412 | |||
413 | if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES) |
||
414 | { |
||
415 | dwReturn = dwBlockAlignIndex | (dwBytesPerSecIndex << 5); |
||
416 | } |
||
417 | } |
||
418 | |||
419 | return dwReturn; |
||
420 | } |
||
421 | |||
422 | |||
423 | void XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const struct WAVEBANKENTRY* entry) const; |
||
424 | |||
425 | DWORD AdpcmSamplesPerBlock() const |
||
426 | { |
||
427 | DWORD nBlockAlign = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels; |
||
428 | return nBlockAlign * 2 / (DWORD)nChannels - 12; |
||
429 | } |
||
430 | |||
431 | void AdpcmFillCoefficientTable(ADPCMWAVEFORMAT *fmt) const |
||
432 | { |
||
433 | // These are fixed since we are always using MS ADPCM |
||
434 | fmt->wNumCoef = 7; /* MSADPCM_NUM_COEFFICIENTS */ |
||
435 | |||
436 | static ADPCMCOEFSET aCoef[7] = { { 256, 0}, {512, -256}, {0,0}, {192,64}, {240,0}, {460, -208}, {392,-232} }; |
||
437 | memcpy( &fmt->aCoef, aCoef, sizeof(aCoef) ); |
||
438 | } |
||
439 | |||
440 | #endif // __cplusplus |
||
441 | |||
442 | } WAVEBANKMINIWAVEFORMAT, *LPWAVEBANKMINIWAVEFORMAT; |
||
443 | |||
444 | typedef const WAVEBANKMINIWAVEFORMAT *LPCWAVEBANKMINIWAVEFORMAT; |
||
445 | |||
446 | // |
||
447 | // Entry meta-data |
||
448 | // |
||
449 | |||
450 | typedef struct WAVEBANKENTRY |
||
451 | { |
||
452 | union |
||
453 | { |
||
454 | struct |
||
455 | { |
||
456 | // Entry flags |
||
457 | DWORD dwFlags : 4; |
||
458 | |||
459 | // Duration of the wave, in units of one sample. |
||
460 | // For instance, a ten second long wave sampled |
||
461 | // at 48KHz would have a duration of 480,000. |
||
462 | // This value is not affected by the number of |
||
463 | // channels, the number of bits per sample, or the |
||
464 | // compression format of the wave. |
||
465 | DWORD Duration : 28; |
||
466 | }; |
||
467 | DWORD dwFlagsAndDuration; |
||
468 | }; |
||
469 | |||
470 | WAVEBANKMINIWAVEFORMAT Format; // Entry format. |
||
471 | WAVEBANKREGION PlayRegion; // Region within the wave data segment that contains this entry. |
||
472 | WAVEBANKSAMPLEREGION LoopRegion; // Region within the wave data (in samples) that should loop. |
||
473 | |||
474 | #ifdef __cplusplus |
||
475 | |||
476 | void SwapBytes(void) |
||
477 | { |
||
478 | XACTWaveBank::SwapBytes(dwFlagsAndDuration); |
||
479 | Format.SwapBytes(); |
||
480 | PlayRegion.SwapBytes(); |
||
481 | LoopRegion.SwapBytes(); |
||
482 | } |
||
483 | |||
484 | #endif // __cplusplus |
||
485 | |||
486 | } WAVEBANKENTRY, *LPWAVEBANKENTRY; |
||
487 | |||
488 | typedef const WAVEBANKENTRY *LPCWAVEBANKENTRY; |
||
489 | |||
490 | // |
||
491 | // Compact entry meta-data |
||
492 | // |
||
493 | |||
494 | typedef struct WAVEBANKENTRYCOMPACT |
||
495 | { |
||
496 | DWORD dwOffset : 21; // Data offset, in sectors |
||
497 | DWORD dwLengthDeviation : 11; // Data length deviation, in bytes |
||
498 | |||
499 | #ifdef __cplusplus |
||
500 | |||
501 | void SwapBytes(void) |
||
502 | { |
||
503 | XACTWaveBank::SwapBytes(*(LPDWORD)this); |
||
504 | } |
||
505 | |||
506 | #endif // __cplusplus |
||
507 | |||
508 | } WAVEBANKENTRYCOMPACT, *LPWAVEBANKENTRYCOMPACT; |
||
509 | |||
510 | typedef const WAVEBANKENTRYCOMPACT *LPCWAVEBANKENTRYCOMPACT; |
||
511 | |||
512 | // |
||
513 | // Bank data segment |
||
514 | // |
||
515 | |||
516 | typedef struct WAVEBANKDATA |
||
517 | { |
||
518 | DWORD dwFlags; // Bank flags |
||
519 | DWORD dwEntryCount; // Number of entries in the bank |
||
520 | CHAR szBankName[WAVEBANK_BANKNAME_LENGTH]; // Bank friendly name |
||
521 | DWORD dwEntryMetaDataElementSize; // Size of each entry meta-data element, in bytes |
||
522 | DWORD dwEntryNameElementSize; // Size of each entry name element, in bytes |
||
523 | DWORD dwAlignment; // Entry alignment, in bytes |
||
524 | WAVEBANKMINIWAVEFORMAT CompactFormat; // Format data for compact bank |
||
525 | FILETIME BuildTime; // Build timestamp |
||
526 | |||
527 | #ifdef __cplusplus |
||
528 | |||
529 | void SwapBytes(void) |
||
530 | { |
||
531 | XACTWaveBank::SwapBytes(dwFlags); |
||
532 | XACTWaveBank::SwapBytes(dwEntryCount); |
||
533 | XACTWaveBank::SwapBytes(dwEntryMetaDataElementSize); |
||
534 | XACTWaveBank::SwapBytes(dwEntryNameElementSize); |
||
535 | XACTWaveBank::SwapBytes(dwAlignment); |
||
536 | CompactFormat.SwapBytes(); |
||
537 | XACTWaveBank::SwapBytes(BuildTime.dwLowDateTime); |
||
538 | XACTWaveBank::SwapBytes(BuildTime.dwHighDateTime); |
||
539 | } |
||
540 | |||
541 | #endif // __cplusplus |
||
542 | |||
543 | } WAVEBANKDATA, *LPWAVEBANKDATA; |
||
544 | |||
545 | typedef const WAVEBANKDATA *LPCWAVEBANKDATA; |
||
546 | |||
547 | inline void WAVEBANKMINIWAVEFORMAT::XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const WAVEBANKENTRY* entry) const |
||
548 | { |
||
549 | // Note caller is responsbile for filling out fmt->wfx with other helper functions. |
||
550 | |||
551 | fmt->NumStreams = (WORD)( (nChannels + 1) / 2 ); |
||
552 | |||
553 | switch (nChannels) |
||
554 | { |
||
555 | case 1: fmt->ChannelMask = SPEAKER_MONO; break; |
||
556 | case 2: fmt->ChannelMask = SPEAKER_STEREO; break; |
||
557 | case 3: fmt->ChannelMask = SPEAKER_2POINT1; break; |
||
558 | case 4: fmt->ChannelMask = SPEAKER_QUAD; break; |
||
559 | case 5: fmt->ChannelMask = SPEAKER_4POINT1; break; |
||
560 | case 6: fmt->ChannelMask = SPEAKER_5POINT1; break; |
||
561 | case 7: fmt->ChannelMask = SPEAKER_5POINT1 | SPEAKER_BACK_CENTER; break; |
||
562 | case 8: fmt->ChannelMask = SPEAKER_7POINT1; break; |
||
563 | default: fmt->ChannelMask = 0; break; |
||
564 | } |
||
565 | |||
566 | fmt->SamplesEncoded = entry->Duration; |
||
567 | fmt->BytesPerBlock = 65536; /* XACT_FIXED_XMA_BLOCK_SIZE */ |
||
568 | |||
569 | fmt->PlayBegin = entry->PlayRegion.dwOffset; |
||
570 | fmt->PlayLength = entry->PlayRegion.dwLength; |
||
571 | |||
572 | if (entry->LoopRegion.dwTotalSamples > 0) |
||
573 | { |
||
574 | fmt->LoopBegin = entry->LoopRegion.dwStartSample; |
||
575 | fmt->LoopLength = entry->LoopRegion.dwTotalSamples; |
||
576 | fmt->LoopCount = 0xff; /* XACTLOOPCOUNT_INFINITE */ |
||
577 | } |
||
578 | else |
||
579 | { |
||
580 | fmt->LoopBegin = 0; |
||
581 | fmt->LoopLength = 0; |
||
582 | fmt->LoopCount = 0; |
||
583 | } |
||
584 | |||
585 | fmt->EncoderVersion = 4; // XMAENCODER_VERSION_XMA2 |
||
586 | |||
587 | fmt->BlockCount = blockCount; |
||
588 | } |
||
589 | |||
590 | #ifdef _M_PPCBE |
||
591 | #pragma bitfield_order(pop) |
||
592 | #endif |
||
593 | |||
594 | #pragma warning(pop) |
||
595 | #pragma pack(pop) |
||
596 | |||
597 | #endif // __XACTWB_H__ |
||
598 |