📄 qdm2.c
字号:
if (++tone->time_index < ((1 << (5 - tone->duration)) - 1)) { memcpy(&q->fft_tones[q->fft_tone_end], tone, sizeof(FFTTone)); q->fft_tone_end = (q->fft_tone_end + 1) % 1000; }}static void qdm2_fft_tone_synthesizer (QDM2Context *q, int sub_packet){ int i, j, ch; const double iscale = 0.25 * M_PI; for (ch = 0; ch < q->channels; ch++) { memset(q->fft.samples_im[ch], 0, q->fft_size * sizeof(float)); memset(q->fft.samples_re[ch], 0, q->fft_size * sizeof(float)); } /* apply FFT tones with duration 4 (1 FFT period) */ if (q->fft_coefs_min_index[4] >= 0) for (i = q->fft_coefs_min_index[4]; i < q->fft_coefs_max_index[4]; i++) { float level; QDM2Complex c; if (q->fft_coefs[i].sub_packet != sub_packet) break; ch = (q->channels == 1) ? 0 : q->fft_coefs[i].channel; level = (q->fft_coefs[i].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[i].exp & 63]; c.re = level * cos(q->fft_coefs[i].phase * iscale); c.im = level * sin(q->fft_coefs[i].phase * iscale); q->fft.samples_re[ch][q->fft_coefs[i].offset + 0] += c.re; q->fft.samples_im[ch][q->fft_coefs[i].offset + 0] += c.im; q->fft.samples_re[ch][q->fft_coefs[i].offset + 1] -= c.re; q->fft.samples_im[ch][q->fft_coefs[i].offset + 1] -= c.im; } /* generate existing FFT tones */ for (i = q->fft_tone_end; i != q->fft_tone_start; ) { qdm2_fft_generate_tone(q, &q->fft_tones[q->fft_tone_start]); q->fft_tone_start = (q->fft_tone_start + 1) % 1000; } /* create and generate new FFT tones with duration 0 (long) to 3 (short) */ for (i = 0; i < 4; i++) if (q->fft_coefs_min_index[i] >= 0) { for (j = q->fft_coefs_min_index[i]; j < q->fft_coefs_max_index[i]; j++) { int offset, four_i; FFTTone tone; if (q->fft_coefs[j].sub_packet != sub_packet) break; four_i = (4 - i); offset = q->fft_coefs[j].offset >> four_i; ch = (q->channels == 1) ? 0 : q->fft_coefs[j].channel; if (offset < q->frequency_range) { if (offset < 2) tone.cutoff = offset; else tone.cutoff = (offset >= 60) ? 3 : 2; tone.level = (q->fft_coefs[j].exp < 0) ? 0.0 : fft_tone_level_table[q->superblocktype_2_3 ? 0 : 1][q->fft_coefs[j].exp & 63]; tone.samples_im = &q->fft.samples_im[ch][offset]; tone.samples_re = &q->fft.samples_re[ch][offset]; tone.table = (float*)fft_tone_sample_table[i][q->fft_coefs[j].offset - (offset << four_i)]; tone.phase = 64 * q->fft_coefs[j].phase - (offset << 8) - 128; tone.phase_shift = (2 * q->fft_coefs[j].offset + 1) << (7 - four_i); tone.duration = i; tone.time_index = 0; qdm2_fft_generate_tone(q, &tone); } } q->fft_coefs_min_index[i] = j; }}static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet){ const int n = 1 << (q->fft_order - 1); const int n2 = n >> 1; const float gain = (q->channels == 1 && q->nb_channels == 2) ? 0.25f : 0.50f; float c, s, f0, f1, f2, f3; int i, j; /* prerotation (or something like that) */ for (i=1; i < n2; i++) { j = (n - i); c = q->exptab[i].re; s = -q->exptab[i].im; f0 = (q->fft.samples_re[channel][i] - q->fft.samples_re[channel][j]) * gain; f1 = (q->fft.samples_im[channel][i] + q->fft.samples_im[channel][j]) * gain; f2 = (q->fft.samples_re[channel][i] + q->fft.samples_re[channel][j]) * gain; f3 = (q->fft.samples_im[channel][i] - q->fft.samples_im[channel][j]) * gain; q->fft.complex[i].re = s * f0 - c * f1 + f2; q->fft.complex[i].im = c * f0 + s * f1 + f3; q->fft.complex[j].re = -s * f0 + c * f1 + f2; q->fft.complex[j].im = c * f0 + s * f1 - f3; } q->fft.complex[ 0].re = q->fft.samples_re[channel][ 0] * gain * 2.0; q->fft.complex[ 0].im = q->fft.samples_re[channel][ 0] * gain * 2.0; q->fft.complex[n2].re = q->fft.samples_re[channel][n2] * gain * 2.0; q->fft.complex[n2].im = -q->fft.samples_im[channel][n2] * gain * 2.0; ff_fft_permute(&q->fft_ctx, (FFTComplex *) q->fft.complex); ff_fft_calc (&q->fft_ctx, (FFTComplex *) q->fft.complex); /* add samples to output buffer */ for (i = 0; i < ((q->fft_frame_size + 15) & ~15); i++) q->output_buffer[q->channels * i + channel] += ((float *) q->fft.complex)[i];}/** * @param q context * @param index subpacket number */static void qdm2_synthesis_filter (QDM2Context *q, int index){ OUT_INT samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; int i, k, ch, sb_used, sub_sampling, dither_state = 0; /* copy sb_samples */ sb_used = QDM2_SB_USED(q->sub_sampling); for (ch = 0; ch < q->channels; ch++) for (i = 0; i < 8; i++) for (k=sb_used; k < SBLIMIT; k++) q->sb_samples[ch][(8 * index) + i][k] = 0; for (ch = 0; ch < q->nb_channels; ch++) { OUT_INT *samples_ptr = samples + ch; for (i = 0; i < 8; i++) { ff_mpa_synth_filter(q->synth_buf[ch], &(q->synth_buf_offset[ch]), mpa_window, &dither_state, samples_ptr, q->nb_channels, q->sb_samples[ch][(8 * index) + i]); samples_ptr += 32 * q->nb_channels; } } /* add samples to output buffer */ sub_sampling = (4 >> q->sub_sampling); for (ch = 0; ch < q->channels; ch++) for (i = 0; i < q->frame_size; i++) q->output_buffer[q->channels * i + ch] += (float)(samples[q->nb_channels * sub_sampling * i + ch] >> (sizeof(OUT_INT)*8-16));}/** * Init static data (does not depend on specific file) * * @param q context */static void qdm2_init(QDM2Context *q) { static int inited = 0; if (inited != 0) return; inited = 1; qdm2_init_vlc(); ff_mpa_synth_init(mpa_window); softclip_table_init(); rnd_table_init(); init_noise_samples(); av_log(NULL, AV_LOG_DEBUG, "init done\n");}#if 0static void dump_context(QDM2Context *q){ int i;#define PRINT(a,b) av_log(NULL,AV_LOG_DEBUG," %s = %d\n", a, b); PRINT("compressed_data",q->compressed_data); PRINT("compressed_size",q->compressed_size); PRINT("frame_size",q->frame_size); PRINT("checksum_size",q->checksum_size); PRINT("channels",q->channels); PRINT("nb_channels",q->nb_channels); PRINT("fft_frame_size",q->fft_frame_size); PRINT("fft_size",q->fft_size); PRINT("sub_sampling",q->sub_sampling); PRINT("fft_order",q->fft_order); PRINT("group_order",q->group_order); PRINT("group_size",q->group_size); PRINT("sub_packet",q->sub_packet); PRINT("frequency_range",q->frequency_range); PRINT("has_errors",q->has_errors); PRINT("fft_tone_end",q->fft_tone_end); PRINT("fft_tone_start",q->fft_tone_start); PRINT("fft_coefs_index",q->fft_coefs_index); PRINT("coeff_per_sb_select",q->coeff_per_sb_select); PRINT("cm_table_select",q->cm_table_select); PRINT("noise_idx",q->noise_idx); for (i = q->fft_tone_start; i < q->fft_tone_end; i++) { FFTTone *t = &q->fft_tones[i]; av_log(NULL,AV_LOG_DEBUG,"Tone (%d) dump:\n", i); av_log(NULL,AV_LOG_DEBUG," level = %f\n", t->level);// PRINT(" level", t->level); PRINT(" phase", t->phase); PRINT(" phase_shift", t->phase_shift); PRINT(" duration", t->duration); PRINT(" samples_im", t->samples_im); PRINT(" samples_re", t->samples_re); PRINT(" table", t->table); }}#endif/** * Init parameters from codec extradata */static int qdm2_decode_init(AVCodecContext *avctx){ QDM2Context *s = avctx->priv_data; uint8_t *extradata; int extradata_size; int tmp_val, tmp, size; int i; float alpha; /* extradata parsing Structure: wave { frma (QDM2) QDCA QDCP } 32 size (including this field) 32 tag (=frma) 32 type (=QDM2 or QDMC) 32 size (including this field, in bytes) 32 tag (=QDCA) // maybe mandatory parameters 32 unknown (=1) 32 channels (=2) 32 samplerate (=44100) 32 bitrate (=96000) 32 block size (=4096) 32 frame size (=256) (for one channel) 32 packet size (=1300) 32 size (including this field, in bytes) 32 tag (=QDCP) // maybe some tuneable parameters 32 float1 (=1.0) 32 zero ? 32 float2 (=1.0) 32 float3 (=1.0) 32 unknown (27) 32 unknown (8) 32 zero ? */ if (!avctx->extradata || (avctx->extradata_size < 48)) { av_log(avctx, AV_LOG_ERROR, "extradata missing or truncated\n"); return -1; } extradata = avctx->extradata; extradata_size = avctx->extradata_size; while (extradata_size > 7) { if (!memcmp(extradata, "frmaQDM", 7)) break; extradata++; extradata_size--; } if (extradata_size < 12) { av_log(avctx, AV_LOG_ERROR, "not enough extradata (%i)\n", extradata_size); return -1; } if (memcmp(extradata, "frmaQDM", 7)) { av_log(avctx, AV_LOG_ERROR, "invalid headers, QDM? not found\n"); return -1; } if (extradata[7] == 'C') {// s->is_qdmc = 1; av_log(avctx, AV_LOG_ERROR, "stream is QDMC version 1, which is not supported\n"); return -1; } extradata += 8; extradata_size -= 8; size = BE_32(extradata); if(size > extradata_size){ av_log(avctx, AV_LOG_ERROR, "extradata size too small, %i < %i\n", extradata_size, size); return -1; } extradata += 4; av_log(avctx, AV_LOG_DEBUG, "size: %d\n", size); if (BE_32(extradata) != MKBETAG('Q','D','C','A')) { av_log(avctx, AV_LOG_ERROR, "invalid extradata, expecting QDCA\n"); return -1; } extradata += 8; avctx->channels = s->nb_channels = s->channels = BE_32(extradata); extradata += 4; avctx->sample_rate = BE_32(extradata); extradata += 4; avctx->bit_rate = BE_32(extradata); extradata += 4; s->group_size = BE_32(extradata); extradata += 4; s->fft_size = BE_32(extradata); extradata += 4; s->checksum_size = BE_32(extradata); extradata += 4; s->fft_order = av_log2(s->fft_size) + 1; s->fft_frame_size = 2 * s->fft_size; // complex has two floats // something like max decodable tones s->group_order = av_log2(s->group_size) + 1; s->frame_size = s->group_size / 16; // 16 iterations per super block s->sub_sampling = s->fft_order - 7; s->frequency_range = 255 / (1 << (2 - s->sub_sampling)); switch ((s->sub_sampling * 2 + s->channels - 1)) { case 0: tmp = 40; break; case 1: tmp = 48; break; case 2: tmp = 56; break; case 3: tmp = 72; break; case 4: tmp = 80; break; case 5: tmp = 100;break; default: tmp=s->sub_sampling; break; } tmp_val = 0; if ((tmp * 1000) < avctx->bit_rate) tmp_val = 1; if ((tmp * 1440) < avctx->bit_rate) tmp_val = 2; if ((tmp * 1760) < avctx->bit_rate) tmp_val = 3; if ((tmp * 2240) < avctx->bit_rate) tmp_val = 4; s->cm_table_select = tmp_val; if (s->sub_sampling == 0) tmp = 7999; else tmp = ((-(s->sub_sampling -1)) & 8000) + 20000; /* 0: 7999 -> 0 1: 20000 -> 2 2: 28000 -> 2 */ if (tmp < 8000) s->coeff_per_sb_select = 0; else if (tmp <= 16000) s->coeff_per_sb_select = 1; else s->coeff_per_sb_select = 2; // Fail on unknown fft order, if it's > 9 it can overflow s->exptab[]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -