zenilib: zenilib/jni/external/sdl/SDL/xma2defs.h Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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