📄 qdm2.c
字号:
value = get_vlc2(gb, vlc->table, vlc->bits, depth);
/* stage-2, 3 bits exponent escape sequence */
if (value-- == 0)
value = get_bits (gb, get_bits (gb, 3) + 1);
/* stage-3, optional */
if (flag) {
int tmp = vlc_stage3_values[value];
if ((value & ~3) > 0)
tmp += get_bits (gb, (value >> 2));
value = tmp;
}
return value;
}
static int qdm2_get_se_vlc (VLC *vlc, GetBitContext *gb, int depth)
{
int value = qdm2_get_vlc (gb, vlc, 0, depth);
return (value & 1) ? ((value + 1) >> 1) : -(value >> 1);
}
/**
* QDM2 checksum
*
* @param data pointer to data to be checksum'ed
* @param length data length
* @param value checksum value
*
* @return 0 if checksum is OK
*/
static uint16_t qdm2_packet_checksum (uint8_t *data, int length, int value) {
int i;
for (i=0; i < length; i++)
value -= data[i];
return (uint16_t)(value & 0xffff);
}
/**
* Fills a QDM2SubPacket structure with packet type, size, and data pointer.
*
* @param gb bitreader context
* @param sub_packet packet under analysis
*/
static void qdm2_decode_sub_packet_header (GetBitContext *gb, QDM2SubPacket *sub_packet)
{
sub_packet->type = get_bits (gb, 8);
if (sub_packet->type == 0) {
sub_packet->size = 0;
sub_packet->data = NULL;
} else {
sub_packet->size = get_bits (gb, 8);
if (sub_packet->type & 0x80) {
sub_packet->size <<= 8;
sub_packet->size |= get_bits (gb, 8);
sub_packet->type &= 0x7f;
}
if (sub_packet->type == 0x7f)
sub_packet->type |= (get_bits (gb, 8) << 8);
sub_packet->data = &gb->buffer[get_bits_count(gb) / 8]; // FIXME: this depends on bitreader internal data
}
av_log(NULL,AV_LOG_DEBUG,"Subpacket: type=%d size=%d start_offs=%x\n",
sub_packet->type, sub_packet->size, get_bits_count(gb) / 8);
}
/**
* Return node pointer to first packet of requested type in list.
*
* @param list list of subpackets to be scanned
* @param type type of searched subpacket
* @return node pointer for subpacket if found, else NULL
*/
static QDM2SubPNode* qdm2_search_subpacket_type_in_list (QDM2SubPNode *list, int type)
{
while (list != NULL && list->packet != NULL) {
if (list->packet->type == type)
return list;
list = list->next;
}
return NULL;
}
/**
* Replaces 8 elements with their average value.
* Called by qdm2_decode_superblock before starting subblock decoding.
*
* @param q context
*/
static void average_quantized_coeffs (QDM2Context *q)
{
int i, j, n, ch, sum;
n = coeff_per_sb_for_avg[q->coeff_per_sb_select][QDM2_SB_USED(q->sub_sampling) - 1] + 1;
for (ch = 0; ch < q->nb_channels; ch++)
for (i = 0; i < n; i++) {
sum = 0;
for (j = 0; j < 8; j++)
sum += q->quantized_coeffs[ch][i][j];
sum /= 8;
if (sum > 0)
sum--;
for (j=0; j < 8; j++)
q->quantized_coeffs[ch][i][j] = sum;
}
}
/**
* Build subband samples with noise weighted by q->tone_level.
* Called by synthfilt_build_sb_samples.
*
* @param q context
* @param sb subband index
*/
static void build_sb_samples_from_noise (QDM2Context *q, int sb)
{
int ch, j;
FIX_NOISE_IDX(q->noise_idx);
if (!q->nb_channels)
return;
for (ch = 0; ch < q->nb_channels; ch++)
for (j = 0; j < 64; j++) {
q->sb_samples[ch][j * 2][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5);
q->sb_samples[ch][j * 2 + 1][sb] = (int32_t)(f2i_scale * SB_DITHERING_NOISE(sb,q->noise_idx) * q->tone_level[ch][sb][j] + .5);
}
}
/**
* Called while processing data from subpackets 11 and 12.
* Used after making changes to coding_method array.
*
* @param sb subband index
* @param channels number of channels
* @param coding_method q->coding_method[0][0][0]
*/
static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method)
{
int j,k;
int ch;
int run, case_val;
int switchtable[23] = {0,5,1,5,5,5,5,5,2,5,5,5,5,5,5,5,3,5,5,5,5,5,4};
for (ch = 0; ch < channels; ch++) {
for (j = 0; j < 64; ) {
if((coding_method[ch][sb][j] - 8) > 22) {
run = 1;
case_val = 8;
} else {
switch (switchtable[coding_method[ch][sb][j]-8]) {
case 0: run = 10; case_val = 10; break;
case 1: run = 1; case_val = 16; break;
case 2: run = 5; case_val = 24; break;
case 3: run = 3; case_val = 30; break;
case 4: run = 1; case_val = 30; break;
case 5: run = 1; case_val = 8; break;
default: run = 1; case_val = 8; break;
}
}
for (k = 0; k < run; k++)
if (j + k < 128)
if (coding_method[ch][sb + (j + k) / 64][(j + k) % 64] > coding_method[ch][sb][j])
if (k > 0) {
SAMPLES_NEEDED
//not debugged, almost never used
memset(&coding_method[ch][sb][j + k], case_val, k * sizeof(int8_t));
memset(&coding_method[ch][sb][j + k], case_val, 3 * sizeof(int8_t));
}
j += run;
}
}
}
/**
* Related to synthesis filter
* Called by process_subpacket_10
*
* @param q context
* @param flag 1 if called after getting data from subpacket 10, 0 if no subpacket 10
*/
static void fill_tone_level_array (QDM2Context *q, int flag)
{
int i, sb, ch, sb_used;
int tmp, tab;
// This should never happen
if (q->nb_channels <= 0)
return;
for (ch = 0; ch < q->nb_channels; ch++)
for (sb = 0; sb < 30; sb++)
for (i = 0; i < 8; i++) {
if ((tab=coeff_per_sb_for_dequant[q->coeff_per_sb_select][sb]) < (last_coeff[q->coeff_per_sb_select] - 1))
tmp = q->quantized_coeffs[ch][tab + 1][i] * dequant_table[q->coeff_per_sb_select][tab + 1][sb]+
q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb];
else
tmp = q->quantized_coeffs[ch][tab][i] * dequant_table[q->coeff_per_sb_select][tab][sb];
if(tmp < 0)
tmp += 0xff;
q->tone_level_idx_base[ch][sb][i] = (tmp / 256) & 0xff;
}
sb_used = QDM2_SB_USED(q->sub_sampling);
if ((q->superblocktype_2_3 != 0) && !flag) {
for (sb = 0; sb < sb_used; sb++)
for (ch = 0; ch < q->nb_channels; ch++)
for (i = 0; i < 64; i++) {
q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8];
if (q->tone_level_idx[ch][sb][i] < 0)
q->tone_level[ch][sb][i] = 0;
else
q->tone_level[ch][sb][i] = fft_tone_level_table[0][q->tone_level_idx[ch][sb][i] & 0x3f];
}
} else {
tab = q->superblocktype_2_3 ? 0 : 1;
for (sb = 0; sb < sb_used; sb++) {
if ((sb >= 4) && (sb <= 23)) {
for (ch = 0; ch < q->nb_channels; ch++)
for (i = 0; i < 64; i++) {
tmp = q->tone_level_idx_base[ch][sb][i / 8] -
q->tone_level_idx_hi1[ch][sb / 8][i / 8][i % 8] -
q->tone_level_idx_mid[ch][sb - 4][i / 8] -
q->tone_level_idx_hi2[ch][sb - 4];
q->tone_level_idx[ch][sb][i] = tmp & 0xff;
if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp))
q->tone_level[ch][sb][i] = 0;
else
q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f];
}
} else {
if (sb > 4) {
for (ch = 0; ch < q->nb_channels; ch++)
for (i = 0; i < 64; i++) {
tmp = q->tone_level_idx_base[ch][sb][i / 8] -
q->tone_level_idx_hi1[ch][2][i / 8][i % 8] -
q->tone_level_idx_hi2[ch][sb - 4];
q->tone_level_idx[ch][sb][i] = tmp & 0xff;
if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp))
q->tone_level[ch][sb][i] = 0;
else
q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f];
}
} else {
for (ch = 0; ch < q->nb_channels; ch++)
for (i = 0; i < 64; i++) {
tmp = q->tone_level_idx[ch][sb][i] = q->tone_level_idx_base[ch][sb][i / 8];
if ((tmp < 0) || (!q->superblocktype_2_3 && !tmp))
q->tone_level[ch][sb][i] = 0;
else
q->tone_level[ch][sb][i] = fft_tone_level_table[tab][tmp & 0x3f];
}
}
}
}
}
return;
}
/**
* Related to synthesis filter
* Called by process_subpacket_11
* c is built with data from subpacket 11
* Most of this function is used only if superblock_type_2_3 == 0, never seen it in samples
*
* @param tone_level_idx
* @param tone_level_idx_temp
* @param coding_method q->coding_method[0][0][0]
* @param nb_channels number of channels
* @param c coming from subpacket 11, passed as 8*c
* @param superblocktype_2_3 flag based on superblock packet type
* @param cm_table_select q->cm_table_select
*/
static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_array tone_level_idx_temp,
sb_int8_array coding_method, int nb_channels,
int c, int superblocktype_2_3, int cm_table_select)
{
int ch, sb, j;
int tmp, acc, esp_40, comp;
int add1, add2, add3, add4;
int64_t multres;
// This should never happen
if (nb_channels <= 0)
return;
if (!superblocktype_2_3) {
/* This case is untested, no samples available */
SAMPLES_NEEDED
for (ch = 0; ch < nb_channels; ch++)
for (sb = 0; sb < 30; sb++) {
for (j = 1; j < 64; j++) {
add1 = tone_level_idx[ch][sb][j] - 10;
if (add1 < 0)
add1 = 0;
add2 = add3 = add4 = 0;
if (sb > 1) {
add2 = tone_level_idx[ch][sb - 2][j] + tone_level_idx_offset_table[sb][0] - 6;
if (add2 < 0)
add2 = 0;
}
if (sb > 0) {
add3 = tone_level_idx[ch][sb - 1][j] + tone_level_idx_offset_table[sb][1] - 6;
if (add3 < 0)
add3 = 0;
}
if (sb < 29) {
add4 = tone_level_idx[ch][sb + 1][j] + tone_level_idx_offset_table[sb][3] - 6;
if (add4 < 0)
add4 = 0;
}
tmp = tone_level_idx[ch][sb][j + 1] * 2 - add4 - add3 - add2 - add1;
if (tmp < 0)
tmp = 0;
tone_level_idx_temp[ch][sb][j + 1] = tmp & 0xff;
}
tone_level_idx_temp[ch][sb][0] = tone_level_idx_temp[ch][sb][1];
}
acc = 0;
for (ch = 0; ch < nb_channels; ch++)
for (sb = 0; sb < 30; sb++)
for (j = 0; j < 64; j++)
acc += tone_level_idx_temp[ch][sb][j];
if (acc)
tmp = c * 256 / (acc & 0xffff);
multres = 0x66666667 * (acc * 10);
esp_40 = (multres >> 32) / 8 + ((multres & 0xffffffff) >> 31);
for (ch = 0; ch < nb_channels; ch++)
for (sb = 0; sb < 30; sb++)
for (j = 0; j < 64; j++) {
comp = tone_level_idx_temp[ch][sb][j]* esp_40 * 10;
if (comp < 0)
comp += 0xff;
comp /= 256; // signed shift
switch(sb) {
case 0:
if (comp < 30)
comp = 30;
comp += 15;
break;
case 1:
if (comp < 24)
comp = 24;
comp += 10;
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -