struct private_wmadec_data {
struct asf_header_info ahi;
struct getbit_context gb;
+ /** Whether to use the bit reservoir. */
int use_bit_reservoir;
+ /** Whether to use variable block length. */
int use_variable_block_len;
- int use_exp_vlc; ///< exponent coding: 0 = lsp, 1 = vlc + delta
- int use_noise_coding; ///< true if perceptual noise is added
+ /** Whether to use exponent coding. */
+ int use_exp_vlc;
+ /** Whether perceptual noise is added. */
+ int use_noise_coding;
int byte_offset_bits;
struct vlc exp_vlc;
int exponent_sizes[BLOCK_NB_SIZES];
uint16_t exponent_bands[BLOCK_NB_SIZES][25];
- int high_band_start[BLOCK_NB_SIZES]; ///< index of first coef in high band
- int coefs_start; ///< first coded coef
+ /** The index of the first coef in high band. */
+ int high_band_start[BLOCK_NB_SIZES];
int coefs_end[BLOCK_NB_SIZES]; ///< max number of coded coefficients
int exponent_high_sizes[BLOCK_NB_SIZES];
int exponent_high_bands[BLOCK_NB_SIZES][HIGH_BAND_MAX_SIZE];
int a, b, pos, lpos, k, block_len, i, j, n;
const uint8_t *table;
- pwd->coefs_start = 0;
for (k = 0; k < pwd->nb_block_sizes; k++) {
block_len = pwd->frame_len >> k;
float mdct_norm = 1.0 / (pwd->block_len / 2);
for (ch = 0; ch < pwd->ahi.channels; ch++) {
- if (pwd->channel_coded[ch]) {
- int16_t *coefs1;
- float *coefs, *exponents, mult, mult1, noise;
- int i, j, n, n1, last_high_band, esize;
- float exp_power[HIGH_BAND_MAX_SIZE];
-
- coefs1 = pwd->coefs1[ch];
- exponents = pwd->exponents[ch];
- esize = pwd->exponents_bsize[ch];
- mult = pow(10, total_gain * 0.05) / pwd->max_exponent[ch];
- mult *= mdct_norm;
- coefs = pwd->coefs[ch];
- if (pwd->use_noise_coding) {
- mult1 = mult;
- /* very low freqs : noise */
- for (i = 0; i < pwd->coefs_start; i++) {
- *coefs++ =
- pwd->noise_table[pwd->noise_index] *
- exponents[i << bsize >> esize] *
- mult1;
- pwd->noise_index =
- (pwd->noise_index +
- 1) & (NOISE_TAB_SIZE - 1);
- }
-
- n1 = pwd->exponent_high_sizes[bsize];
-
- /* compute power of high bands */
- exponents = pwd->exponents[ch] +
- (pwd->high_band_start[bsize] << bsize);
- last_high_band = 0; /* avoid warning */
- for (j = 0; j < n1; j++) {
- n = pwd->exponent_high_bands[pwd->
- frame_len_bits
- -
- pwd->
- block_len_bits]
- [j];
- if (pwd->high_band_coded[ch][j]) {
- float e2, val;
- e2 = 0;
- for (i = 0; i < n; i++) {
- val = exponents[i << bsize
- >> esize];
- e2 += val * val;
- }
- exp_power[j] = e2 / n;
- last_high_band = j;
- }
- exponents += n << bsize;
- }
+ int16_t *coefs1;
+ float *coefs, *exponents, mult, mult1, noise;
+ int i, j, n, n1, last_high_band, esize;
+ float exp_power[HIGH_BAND_MAX_SIZE];
- /* main freqs and high freqs */
- exponents =
- pwd->exponents[ch] +
- (pwd->coefs_start << bsize);
- for (j = -1; j < n1; j++) {
- if (j < 0) {
- n = pwd->high_band_start[bsize] -
- pwd->coefs_start;
- } else {
- n = pwd->exponent_high_bands[pwd->
- frame_len_bits
- -
- pwd->
- block_len_bits]
- [j];
- }
- if (j >= 0 && pwd->high_band_coded[ch][j]) {
- /* use noise with specified power */
- mult1 =
- sqrt(exp_power[j] /
- exp_power
- [last_high_band]);
- /* XXX: use a table */
- mult1 =
- mult1 * pow(10,
- pwd->
- high_band_values
- [ch][j] * 0.05);
- mult1 =
- mult1 /
- (pwd->max_exponent[ch] *
- pwd->noise_mult);
- mult1 *= mdct_norm;
- for (i = 0; i < n; i++) {
- noise =
- pwd->noise_table[pwd->
- noise_index];
- pwd->noise_index =
- (pwd->noise_index +
- 1) &
- (NOISE_TAB_SIZE -
- 1);
- *coefs++ =
- noise *
- exponents[i << bsize
- >> esize]
- * mult1;
- }
- exponents += n << bsize;
- } else {
- /* coded values + small noise */
- for (i = 0; i < n; i++) {
- noise =
- pwd->noise_table[pwd->
- noise_index];
- pwd->noise_index =
- (pwd->noise_index +
- 1) &
- (NOISE_TAB_SIZE -
- 1);
- *coefs++ =
- ((*coefs1++) +
- noise) *
- exponents[i << bsize
- >> esize]
- * mult;
- }
- exponents += n << bsize;
- }
+ if (!pwd->channel_coded[ch])
+ continue;
+ coefs1 = pwd->coefs1[ch];
+ exponents = pwd->exponents[ch];
+ esize = pwd->exponents_bsize[ch];
+ mult = pow(10, total_gain * 0.05) / pwd->max_exponent[ch];
+ mult *= mdct_norm;
+ coefs = pwd->coefs[ch];
+ if (!pwd->use_noise_coding) {
+ /* XXX: optimize more */
+ n = nb_coefs[ch];
+ for (i = 0; i < n; i++)
+ *coefs++ = coefs1[i] *
+ exponents[i << bsize >> esize] * mult;
+ n = pwd->block_len - pwd->coefs_end[bsize];
+ for (i = 0; i < n; i++)
+ *coefs++ = 0.0;
+ continue;
+ }
+ mult1 = mult;
+ n1 = pwd->exponent_high_sizes[bsize];
+ /* compute power of high bands */
+ exponents = pwd->exponents[ch] +
+ (pwd->high_band_start[bsize] << bsize);
+ last_high_band = 0; /* avoid warning */
+ for (j = 0; j < n1; j++) {
+ n = pwd->exponent_high_bands[
+ pwd->frame_len_bits - pwd->block_len_bits][j];
+ if (pwd->high_band_coded[ch][j]) {
+ float e2, val;
+ e2 = 0;
+ for (i = 0; i < n; i++) {
+ val = exponents[i << bsize >> esize];
+ e2 += val * val;
}
-
- /* very high freqs : noise */
- n = pwd->block_len - pwd->coefs_end[bsize];
- mult1 =
- mult * exponents[((-1 << bsize)) >> esize];
+ exp_power[j] = e2 / n;
+ last_high_band = j;
+ }
+ exponents += n << bsize;
+ }
+ /* main freqs and high freqs */
+ exponents = pwd->exponents[ch];
+ for (j = -1; j < n1; j++) {
+ if (j < 0)
+ n = pwd->high_band_start[bsize];
+ else
+ n = pwd->exponent_high_bands[pwd->frame_len_bits
+ - pwd->block_len_bits][j];
+ if (j >= 0 && pwd->high_band_coded[ch][j]) {
+ /* use noise with specified power */
+ mult1 = sqrt(exp_power[j]
+ / exp_power[last_high_band]);
+ /* XXX: use a table */
+ mult1 = mult1 * pow(10,
+ pwd->high_band_values[ch][j] * 0.05);
+ mult1 /= (pwd->max_exponent[ch] * pwd->noise_mult);
+ mult1 *= mdct_norm;
for (i = 0; i < n; i++) {
- *coefs++ =
- pwd->noise_table[pwd->noise_index] *
- mult1;
- pwd->noise_index =
- (pwd->noise_index +
- 1) & (NOISE_TAB_SIZE - 1);
+ noise = pwd->noise_table[pwd->noise_index];
+ pwd->noise_index = (pwd->noise_index + 1)
+ & (NOISE_TAB_SIZE - 1);
+ *coefs++ = noise * exponents[
+ i << bsize >> esize] * mult1;
}
+ exponents += n << bsize;
} else {
- /* XXX: optimize more */
- for (i = 0; i < pwd->coefs_start; i++)
- *coefs++ = 0.0;
- n = nb_coefs[ch];
+ /* coded values + small noise */
for (i = 0; i < n; i++) {
- *coefs++ =
- coefs1[i] *
- exponents[i << bsize >> esize] *
- mult;
+ noise = pwd->noise_table[pwd->noise_index];
+ pwd->noise_index = (pwd->noise_index + 1)
+ & (NOISE_TAB_SIZE - 1);
+ *coefs++ = ((*coefs1++) + noise) *
+ exponents[i << bsize >> esize]
+ * mult;
}
- n = pwd->block_len - pwd->coefs_end[bsize];
- for (i = 0; i < n; i++)
- *coefs++ = 0.0;
+ exponents += n << bsize;
}
}
+ /* very high freqs: noise */
+ n = pwd->block_len - pwd->coefs_end[bsize];
+ mult1 = mult * exponents[((-1 << bsize)) >> esize];
+ for (i = 0; i < n; i++) {
+ *coefs++ = pwd->noise_table[pwd->noise_index] * mult1;
+ pwd->noise_index = (pwd->noise_index + 1)
+ & (NOISE_TAB_SIZE - 1);
+ }
}
}
if (!v)
goto next;
- /* read total gain and extract corresponding number of bits for
- coef escape coding */
+ /*
+ * Read total gain and extract corresponding number of bits for coef
+ * escape coding.
+ */
total_gain = 1;
for (;;) {
int a = get_bits(&pwd->gb, 7);
coef_nb_bits = wma_total_gain_to_bits(total_gain);
/* compute number of coefficients */
- n = pwd->coefs_end[bsize] - pwd->coefs_start;
+ n = pwd->coefs_end[bsize];
for (ch = 0; ch < pwd->ahi.channels; ch++)
nb_coefs[ch] = n;
break;
}
}
-
compute_mdct_coefficients(pwd, bsize, total_gain, nb_coefs);
-
if (pwd->ms_stereo && pwd->channel_coded[1]) {
float a, b;
int i;
-
/*
* Nominal case for ms stereo: we do it before mdct.
*
pwd->coefs[1][i] = a - b;
}
}
-
next:
for (ch = 0; ch < pwd->ahi.channels; ch++) {
int n4, index;
static ssize_t wmadec_convert(char *inbuffer, size_t len,
struct filter_node *fn)
{
- int ret, out_size = fn->bufsize - fn->loaded;
+ int ret, converted = 0;
struct private_wmadec_data *pwd = fn->private_data;
- if (out_size < 128 * 1024)
- return 0;
if (len <= WMA_FRAME_SKIP)
return 0;
if (!pwd) {
fn->fc->samplerate = pwd->ahi.sample_rate;
return pwd->ahi.header_len;
}
- /* skip 31 bytes */
- if (len <= WMA_FRAME_SKIP + pwd->ahi.block_align)
- return 0;
- ret = wma_decode_superframe(pwd, fn->buf + fn->loaded,
- &out_size, (uint8_t *)inbuffer + WMA_FRAME_SKIP,
- len - WMA_FRAME_SKIP);
- if (ret < 0)
- return ret;
- fn->loaded += out_size;
- return ret + WMA_FRAME_SKIP;
+ for (;;) {
+ int out_size;
+ if (converted + WMA_FRAME_SKIP + pwd->ahi.block_align > len)
+ break;
+ out_size = fn->bufsize - fn->loaded;
+ if (out_size < 128 * 1024)
+ break;
+ ret = wma_decode_superframe(pwd, fn->buf + fn->loaded,
+ &out_size, (uint8_t *)inbuffer + converted + WMA_FRAME_SKIP,
+ len - WMA_FRAME_SKIP);
+ if (ret < 0)
+ return ret;
+ fn->loaded += out_size;
+ converted += ret + WMA_FRAME_SKIP;
+ }
+ return converted;
}
static void wmadec_close(struct filter_node *fn)