Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

596 lines
16 KiB

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