mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-19 00:04:04 +01:00
Improve HCA v3.0
This commit is contained in:
parent
12becc0ec3
commit
ae909de292
489
ext_libs/clHCA.c
489
ext_libs/clHCA.c
@ -1,8 +1,9 @@
|
||||
/**
|
||||
* clHCA DECODER
|
||||
*
|
||||
* Decodes CRI's HCA (High Compression Audio) codec. Also supports what CRI calls HCA-MX, which
|
||||
* basically is the same thing with constrained encoder settings.
|
||||
* Decodes CRI's HCA (High Compression Audio), a CBR DCT-based codec (similar to AAC).
|
||||
* Also supports what CRI calls HCA-MX, which basically is the same thing with constrained
|
||||
* encoder settings.
|
||||
*
|
||||
* - Original decompilation and C++ decoder by nyaga
|
||||
* https://github.com/Nyagamon/HCADecoder
|
||||
@ -14,11 +15,11 @@
|
||||
|
||||
/* TODO:
|
||||
* - improve portability on types and float casts, sizeof(int) isn't necessarily sizeof(float)
|
||||
* - check "delta scalefactors" vs VGAudio (CriHcaPacking.DeltaDecode), may be setting wrong values on bad data
|
||||
* - simplify DCT4 code
|
||||
* - add extra validations: encoder_delay/padding < sample_count, coded/bands/totals (max: 128?), track count==1, etc
|
||||
* - coded_scalefactor_count maybe rename coded_band_count or coded_count
|
||||
* - intensity should calloc if intensity is 15 or set in reset
|
||||
* - add extra validations: encoder_delay/padding < sample_count, etc
|
||||
* - intensity should memset if intensity is 15 or set in reset? (no games hit 15?)
|
||||
* - check mdct + tables, add floats
|
||||
* - simplify bitreader to use in decoder only (no need to read +16 bits)
|
||||
*/
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -29,8 +30,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
/* CRI libs only allow last version, though most decoding code takes older versions into account.
|
||||
* lib is identified with "HCA Decoder (Float)" + version string. Some known versions:
|
||||
/* CRI libs may only accept last version in some cases/modes, though most decoding takes older versions
|
||||
* into account. Lib is identified with "HCA Decoder (Float)" + version string. Some known versions:
|
||||
* - ~V1.1 2011 [first public version]
|
||||
* - ~V1.2 2011 [ciph/ath chunks, disabled ATH]
|
||||
* - Ver.1.40 2011-04 [header mask]
|
||||
@ -45,23 +46,28 @@
|
||||
* only change when decoder does. Despite the name, no "Integer" version seems to exist.
|
||||
*/
|
||||
#define HCA_VERSION_V101 0x0101 /* V1.1+ [El Shaddai (PS3/X360)] */
|
||||
#define HCA_VERSION_V102 0x0102 /* V1.2+ [Gekka Ryouran Romance (PSP)]] */
|
||||
#define HCA_VERSION_V102 0x0102 /* V1.2+ [Gekka Ryouran Romance (PSP)] */
|
||||
#define HCA_VERSION_V103 0x0103 /* V1.4+ [Phantasy Star Online 2 (PC), Binary Domain (PS3)] */
|
||||
#define HCA_VERSION_V200 0x0200 /* V2.0+ [Yakuza 5 (PS3)] */
|
||||
#define HCA_VERSION_V300 0x0300 /* V3.0+ [Uma Musume (Android)] */
|
||||
|
||||
/* maxs depend on encoder quality settings (for example, stereo has:
|
||||
* highest=0x400, high=0x2AA, medium=0x200, low=0x155, lowest=0x100) */
|
||||
#define HCA_MAX_FRAME_SIZE 0xFFFF /* max allowed by lib */
|
||||
#define HCA_MIN_FRAME_SIZE 0x8 /* assumed */
|
||||
#define HCA_MIN_FRAME_SIZE 0x8 /* lib min */
|
||||
#define HCA_MAX_FRAME_SIZE 0xFFFF /* lib max */
|
||||
|
||||
#define HCA_MASK 0x7F7F7F7F /* chunk obfuscation when the HCA is encrypted with key */
|
||||
#define HCA_SUBFRAMES_PER_FRAME 8
|
||||
#define HCA_SAMPLES_PER_SUBFRAME 128
|
||||
#define HCA_SAMPLES_PER_SUBFRAME 128 /* also spectrum points/etc */
|
||||
#define HCA_SAMPLES_PER_FRAME (HCA_SUBFRAMES_PER_FRAME*HCA_SAMPLES_PER_SUBFRAME)
|
||||
#define HCA_MDCT_BITS 7 /* (1<<7) = 128 */
|
||||
|
||||
#define HCA_MIN_CHANNELS 1
|
||||
#define HCA_MAX_CHANNELS 16 /* internal max (in practice only 8 can be encoded) */
|
||||
#define HCA_MIN_SAMPLE_RATE 1 /* assumed */
|
||||
#define HCA_MAX_SAMPLE_RATE 0x7FFFFF /* encoder max seems 48000 */
|
||||
|
||||
#define HCA_DEFAULT_RANDOM 1
|
||||
|
||||
#define HCA_ERROR_OK 0
|
||||
#define HCA_ERROR_PARAMS -1
|
||||
@ -78,17 +84,16 @@ typedef enum { DISCRETE = 0, STEREO_PRIMARY = 1, STEREO_SECONDARY = 2 } channel_
|
||||
|
||||
typedef struct stChannel {
|
||||
/* HCA channel config */
|
||||
int type; /* channel_type_t */
|
||||
unsigned char* hfr_scales; /* high frequency scales, pointing to higher scalefactors (simplification) */
|
||||
channel_type_t type;
|
||||
unsigned int coded_count; /* encoded scales/resolutions/coefs */
|
||||
|
||||
/* subframe state */
|
||||
unsigned char intensity[HCA_SUBFRAMES_PER_FRAME]; /* intensity indexes (value max: 15 / 4b) */
|
||||
unsigned char intensity[HCA_SUBFRAMES_PER_FRAME]; /* intensity indexes for joins stereo (value max: 15 / 4b) */
|
||||
unsigned char scalefactors[HCA_SAMPLES_PER_SUBFRAME]; /* scale indexes (value max: 64 / 6b)*/
|
||||
unsigned char resolution[HCA_SAMPLES_PER_SUBFRAME]; /* resolution indexes (value max: 15 / 4b) */
|
||||
unsigned char unknowns[HCA_SAMPLES_PER_SUBFRAME]; /* ? indexes of resolutions 0? (value max: 128 / 8b) */
|
||||
unsigned int coded_scalefactor_count; /* scalefactors used (depending on channel type) */
|
||||
unsigned int unknown1_max; /* resolutions that use other values */
|
||||
unsigned int unknown2_max; /* resolutions that use 0 */
|
||||
unsigned char noises[HCA_SAMPLES_PER_SUBFRAME]; /* indexes to coefs that need noise fill + coefs that don't (value max: 128 / 8b) */
|
||||
unsigned int noise_count; /* resolutions with noise values saved in 'noises' */
|
||||
unsigned int valid_count; /* resolutions with valid values saved in 'noises' */
|
||||
|
||||
float gain[HCA_SAMPLES_PER_SUBFRAME]; /* gain to apply to quantized spectral data */
|
||||
float spectra[HCA_SAMPLES_PER_SUBFRAME]; /* resulting dequantized data */
|
||||
@ -96,7 +101,6 @@ typedef struct stChannel {
|
||||
float dct[HCA_SAMPLES_PER_SUBFRAME]; /* result of DCT-IV */
|
||||
float imdct_previous[HCA_SAMPLES_PER_SUBFRAME]; /* IMDCT */
|
||||
|
||||
|
||||
/* frame state */
|
||||
float wave[HCA_SUBFRAMES_PER_FRAME][HCA_SAMPLES_PER_SUBFRAME]; /* resulting samples */
|
||||
} stChannel;
|
||||
@ -124,8 +128,8 @@ typedef struct clHCA {
|
||||
unsigned int base_band_count;
|
||||
unsigned int stereo_band_count;
|
||||
unsigned int bands_per_hfr_group;
|
||||
unsigned int reserved1;
|
||||
unsigned int reserved2;
|
||||
unsigned int ms_stereo;
|
||||
unsigned int reserved;
|
||||
/* vbr chunk */
|
||||
unsigned int vbr_max_frame_size;
|
||||
unsigned int vbr_noise_Level;
|
||||
@ -147,11 +151,11 @@ typedef struct clHCA {
|
||||
char comment[255+1];
|
||||
|
||||
/* initial state */
|
||||
int v3_flag;
|
||||
unsigned int hfr_group_count;
|
||||
unsigned int hfr_group_count; /* high frequency band groups not encoded directly */
|
||||
unsigned char ath_curve[HCA_SAMPLES_PER_SUBFRAME];
|
||||
unsigned char cipher_table[256];
|
||||
/* variable state */
|
||||
unsigned int random;
|
||||
stChannel channel[HCA_MAX_CHANNELS];
|
||||
} clHCA;
|
||||
|
||||
@ -165,8 +169,7 @@ typedef struct clData {
|
||||
//--------------------------------------------------
|
||||
// Checksum
|
||||
//--------------------------------------------------
|
||||
//hcacommon_crc_mask_table
|
||||
static const unsigned short crc16_lookup_table[256] = {
|
||||
static const unsigned short hcacommon_crc_mask_table[256] = {
|
||||
0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011,0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022,
|
||||
0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072,0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041,
|
||||
0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2,0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1,
|
||||
@ -192,7 +195,7 @@ static unsigned short crc16_checksum(const unsigned char* data, unsigned int siz
|
||||
|
||||
/* HCA header/frames should always have checksum 0 (checksum(size-16b) = last 16b) */
|
||||
for (i = 0; i < size; i++) {
|
||||
sum = (sum << 8) ^ crc16_lookup_table[(sum >> 8) ^ data[i]];
|
||||
sum = (sum << 8) ^ hcacommon_crc_mask_table[(sum >> 8) ^ data[i]];
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
@ -206,6 +209,8 @@ static void bitreader_init(clData* br, const void *data, int size) {
|
||||
br->bit = 0;
|
||||
}
|
||||
|
||||
/* CRI's bitreader only handles 16b max during decode (header just reads bytes)
|
||||
* so maybe could be optimized by ignoring higher cases */
|
||||
static unsigned int bitreader_peek(clData* br, int bitsize) {
|
||||
const unsigned int bit = br->bit;
|
||||
const unsigned int bit_rem = bit & 7;
|
||||
@ -606,7 +611,9 @@ static int cipher_init(unsigned char* cipher_table, int type, unsigned long long
|
||||
// Parse
|
||||
//--------------------------------------------------
|
||||
static unsigned int header_ceil2(unsigned int a, unsigned int b) {
|
||||
return (b > 0) ? (a / b + ((a % b) ? 1 : 0)) : 0;
|
||||
if (b < 1)
|
||||
return 0;
|
||||
return (a / b + ((a % b) ? 1 : 0)); /* lib modulo: a - (a / b * b) */
|
||||
}
|
||||
|
||||
int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
@ -623,12 +630,12 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
|
||||
bitreader_init(&br, data, size);
|
||||
|
||||
/* read header chunks */
|
||||
/* read header chunks (in HCA chunks must follow a fixed order) */
|
||||
|
||||
/* HCA base header */
|
||||
if ((bitreader_peek(&br, 32) & HCA_MASK) == 0x48434100) { /* "HCA\0" */
|
||||
bitreader_skip(&br, 32);
|
||||
hca->version = bitreader_read(&br, 16);
|
||||
hca->version = bitreader_read(&br, 16); /* lib reads as version + subversion (uses main version for feature checks) */
|
||||
hca->header_size = bitreader_read(&br, 16);
|
||||
|
||||
if (hca->version != HCA_VERSION_V101 &&
|
||||
@ -659,13 +666,13 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
hca->encoder_delay = bitreader_read(&br, 16);
|
||||
hca->encoder_padding = bitreader_read(&br, 16);
|
||||
|
||||
if (!(hca->channels >= 1 && hca->channels <= HCA_MAX_CHANNELS))
|
||||
if (!(hca->channels >= HCA_MIN_CHANNELS && hca->channels <= HCA_MAX_CHANNELS))
|
||||
return HCA_ERROR_HEADER;
|
||||
|
||||
if (hca->frame_count == 0)
|
||||
return HCA_ERROR_HEADER;
|
||||
|
||||
if (!(hca->sample_rate >= 1 && hca->sample_rate <= 0x7FFFFF)) /* encoder max seems 48000 */
|
||||
if (!(hca->sample_rate >= HCA_MIN_SAMPLE_RATE && hca->sample_rate <= HCA_MAX_SAMPLE_RATE))
|
||||
return HCA_ERROR_HEADER;
|
||||
|
||||
size -= 0x10;
|
||||
@ -686,8 +693,8 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
hca->base_band_count = bitreader_read(&br, 8);
|
||||
hca->stereo_band_count = bitreader_read(&br, 8);
|
||||
hca->bands_per_hfr_group = bitreader_read(&br, 8);
|
||||
hca->reserved1 = bitreader_read(&br, 8);
|
||||
hca->reserved2 = bitreader_read(&br, 8);
|
||||
hca->ms_stereo = bitreader_read(&br, 8);
|
||||
hca->reserved = bitreader_read(&br, 8); /* not actually read by lib */
|
||||
|
||||
size -= 0x10;
|
||||
}
|
||||
@ -791,7 +798,7 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
|
||||
size -= 0x08;
|
||||
} else {
|
||||
hca->rva_volume = 1.0f;
|
||||
hca->rva_volume = 1.0f; /* encoder volume setting is pre-applied to data, though chunk still exists in +v3.0 */
|
||||
}
|
||||
|
||||
/* comment */
|
||||
@ -828,20 +835,30 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
return HCA_ERROR_HEADER; /* theoretically can be 0 if VBR (not seen) */
|
||||
|
||||
if (hca->version <= HCA_VERSION_V200) {
|
||||
if (!(hca->min_resolution == 1 && hca->max_resolution == 15))
|
||||
if (hca->min_resolution != 1 || hca->max_resolution != 15)
|
||||
return HCA_ERROR_HEADER;
|
||||
}
|
||||
else {
|
||||
if (hca->min_resolution > hca->max_resolution || hca->max_resolution > 31)
|
||||
if (hca->min_resolution > hca->max_resolution || hca->max_resolution > 15) /* header seems to allow 31, but later max is 15 */
|
||||
return HCA_ERROR_HEADER;
|
||||
}
|
||||
|
||||
|
||||
/* init state */
|
||||
if (hca->track_count == 0) //todo lib gives error?
|
||||
hca->track_count = 1; /* default to avoid division by zero */
|
||||
|
||||
hca->v3_flag = 0; //hca->version >= HCA_VERSION_V300; //todo check actual flag
|
||||
if (hca->track_count == 0)
|
||||
hca->track_count = 1; /* as done by lib, can be 0 in old HCAs */
|
||||
|
||||
if (hca->track_count > hca->channels)
|
||||
return HCA_ERROR_HEADER;
|
||||
|
||||
/* encoded coefs (up to 128) depend in the encoder's "cutoff" hz option */
|
||||
if (hca->total_band_count > HCA_SAMPLES_PER_SUBFRAME ||
|
||||
hca->base_band_count > HCA_SAMPLES_PER_SUBFRAME ||
|
||||
hca->stereo_band_count > HCA_SAMPLES_PER_SUBFRAME ||
|
||||
hca->base_band_count + hca->stereo_band_count > HCA_SAMPLES_PER_SUBFRAME ||
|
||||
hca->bands_per_hfr_group > HCA_SAMPLES_PER_SUBFRAME)
|
||||
return HCA_ERROR_HEADER;
|
||||
|
||||
hca->hfr_group_count = header_ceil2(
|
||||
hca->total_band_count - hca->base_band_count - hca->stereo_band_count,
|
||||
@ -855,14 +872,16 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
return res;
|
||||
|
||||
|
||||
//todo separate into function, cleanup
|
||||
//HCAHeaderUtility_GetElementTypes
|
||||
/* init channels */
|
||||
{
|
||||
int channel_types[HCA_MAX_CHANNELS] = {0};
|
||||
channel_type_t channel_types[HCA_MAX_CHANNELS] = {0}; /* part of lib struct */
|
||||
unsigned int i, channels_per_track;
|
||||
|
||||
channels_per_track = hca->channels / hca->track_count;
|
||||
if (hca->stereo_band_count > 0 && channels_per_track > 1) {
|
||||
int *ct = channel_types;
|
||||
channel_type_t* ct = channel_types;
|
||||
for (i = 0; i < hca->track_count; i++, ct += channels_per_track) {
|
||||
switch (channels_per_track) {
|
||||
case 2:
|
||||
@ -924,6 +943,9 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
ct[6] = STEREO_PRIMARY;
|
||||
ct[7] = STEREO_SECONDARY;
|
||||
break;
|
||||
default:
|
||||
/* implied all 0 (DISCRETE) */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -931,14 +953,21 @@ int clHCA_DecodeHeader(clHCA* hca, const void *data, unsigned int size) {
|
||||
memset(hca->channel, 0, sizeof(hca->channel));
|
||||
for (i = 0; i < hca->channels; i++) {
|
||||
hca->channel[i].type = channel_types[i];
|
||||
hca->channel[i].coded_scalefactor_count = (channel_types[i] != 2) ?
|
||||
|
||||
hca->channel[i].coded_count = (channel_types[i] != STEREO_SECONDARY) ?
|
||||
hca->base_band_count + hca->stereo_band_count :
|
||||
hca->base_band_count;
|
||||
/* simplifies usage a bit but isn't pre-saved as such in reversed original lib (calc'd during decode) */
|
||||
hca->channel[i].hfr_scales = &hca->channel[i].scalefactors[hca->base_band_count + hca->stereo_band_count];
|
||||
}
|
||||
}
|
||||
|
||||
hca->random = HCA_DEFAULT_RANDOM;
|
||||
|
||||
|
||||
//TODO: should work but untested
|
||||
if (hca->ms_stereo)
|
||||
return HCA_ERROR_HEADER;
|
||||
if (hca->hfr_group_count > 0 && hca->version == HCA_VERSION_V300)
|
||||
return HCA_ERROR_HEADER;
|
||||
|
||||
/* clHCA is correctly initialized and decoder state reset
|
||||
* (keycode is not changed between calls) */
|
||||
@ -1040,6 +1069,8 @@ void clHCA_DecodeReset(clHCA * hca) {
|
||||
if (!hca || !hca->is_valid)
|
||||
return;
|
||||
|
||||
hca->random = HCA_DEFAULT_RANDOM;
|
||||
|
||||
for (i = 0; i < hca->channels; i++) {
|
||||
stChannel* ch = &hca->channel[i];
|
||||
|
||||
@ -1070,20 +1101,20 @@ static void calculate_gain(stChannel* ch);
|
||||
|
||||
static void dequantize_coefficients(stChannel* ch, clData* br);
|
||||
|
||||
static void reconstruct_high_frequency(stChannel* ch,
|
||||
unsigned int hfr_group_count, unsigned int bands_per_hfr_group,
|
||||
unsigned int stereo_band_count, unsigned int base_band_count, unsigned int total_band_count);
|
||||
static void reconstruct_noise(stChannel* ch, unsigned int min_resolution, unsigned int ms_stereo, unsigned int* random_p);
|
||||
|
||||
static void reconstruct_resolution_0(stChannel* ch, unsigned int min_resolution, int v3_flag);
|
||||
static void reconstruct_high_frequency(stChannel* ch, unsigned int hfr_group_count, unsigned int bands_per_hfr_group,
|
||||
unsigned int stereo_band_count, unsigned int base_band_count, unsigned int total_band_count, unsigned int version);
|
||||
|
||||
static void apply_intensity_stereo(stChannel* ch_pair, int subframe,
|
||||
unsigned int usable_band_count, unsigned int base_band_count, unsigned int stereo_band_count);
|
||||
static void apply_intensity_stereo(stChannel* ch_pair, int subframe, unsigned int base_band_count, unsigned int total_band_count);
|
||||
|
||||
static void apply_unknown_stereo(stChannel* ch_pair, int v3_flag, unsigned int base_band_count);
|
||||
static void apply_ms_stereo(stChannel* ch_pair, unsigned int ms_stereo, unsigned int base_band_count, unsigned int total_band_count);
|
||||
|
||||
static void imdct_transform(stChannel* ch, int subframe);
|
||||
|
||||
|
||||
/* takes HCA data and decodes all of a frame's samples */
|
||||
//hcadecoder_decode_block
|
||||
int clHCA_DecodeBlock(clHCA* hca, void *data, unsigned int size) {
|
||||
clData br;
|
||||
unsigned short sync;
|
||||
@ -1109,8 +1140,10 @@ int clHCA_DecodeBlock(clHCA* hca, void *data, unsigned int size) {
|
||||
|
||||
/* unpack frame values */
|
||||
{
|
||||
unsigned int frame_acceptable_noise_level = bitreader_read(&br, 9); //todo part of struct
|
||||
/* lib saves this in the struct since they can stop/resume subframe decoding */
|
||||
unsigned int frame_acceptable_noise_level = bitreader_read(&br, 9);
|
||||
unsigned int frame_evaluation_boundary = bitreader_read(&br, 7);
|
||||
|
||||
unsigned int packed_noise_level = (frame_acceptable_noise_level << 8) - frame_evaluation_boundary;
|
||||
|
||||
for (ch = 0; ch < hca->channels; ch++) {
|
||||
@ -1126,6 +1159,7 @@ int clHCA_DecodeBlock(clHCA* hca, void *data, unsigned int size) {
|
||||
}
|
||||
}
|
||||
|
||||
/* lib seems to use a state value to skip parts (unpacking/subframe N/etc) as needed */
|
||||
for (subframe = 0; subframe < HCA_SUBFRAMES_PER_FRAME; subframe++) {
|
||||
|
||||
/* unpack channel data and get dequantized spectra */
|
||||
@ -1133,21 +1167,21 @@ int clHCA_DecodeBlock(clHCA* hca, void *data, unsigned int size) {
|
||||
dequantize_coefficients(&hca->channel[ch], &br);
|
||||
}
|
||||
|
||||
/* restore missing bands from spectra 1 */
|
||||
/* restore missing bands from spectra */
|
||||
for (ch = 0; ch < hca->channels; ch++) {
|
||||
reconstruct_resolution_0(&hca->channel[ch], hca->min_resolution, hca->v3_flag);
|
||||
reconstruct_noise(&hca->channel[ch], hca->min_resolution, hca->ms_stereo, &hca->random);
|
||||
|
||||
reconstruct_high_frequency(&hca->channel[ch],
|
||||
hca->hfr_group_count, hca->bands_per_hfr_group,
|
||||
hca->stereo_band_count, hca->base_band_count, hca->total_band_count);
|
||||
reconstruct_high_frequency(&hca->channel[ch], hca->hfr_group_count, hca->bands_per_hfr_group,
|
||||
hca->stereo_band_count, hca->base_band_count, hca->total_band_count, hca->version);
|
||||
}
|
||||
|
||||
/* restore missing bands from spectra 2 */
|
||||
/* restore missing joint stereo bands */
|
||||
if (hca->stereo_band_count > 0) {
|
||||
for (ch = 0; ch < hca->channels - 1; ch++) {
|
||||
apply_intensity_stereo(&hca->channel[ch], subframe,
|
||||
hca->total_band_count, hca->base_band_count, hca->stereo_band_count);
|
||||
apply_intensity_stereo(&hca->channel[ch], subframe, hca->base_band_count, hca->total_band_count);
|
||||
|
||||
apply_unknown_stereo(&hca->channel[ch], hca->v3_flag, hca->base_band_count);
|
||||
apply_ms_stereo(&hca->channel[ch], hca->ms_stereo, hca->base_band_count, hca->total_band_count);
|
||||
}
|
||||
}
|
||||
|
||||
/* apply imdct */
|
||||
@ -1156,6 +1190,7 @@ int clHCA_DecodeBlock(clHCA* hca, void *data, unsigned int size) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* should read all frame sans checksum (16b) at most */
|
||||
/* one frame was found to read up to 14b left (cross referenced with CRI's tools),
|
||||
* perhaps some encoding hiccup [World of Final Fantasy Maxima (Switch) am_ev21_0170 video],
|
||||
@ -1164,7 +1199,7 @@ int clHCA_DecodeBlock(clHCA* hca, void *data, unsigned int size) {
|
||||
return HCA_ERROR_BITREADER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return HCA_ERROR_OK;
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -1180,9 +1215,8 @@ static const unsigned char hcadecoder_invert_table[66] = {
|
||||
/* indexes after 56 are not defined in v2.0<= (manually clamped to 1) */
|
||||
};
|
||||
|
||||
//hcadequantizer_scaling_table_float
|
||||
/* scalefactor-to-scaling table, generated from sqrt(128) * (2^(53/128))^(scale_factor - 63) */
|
||||
static const unsigned int decode1_dequantizer_scaling_table_hex[64] = {
|
||||
static const unsigned int hcadequantizer_scaling_table_float_hex[64] = {
|
||||
0x342A8D26,0x34633F89,0x3497657D,0x34C9B9BE,0x35066491,0x353311C4,0x356E9910,0x359EF532,
|
||||
0x35D3CCF1,0x360D1ADF,0x363C034A,0x367A83B3,0x36A6E595,0x36DE60F5,0x371426FF,0x3745672A,
|
||||
0x37838359,0x37AF3B79,0x37E97C38,0x381B8D3A,0x384F4319,0x388A14D5,0x38B7FBF0,0x38F5257D,
|
||||
@ -1192,22 +1226,21 @@ static const unsigned int decode1_dequantizer_scaling_table_hex[64] = {
|
||||
0x3E1C6573,0x3E506334,0x3E8AD4C6,0x3EB8FBAF,0x3EF67A41,0x3F243516,0x3F5ACB94,0x3F91C3D3,
|
||||
0x3FC238D2,0x400164D2,0x402C6897,0x4065B907,0x40990B88,0x40CBEC15,0x4107DB35,0x413504F3,
|
||||
};
|
||||
static const float* decode1_dequantizer_scaling_table = (const float*)decode1_dequantizer_scaling_table_hex;
|
||||
static const float* hcadequantizer_scaling_table_float = (const float*)hcadequantizer_scaling_table_float_hex;
|
||||
|
||||
//hcadequantizer_range_table_float
|
||||
static const unsigned int decode1_quantizer_step_size_hex[16] = {
|
||||
0x00000000,0x3F2AAAAB,0x3ECCCCCD,0x3E924925,0x3E638E39,0x3E3A2E8C,0x3E1D89D9,0x3E088889,
|
||||
/* in v2.0 lib index 0 is 0x00000000, but resolution 0 is only valid in v3.0 files */
|
||||
static const unsigned int hcadequantizer_range_table_float_hex[16] = {
|
||||
0x3F800000,0x3F2AAAAB,0x3ECCCCCD,0x3E924925,0x3E638E39,0x3E3A2E8C,0x3E1D89D9,0x3E088889,
|
||||
0x3D842108,0x3D020821,0x3C810204,0x3C008081,0x3B804020,0x3B002008,0x3A801002,0x3A000801,
|
||||
};
|
||||
static const float* decode1_quantizer_step_size = (const float*)decode1_quantizer_step_size_hex;
|
||||
static const float* hcadequantizer_range_table_float = (const float*)hcadequantizer_range_table_float_hex;
|
||||
|
||||
/* get scale indexes to normalize dequantized coefficients */
|
||||
static int unpack_scalefactors(stChannel* ch, clData* br, unsigned int hfr_group_count, unsigned int version) {
|
||||
int i;
|
||||
unsigned int csf_count = ch->coded_scalefactor_count;
|
||||
unsigned char delta_bits = bitreader_read(br, 3);
|
||||
unsigned int cs_count = ch->coded_count;
|
||||
unsigned int extra_count;
|
||||
|
||||
unsigned char delta_bits = bitreader_read(br, 3);
|
||||
|
||||
/* added in v3.0 */
|
||||
if (ch->type == STEREO_SECONDARY || hfr_group_count <= 0 || version <= HCA_VERSION_V200) {
|
||||
@ -1215,55 +1248,47 @@ static int unpack_scalefactors(stChannel* ch, clData* br, unsigned int hfr_group
|
||||
}
|
||||
else {
|
||||
extra_count = hfr_group_count;
|
||||
csf_count = csf_count + extra_count;
|
||||
}
|
||||
cs_count = cs_count + extra_count;
|
||||
|
||||
/* just in case */
|
||||
if (csf_count > HCA_SAMPLES_PER_SUBFRAME)
|
||||
if (cs_count > HCA_SAMPLES_PER_SUBFRAME)
|
||||
return HCA_ERROR_UNPACK;
|
||||
}
|
||||
|
||||
/* lib does check that csf_count is 2+, but doesn't seem to affect anything */
|
||||
/* lib does check that cs_count is 2+ in fixed/delta case, but doesn't seem to affect anything */
|
||||
if (delta_bits >= 6) {
|
||||
/* fixed scalefactors */
|
||||
if (csf_count > 1) {
|
||||
for (i = 0; i < csf_count; i++) {
|
||||
for (i = 0; i < cs_count; i++) {
|
||||
ch->scalefactors[i] = bitreader_read(br, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (delta_bits > 0) {
|
||||
/* delta scalefactors */
|
||||
if (csf_count > 1) {
|
||||
const unsigned char expected_delta = (1 << delta_bits) - 1;
|
||||
const unsigned char extra_delta = expected_delta >> 1;
|
||||
unsigned char scalefactor_prev = bitreader_read(br, 6);
|
||||
unsigned char value = bitreader_read(br, 6);
|
||||
|
||||
ch->scalefactors[0] = scalefactor_prev;
|
||||
for (i = 1; i < csf_count; i++) {
|
||||
ch->scalefactors[0] = value;
|
||||
for (i = 1; i < cs_count; i++) {
|
||||
unsigned char delta = bitreader_read(br, delta_bits);
|
||||
|
||||
if (delta == expected_delta) {
|
||||
/* fixed scalefactor */
|
||||
scalefactor_prev = bitreader_read(br, 6);
|
||||
value = bitreader_read(br, 6); /* encoded */
|
||||
}
|
||||
else {
|
||||
/* delta scalefactor */
|
||||
|
||||
/* may happen with bad keycodes, scalefactors must be 6b indexes */
|
||||
int scalefactor_test = (int)scalefactor_prev + ((int)delta - (int)extra_delta);
|
||||
int scalefactor_test = (int)value + ((int)delta - (int)(expected_delta >> 1));
|
||||
if (scalefactor_test < 0 || scalefactor_test >= 64) {
|
||||
return HCA_ERROR_UNPACK;
|
||||
}
|
||||
|
||||
scalefactor_prev = scalefactor_prev - extra_delta + delta;
|
||||
value = value - (expected_delta >> 1) + delta; /* differential */
|
||||
value = value & 0x3F; /* v3.0 lib */
|
||||
|
||||
//todo as negative better? (may roll otherwise?)
|
||||
//if (scalefactor_prev >= 64) {
|
||||
//if (value >= 64)
|
||||
// return HCA_ERROR_UNPACK;
|
||||
//}
|
||||
}
|
||||
ch->scalefactors[i] = scalefactor_prev;
|
||||
}
|
||||
ch->scalefactors[i] = value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1273,14 +1298,15 @@ static int unpack_scalefactors(stChannel* ch, clData* br, unsigned int hfr_group
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* set derived HFR scales for v3.0 */
|
||||
for (i = 0; i < extra_count; i++) {
|
||||
ch->...[x] = ch->...[x];
|
||||
ch->scalefactors[HCA_SAMPLES_PER_SUBFRAME - 1 - i] = ch->scalefactors[cs_count - i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return HCA_ERROR_OK;
|
||||
}
|
||||
|
||||
/* read intensity (for joint stereo R) or v2.0 high frequency scales (for regular channels) */
|
||||
static int unpack_intensity(stChannel* ch, clData* br, unsigned int hfr_group_count, unsigned int version) {
|
||||
int i;
|
||||
|
||||
@ -1296,23 +1322,23 @@ static int unpack_intensity(stChannel* ch, clData* br, unsigned int hfr_group_co
|
||||
ch->intensity[i] = bitreader_read(br, 4);
|
||||
}
|
||||
}
|
||||
/* 15 may be an invalid value? (index 15 is 0, but may imply "reuse last subframe's intensity") */
|
||||
/* 15 may be an invalid value? index 15 is 0, but may imply "reuse last subframe's intensity".
|
||||
* no games seem to use 15 though */
|
||||
//else {
|
||||
// return HCA_ERROR_UNPACK;
|
||||
//}
|
||||
}
|
||||
else {
|
||||
unsigned char pack = bitreader_peek(br, 6);
|
||||
unsigned char value, delta_bits, bits, bmax, code;
|
||||
unsigned char value = bitreader_peek(br, 4);
|
||||
unsigned char delta_bits;
|
||||
|
||||
if (pack < 60) {
|
||||
bitreader_skip(br, 6);
|
||||
if (value < 15) {
|
||||
bitreader_skip(br, 4);
|
||||
|
||||
value = pack >> 2; /* 4b */
|
||||
delta_bits = pack & 0x3; /* 2b */
|
||||
delta_bits = bitreader_read(br, 2); /* +1 */
|
||||
|
||||
ch->intensity[0] = value;
|
||||
if (delta_bits == 3) {
|
||||
if (delta_bits == 3) { /* 3+1 = 4b */
|
||||
/* fixed intensities */
|
||||
for (i = 1; i < HCA_SUBFRAMES_PER_FRAME; i++) {
|
||||
ch->intensity[i] = bitreader_read(br, 4);
|
||||
@ -1320,21 +1346,18 @@ static int unpack_intensity(stChannel* ch, clData* br, unsigned int hfr_group_co
|
||||
}
|
||||
else {
|
||||
/* delta intensities */
|
||||
bmax = (2 << delta_bits) - 1;
|
||||
bits = delta_bits + 1;
|
||||
unsigned char bmax = (2 << delta_bits) - 1;
|
||||
unsigned char bits = delta_bits + 1;
|
||||
|
||||
for (i = 1; i < HCA_SUBFRAMES_PER_FRAME; i++) {
|
||||
code = bitreader_read(br, bits);
|
||||
if (code == bmax) {
|
||||
unsigned char delta = bitreader_read(br, bits);
|
||||
if (delta == bmax) {
|
||||
value = bitreader_read(br, 4); /* encoded */
|
||||
}
|
||||
else {
|
||||
value = value - (bmax >> 1) + code; /* differential */
|
||||
|
||||
if (value > 15) { /* not done originally */
|
||||
//todo check
|
||||
return HCA_ERROR_UNPACK;
|
||||
}
|
||||
value = value - (bmax >> 1) + delta; /* differential */
|
||||
if (value > 15) //todo check
|
||||
return HCA_ERROR_UNPACK; /* not done in lib */
|
||||
}
|
||||
|
||||
ch->intensity[i] = value;
|
||||
@ -1342,7 +1365,7 @@ static int unpack_intensity(stChannel* ch, clData* br, unsigned int hfr_group_co
|
||||
}
|
||||
}
|
||||
else {
|
||||
bitreader_skip(br, 4); /* not 6! */
|
||||
bitreader_skip(br, 4);
|
||||
for (i = 0; i < HCA_SUBFRAMES_PER_FRAME; i++) {
|
||||
ch->intensity[i] = 7;
|
||||
}
|
||||
@ -1350,10 +1373,15 @@ static int unpack_intensity(stChannel* ch, clData* br, unsigned int hfr_group_co
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* read high frequency scalefactors */
|
||||
/* read high frequency scalefactors (v3.0 uses derived values in unpack_scalefactors instead) */
|
||||
if (version <= HCA_VERSION_V200) {
|
||||
/* pointer in v2.0 lib for v2.0 files is base+stereo bands, while v3.0 lib for v2.0 files
|
||||
* is last HFR. No output difference but v3.0 files need that to handle HFR */
|
||||
//unsigned char* hfr_scales = &ch->scalefactors[base_band_count + stereo_band_count]; /* v2.0 lib */
|
||||
unsigned char* hfr_scales = &ch->scalefactors[128 - hfr_group_count]; /* v3.0 lib */
|
||||
|
||||
for (i = 0; i < hfr_group_count; i++) {
|
||||
ch->hfr_scales[i] = bitreader_read(br, 6);
|
||||
hfr_scales[i] = bitreader_read(br, 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1361,16 +1389,14 @@ static int unpack_intensity(stChannel* ch, clData* br, unsigned int hfr_group_co
|
||||
return HCA_ERROR_OK;
|
||||
}
|
||||
|
||||
/* resolution determines the range of values per encoded spectra,
|
||||
* using codebooks for lower resolutions during dequantization */
|
||||
/* get resolutions, that determines range of values per encoded spectrum coefficients */
|
||||
static void calculate_resolution(stChannel* ch, unsigned int packed_noise_level, const unsigned char* ath_curve, unsigned int min_resolution, unsigned int max_resolution) {
|
||||
const unsigned int csf_count = ch->coded_scalefactor_count;
|
||||
int i;
|
||||
unsigned int cr_count = ch->coded_count;
|
||||
unsigned int noise_count = 0;
|
||||
unsigned int valid_count = 0;
|
||||
|
||||
int unknown1_pos = 0;
|
||||
int unknown2_pos = 0;
|
||||
|
||||
for (i = 0; i < csf_count; i++) {
|
||||
for (i = 0; i < cr_count; i++) {
|
||||
unsigned char new_resolution = 0;
|
||||
unsigned char scalefactor = ch->scalefactors[i];
|
||||
|
||||
@ -1391,40 +1417,40 @@ static void calculate_resolution(stChannel* ch, unsigned int packed_noise_level,
|
||||
new_resolution = 0;
|
||||
}
|
||||
|
||||
/* resolution 0 handling added in v3.0 */
|
||||
/* added in v3.0 (before, min_resolution was always 1) */
|
||||
if (new_resolution > max_resolution)
|
||||
new_resolution = max_resolution;
|
||||
else if (new_resolution < min_resolution)
|
||||
new_resolution = min_resolution;
|
||||
|
||||
/* indexes for resolution 0 (from 0..N) and other values (from N..0) */
|
||||
/* save resolution 0 (not encoded) indexes (from 0..N), and regular indexes (from N..0) */
|
||||
if (new_resolution < 1) {
|
||||
ch->unknowns[unknown2_pos] = i;
|
||||
unknown2_pos++;
|
||||
ch->noises[noise_count] = i;
|
||||
noise_count++;
|
||||
}
|
||||
else {
|
||||
ch->unknowns[127 - unknown1_pos] = i;
|
||||
unknown1_pos++;
|
||||
ch->noises[HCA_SAMPLES_PER_SUBFRAME - 1 - valid_count] = i;
|
||||
valid_count++;
|
||||
}
|
||||
}
|
||||
ch->resolution[i] = new_resolution;
|
||||
}
|
||||
|
||||
ch->unknown1_max = unknown1_pos;
|
||||
ch->unknown2_max = unknown2_pos;
|
||||
ch->noise_count = noise_count;
|
||||
ch->valid_count = valid_count;
|
||||
|
||||
memset(&ch->resolution[csf_count], 0, sizeof(ch->resolution[0]) * (HCA_SAMPLES_PER_SUBFRAME - csf_count));
|
||||
memset(&ch->resolution[cr_count], 0, sizeof(ch->resolution[0]) * (HCA_SAMPLES_PER_SUBFRAME - cr_count));
|
||||
}
|
||||
|
||||
/* HCADequantizer_CalculateGain */
|
||||
/* get actual scales to dequantize based on saved scalefactors */
|
||||
// HCADequantizer_CalculateGain
|
||||
static void calculate_gain(stChannel* ch) {
|
||||
int i;
|
||||
const unsigned int csf_count = ch->coded_scalefactor_count;
|
||||
unsigned int cg_count = ch->coded_count;
|
||||
|
||||
/* get actual scales to dequantize */
|
||||
for (i = 0; i < csf_count; i++) {
|
||||
float scalefactor_scale = decode1_dequantizer_scaling_table[ ch->scalefactors[i] ];
|
||||
float resolution_scale = decode1_quantizer_step_size[ ch->resolution[i] ];
|
||||
for (i = 0; i < cg_count; i++) {
|
||||
float scalefactor_scale = hcadequantizer_scaling_table_float[ ch->scalefactors[i] ];
|
||||
float resolution_scale = hcadequantizer_range_table_float[ ch->resolution[i] ];
|
||||
ch->gain[i] = scalefactor_scale * resolution_scale;
|
||||
}
|
||||
}
|
||||
@ -1434,46 +1460,45 @@ static void calculate_gain(stChannel* ch) {
|
||||
//--------------------------------------------------
|
||||
/* coded resolution to max bits */
|
||||
static const unsigned char hcatbdecoder_max_bit_table[16] = {
|
||||
0,2,3,3,4,4,4,4,5,6,7,8,9,10,11,12
|
||||
0,2,3,3,4,4,4,4, 5,6,7,8,9,10,11,12
|
||||
};
|
||||
/* bits used for quant codes */
|
||||
static const unsigned char hcatbdecoder_read_bit_table[128] = {
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
2,2,2,2,2,2,3,3,0,0,0,0,0,0,0,0,
|
||||
2,2,3,3,3,3,3,3,0,0,0,0,0,0,0,0,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,
|
||||
3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,
|
||||
3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,
|
||||
3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
1,1,2,2,0,0,0,0, 0,0,0,0,0,0,0,0,
|
||||
2,2,2,2,2,2,3,3, 0,0,0,0,0,0,0,0,
|
||||
2,2,3,3,3,3,3,3, 0,0,0,0,0,0,0,0,
|
||||
3,3,3,3,3,3,3,3, 3,3,3,3,3,3,4,4,
|
||||
3,3,3,3,3,3,3,3, 3,3,4,4,4,4,4,4,
|
||||
3,3,3,3,3,3,4,4, 4,4,4,4,4,4,4,4,
|
||||
3,3,4,4,4,4,4,4, 4,4,4,4,4,4,4,4,
|
||||
};
|
||||
/* code to quantized spectrum value */
|
||||
static const float hcatbdecoder_read_val_table[128] = {
|
||||
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
|
||||
+0,+0,+1,-1,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
|
||||
+0,+0,+1,+1,-1,-1,+2,-2,+0,+0,+0,+0,+0,+0,+0,+0,
|
||||
+0,+0,+1,-1,+2,-2,+3,-3,+0,+0,+0,+0,+0,+0,+0,+0,
|
||||
+0,+0,+1,+1,-1,-1,+2,+2,-2,-2,+3,+3,-3,-3,+4,-4,
|
||||
+0,+0,+1,+1,-1,-1,+2,+2,-2,-2,+3,-3,+4,-4,+5,-5,
|
||||
+0,+0,+1,+1,-1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6,
|
||||
+0,+0,+1,-1,+2,-2,+3,-3,+4,-4,+5,-5,+6,-6,+7,-7,
|
||||
+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f, +0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,
|
||||
+0.0f,+0.0f,+1.0f,-1.0f,+0.0f,+0.0f,+0.0f,+0.0f, +0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,
|
||||
+0.0f,+0.0f,+1.0f,+1.0f,-1.0f,-1.0f,+2.0f,-2.0f, +0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,
|
||||
+0.0f,+0.0f,+1.0f,-1.0f,+2.0f,-2.0f,+3.0f,-3.0f, +0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,+0.0f,
|
||||
+0.0f,+0.0f,+1.0f,+1.0f,-1.0f,-1.0f,+2.0f,+2.0f, -2.0f,-2.0f,+3.0f,+3.0f,-3.0f,-3.0f,+4.0f,-4.0f,
|
||||
+0.0f,+0.0f,+1.0f,+1.0f,-1.0f,-1.0f,+2.0f,+2.0f, -2.0f,-2.0f,+3.0f,-3.0f,+4.0f,-4.0f,+5.0f,-5.0f,
|
||||
+0.0f,+0.0f,+1.0f,+1.0f,-1.0f,-1.0f,+2.0f,-2.0f, +3.0f,-3.0f,+4.0f,-4.0f,+5.0f,-5.0f,+6.0f,-6.0f,
|
||||
+0.0f,+0.0f,+1.0f,-1.0f,+2.0f,-2.0f,+3.0f,-3.0f, +4.0f,-4.0f,+5.0f,-5.0f,+6.0f,-6.0f,+7.0f,-7.0f,
|
||||
};
|
||||
|
||||
/* read spectral coefficients in the bitstream */
|
||||
static void dequantize_coefficients(stChannel* ch, clData* br) {
|
||||
int i;
|
||||
const unsigned int csf_count = ch->coded_scalefactor_count;
|
||||
unsigned int cc_count = ch->coded_count;
|
||||
|
||||
|
||||
for (i = 0; i < csf_count; i++) {
|
||||
for (i = 0; i < cc_count; i++) {
|
||||
float qc;
|
||||
unsigned char resolution = ch->resolution[i];
|
||||
unsigned char bits = hcatbdecoder_max_bit_table[resolution];
|
||||
unsigned int code = bitreader_read(br, bits);
|
||||
|
||||
/* read spectral coefficients */
|
||||
if (resolution > 7) {
|
||||
/* parse values in sign-magnitude form (lowest bit = sign) */
|
||||
int signed_code = (1 - ((code & 1) << 1)) * (code >> 1); /* move sign */
|
||||
int signed_code = (1 - ((code & 1) << 1)) * (code >> 1); /* move sign from low to up */
|
||||
if (signed_code == 0)
|
||||
bitreader_skip(br, -1); /* zero uses one less bit since it has no sign */
|
||||
qc = (float)signed_code;
|
||||
@ -1491,9 +1516,10 @@ static void dequantize_coefficients(stChannel* ch, clData* br) {
|
||||
}
|
||||
|
||||
/* clean rest of spectra */
|
||||
memset(&ch->spectra[csf_count], 0, sizeof(ch->spectra[0]) * (HCA_SAMPLES_PER_SUBFRAME - csf_count));
|
||||
memset(&ch->spectra[cc_count], 0, sizeof(ch->spectra[0]) * (HCA_SAMPLES_PER_SUBFRAME - cc_count));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Decode 3rd step
|
||||
//--------------------------------------------------
|
||||
@ -1520,51 +1546,86 @@ static const unsigned int hcadecoder_scale_conversion_table_hex[128] = {
|
||||
};
|
||||
static const float* hcadecoder_scale_conversion_table = (const float*)hcadecoder_scale_conversion_table_hex;
|
||||
|
||||
|
||||
static void reconstruct_resolution_0(stChannel* ch, unsigned int min_resolution, int v3_flag) {
|
||||
/* recreate resolution 0 coefs (not encoded) with pseudo-random noise based on
|
||||
* other coefs/scales (probably similar to AAC's perceptual noise substitution) */
|
||||
static void reconstruct_noise(stChannel* ch, unsigned int min_resolution, unsigned int ms_stereo, unsigned int* random_p) {
|
||||
if (min_resolution > 0) /* added in v3.0 */
|
||||
return;
|
||||
if (ch->type != STEREO_PRIMARY || v3_flag)
|
||||
if (ch->valid_count <= 0 || ch->noise_count <= 0)
|
||||
return;
|
||||
if (!(!ms_stereo || ch->type == STEREO_PRIMARY))
|
||||
return;
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
||||
static void reconstruct_high_frequency(stChannel* ch,
|
||||
unsigned int hfr_group_count, unsigned int bands_per_hfr_group,
|
||||
unsigned int stereo_band_count, unsigned int base_band_count, unsigned int total_band_count) {
|
||||
if (ch->type == STEREO_SECONDARY)
|
||||
return;
|
||||
if (bands_per_hfr_group == 0) /* added in v2.0 */
|
||||
return;
|
||||
//if (stereo_band_count == 0) //todo affects some mono files, recheck
|
||||
// return;
|
||||
|
||||
//todo handle v3
|
||||
{
|
||||
int i;
|
||||
unsigned int group;
|
||||
unsigned int start_band = stereo_band_count + base_band_count;
|
||||
unsigned int highband = start_band;
|
||||
unsigned int lowband = start_band - 1;
|
||||
unsigned int sc_index;
|
||||
int random_index, noise_index, valid_index, sf_noise, sf_valid, sc_index;
|
||||
unsigned int random = *random_p;
|
||||
|
||||
for (i = 0; i < ch->noise_count; i++) {
|
||||
random = 0x343FD * random + 0x269EC3; /* typical rand() */
|
||||
|
||||
random_index = HCA_SAMPLES_PER_SUBFRAME - ch->valid_count + (((random & 0x7FFF) * ch->valid_count) >> 15); /* can't go over 128 */
|
||||
|
||||
/* points to next resolution 0 index and random non-resolution 0 index */
|
||||
noise_index = ch->noises[i];
|
||||
valid_index = ch->noises[random_index];
|
||||
|
||||
/* get final scale index */
|
||||
sf_noise = ch->scalefactors[noise_index];
|
||||
sf_valid = ch->scalefactors[valid_index];
|
||||
sc_index = (sf_noise - sf_valid + 62) & ~((sf_noise - sf_valid + 62) >> 31);
|
||||
|
||||
ch->spectra[noise_index] = hcadecoder_scale_conversion_table[sc_index] * ch->spectra[valid_index];
|
||||
}
|
||||
|
||||
*random_p = random; /* lib saves this in the bitreader, maybe for simplified passing around */
|
||||
}
|
||||
}
|
||||
|
||||
/* recreate missing coefs in high bands based on lower bands (probably similar to AAC's spectral band replication) */
|
||||
static void reconstruct_high_frequency(stChannel* ch, unsigned int hfr_group_count, unsigned int bands_per_hfr_group,
|
||||
unsigned int stereo_band_count, unsigned int base_band_count, unsigned int total_band_count, unsigned int version) {
|
||||
if (bands_per_hfr_group == 0) /* added in v2.0, skipped in v2.0 files with 0 bands too */
|
||||
return;
|
||||
if (ch->type == STEREO_SECONDARY)
|
||||
return;
|
||||
|
||||
{
|
||||
int i;
|
||||
int group, group_limit;
|
||||
int start_band = stereo_band_count + base_band_count;
|
||||
int highband = start_band;
|
||||
int lowband = start_band - 1;
|
||||
int sc_index;
|
||||
//unsigned char* hfr_scales = &ch->scalefactors[base_band_count + stereo_band_count]; /* v2.0 lib */
|
||||
unsigned char* hfr_scales = &ch->scalefactors[128 - hfr_group_count]; /* v3.0 lib */
|
||||
|
||||
if (version <= HCA_VERSION_V200) {
|
||||
group_limit = hfr_group_count;
|
||||
}
|
||||
else {
|
||||
group_limit = (hfr_group_count >= 0) ? hfr_group_count : hfr_group_count + 1; /* ??? */
|
||||
group_limit = group_limit >> 1;
|
||||
}
|
||||
|
||||
for (group = 0; group < hfr_group_count; group++) {
|
||||
int lowband_sub = (group < group_limit) ? 1 : 0; /* move lowband towards 0 until group reachs limit */
|
||||
|
||||
for (i = 0; i < bands_per_hfr_group; i++) {
|
||||
if (highband >= total_band_count || lowband < 0)
|
||||
break;
|
||||
|
||||
sc_index = ch->hfr_scales[group] - ch->scalefactors[lowband] + 63;
|
||||
/* as clamped in lib in v3.0, though in theory 6b scalefactors don't reach this */
|
||||
sc_index = sc_index & ~(sc_index >> 31);
|
||||
sc_index = hfr_scales[group] - ch->scalefactors[lowband] + 63;
|
||||
sc_index = sc_index & ~(sc_index >> 31); /* clamped in v3.0 lib (in theory 6b sf are 0..128) */
|
||||
|
||||
ch->spectra[highband] = hcadecoder_scale_conversion_table[sc_index] * ch->spectra[lowband];
|
||||
highband++;
|
||||
lowband--;
|
||||
|
||||
highband += 1;
|
||||
lowband -= lowband_sub;
|
||||
}
|
||||
}
|
||||
|
||||
/* last spectrum coefficient is 0 (highband = 128 here, but perhaps could 'break' before) */
|
||||
/* last spectrum coefficient is 0 (normally highband = 128, but perhaps could 'break' before) */
|
||||
ch->spectra[highband - 1] = 0.0f;
|
||||
}
|
||||
}
|
||||
@ -1572,43 +1633,55 @@ static void reconstruct_high_frequency(stChannel* ch,
|
||||
//--------------------------------------------------
|
||||
// Decode 4th step
|
||||
//--------------------------------------------------
|
||||
|
||||
/* index to scale */
|
||||
static const unsigned int hcadecoder_intensity_ratio_table_hex[16] = { /* max 4b */
|
||||
0x40000000,0x3FEDB6DB,0x3FDB6DB7,0x3FC92492,0x3FB6DB6E,0x3FA49249,0x3F924925,0x3F800000,
|
||||
0x3F5B6DB7,0x3F36DB6E,0x3F124925,0x3EDB6DB7,0x3E924925,0x3E124925,0x00000000,0x00000000,
|
||||
};
|
||||
static const float* hcadecoder_intensity_ratio_table = (const float*)hcadecoder_intensity_ratio_table_hex;
|
||||
|
||||
static void apply_intensity_stereo(stChannel* ch_pair, int subframe,
|
||||
unsigned int total_band_count, unsigned int base_band_count, unsigned int stereo_band_count) {
|
||||
/* restore L/R bands based on channel coef + panning */
|
||||
static void apply_intensity_stereo(stChannel* ch_pair, int subframe, unsigned int base_band_count, unsigned int total_band_count) {
|
||||
if (ch_pair[0].type != STEREO_PRIMARY)
|
||||
return;
|
||||
if (stereo_band_count == 0)
|
||||
return;
|
||||
|
||||
{
|
||||
int band;
|
||||
float ratio_l = hcadecoder_intensity_ratio_table[ ch_pair[1].intensity[subframe] ];
|
||||
float ratio_r = ratio_l - 2.0f; //todo 2.0 - ratio_l
|
||||
float ratio_r = ratio_l - 2.0f; //TODO remove
|
||||
//float ratio_r = 2.0f - ratio_l; /* correct, though other decoders substract 2.0 (it does use 'fsubr 2.0' and such) */
|
||||
float* sp_l = ch_pair[0].spectra;
|
||||
float* sp_r = ch_pair[1].spectra;
|
||||
unsigned int band;
|
||||
|
||||
for (band = base_band_count; band < total_band_count; band++) {
|
||||
sp_r[band] = sp_l[band] * ratio_r;
|
||||
sp_l[band] = sp_l[band] * ratio_l;
|
||||
float coef_l = sp_l[band] * ratio_l;
|
||||
float coef_r = sp_l[band] * ratio_r;
|
||||
sp_l[band] = coef_l;
|
||||
sp_r[band] = coef_r;
|
||||
}
|
||||
|
||||
//todo lib seems to do extra processing here
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_unknown_stereo(stChannel* ch_pair, int v3_flag, unsigned int base_band_count) {
|
||||
if (!v3_flag) /* added in v3.0 */
|
||||
/* restore L/R bands based on mid channel + side differences */
|
||||
static void apply_ms_stereo(stChannel* ch_pair, unsigned int ms_stereo, unsigned int base_band_count, unsigned int total_band_count) {
|
||||
if (!ms_stereo) /* added in v3.0 */
|
||||
return;
|
||||
if (ch_pair[0].type != STEREO_PRIMARY || base_band_count == 0)
|
||||
if (ch_pair[0].type != STEREO_PRIMARY)
|
||||
return;
|
||||
|
||||
//TODO
|
||||
{
|
||||
int band;
|
||||
const float ratio = 0.70710676908493; /* 0x3F3504F3 */
|
||||
float* sp_l = ch_pair[0].spectra;
|
||||
float* sp_r = ch_pair[1].spectra;
|
||||
|
||||
for (band = base_band_count; band < total_band_count; band++) {
|
||||
float coef_l = (sp_l[band] + sp_r[band]) * ratio;
|
||||
float coef_r = (sp_l[band] - sp_r[band]) * ratio;
|
||||
sp_l[band] = coef_l;
|
||||
sp_r[band] = coef_r;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
@ -1769,7 +1842,7 @@ static const unsigned int hcaimdct_window_float_hex[128] = {
|
||||
};
|
||||
static const float* hcaimdct_window_float = (const float*)hcaimdct_window_float_hex;
|
||||
|
||||
/* apply DCT-IV to dequantized spectra */
|
||||
/* apply DCT-IV to dequantized spectra to get final samples */
|
||||
//HCAIMDCT_Transform
|
||||
static void imdct_transform(stChannel* ch, int subframe) {
|
||||
static const unsigned int size = HCA_SAMPLES_PER_SUBFRAME;
|
||||
|
@ -42,7 +42,10 @@ hca_codec_data* init_hca(STREAMFILE* sf) {
|
||||
clHCA_clear(data->handle);
|
||||
|
||||
status = clHCA_DecodeHeader(data->handle, header_buffer, header_size); /* parse header */
|
||||
if (status < 0) goto fail;
|
||||
if (status < 0) {
|
||||
VGM_LOG("HCA: unsupported header found, %i\n", status);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
status = clHCA_getInfo(data->handle, &data->info); /* extract header info */
|
||||
if (status < 0) goto fail;
|
||||
|
Loading…
x
Reference in New Issue
Block a user