UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
radaudio_common.inl
Go to the documentation of this file.
1// Copyright Epic Games Tools, LLC. All Rights Reserved.
2#include "radaudio_common.h"
3#include "rrCore.h"
4#include <string.h>
5#include <stdio.h>
6
7static int sample_rates[4] =
8{
9 48000,
10 44100,
11 32000,
12 24000,
13};
14
17
18static radaudio_huffman *rada_nonzero_bitflags_huff[6] =
19{
20 &rada_nonzero_bitflags_huff0,
21 &rada_nonzero_bitflags_huff1,
22 &rada_nonzero_bitflags_huff2,
23 &rada_nonzero_bitflags_huff3,
24 &rada_nonzero_bitflags_huff4,
25 &rada_nonzero_bitflags_huff5,
26};
27
28static radaudio_huffman *rada_nonzero_coefficient_pair_huff[4] =
29{
30 &rada_nonzero_coefficient_pair_huff0,
31 &rada_nonzero_coefficient_pair_huff1,
32 &rada_nonzero_coefficient_pair_huff2,
33 &rada_nonzero_coefficient_pair_huff3,
34};
35
36static radaudio_huffman *rada_nonzero_coefficient_big_huff[4] =
37{
38 &rada_nonzero_coefficient_big_huff0,
39 &rada_nonzero_coefficient_big_huff1,
40 &rada_nonzero_coefficient_big_huff2,
41 &rada_nonzero_coefficient_big_huff3,
42};
43
44
45// each block picks between 4 modes using two bits in the block header.
46//
47// the meaning of the 4 modes is specified in the stream header, which is currently 128 bytes.
48// (a 1 second stereo sample at 100 kbps uses 12500 bytes, so stream header is 1% in this extreme case; not worth worrying about)
49//
50// for each of the four modes, the header specifies:
51// - which of 4 huffman tables to compress pairs of coefficients packed as nibbles (-7..7, plus overflow code)
52// - which of 4 huffman tables to compress coefficients whose magnitude exceeds 7
53// - how to encode the nonzero/zero information about the coefficients:
54// - when to transition between bit-encoding into 8 zero/non-zero flags per byte and using run length compression
55// - for each group of 8 bytes, which of 6 huffman tables to use to compress those 8 bytes
56// - whether to xor each byte with 255 before encoding
57// - in theory this effectively doubles the available huffman tables
58// - it was very effective in the original design that had one global huffman table
59// - it's used almost never in the current scheme with 6 huffman tables
60
61// slots in huffman selector array
62enum
63{
64 HS_COEFF_PAIR=0, // nibble pairs
65 HS_COEFF_BIG=1 // values whose magnitude exceeeds 7
66};
67
68// compute derived data about the bitflag byte packing to make decoding not require
69// any branching. all 8-byte blocks that use the same huffman table will be packed
70// together, and a table is built for how to reorder those to original order.
71static void compute_packorder(radaudio_nonzero_blockmode_descriptor *nz_desc)
72{
73 for (int i=0; i < nz_desc->num_8byte_chunks; ++i)
74 ++nz_desc->num_chunks_per_huff[nz_desc->huffman_table_for_chunk[i]];
75
76 // current output position for each huff; 0 is a placeholder for numbering convention
77 U8 pos[NUM_NZ_HUFF] = { 0 };
78
79 // mono
80 pos[0] = 0;
81 for (int i=1; i < NUM_NZ_HUFF; ++i) {
82 // starting position for each huff output is after all previous output, i.e. previous start + previous len
83 pos[i] = pos[i-1] + nz_desc->num_chunks_per_huff[i-1];
84 }
85
86 for (int i=0; i < nz_desc->num_8byte_chunks; ++i) {
87 int ht = nz_desc->huffman_table_for_chunk[i];
88 nz_desc->source_pos[0][i] = pos[ht];
89 ++pos[ht];
90 }
91
92 // stereo
93 pos[0] = 0;
94 for (int i=1; i < NUM_NZ_HUFF; ++i) {
95 // starting position for each huff output is after all previous output, i.e. previous start + previous len
96 pos[i] = pos[i-1] + 2*nz_desc->num_chunks_per_huff[i-1];
97 }
98
99 for (int c=0; c < MAX_RADAUD_CHANNELS; ++c) {
100 for (int i=0; i < nz_desc->num_8byte_chunks; ++i) {
101 int ht = nz_desc->huffman_table_for_chunk[i];
102 nz_desc->source_pos[1+c][i] = pos[ht];
103 ++pos[ht];
104 }
105 }
106}
107
108static void radaudio_init_nz_desc(radaudio_nonzero_blockmode_descriptor nz_desc[4])
109{
110 for (int i=0; i < 3; ++i)
111 compute_packorder(&nz_desc[i]);
112 // slot 3 is always all run-length
113}
114
115// mdct windows
116static float *radaudio_windows [2] = { window_long , window_short };
117
118static radaudio_cpu_features cpu_detect(void)
119{
120 radaudio_cpu_features f = { 0 };
121
122 #ifdef __RADX86__
123 // this function caches results so won't be an issue to call multiple times.
125
131 #endif
132
133 return f;
134}
135
136// values to scale band energy by to "normalize" for sample rate
137static int rate_scale[4] = {
138 235, // 48,000
139 256, // 44,100
140 353, // 32,000
141 470, // 24,000
142};
143
144// this function must compute same data in encoder and decoder so they stay in sync,
145// so it's integer/fixed-point only
146static void compute_mantissa_bitcount(int rate_mode,
147 int is_short_block,
148 S8 mantissa_param[][MAX_BANDS][2],
149 int *exponents,
151{
152 radaudio_rate_info *info = &radaudio_rateinfo[is_short_block][rate_mode];
153 int j;
154 int limit = 12 * rate_scale[rate_mode];
155 if (limit > 16*256) limit = 16*256; // never useful to have more than 16 bits of mantissa
156
157 for (j=0; j < info->num_bands; ++j) {
158 int be_log2 = exponents[j];
159 int mantissa_bits;
160 int base_bits = mantissa_param[is_short_block][j][0]<<5;
161 int bits_for_energy = be_log2 * mantissa_param[is_short_block][j][1];
163 mantissa_bits = 0;
164 else {
166 mantissa_bits = (mantissa_bits * rate_scale[rate_mode]) >> 8;
167 }
168 if (mantissa_bits < 0) mantissa_bits = 0;
170 mantissa_bitcount[j] = (U8) (mantissa_bits >> 8);
171 }
172}
173
174static int radaudio_code_sample_rate(int rate)
175{
176 int i;
177 if (rate > 0)
178 for (i=0; i < 4; ++i)
179 if (sample_rates[i] == rate)
180 return i;
181 return -1;
182}
183
184static void compute_bias_set(radaudio_block_header_biases *bc, U16 bias)
185{
186 bc->bytes_bias[0][0] = bc->bytes_bias[0][1] = bc->bytes_bias[0][2] = 0;
187 bc->bytes_bias[1][0] = bc->bytes_bias[1][1] = bc->bytes_bias[1][2] = 0;
188
189 // supplied value is stereo long block
190 bc->bytes_bias[0][2] = bias;
191
192 // mono long block uses half the bias
193 bc->bytes_bias[0][1] = (bias >> 1);
194}
195
196
197// flags at start of block packet
198
199// 0 overhead to use:
200#define RADAUDIO_BLOCKFLAG_8BIT_PARITY (1u << 0)
201#define RADAUDIO_BLOCKFLAG_THIS_SHORT (1u << 1)
202#define RADAUDIO_BLOCKFLAG_NEXT_SHORT (1u << 2)
203#define RADAUDIO_BLOCKFLAG_STEREO (1u << 3)
204#define RADAUDIO_BLOCKFLAG_MIDSIDE_BANDS (1u << 4)
205#define RADAUDIO_BLOCKFLAG_PREDICT_SUBBAND_STEREO (1u << 5)
206#define RADAUDIO_BLOCKFLAG_PREDICT_EXPONENT_STEREO (1u << 6)
207#define RADAUDIO_BLOCKFLAG_16BIT_FLAGS (1u << 7)
208// if any of these are set, it costs one more byte:
209#define RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MASK (3u << 8)
210#define RADAUDIO_BLOCKFLAG_DISABLE_SUBBAND_PREDICT (1u << 10)
211#define RADAUDIO_BLOCKFLAG_MIDSIDE_ENCODED (1u << 11)
212#define RADAUDIO_BLOCKFLAG_EXCESS_RUNLENGTH_ARRAY (1u << 12)
213#define RADAUDIO_BLOCKFLAG_EXCESS_VBSTREAM0_LENGTH (1u << 13)
214#define RADAUDIO_BLOCKFLAG_EXCESS_BLOCK_BYTES (1u << 14)
215#define RADAUDIO_BLOCKFLAG_FINAL (1u << 15)
216
217#define RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MODE_GET(x) (((x) >> 8) & 3u)
218#define RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MODE_SET(x) ((x) << 8)
219
220// use invalid flag combination as first byte of stream header, allows us to detect looping automatically
221// mono block, but stereo predict, also incorrect parity
222#define RADAUDIO_STREAMHEADER_FLAGS ( \
223 RADAUDIO_BLOCKFLAG_PREDICT_SUBBAND_STEREO \
224 | RADAUDIO_BLOCKFLAG_PREDICT_EXPONENT_STEREO \
225 )
226
227static int countbits8(U32 flags)
228{
229 flags = ((flags>>1) & 0x5555) + (flags & 0x5555); // binary: (0q0s0u0w & 01010101) + (0r0t0v0x & 01010101)
230 flags = ((flags>>2) & 0x3333) + (flags & 0x3333); // binary: foo & 00110011) + ( bar & 00110011)
231 return ((flags>>4) & 0x0f0f) + (flags & 0x0f0f); // binary: baz & 00001111) + ( quux & 00001111)
232}
233
234static int put_8bits_or_16bits(U8 buffer[9], int offset, U16 value)
235{
236 buffer[offset++] = (U8) (value & 255);
237 if (value >= 256)
238 buffer[offset++] = (U8) (value >> 8);
239 return offset;
240}
241
242typedef struct
243{
244 U16 flags, bytes, runlen, vbstream0;
246
247enum
248{
253
254static int radaudio_encode_block_header(U8 buffer[10], const radaudio_block_header_biases *bc, const radaudio_block_header_unpacked *bh)
255{
256 int offset=0;
257 U32 flags = 0;
258
259 // validate limits of what can be encoded in the header
260 if (bh->vbstream0_length > 65535)
261 return COMMON_INVALID_DATA;
262 if (bh->block_bytes > 65535)
263 return COMMON_INVALID_DATA;
264 if (bh->num_runlength_array > 65535)
265 return COMMON_INVALID_DATA;
266
267 // validate other aspects of configuration
268 if (bh->num_channels_encoded != 1 && bh->num_channels_encoded != 2)
269 return COMMON_INVALID_DATA;
270 if (bh->num_runlength_array > 2u * (bh->this_block_short ? RADAUDIO_SHORT_BLOCK_LEN+1 : RADAUDIO_LONG_BLOCK_LEN+1))
271 return COMMON_INVALID_DATA;
272
273 if (bh->final_block) {
274 if (bh->this_block_short) {
275 if (bh->final_samples_discard > RADAUDIO_SHORT_BLOCK_LEN)
276 return COMMON_INVALID_DATA;
277 } else {
278 // if we would ever discard final samples from a long block,
279 // it should have been sent as a series of short blocks instead
280 if (bh->final_samples_discard != 0)
281 return COMMON_INVALID_DATA;
282 }
283 }
284
285 U16 bias = bc->bytes_bias[bh->this_block_short][bh->num_channels_encoded];
286
287 U16 block_bytes_biased = (U16) ((bh->block_bytes - bias) & 0xffff);
288 U16 num_runlength_biased = (U16) ((bh->num_runlength_array - 0 ) & 0xffff);
289 U16 vbstream0_length_biased = (U16) ((bh->vbstream0_length - 0 ) & 0xffff);
290
291 if ( bh->this_block_short ) flags |= RADAUDIO_BLOCKFLAG_THIS_SHORT;
292 if ( bh->next_block_short ) flags |= RADAUDIO_BLOCKFLAG_NEXT_SHORT;
293 if ( bh->num_channels_encoded == 2 ) flags |= RADAUDIO_BLOCKFLAG_STEREO;
294 if ( bh->predict_stereo_subband ) flags |= RADAUDIO_BLOCKFLAG_PREDICT_SUBBAND_STEREO;
295 if ( bh->predict_stereo_exponent ) flags |= RADAUDIO_BLOCKFLAG_PREDICT_EXPONENT_STEREO;
296
297 flags |= RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MODE_SET(bh->nonzero_bitarray_mode);
298 if ( bh->final_block ) flags |= RADAUDIO_BLOCKFLAG_FINAL;
299 if ( bh->disable_final_subband_predict ) flags |= RADAUDIO_BLOCKFLAG_DISABLE_SUBBAND_PREDICT;
300 if ( bh->mid_side_encoded ) flags |= RADAUDIO_BLOCKFLAG_MIDSIDE_ENCODED;
301 if ( bh->mid_side_bands ) flags |= RADAUDIO_BLOCKFLAG_MIDSIDE_BANDS;
302
306
307 if ( flags >= 256 ) flags |= RADAUDIO_BLOCKFLAG_16BIT_FLAGS;
308
309 // force odd parity
310 if ( (countbits8(flags&255) & 1) == 0 ) flags |= RADAUDIO_BLOCKFLAG_8BIT_PARITY;
311
312 // write 1 byte if 0..255, otherwise 2 bytes
313 offset = put_8bits_or_16bits(buffer, offset, (U16) flags);
314 offset = put_8bits_or_16bits(buffer, offset, block_bytes_biased);
315 offset = put_8bits_or_16bits(buffer, offset, num_runlength_biased);
316 offset = put_8bits_or_16bits(buffer, offset, vbstream0_length_biased);
317
318 if (bh->final_block) {
319 RR_PUT16_LE(&buffer[offset], (U16) bh->final_samples_discard);
320 offset += 2;
321 }
322
323 // maximum written is 5 16-bit values, i.e. 10 bytes
324
325 return offset;
326}
327
328// returns length of header in bytes
329// returns RADAUDIO_INCOMPLETE_DATA if there's not enough data to decode the header
330// returns RADAUDIO_INVALID_DATA if the header fails some simple validity tests
331static int radaudio_decode_block_header(const U8 buffer[10], const radaudio_block_header_biases *bc, radaudio_block_header_unpacked *bh, size_t memavail)
332{
333 int offset = 0;
334
335 // block header is a minimum of 4 bytes
336 if (memavail < 4)
338
339 U16 flags = buffer[offset++];
340
341 // if flags value is the magic byte that's the first byte of a stream, assume we're scanning the beginning of the stream
342 if (flags == RADAUDIO_STREAMHEADER_FLAGS)
344
345 // check parity of first flag byte to catch corrupt streams as soon as possible
346 // can't check before above test because RADAUDIO_STREAMHEADER_FLAGS intentionally has wrong parity
347 if ((countbits8(flags) & 1) == 0)
348 return COMMON_INVALID_DATA;
349
350 // read second byte of flags if there is one
352 flags |= buffer[offset++] << 8;
353
354 // compute header length based on flags
355 size_t header_length = offset;
356
357 header_length += (flags & RADAUDIO_BLOCKFLAG_EXCESS_BLOCK_BYTES) ? 2 : 1;
358 header_length += (flags & RADAUDIO_BLOCKFLAG_EXCESS_RUNLENGTH_ARRAY) ? 2 : 1;
359 header_length += (flags & RADAUDIO_BLOCKFLAG_EXCESS_VBSTREAM0_LENGTH) ? 2 : 1;
360 header_length += (flags & RADAUDIO_BLOCKFLAG_FINAL) ? 2 : 0;
361
362 if ((size_t)header_length > memavail)
364
365 // at this point all data should be available, so no length checking is needed
366
367 bh->this_block_short = ((flags & RADAUDIO_BLOCKFLAG_THIS_SHORT ) != 0 );
368 bh->next_block_short = ((flags & RADAUDIO_BLOCKFLAG_NEXT_SHORT ) != 0 );
369 bh->num_channels_encoded = ((flags & RADAUDIO_BLOCKFLAG_STEREO ) ? 2 : 1);
370 bh->predict_stereo_subband = ((flags & RADAUDIO_BLOCKFLAG_PREDICT_SUBBAND_STEREO ) != 0 );
371 bh->predict_stereo_exponent = ((flags & RADAUDIO_BLOCKFLAG_PREDICT_EXPONENT_STEREO ) != 0 );
372
373 bh->nonzero_bitarray_mode = RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MODE_GET(flags);
374 bh->final_block = ((flags & RADAUDIO_BLOCKFLAG_FINAL ) != 0 );
375 bh->disable_final_subband_predict = ((flags & RADAUDIO_BLOCKFLAG_DISABLE_SUBBAND_PREDICT ) != 0 );
376 bh->mid_side_encoded = ((flags & RADAUDIO_BLOCKFLAG_MIDSIDE_ENCODED ) != 0 );
377 bh->mid_side_bands = ((flags & RADAUDIO_BLOCKFLAG_MIDSIDE_BANDS ) != 0 );
378
379 U16 block_bytes, num_runlength_array, vbstream0_length;
380
381 // if values are sent as two bytes, verify that they required two bytes.
382 // unlikely to catch stream corruption, but it can't hurt.
383
384 if ((flags & RADAUDIO_BLOCKFLAG_EXCESS_BLOCK_BYTES)==0) {
385 block_bytes = buffer[offset++];
386 } else {
387 block_bytes = RR_GET16_LE(&buffer[offset]);
388 if (block_bytes < 256)
389 return COMMON_INVALID_DATA;
390 offset += 2;
391 }
392
394 num_runlength_array = buffer[offset++];
395 } else {
396 num_runlength_array = RR_GET16_LE(&buffer[offset]);
397 if (num_runlength_array < 256)
398 return COMMON_INVALID_DATA;
399 offset += 2;
400 }
401
403 vbstream0_length = buffer[offset++];
404 } else {
405 vbstream0_length = RR_GET16_LE(&buffer[offset]);
406 if (vbstream0_length < 256)
407 return COMMON_INVALID_DATA;
408 offset += 2;
409 }
410
411 if (bh->final_block) {
412 bh->final_samples_discard = RR_GET16_LE(&buffer[offset]);
413 offset += 2;
414 }
415
416 bh->block_bytes = (U16) (block_bytes + bc->bytes_bias[bh->this_block_short][bh->num_channels_encoded]);
417 bh->num_runlength_array = (U16) (num_runlength_array + 0 );
418 bh->vbstream0_length = (U16) (vbstream0_length + 0 );
419
420 // let caller do further sanity checking
421
422 return offset;
423}
424
425// all values little-endian
426typedef struct
427{
428 char magic[8];
432 // 16 bytes
433
434 U8 num_channels; // must be 1 or 2
435 U8 nzmode_data1[NUM_NZ_MODE/2]; // 4 modes, 1 nibble each, packed number of 8-byte chunks for 4 modes
436 U8 nzmode_data2[NUM_SELECTOR_MODES*1]; // 5 modes, 1 byte each, coding 4 2-bit huffman selectors
437 U8 nzmode_data3[(NUM_NZ_MODE-1)*(MAX_NZ_BLOCKS/2)]; // 3 modes, 12 nibbles each, coding 12 4-bit huffman selectors + inversion bit
438 // 26 bytes
439
440 U8 subband_predicted_sum[MAX_BANDS];
441 S8 mantissa_param[2][MAX_BANDS/4][2];
442 // 48 bytes
443
444 U8 padding[128-16-26-48];
446
448
449static const char RADAUDIO_MAGIC[8] = {
451 'R', 'a', 'd',
452
453 'A', 'u', 'd',
454 '\032', // ^Z
455};
456
457// bitflag in packed and unpacked stream header signalling to if an 8-byte block should be xor-with-255
458// we don't process it here, we let client process it
459#define NZ_MODE_INVERT (1<<3)
460
461static size_t radaudio_pack_stream_header(U8 *raw_header,
463{
464 if (h->sample_rate <= 0 || h->sample_rate > 65535)
465 return 0;
466 if (h->version < 0 || h->version > MAX_VALID_VERSION )
467 return 0;
468 if (h->num_channels <= 0 || h->num_channels > 2 )
469 return 0;
470
471 if (h->sample_rate != 48000 && h->sample_rate != 44100 && h->sample_rate != 32000 && h->sample_rate != 24000)
472 return 0;
473
475 memset(header, 0, sizeof(*header));
476
477 memcpy(header->magic, RADAUDIO_MAGIC, sizeof(header->magic));
478 header->version = h->version;
479 header->num_channels = (U8 ) h->num_channels;
480 header->sample_rate = (U16) h->sample_rate;
481
483 for (int i=0; i < MAX_BANDS/4; ++i) {
484 header->mantissa_param[0][i][0] = h->mantissa_param[0][i*4+0][0];
485 header->mantissa_param[0][i][1] = h->mantissa_param[0][i*4+0][1];
486 header->mantissa_param[1][i][0] = h->mantissa_param[1][i*4+0][0];
487 header->mantissa_param[1][i][1] = h->mantissa_param[1][i*4+0][1];
488 }
489 header->bytes_bias = h->bytes_bias;
490
491 // pack each mode
492 for (int i=0; i < NUM_NZ_MODE/2; ++i)
493 header->nzmode_data1[i] = h->nzmode_num64[2*i+0] | (h->nzmode_num64[2*i+1] << 4);
494
495 // pack general huff selectors
496 for (int i=0; i < NUM_SELECTOR_MODES; ++i) {
497 U8 value = 0;
498 for (int j=0; j < 4; ++j)
499 value |= h->nzmode_selectors[j][i] << (2*j);
500 header->nzmode_data2[i] = value;
501 }
502
503 // pack nz huff selectors
504 for (int i=0; i < NUM_NZ_MODE-1; ++i) {
505 for (int j=0; j < MAX_NZ_BLOCKS/2; ++j) {
506 U8 value;
507 value = h->nzmode_huff[i][j*2+0] ;
508 value |= h->nzmode_huff[i][j*2+1] << 4;
509 header->nzmode_data3[i*MAX_NZ_BLOCKS/2+j] = value;
510 }
511 }
512
513 return sizeof(*header);
514}
515
516static rrbool radaudio_check_stream_header(U8 *raw_header, size_t raw_header_bytes_valid)
517{
519 if (raw_header_bytes_valid < 8) // can we check MAGIC?
520 return false;
521 return (0 == memcmp(header->magic, RADAUDIO_MAGIC, sizeof(header->magic)));
522}
523
524static size_t radaudio_unpack_stream_header(U8 *raw_header, size_t raw_header_bytes_valid, radaudio_stream_header_unpacked *h)
525{
527
528 if (!radaudio_check_stream_header(raw_header, raw_header_bytes_valid))
529 return 0;
530
531 // we are going to directly address everything up to the padding
532 // in the header
533 size_t required_header_bytes = sizeof(radaudio_stream_header) - sizeof(header->padding);
535 return 0;
536
537 h->sample_rate_mode = radaudio_code_sample_rate(header->sample_rate);
538 if (h->sample_rate_mode < 0)
539 return 0;
540
541 h->sample_rate = header->sample_rate;
542 h->num_channels = header->num_channels;
543 h->version = header->version;
544 h->bytes_bias = header->bytes_bias;
546 memcpy(h->mantissa_param, header->mantissa_param, sizeof(header->mantissa_param));
547
548 for (int i=0; i < MAX_BANDS/4; ++i) {
549 for (int j=0; j < 4; ++j) {
550 h->mantissa_param[0][i*4+j][0] = header->mantissa_param[0][i][0];
551 h->mantissa_param[0][i*4+j][1] = header->mantissa_param[0][i][1];
552 h->mantissa_param[1][i*4+j][0] = header->mantissa_param[1][i][0];
553 h->mantissa_param[1][i*4+j][1] = header->mantissa_param[1][i][1];
554 }
555 }
556
557 // unpack each mode
558 for (int i=0; i < NUM_NZ_MODE/2; ++i) {
559 h->nzmode_num64[2*i+0] = header->nzmode_data1[i] & 15;
560 h->nzmode_num64[2*i+1] = header->nzmode_data1[i] >> 4;
561 }
562
563 // unpack general huff selectors
564 for (int i=0; i < NUM_SELECTOR_MODES; ++i) {
565 U8 value = header->nzmode_data2[i];
566 for (int j=0; j < 4; ++j) {
567 h->nzmode_selectors[j][i] = (value >> (2*j)) & 3;
568 }
569 }
570
571 // unpack nz huff selectors
572 for (int i=0; i < NUM_NZ_MODE-1; ++i) {
573 for (int j=0; j < MAX_NZ_BLOCKS/2; ++j) {
574 U8 value = header->nzmode_data3[i*MAX_NZ_BLOCKS/2+j];
575 h->nzmode_huff[i][j*2+0] = value & 15;
576 h->nzmode_huff[i][j*2+1] = value >> 4;
577 }
578 }
579
580 radaudio_rate_info *bi = &radaudio_rateinfo[0][h->sample_rate_mode];
581 // compute derived bias values
582 for (int i=0; i < bi->num_bands; ++i)
583 if (bi->num_subbands_for_band[i] != 1) {
585 }
586 else
587 h->subband_bias[i] = (S8) -1;
588
589 if (h->num_channels < 1 || h->num_channels > 2)
590 return 0;
591 if (h->version > MAX_VALID_VERSION)
592 return 0;
593
594 return sizeof(*header);
595}
RAD_S8 S8
Definition egttypes.h:476
RAD_U32 U32
Definition egttypes.h:501
RAD_U8 U8
Definition egttypes.h:481
#define RR_COMPILER_ASSERT(exp)
Definition egttypes.h:411
S32 rrbool
Definition egttypes.h:536
RAD_U16 U16
Definition egttypes.h:491
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
memcpy(InputBufferBase, BinkBlocksData, BinkBlocksSize)
#define RRX86_CPU_AVX2
Definition cpux86.h:25
#define RRX86_CPU_SSE41
Definition cpux86.h:20
#define RRX86_CPU_SSE2
Definition cpux86.h:18
#define RRX86_CPU_SSSE3
Definition cpux86.h:19
#define rrCPUx86_feature_present(bit)
Definition cpux86.h:89
#define RRX86_CPU_POPCNT
Definition cpux86.h:30
#define rrCPUx86_detect()
Definition cpux86.h:88
#define MAX_BANDS
Definition radaudio_common.h:29
#define NUM_NZ_HUFF
Definition radaudio_common.h:61
#define BAND_EXPONENT_NONE
Definition radaudio_common.h:50
#define RADAUDIO_LONG_BLOCK_LEN
Definition radaudio_common.h:26
#define MAX_VALID_VERSION
Definition radaudio_common.h:5
#define MAX_NZ_BLOCKS
Definition radaudio_common.h:62
#define SUBBAND_BIAS_CENTER
Definition radaudio_common.h:56
#define NUM_NZ_MODE
Definition radaudio_common.h:58
#define NUM_SELECTOR_MODES
Definition radaudio_common.h:59
#define RADAUDIO_SHORT_BLOCK_LEN
Definition radaudio_common.h:27
#define MAX_RADAUD_CHANNELS
Definition radaudio_common.h:34
#define RADAUDIO_BLOCKFLAG_THIS_SHORT
Definition radaudio_common.inl:201
@ COMMON_STREAM_HEADER
Definition radaudio_common.inl:251
@ COMMON_INCOMPLETE_DATA
Definition radaudio_common.inl:249
@ COMMON_INVALID_DATA
Definition radaudio_common.inl:250
#define RADAUDIO_BLOCKFLAG_8BIT_PARITY
Definition radaudio_common.inl:200
#define RADAUDIO_BLOCKFLAG_DISABLE_SUBBAND_PREDICT
Definition radaudio_common.inl:210
#define RADAUDIO_BLOCKFLAG_NEXT_SHORT
Definition radaudio_common.inl:202
#define RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MODE_SET(x)
Definition radaudio_common.inl:218
#define RADAUDIO_BLOCKFLAG_NONZERO_BITARRAY_MODE_GET(x)
Definition radaudio_common.inl:217
#define RADAUDIO_BLOCKFLAG_MIDSIDE_ENCODED
Definition radaudio_common.inl:211
@ HS_COEFF_PAIR
Definition radaudio_common.inl:64
@ HS_COEFF_BIG
Definition radaudio_common.inl:65
#define RADAUDIO_BLOCKFLAG_EXCESS_BLOCK_BYTES
Definition radaudio_common.inl:214
#define RADAUDIO_BLOCKFLAG_PREDICT_SUBBAND_STEREO
Definition radaudio_common.inl:205
#define RADAUDIO_BLOCKFLAG_EXCESS_VBSTREAM0_LENGTH
Definition radaudio_common.inl:213
#define RADAUDIO_BLOCKFLAG_16BIT_FLAGS
Definition radaudio_common.inl:207
#define RADAUDIO_BLOCKFLAG_EXCESS_RUNLENGTH_ARRAY
Definition radaudio_common.inl:212
#define RADAUDIO_BLOCKFLAG_FINAL
Definition radaudio_common.inl:215
#define RADAUDIO_BLOCKFLAG_MIDSIDE_BANDS
Definition radaudio_common.inl:204
#define RADAUDIO_STREAMHEADER_FLAGS
Definition radaudio_common.inl:222
#define RADAUDIO_BLOCKFLAG_PREDICT_EXPONENT_STEREO
Definition radaudio_common.inl:206
#define RADAUDIO_BLOCKFLAG_STEREO
Definition radaudio_common.inl:203
Definition radaudio_common.inl:243
U16 bytes
Definition radaudio_common.inl:244
Definition radaudio_common.h:105
Definition radaudio_common.h:175
Definition radaudio_common.h:73
Definition radaudio_common.h:207
Definition radaudio_common.h:126
U8 num_chunks_per_huff[NUM_NZ_HUFF]
Definition radaudio_common.h:133
U8 num_8byte_chunks
Definition radaudio_common.h:128
U8 huffman_table_for_chunk[MAX_NZ_BLOCKS]
Definition radaudio_common.h:129
U8 source_pos[3][MAX_NZ_BLOCKS]
Definition radaudio_common.h:134
Definition radaudio_common.h:154
int num_bands
Definition radaudio_common.h:156
int num_subbands_for_band[MAX_BANDS]
Definition radaudio_common.h:163
Definition radaudio_common.h:110
int num_channels
Definition radaudio_common.h:112
U16 bytes_bias
Definition radaudio_common.h:119
U8 nzmode_selectors[NUM_NZ_SELECTOR][NUM_SELECTOR_MODES]
Definition radaudio_common.h:122
U8 nzmode_num64[NUM_NZ_MODE]
Definition radaudio_common.h:120
S8 subband_bias[MAX_BANDS]
Definition radaudio_common.h:118
S8 mantissa_param[2][MAX_BANDS][2]
Definition radaudio_common.h:116
int sample_rate
Definition radaudio_common.h:115
U8 subband_predicted_sum[MAX_BANDS]
Definition radaudio_common.h:117
S8 nzmode_huff[3][12]
Definition radaudio_common.h:121
U32 version
Definition radaudio_common.h:111
int sample_rate_mode
Definition radaudio_common.h:113
Definition radaudio_common.inl:427
S8 mantissa_param[2][MAX_BANDS/4][2]
Definition radaudio_common.inl:441
U16 bytes_bias
Definition radaudio_common.inl:431
U8 nzmode_data2[NUM_SELECTOR_MODES *1]
Definition radaudio_common.inl:436
U16 sample_rate
Definition radaudio_common.inl:430
U8 padding[128-16-26-48]
Definition radaudio_common.inl:444
U8 num_channels
Definition radaudio_common.inl:434
U8 nzmode_data1[NUM_NZ_MODE/2]
Definition radaudio_common.inl:435
char magic[8]
Definition radaudio_common.inl:428
U8 subband_predicted_sum[MAX_BANDS]
Definition radaudio_common.inl:440
U8 nzmode_data3[(NUM_NZ_MODE-1) *(MAX_NZ_BLOCKS/2)]
Definition radaudio_common.inl:437
U32 version
Definition radaudio_common.inl:429