📄 qdm2.c
字号:
fill_coding_method_array (q->tone_level_idx, q->tone_level_idx_temp, q->coding_method, q->nb_channels, 8*c, q->superblocktype_2_3, q->cm_table_select); } synthfilt_build_sb_samples(q, &gb, length, 0, 8);}/** * Process subpacket 12 * * @param q context * @param node pointer to node with packet * @param length packet length in bits */static void process_subpacket_12 (QDM2Context *q, QDM2SubPNode *node, int length){ GetBitContext gb; init_get_bits(&gb, ((node == NULL) ? empty_buffer : node->packet->data), ((node == NULL) ? 0 : node->packet->size*8)); synthfilt_build_sb_samples(q, &gb, length, 8, QDM2_SB_USED(q->sub_sampling));}/* * Process new subpackets for synthesis filter * * @param q context * @param list list with synthesis filter packets (list D) */static void process_synthesis_subpackets (QDM2Context *q, QDM2SubPNode *list){ QDM2SubPNode *nodes[4]; nodes[0] = qdm2_search_subpacket_type_in_list(list, 9); if (nodes[0] != NULL) process_subpacket_9(q, nodes[0]); nodes[1] = qdm2_search_subpacket_type_in_list(list, 10); if (nodes[1] != NULL) process_subpacket_10(q, nodes[1], nodes[1]->packet->size << 3); else process_subpacket_10(q, NULL, 0); nodes[2] = qdm2_search_subpacket_type_in_list(list, 11); if (nodes[0] != NULL && nodes[1] != NULL && nodes[2] != NULL) process_subpacket_11(q, nodes[2], (nodes[2]->packet->size << 3)); else process_subpacket_11(q, NULL, 0); nodes[3] = qdm2_search_subpacket_type_in_list(list, 12); if (nodes[0] != NULL && nodes[1] != NULL && nodes[3] != NULL) process_subpacket_12(q, nodes[3], (nodes[3]->packet->size << 3)); else process_subpacket_12(q, NULL, 0);}/* * Decode superblock, fill packet lists. * * @param q context */static void qdm2_decode_super_block (QDM2Context *q){ GetBitContext gb; QDM2SubPacket header, *packet; int i, packet_bytes, sub_packet_size, sub_packets_D; unsigned int next_index = 0; memset(q->tone_level_idx_hi1, 0, sizeof(q->tone_level_idx_hi1)); memset(q->tone_level_idx_mid, 0, sizeof(q->tone_level_idx_mid)); memset(q->tone_level_idx_hi2, 0, sizeof(q->tone_level_idx_hi2)); q->sub_packets_B = 0; sub_packets_D = 0; average_quantized_coeffs(q); // average elements in quantized_coeffs[max_ch][10][8] init_get_bits(&gb, q->compressed_data, q->compressed_size*8); qdm2_decode_sub_packet_header(&gb, &header); if (header.type < 2 || header.type >= 8) { q->has_errors = 1; av_log(NULL,AV_LOG_ERROR,"bad superblock type\n"); return; } q->superblocktype_2_3 = (header.type == 2 || header.type == 3); packet_bytes = (q->compressed_size - get_bits_count(&gb) / 8); init_get_bits(&gb, header.data, header.size*8); if (header.type == 2 || header.type == 4 || header.type == 5) { int csum = 257 * get_bits(&gb, 8) + 2 * get_bits(&gb, 8); csum = qdm2_packet_checksum(q->compressed_data, q->checksum_size, csum); if (csum != 0) { q->has_errors = 1; av_log(NULL,AV_LOG_ERROR,"bad packet checksum\n"); return; } } q->sub_packet_list_B[0].packet = NULL; q->sub_packet_list_D[0].packet = NULL; for (i = 0; i < 6; i++) if (--q->fft_level_exp[i] < 0) q->fft_level_exp[i] = 0; for (i = 0; packet_bytes > 0; i++) { int j; q->sub_packet_list_A[i].next = NULL; if (i > 0) { q->sub_packet_list_A[i - 1].next = &q->sub_packet_list_A[i]; /* seek to next block */ init_get_bits(&gb, header.data, header.size*8); skip_bits(&gb, next_index*8); if (next_index >= header.size) break; } /* decode subpacket */ packet = &q->sub_packets[i]; qdm2_decode_sub_packet_header(&gb, packet); next_index = packet->size + get_bits_count(&gb) / 8; sub_packet_size = ((packet->size > 0xff) ? 1 : 0) + packet->size + 2; if (packet->type == 0) break; if (sub_packet_size > packet_bytes) { if (packet->type != 10 && packet->type != 11 && packet->type != 12) break; packet->size += packet_bytes - sub_packet_size; } packet_bytes -= sub_packet_size; /* add subpacket to 'all subpackets' list */ q->sub_packet_list_A[i].packet = packet; /* add subpacket to related list */ if (packet->type == 8) { SAMPLES_NEEDED_2("packet type 8"); return; } else if (packet->type >= 9 && packet->type <= 12) { /* packets for MPEG Audio like Synthesis Filter */ QDM2_LIST_ADD(q->sub_packet_list_D, sub_packets_D, packet); } else if (packet->type == 13) { for (j = 0; j < 6; j++) q->fft_level_exp[j] = get_bits(&gb, 6); } else if (packet->type == 14) { for (j = 0; j < 6; j++) q->fft_level_exp[j] = qdm2_get_vlc(&gb, &fft_level_exp_vlc, 0, 2); } else if (packet->type == 15) { SAMPLES_NEEDED_2("packet type 15") return; } else if (packet->type >= 16 && packet->type < 48 && !fft_subpackets[packet->type - 16]) { /* packets for FFT */ QDM2_LIST_ADD(q->sub_packet_list_B, q->sub_packets_B, packet); } } // Packet bytes loop/* **************************************************************** */ if (q->sub_packet_list_D[0].packet != NULL) { process_synthesis_subpackets(q, q->sub_packet_list_D); q->do_synth_filter = 1; } else if (q->do_synth_filter) { process_subpacket_10(q, NULL, 0); process_subpacket_11(q, NULL, 0); process_subpacket_12(q, NULL, 0); }/* **************************************************************** */}static void qdm2_fft_init_coefficient (QDM2Context *q, int sub_packet, int offset, int duration, int channel, int exp, int phase){ if (q->fft_coefs_min_index[duration] < 0) q->fft_coefs_min_index[duration] = q->fft_coefs_index; q->fft_coefs[q->fft_coefs_index].sub_packet = ((sub_packet >= 16) ? (sub_packet - 16) : sub_packet); q->fft_coefs[q->fft_coefs_index].channel = channel; q->fft_coefs[q->fft_coefs_index].offset = offset; q->fft_coefs[q->fft_coefs_index].exp = exp; q->fft_coefs[q->fft_coefs_index].phase = phase; q->fft_coefs_index++;}static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext *gb, int b){ int channel, stereo, phase, exp; int local_int_4, local_int_8, stereo_phase, local_int_10; int local_int_14, stereo_exp, local_int_20, local_int_28; int n, offset; local_int_4 = 0; local_int_28 = 0; local_int_20 = 2; local_int_8 = (4 - duration); local_int_10 = 1 << (q->group_order - duration - 1); offset = 1; while (1) { if (q->superblocktype_2_3) { while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) { offset = 1; if (n == 0) { local_int_4 += local_int_10; local_int_28 += (1 << local_int_8); } else { local_int_4 += 8*local_int_10; local_int_28 += (8 << local_int_8); } } offset += (n - 2); } else { offset += qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2); while (offset >= (local_int_10 - 1)) { offset += (1 - (local_int_10 - 1)); local_int_4 += local_int_10; local_int_28 += (1 << local_int_8); } } if (local_int_4 >= q->group_size) return; local_int_14 = (offset >> local_int_8); if (q->nb_channels > 1) { channel = get_bits1(gb); stereo = get_bits1(gb); } else { channel = 0; stereo = 0; } exp = qdm2_get_vlc(gb, (b ? &fft_level_exp_vlc : &fft_level_exp_alt_vlc), 0, 2); exp += q->fft_level_exp[fft_level_index_table[local_int_14]]; exp = (exp < 0) ? 0 : exp; phase = get_bits(gb, 3); stereo_exp = 0; stereo_phase = 0; if (stereo) { stereo_exp = (exp - qdm2_get_vlc(gb, &fft_stereo_exp_vlc, 0, 1)); stereo_phase = (phase - qdm2_get_vlc(gb, &fft_stereo_phase_vlc, 0, 1)); if (stereo_phase < 0) stereo_phase += 8; } if (q->frequency_range > (local_int_14 + 1)) { int sub_packet = (local_int_20 + local_int_28); qdm2_fft_init_coefficient(q, sub_packet, offset, duration, channel, exp, phase); if (stereo) qdm2_fft_init_coefficient(q, sub_packet, offset, duration, (1 - channel), stereo_exp, stereo_phase); } offset++; }}static void qdm2_decode_fft_packets (QDM2Context *q){ int i, j, min, max, value, type, unknown_flag; GetBitContext gb; if (q->sub_packet_list_B[0].packet == NULL) return; /* reset minimum indices for FFT coefficients */ q->fft_coefs_index = 0; for (i=0; i < 5; i++) q->fft_coefs_min_index[i] = -1; /* process subpackets ordered by type, largest type first */ for (i = 0, max = 256; i < q->sub_packets_B; i++) { QDM2SubPacket *packet; /* find subpacket with largest type less than max */ for (j = 0, min = 0, packet = NULL; j < q->sub_packets_B; j++) { value = q->sub_packet_list_B[j].packet->type; if (value > min && value < max) { min = value; packet = q->sub_packet_list_B[j].packet; } } max = min; /* check for errors (?) */ if (i == 0 && (packet->type < 16 || packet->type >= 48 || fft_subpackets[packet->type - 16])) return; /* decode FFT tones */ init_get_bits (&gb, packet->data, packet->size*8); if (packet->type >= 32 && packet->type < 48 && !fft_subpackets[packet->type - 16]) unknown_flag = 1; else unknown_flag = 0; type = packet->type; if ((type >= 17 && type < 24) || (type >= 33 && type < 40)) { int duration = q->sub_sampling + 5 - (type & 15); if (duration >= 0 && duration < 4) qdm2_fft_decode_tones(q, duration, &gb, unknown_flag); } else if (type == 31) { for (i=0; i < 4; i++) qdm2_fft_decode_tones(q, i, &gb, unknown_flag); } else if (type == 46) { for (i=0; i < 6; i++) q->fft_level_exp[i] = get_bits(&gb, 6); for (i=0; i < 4; i++) qdm2_fft_decode_tones(q, i, &gb, unknown_flag); } } // Loop on B packets /* calculate maximum indices for FFT coefficients */ for (i = 0, j = -1; i < 5; i++) if (q->fft_coefs_min_index[i] >= 0) { if (j >= 0) q->fft_coefs_max_index[j] = q->fft_coefs_min_index[i]; j = i; } if (j >= 0) q->fft_coefs_max_index[j] = q->fft_coefs_index;}static void qdm2_fft_generate_tone (QDM2Context *q, FFTTone *tone){ float level, f[6]; int i; QDM2Complex c; const double iscale = 2.0*M_PI / 512.0; tone->phase += tone->phase_shift; /* calculate current level (maximum amplitude) of tone */ level = fft_tone_envelope_table[tone->duration][tone->time_index] * tone->level; c.im = level * sin(tone->phase*iscale); c.re = level * cos(tone->phase*iscale); /* generate FFT coefficients for tone */ if (tone->duration >= 3 || tone->cutoff >= 3) { tone->samples_im[0] += c.im; tone->samples_re[0] += c.re; tone->samples_im[1] -= c.im; tone->samples_re[1] -= c.re; } else { f[1] = -tone->table[4]; f[0] = tone->table[3] - tone->table[0]; f[2] = 1.0 - tone->table[2] - tone->table[3]; f[3] = tone->table[1] + tone->table[4] - 1.0; f[4] = tone->table[0] - tone->table[1]; f[5] = tone->table[2]; for (i = 0; i < 2; i++) { tone->samples_re[fft_cutoff_index_table[tone->cutoff][i]] += c.re * f[i]; tone->samples_im[fft_cutoff_index_table[tone->cutoff][i]] += c.im *((tone->cutoff <= i) ? -f[i] : f[i]); } for (i = 0; i < 4; i++) { tone->samples_re[i] += c.re * f[i+2]; tone->samples_im[i] += c.im * f[i+2]; } } /* copy the tone if it has not yet died out */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -