xma2defs.h 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /***************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation. All rights reserved.
  4. *
  5. * File: xma2defs.h
  6. * Content: Constants, data types and functions for XMA2 compressed audio.
  7. *
  8. ***************************************************************************/
  9. #ifndef __XMA2DEFS_INCLUDED__
  10. #define __XMA2DEFS_INCLUDED__
  11. #include <sal.h> // Markers for documenting API semantics
  12. #include <winerror.h> // For S_OK, E_FAIL
  13. #include <audiodefs.h> // Basic data types and constants for audio work
  14. /***************************************************************************
  15. * Overview
  16. ***************************************************************************/
  17. // A typical XMA2 file contains these RIFF chunks:
  18. //
  19. // 'fmt' or 'XMA2' chunk (or both): A description of the XMA data's structure
  20. // and characteristics (length, channels, sample rate, loops, block size, etc).
  21. //
  22. // 'seek' chunk: A seek table to help navigate the XMA data.
  23. //
  24. // 'data' chunk: The encoded XMA2 data.
  25. //
  26. // The encoded XMA2 data is structured as a set of BLOCKS, which contain PACKETS,
  27. // which contain FRAMES, which contain SUBFRAMES (roughly speaking). The frames
  28. // in a file may also be divided into several subsets, called STREAMS.
  29. //
  30. // FRAME: A variable-sized segment of XMA data that decodes to exactly 512 mono
  31. // or stereo PCM samples. This is the smallest unit of XMA data that can
  32. // be decoded in isolation. Frames are an arbitrary number of bits in
  33. // length, and need not be byte-aligned. See "XMA frame structure" below.
  34. //
  35. // SUBFRAME: A region of bits in an XMA frame that decodes to 128 mono or stereo
  36. // samples. The XMA decoder cannot decode a subframe in isolation; it needs
  37. // a whole frame to work with. However, it can begin emitting the frame's
  38. // decoded samples at any one of the four subframe boundaries. Subframes
  39. // can be addressed for seeking and looping purposes.
  40. //
  41. // PACKET: A 2Kb region containing a 32-bit header and some XMA frames. Frames
  42. // can (and usually do) span packets. A packet's header includes the offset
  43. // in bits of the first frame that begins within that packet. All of the
  44. // frames that begin in a given packet belong to the same "stream" (see the
  45. // Multichannel Audio section below).
  46. //
  47. // STREAM: A set of packets within an XMA file that all contain data for the
  48. // same mono or stereo component of a PCM file with more than two channels.
  49. // The packets comprising a given stream may be interleaved with each other
  50. // more or less arbitrarily; see Multichannel Audio.
  51. //
  52. // BLOCK: An array of XMA packets; or, to break it down differently, a series of
  53. // consecutive XMA frames, padded at the end with reserved data. A block
  54. // must contain at least one 2Kb packet per stream, and it can hold up to
  55. // 4095 packets (8190Kb), but its size is typically in the 32Kb-128Kb range.
  56. // (The size chosen involves a trade-off between memory use and efficiency
  57. // of reading from permanent storage.)
  58. //
  59. // XMA frames do not span blocks, so a block is guaranteed to begin with a
  60. // set of complete frames, one per stream. Also, a block in a multi-stream
  61. // XMA2 file always contains the same number of samples for each stream;
  62. // see Multichannel Audio.
  63. //
  64. // The 'data' chunk in an XMA2 file is an array of XMA2WAVEFORMAT.BlockCount XMA
  65. // blocks, all the same size (as specified in XMA2WAVEFORMAT.BlockSizeInBytes)
  66. // except for the last one, which may be shorter.
  67. // MULTICHANNEL AUDIO: the XMA decoder can only decode raw XMA data into either
  68. // mono or stereo PCM data. In order to encode a 6-channel file (say), the file
  69. // must be deinterleaved into 3 stereo streams that are encoded independently,
  70. // producing 3 encoded XMA data streams. Then the packets in these 3 streams
  71. // are interleaved to produce a single XMA2 file, and some information is added
  72. // to the file so that the original 6-channel audio can be reconstructed at
  73. // decode time. This works using the concept of an XMA stream (see above).
  74. //
  75. // The frames for all the streams in an XMA file are interleaved in an arbitrary
  76. // order. To locate a frame that belongs to a given stream in a given XMA block,
  77. // you must examine the first few packets in the block. Here (and only here) the
  78. // packets are guaranteed to be presented in stream order, so that all frames
  79. // beginning in packet 0 belong to stream 0 (the first stereo pair), etc.
  80. //
  81. // (This means that when decoding multi-stream XMA files, only entire XMA blocks
  82. // should be submitted to the decoder; otherwise it cannot know which frames
  83. // belong to which stream.)
  84. //
  85. // Once you have one frame that belongs to a given stream, you can find the next
  86. // one by looking at the frame's 'NextFrameOffsetBits' value (which is stored in
  87. // its first 15 bits; see XMAFRAME below). The GetXmaFrameBitPosition function
  88. // uses this technique.
  89. // SEEKING IN XMA2 FILES: Here is some pseudocode to find the byte position and
  90. // subframe in an XMA2 file which will contain sample S when decoded.
  91. //
  92. // 1. Traverse the seek table to find the XMA2 block containing sample S. The
  93. // seek table is an array of big-endian DWORDs, one per block in the file.
  94. // The Nth DWORD is the total number of PCM samples that would be obtained
  95. // by decoding the entire XMA file up to the end of block N. Hence, the
  96. // block we want is the first one whose seek table entry is greater than S.
  97. // (See the GetXmaBlockContainingSample helper function.)
  98. //
  99. // 2. Calculate which frame F within the block found above contains sample S.
  100. // Since each frame decodes to 512 samples, this is straightforward. The
  101. // first frame in the block produces samples X to X + 512, where X is the
  102. // seek table entry for the prior block. So F is (S - X) / 512.
  103. //
  104. // 3. Find the bit offset within the block where frame F starts. Since frames
  105. // are variable-sized, this can only be done by traversing all the frames in
  106. // the block until we reach frame F. (See GetXmaFrameBitPosition.)
  107. //
  108. // 4. Frame F has four 128-sample subframes. To find the subframe containing S,
  109. // we can use the formula (S % 512) / 128.
  110. //
  111. // In the case of multi-stream XMA files, sample S is a multichannel sample with
  112. // parts coming from several frames, one per stream. To find all these frames,
  113. // steps 2-4 need to be repeated for each stream N, using the knowledge that the
  114. // first packets in a block are presented in stream order. The frame traversal
  115. // in step 3 must be started at the first frame in the Nth packet of the block,
  116. // which will be the first frame for stream N. (And the packet header will tell
  117. // you the first frame's start position within the packet.)
  118. //
  119. // Step 1 can be performed using the GetXmaBlockContainingSample function below,
  120. // and steps 2-4 by calling GetXmaDecodePositionForSample once for each stream.
  121. /***************************************************************************
  122. * XMA constants
  123. ***************************************************************************/
  124. // Size of the PCM samples produced by the XMA decoder
  125. #define XMA_OUTPUT_SAMPLE_BYTES 2u
  126. #define XMA_OUTPUT_SAMPLE_BITS (XMA_OUTPUT_SAMPLE_BYTES * 8u)
  127. // Size of an XMA packet
  128. #define XMA_BYTES_PER_PACKET 2048u
  129. #define XMA_BITS_PER_PACKET (XMA_BYTES_PER_PACKET * 8u)
  130. // Size of an XMA packet header
  131. #define XMA_PACKET_HEADER_BYTES 4u
  132. #define XMA_PACKET_HEADER_BITS (XMA_PACKET_HEADER_BYTES * 8u)
  133. // Sample blocks in a decoded XMA frame
  134. #define XMA_SAMPLES_PER_FRAME 512u
  135. // Sample blocks in a decoded XMA subframe
  136. #define XMA_SAMPLES_PER_SUBFRAME 128u
  137. // Maximum encoded data that can be submitted to the XMA decoder at a time
  138. #define XMA_READBUFFER_MAX_PACKETS 4095u
  139. #define XMA_READBUFFER_MAX_BYTES (XMA_READBUFFER_MAX_PACKETS * XMA_BYTES_PER_PACKET)
  140. // Maximum size allowed for the XMA decoder's output buffers
  141. #define XMA_WRITEBUFFER_MAX_BYTES (31u * 256u)
  142. // Required byte alignment of the XMA decoder's output buffers
  143. #define XMA_WRITEBUFFER_BYTE_ALIGNMENT 256u
  144. // Decode chunk sizes for the XMA_PLAYBACK_INIT.subframesToDecode field
  145. #define XMA_MIN_SUBFRAMES_TO_DECODE 1u
  146. #define XMA_MAX_SUBFRAMES_TO_DECODE 8u
  147. #define XMA_OPTIMAL_SUBFRAMES_TO_DECODE 4u
  148. // LoopCount<255 means finite repetitions; LoopCount=255 means infinite looping
  149. #define XMA_MAX_LOOPCOUNT 254u
  150. #define XMA_INFINITE_LOOP 255u
  151. /***************************************************************************
  152. * XMA format structures
  153. ***************************************************************************/
  154. // The currently recommended way to express format information for XMA2 files
  155. // is the XMA2WAVEFORMATEX structure. This structure is fully compliant with
  156. // the WAVEFORMATEX standard and contains all the information needed to parse
  157. // and manage XMA2 files in a compact way.
  158. #define WAVE_FORMAT_XMA2 0x166
  159. typedef struct XMA2WAVEFORMATEX
  160. {
  161. WAVEFORMATEX wfx;
  162. // Meaning of the WAVEFORMATEX fields here:
  163. // wFormatTag; // Audio format type; always WAVE_FORMAT_XMA2
  164. // nChannels; // Channel count of the decoded audio
  165. // nSamplesPerSec; // Sample rate of the decoded audio
  166. // nAvgBytesPerSec; // Used internally by the XMA encoder
  167. // nBlockAlign; // Decoded sample size; channels * wBitsPerSample / 8
  168. // wBitsPerSample; // Bits per decoded mono sample; always 16 for XMA
  169. // cbSize; // Size in bytes of the rest of this structure (34)
  170. WORD NumStreams; // Number of audio streams (1 or 2 channels each)
  171. DWORD ChannelMask; // Spatial positions of the channels in this file,
  172. // stored as SPEAKER_xxx values (see audiodefs.h)
  173. DWORD SamplesEncoded; // Total number of PCM samples the file decodes to
  174. DWORD BytesPerBlock; // XMA block size (but the last one may be shorter)
  175. DWORD PlayBegin; // First valid sample in the decoded audio
  176. DWORD PlayLength; // Length of the valid part of the decoded audio
  177. DWORD LoopBegin; // Beginning of the loop region in decoded sample terms
  178. DWORD LoopLength; // Length of the loop region in decoded sample terms
  179. BYTE LoopCount; // Number of loop repetitions; 255 = infinite
  180. BYTE EncoderVersion; // Version of XMA encoder that generated the file
  181. WORD BlockCount; // XMA blocks in file (and entries in its seek table)
  182. } XMA2WAVEFORMATEX, *PXMA2WAVEFORMATEX;
  183. // The legacy XMA format structures are described here for reference, but they
  184. // should not be used in new content. XMAWAVEFORMAT was the structure used in
  185. // XMA version 1 files. XMA2WAVEFORMAT was used in early XMA2 files; it is not
  186. // placed in the usual 'fmt' RIFF chunk but in its own 'XMA2' chunk.
  187. #ifndef WAVE_FORMAT_XMA
  188. #define WAVE_FORMAT_XMA 0x0165
  189. // Values used in the ChannelMask fields below. Similar to the SPEAKER_xxx
  190. // values defined in audiodefs.h, but modified to fit in a single byte.
  191. #ifndef XMA_SPEAKER_LEFT
  192. #define XMA_SPEAKER_LEFT 0x01
  193. #define XMA_SPEAKER_RIGHT 0x02
  194. #define XMA_SPEAKER_CENTER 0x04
  195. #define XMA_SPEAKER_LFE 0x08
  196. #define XMA_SPEAKER_LEFT_SURROUND 0x10
  197. #define XMA_SPEAKER_RIGHT_SURROUND 0x20
  198. #define XMA_SPEAKER_LEFT_BACK 0x40
  199. #define XMA_SPEAKER_RIGHT_BACK 0x80
  200. #endif
  201. // Used in XMAWAVEFORMAT for per-stream data
  202. typedef struct XMASTREAMFORMAT
  203. {
  204. DWORD PsuedoBytesPerSec; // Used by the XMA encoder (typo preserved for legacy reasons)
  205. DWORD SampleRate; // The stream's decoded sample rate (in XMA2 files,
  206. // this is the same for all streams in the file).
  207. DWORD LoopStart; // Bit offset of the frame containing the loop start
  208. // point, relative to the beginning of the stream.
  209. DWORD LoopEnd; // Bit offset of the frame containing the loop end.
  210. BYTE SubframeData; // Two 4-bit numbers specifying the exact location of
  211. // the loop points within the frames that contain them.
  212. // SubframeEnd: Subframe of the loop end frame where
  213. // the loop ends. Ranges from 0 to 3.
  214. // SubframeSkip: Subframes to skip in the start frame to
  215. // reach the loop. Ranges from 0 to 4.
  216. BYTE Channels; // Number of channels in the stream (1 or 2)
  217. WORD ChannelMask; // Spatial positions of the channels in the stream
  218. } XMASTREAMFORMAT;
  219. // Legacy XMA1 format structure
  220. typedef struct XMAWAVEFORMAT
  221. {
  222. WORD FormatTag; // Audio format type (always WAVE_FORMAT_XMA)
  223. WORD BitsPerSample; // Bit depth (currently required to be 16)
  224. WORD EncodeOptions; // Options for XMA encoder/decoder
  225. WORD LargestSkip; // Largest skip used in interleaving streams
  226. WORD NumStreams; // Number of interleaved audio streams
  227. BYTE LoopCount; // Number of loop repetitions; 255 = infinite
  228. BYTE Version; // XMA encoder version that generated the file.
  229. // Always 3 or higher for XMA2 files.
  230. XMASTREAMFORMAT XmaStreams[1]; // Per-stream format information; the actual
  231. // array length is in the NumStreams field.
  232. } XMAWAVEFORMAT;
  233. // Used in XMA2WAVEFORMAT for per-stream data
  234. typedef struct XMA2STREAMFORMAT
  235. {
  236. BYTE Channels; // Number of channels in the stream (1 or 2)
  237. BYTE RESERVED; // Reserved for future use
  238. WORD ChannelMask; // Spatial positions of the channels in the stream
  239. } XMA2STREAMFORMAT;
  240. // Legacy XMA2 format structure (big-endian byte ordering)
  241. typedef struct XMA2WAVEFORMAT
  242. {
  243. BYTE Version; // XMA encoder version that generated the file.
  244. // Always 3 or higher for XMA2 files.
  245. BYTE NumStreams; // Number of interleaved audio streams
  246. BYTE RESERVED; // Reserved for future use
  247. BYTE LoopCount; // Number of loop repetitions; 255 = infinite
  248. DWORD LoopBegin; // Loop begin point, in samples
  249. DWORD LoopEnd; // Loop end point, in samples
  250. DWORD SampleRate; // The file's decoded sample rate
  251. DWORD EncodeOptions; // Options for the XMA encoder/decoder
  252. DWORD PsuedoBytesPerSec; // Used internally by the XMA encoder
  253. DWORD BlockSizeInBytes; // Size in bytes of this file's XMA blocks (except
  254. // possibly the last one). Always a multiple of
  255. // 2Kb, since XMA blocks are arrays of 2Kb packets.
  256. DWORD SamplesEncoded; // Total number of PCM samples encoded in this file
  257. DWORD SamplesInSource; // Actual number of PCM samples in the source
  258. // material used to generate this file
  259. DWORD BlockCount; // Number of XMA blocks in this file (and hence
  260. // also the number of entries in its seek table)
  261. XMA2STREAMFORMAT Streams[1]; // Per-stream format information; the actual
  262. // array length is in the NumStreams field.
  263. } XMA2WAVEFORMAT;
  264. #endif // #ifndef WAVE_FORMAT_XMA
  265. /***************************************************************************
  266. * XMA packet structure (in big-endian form)
  267. ***************************************************************************/
  268. typedef struct XMA2PACKET
  269. {
  270. int FrameCount : 6; // Number of XMA frames that begin in this packet
  271. int FrameOffsetInBits : 15; // Bit of XmaData where the first complete frame begins
  272. int PacketMetaData : 3; // Metadata stored in the packet (always 1 for XMA2)
  273. int PacketSkipCount : 8; // How many packets belonging to other streams must be
  274. // skipped to find the next packet belonging to this one
  275. BYTE XmaData[XMA_BYTES_PER_PACKET - sizeof(DWORD)]; // XMA encoded data
  276. } XMA2PACKET;
  277. // E.g. if the first DWORD of a packet is 0x30107902:
  278. //
  279. // 001100 000001000001111 001 00000010
  280. // | | | |____ Skip 2 packets to find the next one for this stream
  281. // | | |___________ XMA2 signature (always 001)
  282. // | |_____________________ First frame starts 527 bits into packet
  283. // |________________________________ Packet contains 12 frames
  284. // Helper functions to extract the fields above from an XMA packet. (Note that
  285. // the bitfields cannot be read directly on little-endian architectures such as
  286. // the Intel x86, as they are laid out in big-endian form.)
  287. __inline DWORD GetXmaPacketFrameCount(__in_bcount(1) const BYTE* pPacket)
  288. {
  289. return (DWORD)(pPacket[0] >> 2);
  290. }
  291. __inline DWORD GetXmaPacketFirstFrameOffsetInBits(__in_bcount(3) const BYTE* pPacket)
  292. {
  293. return ((DWORD)(pPacket[0] & 0x3) << 13) |
  294. ((DWORD)(pPacket[1]) << 5) |
  295. ((DWORD)(pPacket[2]) >> 3);
  296. }
  297. __inline DWORD GetXmaPacketMetadata(__in_bcount(3) const BYTE* pPacket)
  298. {
  299. return (DWORD)(pPacket[2] & 0x7);
  300. }
  301. __inline DWORD GetXmaPacketSkipCount(__in_bcount(4) const BYTE* pPacket)
  302. {
  303. return (DWORD)(pPacket[3]);
  304. }
  305. /***************************************************************************
  306. * XMA frame structure
  307. ***************************************************************************/
  308. // There is no way to represent the XMA frame as a C struct, since it is a
  309. // variable-sized string of bits that need not be stored at a byte-aligned
  310. // position in memory. This is the layout:
  311. //
  312. // XMAFRAME
  313. // {
  314. // LengthInBits: A 15-bit number representing the length of this frame.
  315. // XmaData: Encoded XMA data; its size in bits is (LengthInBits - 15).
  316. // }
  317. // Size in bits of the frame's initial LengthInBits field
  318. #define XMA_BITS_IN_FRAME_LENGTH_FIELD 15
  319. // Special LengthInBits value that marks an invalid final frame
  320. #define XMA_FINAL_FRAME_MARKER 0x7FFF
  321. /***************************************************************************
  322. * XMA helper functions
  323. ***************************************************************************/
  324. // We define a local ASSERT macro to equal the global one if it exists.
  325. // You can define XMA2DEFS_ASSERT in advance to override this default.
  326. #ifndef XMA2DEFS_ASSERT
  327. #ifdef ASSERT
  328. #define XMA2DEFS_ASSERT ASSERT
  329. #else
  330. #define XMA2DEFS_ASSERT(a) /* No-op by default */
  331. #endif
  332. #endif
  333. // GetXmaBlockContainingSample: Use a given seek table to find the XMA block
  334. // containing a given decoded sample. Note that the seek table entries in an
  335. // XMA file are stored in big-endian form and may need to be converted prior
  336. // to calling this function.
  337. __inline HRESULT GetXmaBlockContainingSample
  338. (
  339. DWORD nBlockCount, // Blocks in the file (= seek table entries)
  340. __in_ecount(nBlockCount) const DWORD* pSeekTable, // Pointer to the seek table data
  341. DWORD nDesiredSample, // Decoded sample to locate
  342. __out DWORD* pnBlockContainingSample, // Index of the block containing the sample
  343. __out DWORD* pnSampleOffsetWithinBlock // Position of the sample in this block
  344. )
  345. {
  346. DWORD nPreviousTotalSamples = 0;
  347. DWORD nBlock;
  348. DWORD nTotalSamplesSoFar;
  349. XMA2DEFS_ASSERT(pSeekTable);
  350. XMA2DEFS_ASSERT(pnBlockContainingSample);
  351. XMA2DEFS_ASSERT(pnSampleOffsetWithinBlock);
  352. for (nBlock = 0; nBlock < nBlockCount; ++nBlock)
  353. {
  354. nTotalSamplesSoFar = pSeekTable[nBlock];
  355. if (nTotalSamplesSoFar > nDesiredSample)
  356. {
  357. *pnBlockContainingSample = nBlock;
  358. *pnSampleOffsetWithinBlock = nDesiredSample - nPreviousTotalSamples;
  359. return S_OK;
  360. }
  361. nPreviousTotalSamples = nTotalSamplesSoFar;
  362. }
  363. return E_FAIL;
  364. }
  365. // GetXmaFrameLengthInBits: Reads a given frame's LengthInBits field.
  366. __inline DWORD GetXmaFrameLengthInBits
  367. (
  368. __in_bcount(nBitPosition / 8 + 3)
  369. __in const BYTE* pPacket, // Pointer to XMA packet[s] containing the frame
  370. DWORD nBitPosition // Bit offset of the frame within this packet
  371. )
  372. {
  373. DWORD nRegion;
  374. DWORD nBytePosition = nBitPosition / 8;
  375. DWORD nBitOffset = nBitPosition % 8;
  376. if (nBitOffset < 2) // Only need to read 2 bytes (and might not be safe to read more)
  377. {
  378. nRegion = (DWORD)(pPacket[nBytePosition+0]) << 8 |
  379. (DWORD)(pPacket[nBytePosition+1]);
  380. return (nRegion >> (1 - nBitOffset)) & 0x7FFF; // Last 15 bits
  381. }
  382. else // Need to read 3 bytes
  383. {
  384. nRegion = (DWORD)(pPacket[nBytePosition+0]) << 16 |
  385. (DWORD)(pPacket[nBytePosition+1]) << 8 |
  386. (DWORD)(pPacket[nBytePosition+2]);
  387. return (nRegion >> (9 - nBitOffset)) & 0x7FFF; // Last 15 bits
  388. }
  389. }
  390. // GetXmaFrameBitPosition: Calculates the bit offset of a given frame within
  391. // an XMA block or set of blocks. Returns 0 on failure.
  392. __inline DWORD GetXmaFrameBitPosition
  393. (
  394. __in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s]
  395. DWORD nXmaDataBytes, // Size of pXmaData in bytes
  396. DWORD nStreamIndex, // Stream within which to seek
  397. DWORD nDesiredFrame // Frame sought
  398. )
  399. {
  400. const BYTE* pCurrentPacket;
  401. DWORD nPacketsExamined = 0;
  402. DWORD nFrameCountSoFar = 0;
  403. DWORD nFramesToSkip;
  404. DWORD nFrameBitOffset;
  405. XMA2DEFS_ASSERT(pXmaData);
  406. XMA2DEFS_ASSERT(nXmaDataBytes % XMA_BYTES_PER_PACKET == 0);
  407. // Get the first XMA packet belonging to the desired stream, relying on the
  408. // fact that the first packets for each stream are in consecutive order at
  409. // the beginning of an XMA block.
  410. pCurrentPacket = pXmaData + nStreamIndex * XMA_BYTES_PER_PACKET;
  411. for (;;)
  412. {
  413. // If we have exceeded the size of the XMA data, return failure
  414. if (pCurrentPacket + XMA_BYTES_PER_PACKET > pXmaData + nXmaDataBytes)
  415. {
  416. return 0;
  417. }
  418. // If the current packet contains the frame we are looking for...
  419. if (nFrameCountSoFar + GetXmaPacketFrameCount(pCurrentPacket) > nDesiredFrame)
  420. {
  421. // See how many frames in this packet we need to skip to get to it
  422. XMA2DEFS_ASSERT(nDesiredFrame >= nFrameCountSoFar);
  423. nFramesToSkip = nDesiredFrame - nFrameCountSoFar;
  424. // Get the bit offset of the first frame in this packet
  425. nFrameBitOffset = XMA_PACKET_HEADER_BITS + GetXmaPacketFirstFrameOffsetInBits(pCurrentPacket);
  426. // Advance nFrameBitOffset to the frame of interest
  427. while (nFramesToSkip--)
  428. {
  429. nFrameBitOffset += GetXmaFrameLengthInBits(pCurrentPacket, nFrameBitOffset);
  430. }
  431. // The bit offset to return is the number of bits from pXmaData to
  432. // pCurrentPacket plus the bit offset of the frame of interest
  433. return (DWORD)(pCurrentPacket - pXmaData) * 8 + nFrameBitOffset;
  434. }
  435. // If we haven't found the right packet yet, advance our counters
  436. ++nPacketsExamined;
  437. nFrameCountSoFar += GetXmaPacketFrameCount(pCurrentPacket);
  438. // And skip to the next packet belonging to the same stream
  439. pCurrentPacket += XMA_BYTES_PER_PACKET * (GetXmaPacketSkipCount(pCurrentPacket) + 1);
  440. }
  441. }
  442. // GetLastXmaFrameBitPosition: Calculates the bit offset of the last complete
  443. // frame in an XMA block or set of blocks.
  444. __inline DWORD GetLastXmaFrameBitPosition
  445. (
  446. __in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s]
  447. DWORD nXmaDataBytes, // Size of pXmaData in bytes
  448. DWORD nStreamIndex // Stream within which to seek
  449. )
  450. {
  451. const BYTE* pLastPacket;
  452. DWORD nBytesToNextPacket;
  453. DWORD nFrameBitOffset;
  454. DWORD nFramesInLastPacket;
  455. XMA2DEFS_ASSERT(pXmaData);
  456. XMA2DEFS_ASSERT(nXmaDataBytes % XMA_BYTES_PER_PACKET == 0);
  457. XMA2DEFS_ASSERT(nXmaDataBytes >= XMA_BYTES_PER_PACKET * (nStreamIndex + 1));
  458. // Get the first XMA packet belonging to the desired stream, relying on the
  459. // fact that the first packets for each stream are in consecutive order at
  460. // the beginning of an XMA block.
  461. pLastPacket = pXmaData + nStreamIndex * XMA_BYTES_PER_PACKET;
  462. // Search for the last packet belonging to the desired stream
  463. for (;;)
  464. {
  465. nBytesToNextPacket = XMA_BYTES_PER_PACKET * (GetXmaPacketSkipCount(pLastPacket) + 1);
  466. XMA2DEFS_ASSERT(nBytesToNextPacket);
  467. if (pLastPacket + nBytesToNextPacket + XMA_BYTES_PER_PACKET > pXmaData + nXmaDataBytes)
  468. {
  469. break; // The next packet would extend beyond the end of pXmaData
  470. }
  471. pLastPacket += nBytesToNextPacket;
  472. }
  473. // The last packet can sometimes have no seekable frames, in which case we
  474. // have to use the previous one
  475. if (GetXmaPacketFrameCount(pLastPacket) == 0)
  476. {
  477. pLastPacket -= nBytesToNextPacket;
  478. }
  479. // Found the last packet. Get the bit offset of its first frame.
  480. nFrameBitOffset = XMA_PACKET_HEADER_BITS + GetXmaPacketFirstFrameOffsetInBits(pLastPacket);
  481. // Traverse frames until we reach the last one
  482. nFramesInLastPacket = GetXmaPacketFrameCount(pLastPacket);
  483. while (--nFramesInLastPacket)
  484. {
  485. nFrameBitOffset += GetXmaFrameLengthInBits(pLastPacket, nFrameBitOffset);
  486. }
  487. // The bit offset to return is the number of bits from pXmaData to
  488. // pLastPacket plus the offset of the last frame in this packet.
  489. return (DWORD)(pLastPacket - pXmaData) * 8 + nFrameBitOffset;
  490. }
  491. // GetXmaDecodePositionForSample: Obtains the information needed to make the
  492. // decoder generate audio starting at a given sample position relative to the
  493. // beginning of the given XMA block: the bit offset of the appropriate frame,
  494. // and the right subframe within that frame. This data can be passed directly
  495. // to the XMAPlaybackSetDecodePosition function.
  496. __inline HRESULT GetXmaDecodePositionForSample
  497. (
  498. __in_bcount(nXmaDataBytes) const BYTE* pXmaData, // Pointer to XMA block[s]
  499. DWORD nXmaDataBytes, // Size of pXmaData in bytes
  500. DWORD nStreamIndex, // Stream within which to seek
  501. DWORD nDesiredSample, // Sample sought
  502. __out DWORD* pnBitOffset, // Returns the bit offset within pXmaData of
  503. // the frame containing the sample sought
  504. __out DWORD* pnSubFrame // Returns the subframe containing the sample
  505. )
  506. {
  507. DWORD nDesiredFrame = nDesiredSample / XMA_SAMPLES_PER_FRAME;
  508. DWORD nSubFrame = (nDesiredSample % XMA_SAMPLES_PER_FRAME) / XMA_SAMPLES_PER_SUBFRAME;
  509. DWORD nBitOffset = GetXmaFrameBitPosition(pXmaData, nXmaDataBytes, nStreamIndex, nDesiredFrame);
  510. XMA2DEFS_ASSERT(pnBitOffset);
  511. XMA2DEFS_ASSERT(pnSubFrame);
  512. if (nBitOffset)
  513. {
  514. *pnBitOffset = nBitOffset;
  515. *pnSubFrame = nSubFrame;
  516. return S_OK;
  517. }
  518. else
  519. {
  520. return E_FAIL;
  521. }
  522. }
  523. // GetXmaSampleRate: Obtains the legal XMA sample rate (24, 32, 44.1 or 48Khz)
  524. // corresponding to a generic sample rate.
  525. __inline DWORD GetXmaSampleRate(DWORD dwGeneralRate)
  526. {
  527. DWORD dwXmaRate = 48000; // Default XMA rate for all rates above 44100Hz
  528. if (dwGeneralRate <= 24000) dwXmaRate = 24000;
  529. else if (dwGeneralRate <= 32000) dwXmaRate = 32000;
  530. else if (dwGeneralRate <= 44100) dwXmaRate = 44100;
  531. return dwXmaRate;
  532. }
  533. // Functions to convert between WAVEFORMATEXTENSIBLE channel masks (combinations
  534. // of the SPEAKER_xxx flags defined in audiodefs.h) and XMA channel masks (which
  535. // are limited to eight possible speaker positions: left, right, center, low
  536. // frequency, side left, side right, back left and back right).
  537. __inline DWORD GetStandardChannelMaskFromXmaMask(BYTE bXmaMask)
  538. {
  539. DWORD dwStandardMask = 0;
  540. if (bXmaMask & XMA_SPEAKER_LEFT) dwStandardMask |= SPEAKER_FRONT_LEFT;
  541. if (bXmaMask & XMA_SPEAKER_RIGHT) dwStandardMask |= SPEAKER_FRONT_RIGHT;
  542. if (bXmaMask & XMA_SPEAKER_CENTER) dwStandardMask |= SPEAKER_FRONT_CENTER;
  543. if (bXmaMask & XMA_SPEAKER_LFE) dwStandardMask |= SPEAKER_LOW_FREQUENCY;
  544. if (bXmaMask & XMA_SPEAKER_LEFT_SURROUND) dwStandardMask |= SPEAKER_SIDE_LEFT;
  545. if (bXmaMask & XMA_SPEAKER_RIGHT_SURROUND) dwStandardMask |= SPEAKER_SIDE_RIGHT;
  546. if (bXmaMask & XMA_SPEAKER_LEFT_BACK) dwStandardMask |= SPEAKER_BACK_LEFT;
  547. if (bXmaMask & XMA_SPEAKER_RIGHT_BACK) dwStandardMask |= SPEAKER_BACK_RIGHT;
  548. return dwStandardMask;
  549. }
  550. __inline BYTE GetXmaChannelMaskFromStandardMask(DWORD dwStandardMask)
  551. {
  552. BYTE bXmaMask = 0;
  553. if (dwStandardMask & SPEAKER_FRONT_LEFT) bXmaMask |= XMA_SPEAKER_LEFT;
  554. if (dwStandardMask & SPEAKER_FRONT_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT;
  555. if (dwStandardMask & SPEAKER_FRONT_CENTER) bXmaMask |= XMA_SPEAKER_CENTER;
  556. if (dwStandardMask & SPEAKER_LOW_FREQUENCY) bXmaMask |= XMA_SPEAKER_LFE;
  557. if (dwStandardMask & SPEAKER_SIDE_LEFT) bXmaMask |= XMA_SPEAKER_LEFT_SURROUND;
  558. if (dwStandardMask & SPEAKER_SIDE_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT_SURROUND;
  559. if (dwStandardMask & SPEAKER_BACK_LEFT) bXmaMask |= XMA_SPEAKER_LEFT_BACK;
  560. if (dwStandardMask & SPEAKER_BACK_RIGHT) bXmaMask |= XMA_SPEAKER_RIGHT_BACK;
  561. return bXmaMask;
  562. }
  563. // LocalizeXma2Format: Modifies a XMA2WAVEFORMATEX structure in place to comply
  564. // with the current platform's byte-ordering rules (little- or big-endian).
  565. __inline HRESULT LocalizeXma2Format(__inout XMA2WAVEFORMATEX* pXma2Format)
  566. {
  567. #define XMASWAP2BYTES(n) ((WORD)(((n) >> 8) | (((n) & 0xff) << 8)))
  568. #define XMASWAP4BYTES(n) ((DWORD)((n) >> 24 | (n) << 24 | ((n) & 0xff00) << 8 | ((n) & 0xff0000) >> 8))
  569. if (pXma2Format->wfx.wFormatTag == WAVE_FORMAT_XMA2)
  570. {
  571. return S_OK;
  572. }
  573. else if (XMASWAP2BYTES(pXma2Format->wfx.wFormatTag) == WAVE_FORMAT_XMA2)
  574. {
  575. pXma2Format->wfx.wFormatTag = XMASWAP2BYTES(pXma2Format->wfx.wFormatTag);
  576. pXma2Format->wfx.nChannels = XMASWAP2BYTES(pXma2Format->wfx.nChannels);
  577. pXma2Format->wfx.nSamplesPerSec = XMASWAP4BYTES(pXma2Format->wfx.nSamplesPerSec);
  578. pXma2Format->wfx.nAvgBytesPerSec = XMASWAP4BYTES(pXma2Format->wfx.nAvgBytesPerSec);
  579. pXma2Format->wfx.nBlockAlign = XMASWAP2BYTES(pXma2Format->wfx.nBlockAlign);
  580. pXma2Format->wfx.wBitsPerSample = XMASWAP2BYTES(pXma2Format->wfx.wBitsPerSample);
  581. pXma2Format->wfx.cbSize = XMASWAP2BYTES(pXma2Format->wfx.cbSize);
  582. pXma2Format->NumStreams = XMASWAP2BYTES(pXma2Format->NumStreams);
  583. pXma2Format->ChannelMask = XMASWAP4BYTES(pXma2Format->ChannelMask);
  584. pXma2Format->SamplesEncoded = XMASWAP4BYTES(pXma2Format->SamplesEncoded);
  585. pXma2Format->BytesPerBlock = XMASWAP4BYTES(pXma2Format->BytesPerBlock);
  586. pXma2Format->PlayBegin = XMASWAP4BYTES(pXma2Format->PlayBegin);
  587. pXma2Format->PlayLength = XMASWAP4BYTES(pXma2Format->PlayLength);
  588. pXma2Format->LoopBegin = XMASWAP4BYTES(pXma2Format->LoopBegin);
  589. pXma2Format->LoopLength = XMASWAP4BYTES(pXma2Format->LoopLength);
  590. pXma2Format->BlockCount = XMASWAP2BYTES(pXma2Format->BlockCount);
  591. return S_OK;
  592. }
  593. else
  594. {
  595. return E_FAIL; // Not a recognizable XMA2 format
  596. }
  597. #undef XMASWAP2BYTES
  598. #undef XMASWAP4BYTES
  599. }
  600. #endif // #ifndef __XMA2DEFS_INCLUDED__