📄 wmadec.c
字号:
tprintf(" %d", s->exponent_bands[i][j]); tprintf("\n"); } }#endif /* init MDCT */ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1); /* init MDCT windows : simple sinus window */ for(i = 0; i < s->nb_block_sizes; i++) { int n, j; float alpha; n = 1 << (s->frame_len_bits - i); window = av_malloc(sizeof(float) * n); alpha = M_PI / (2.0 * n); for(j=0;j<n;j++) { window[n - j - 1] = sin((j + 0.5) * alpha); } s->windows[i] = window; } s->reset_block_lengths = 1; if (s->use_noise_coding) { /* init the noise generator */ if (s->use_exp_vlc) s->noise_mult = 0.02; else s->noise_mult = 0.04; #ifdef TRACE for(i=0;i<NOISE_TAB_SIZE;i++) s->noise_table[i] = 1.0 * s->noise_mult;#else { unsigned int seed; float norm; seed = 1; norm = (1.0 / (float)(1LL << 31)) * sqrt(3) * s->noise_mult; for(i=0;i<NOISE_TAB_SIZE;i++) { seed = seed * 314159 + 1; s->noise_table[i] = (float)((int)seed) * norm; } }#endif init_vlc(&s->hgain_vlc, 9, sizeof(hgain_huffbits), hgain_huffbits, 1, 1, hgain_huffcodes, 2, 2, 0); } if (s->use_exp_vlc) { init_vlc(&s->exp_vlc, 9, sizeof(scale_huffbits), scale_huffbits, 1, 1, scale_huffcodes, 4, 4, 0); } else { wma_lsp_to_curve_init(s, s->frame_len); } /* choose the VLC tables for the coefficients */ coef_vlc_table = 2; if (s->sample_rate >= 32000) { if (bps1 < 0.72) coef_vlc_table = 0; else if (bps1 < 1.16) coef_vlc_table = 1; } init_coef_vlc(&s->coef_vlc[0], &s->run_table[0], &s->level_table[0], &coef_vlcs[coef_vlc_table * 2]); init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], &coef_vlcs[coef_vlc_table * 2 + 1]); return 0;}/* interpolate values for a bigger or smaller block. The block must have multiple sizes */static void interpolate_array(float *scale, int old_size, int new_size){ int i, j, jincr, k; float v; if (new_size > old_size) { jincr = new_size / old_size; j = new_size; for(i = old_size - 1; i >=0; i--) { v = scale[i]; k = jincr; do { scale[--j] = v; } while (--k); } } else if (new_size < old_size) { j = 0; jincr = old_size / new_size; for(i = 0; i < new_size; i++) { scale[i] = scale[j]; j += jincr; } }}/* compute x^-0.25 with an exponent and mantissa table. We use linear interpolation to reduce the mantissa table size at a small speed expense (linear interpolation approximately doubles the number of bits of precision). */static inline float pow_m1_4(WMADecodeContext *s, float x){ union { float f; unsigned int v; } u, t; unsigned int e, m; float a, b; u.f = x; e = u.v >> 23; m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1); /* build interpolation scale: 1 <= t < 2. */ t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23); a = s->lsp_pow_m_table1[m]; b = s->lsp_pow_m_table2[m]; return s->lsp_pow_e_table[e] * (a + b * t.f);}static void wma_lsp_to_curve_init(WMADecodeContext *s, int frame_len){ float wdel, a, b; int i, e, m; wdel = M_PI / frame_len; for(i=0;i<frame_len;i++) s->lsp_cos_table[i] = 2.0f * cos(wdel * i); /* tables for x^-0.25 computation */ for(i=0;i<256;i++) { e = i - 126; s->lsp_pow_e_table[i] = pow(2.0, e * -0.25); } /* NOTE: these two tables are needed to avoid two operations in pow_m1_4 */ b = 1.0; for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) { m = (1 << LSP_POW_BITS) + i; a = (float)m * (0.5 / (1 << LSP_POW_BITS)); a = pow(a, -0.25); s->lsp_pow_m_table1[i] = 2 * a - b; s->lsp_pow_m_table2[i] = b - a; b = a; }#if 0 for(i=1;i<20;i++) { float v, r1, r2; v = 5.0 / i; r1 = pow_m1_4(s, v); r2 = pow(v,-0.25); printf("%f^-0.25=%f e=%f\n", v, r1, r2 - r1); }#endif}/* NOTE: We use the same code as Vorbis here *//* XXX: optimize it further with SSE/3Dnow */static void wma_lsp_to_curve(WMADecodeContext *s, float *out, float *val_max_ptr, int n, float *lsp){ int i, j; float p, q, w, v, val_max; val_max = 0; for(i=0;i<n;i++) { p = 0.5f; q = 0.5f; w = s->lsp_cos_table[i]; for(j=1;j<NB_LSP_COEFS;j+=2){ q *= w - lsp[j - 1]; p *= w - lsp[j]; } p *= p * (2.0f - w); q *= q * (2.0f + w); v = p + q; v = pow_m1_4(s, v); if (v > val_max) val_max = v; out[i] = v; } *val_max_ptr = val_max;}/* decode exponents coded with LSP coefficients (same idea as Vorbis) */static void decode_exp_lsp(WMADecodeContext *s, int ch){ float lsp_coefs[NB_LSP_COEFS]; int val, i; for(i = 0; i < NB_LSP_COEFS; i++) { if (i == 0 || i >= 8) val = get_bits(&s->gb, 3); else val = get_bits(&s->gb, 4); lsp_coefs[i] = lsp_codebook[i][val]; } wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch], s->block_len, lsp_coefs);}/* decode exponents coded with VLC codes */static int decode_exp_vlc(WMADecodeContext *s, int ch){ int last_exp, n, code; const uint16_t *ptr, *band_ptr; float v, *q, max_scale, *q_end; band_ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; ptr = band_ptr; q = s->exponents[ch]; q_end = q + s->block_len; max_scale = 0; if (s->version == 1) { last_exp = get_bits(&s->gb, 5) + 10; /* XXX: use a table */ v = pow(10, last_exp * (1.0 / 16.0)); max_scale = v; n = *ptr++; do { *q++ = v; } while (--n); } last_exp = 36; while (q < q_end) { code = get_vlc(&s->gb, &s->exp_vlc); if (code < 0) return -1; /* NOTE: this offset is the same as MPEG4 AAC ! */ last_exp += code - 60; /* XXX: use a table */ v = pow(10, last_exp * (1.0 / 16.0)); if (v > max_scale) max_scale = v; n = *ptr++; do { *q++ = v; } while (--n); } s->max_exponent[ch] = max_scale; return 0;}/* return 0 if OK. return 1 if last block of frame. return -1 if unrecorrable error. */static int wma_decode_block(WMADecodeContext *s){ int n, v, a, ch, code, bsize; int coef_nb_bits, total_gain, parse_exponents; float window[BLOCK_MAX_SIZE * 2];// XXX: FIXME!! there's a bug somewhere which makes this mandatory under altivec#ifdef HAVE_ALTIVEC volatile int nb_coefs[MAX_CHANNELS] __attribute__((aligned(16)));#else int nb_coefs[MAX_CHANNELS];#endif float mdct_norm;#ifdef TRACE tprintf("***decode_block: %d:%d\n", s->frame_count - 1, s->block_num);#endif /* compute current block length */ if (s->use_variable_block_len) { n = av_log2(s->nb_block_sizes - 1) + 1; if (s->reset_block_lengths) { s->reset_block_lengths = 0; v = get_bits(&s->gb, n); if (v >= s->nb_block_sizes) return -1; s->prev_block_len_bits = s->frame_len_bits - v; v = get_bits(&s->gb, n); if (v >= s->nb_block_sizes) return -1; s->block_len_bits = s->frame_len_bits - v; } else { /* update block lengths */ s->prev_block_len_bits = s->block_len_bits; s->block_len_bits = s->next_block_len_bits; } v = get_bits(&s->gb, n); if (v >= s->nb_block_sizes) return -1; s->next_block_len_bits = s->frame_len_bits - v; } else { /* fixed block len */ s->next_block_len_bits = s->frame_len_bits; s->prev_block_len_bits = s->frame_len_bits; s->block_len_bits = s->frame_len_bits; } /* now check if the block length is coherent with the frame length */ s->block_len = 1 << s->block_len_bits; if ((s->block_pos + s->block_len) > s->frame_len) return -1; if (s->nb_channels == 2) { s->ms_stereo = get_bits(&s->gb, 1); } v = 0; for(ch = 0; ch < s->nb_channels; ch++) { a = get_bits(&s->gb, 1); s->channel_coded[ch] = a; v |= a; } /* if no channel coded, no need to go further */ /* XXX: fix potential framing problems */ if (!v) goto next; bsize = s->frame_len_bits - s->block_len_bits; /* read total gain and extract corresponding number of bits for coef escape coding */ total_gain = 1; for(;;) { a = get_bits(&s->gb, 7); total_gain += a; if (a != 127) break; } if (total_gain < 15) coef_nb_bits = 13; else if (total_gain < 32) coef_nb_bits = 12; else if (total_gain < 40) coef_nb_bits = 11; else if (total_gain < 45) coef_nb_bits = 10; else coef_nb_bits = 9; /* compute number of coefficients */ n = s->coefs_end[bsize] - s->coefs_start; for(ch = 0; ch < s->nb_channels; ch++) nb_coefs[ch] = n; /* complex coding */ if (s->use_noise_coding) { for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { int i, n, a; n = s->exponent_high_sizes[bsize]; for(i=0;i<n;i++) { a = get_bits(&s->gb, 1); s->high_band_coded[ch][i] = a; /* if noise coding, the coefficients are not transmitted */ if (a) nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; } } } for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { int i, n, val, code; n = s->exponent_high_sizes[bsize]; val = (int)0x80000000; for(i=0;i<n;i++) { if (s->high_band_coded[ch][i]) { if (val == (int)0x80000000) { val = get_bits(&s->gb, 7) - 19; } else { code = get_vlc(&s->gb, &s->hgain_vlc); if (code < 0) return -1; val += code - 18; } s->high_band_values[ch][i] = val; } } } } } /* exposant can be interpolated in short blocks. */ parse_exponents = 1; if (s->block_len_bits != s->frame_len_bits) { parse_exponents = get_bits(&s->gb, 1); } if (parse_exponents) { for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { if (s->use_exp_vlc) { if (decode_exp_vlc(s, ch) < 0) return -1; } else { decode_exp_lsp(s, ch); } } } } else { for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { interpolate_array(s->exponents[ch], 1 << s->prev_block_len_bits, s->block_len); } } } /* parse spectral coefficients : just RLE encoding */ for(ch = 0; ch < s->nb_channels; ch++) { if (s->channel_coded[ch]) { VLC *coef_vlc; int level, run, sign, tindex; int16_t *ptr, *eptr; const int16_t *level_table, *run_table; /* special VLC tables are used for ms stereo because there is potentially less energy there */ tindex = (ch == 1 && s->ms_stereo); coef_vlc = &s->coef_vlc[tindex]; run_table = s->run_table[tindex]; level_table = s->level_table[tindex]; /* XXX: optimize */ ptr = &s->coefs1[ch][0]; eptr = ptr + nb_coefs[ch]; memset(ptr, 0, s->block_len * sizeof(int16_t)); for(;;) { code = get_vlc(&s->gb, coef_vlc); if (code < 0) return -1; if (code == 1) { /* EOB */ break; } else if (code == 0) { /* escape */ level = get_bits(&s->gb, coef_nb_bits); /* NOTE: this is rather suboptimal. reading block_len_bits would be better */ run = get_bits(&s->gb, s->frame_len_bits); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -