X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=wmadec_filter.c;h=befc39434d9c2aa8a8057957db37ad8eae4b406e;hp=401dfd2535955681c1085edce795ba59dbed79d0;hb=d1ff8d2c414883209717cf65e37113f9f52fef63;hpb=a7722850be9f23daf1e095bc9527ba24faa9719b diff --git a/wmadec_filter.c b/wmadec_filter.c index 401dfd25..befc3943 100644 --- a/wmadec_filter.c +++ b/wmadec_filter.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "para.h" #include "error.h" @@ -83,7 +84,6 @@ struct private_wmadec_data { struct vlc coef_vlc[2]; uint16_t *run_table[2]; uint16_t *level_table[2]; - uint16_t *int_table[2]; const struct coef_vlc_table *coef_vlcs[2]; /* frame info */ int frame_len; ///< frame length in samples @@ -131,16 +131,17 @@ struct private_wmadec_data { #define VLCBITS 9 #define VLCMAX ((22 + VLCBITS - 1) / VLCBITS) -DECLARE_ALIGNED(16, float, ff_sine_128[128]); -DECLARE_ALIGNED(16, float, ff_sine_256[256]); -DECLARE_ALIGNED(16, float, ff_sine_512[512]); -DECLARE_ALIGNED(16, float, ff_sine_1024[1024]); -DECLARE_ALIGNED(16, float, ff_sine_2048[2048]); -DECLARE_ALIGNED(16, float, ff_sine_4096[4096]); +#define SINE_WINDOW(x) float sine_ ## x[x] __aligned(16) -static float *ff_sine_windows[6] = { - ff_sine_128, ff_sine_256, ff_sine_512, ff_sine_1024, - ff_sine_2048, ff_sine_4096 +SINE_WINDOW(128); +SINE_WINDOW(256); +SINE_WINDOW(512); +SINE_WINDOW(1024); +SINE_WINDOW(2048); +SINE_WINDOW(4096); + +static float *sine_windows[6] = { + sine_128, sine_256, sine_512, sine_1024, sine_2048, sine_4096 }; /* Generate a sine window. */ @@ -166,33 +167,27 @@ static void wmadec_cleanup(struct private_wmadec_data *pwd) free_vlc(&pwd->coef_vlc[i]); free(pwd->run_table[i]); free(pwd->level_table[i]); - free(pwd->int_table[i]); } } -/* XXX: use same run/length optimization as mpeg decoders */ -//FIXME maybe split decode / encode or pass flag static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table, - uint16_t **plevel_table, uint16_t **pint_table, - const struct coef_vlc_table *vlc_table) + uint16_t **plevel_table, const struct coef_vlc_table *vlc_table) { int n = vlc_table->n; const uint8_t *table_bits = vlc_table->huffbits; const uint32_t *table_codes = vlc_table->huffcodes; const uint16_t *levels_table = vlc_table->levels; - uint16_t *run_table, *level_table, *int_table; + uint16_t *run_table, *level_table; int i, l, j, k, level; init_vlc(vlc, VLCBITS, n, table_bits, table_codes, 4); run_table = para_malloc(n * sizeof(uint16_t)); level_table = para_malloc(n * sizeof(uint16_t)); - int_table = para_malloc(n * sizeof(uint16_t)); i = 2; level = 1; k = 0; while (i < n) { - int_table[k] = i; l = levels_table[k++]; for (j = 0; j < l; j++) { run_table[i] = j; @@ -203,7 +198,6 @@ static void init_coef_vlc(struct vlc *vlc, uint16_t **prun_table, } *prun_table = run_table; *plevel_table = level_table; - *pint_table = int_table; } /* compute the scale factor band sizes for each MDCT block size */ @@ -390,8 +384,8 @@ static int wma_init(struct private_wmadec_data *pwd) for (i = 0; i < pwd->nb_block_sizes; i++) { int n; n = 1 << (pwd->frame_len_bits - i); - sine_window_init(ff_sine_windows[pwd->frame_len_bits - i - 7], n); - pwd->windows[i] = ff_sine_windows[pwd->frame_len_bits - i - 7]; + sine_window_init(sine_windows[pwd->frame_len_bits - i - 7], n); + pwd->windows[i] = sine_windows[pwd->frame_len_bits - i - 7]; } pwd->reset_block_lengths = 1; @@ -426,9 +420,9 @@ static int wma_init(struct private_wmadec_data *pwd) pwd->coef_vlcs[0] = &coef_vlcs[coef_vlc_table * 2]; pwd->coef_vlcs[1] = &coef_vlcs[coef_vlc_table * 2 + 1]; init_coef_vlc(&pwd->coef_vlc[0], &pwd->run_table[0], &pwd->level_table[0], - &pwd->int_table[0], pwd->coef_vlcs[0]); + pwd->coef_vlcs[0]); init_coef_vlc(&pwd->coef_vlc[1], &pwd->run_table[1], &pwd->level_table[1], - &pwd->int_table[1], pwd->coef_vlcs[1]); + pwd->coef_vlcs[1]); return 0; } @@ -488,15 +482,15 @@ static int wma_decode_init(char *initial_buf, int len, struct private_wmadec_dat if (pwd->use_noise_coding) { PARA_INFO_LOG("using noise coding\n"); init_vlc(&pwd->hgain_vlc, HGAINVLCBITS, - sizeof(ff_wma_hgain_huffbits), ff_wma_hgain_huffbits, - ff_wma_hgain_huffcodes, 2); + sizeof(wma_hgain_huffbits), wma_hgain_huffbits, + wma_hgain_huffcodes, 2); } if (pwd->use_exp_vlc) { PARA_INFO_LOG("using exp_vlc\n"); init_vlc(&pwd->exp_vlc, EXPVLCBITS, - sizeof(ff_wma_scale_huffbits), ff_wma_scale_huffbits, - ff_wma_scale_huffcodes, 4); + sizeof(wma_scale_huffbits), wma_scale_huffbits, + wma_scale_huffcodes, 4); } else { PARA_INFO_LOG("using curve\n"); wma_lsp_to_curve_init(pwd, pwd->frame_len); @@ -567,7 +561,7 @@ static void decode_exp_lsp(struct private_wmadec_data *pwd, int ch) val = get_bits(&pwd->gb, 3); else val = get_bits(&pwd->gb, 4); - lsp_coefs[i] = ff_wma_lsp_codebook[i][val]; + lsp_coefs[i] = wma_lsp_codebook[i][val]; } wma_lsp_to_curve(pwd, pwd->exponents[ch], &pwd->max_exponent[ch], @@ -684,6 +678,162 @@ static int wma_total_gain_to_bits(int total_gain) return 9; } +static int compute_high_band_values(struct private_wmadec_data *pwd, + int bsize, int nb_coefs[MAX_CHANNELS]) +{ + int ch; + + if (!pwd->use_noise_coding) + return 0; + for (ch = 0; ch < pwd->ahi.channels; ch++) { + int i, m, a; + if (!pwd->channel_coded[ch]) + continue; + m = pwd->exponent_high_sizes[bsize]; + for (i = 0; i < m; i++) { + a = get_bit(&pwd->gb); + pwd->high_band_coded[ch][i] = a; + if (!a) + continue; + nb_coefs[ch] -= pwd->exponent_high_bands[bsize][i]; + } + } + for (ch = 0; ch < pwd->ahi.channels; ch++) { + int i, n, val; + if (!pwd->channel_coded[ch]) + continue; + n = pwd->exponent_high_sizes[bsize]; + val = (int)0x80000000; + for (i = 0; i < n; i++) { + if (!pwd->high_band_coded[ch][i]) + continue; + if (val == (int)0x80000000) + val = get_bits(&pwd->gb, 7) - 19; + else { + int code = get_vlc(&pwd->gb, + pwd->hgain_vlc.table, HGAINVLCBITS, + HGAINMAX); + if (code < 0) + return -1; + val += code - 18; + } + pwd->high_band_values[ch][i] = val; + } + } + return 1; +} + +static void compute_mdct_coefficients(struct private_wmadec_data *pwd, + int bsize, int total_gain, int nb_coefs[MAX_CHANNELS]) +{ + int ch; + float mdct_norm = 1.0 / (pwd->block_len / 2); + + for (ch = 0; ch < pwd->ahi.channels; 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]; + + 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 */ + for (i = 0; i < pwd->coefs_start; i++) + *coefs++ = 0.0; + 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; + /* 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; + } + /* 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 /= (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; + } + } + /* 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); + } + } +} + /** * @return 0 if OK. 1 if last block of frame. return -1 if * unrecorrable error. @@ -693,7 +843,6 @@ static int wma_decode_block(struct private_wmadec_data *pwd) int n, v, ch, code, bsize; int coef_nb_bits, total_gain; int nb_coefs[MAX_CHANNELS]; - float mdct_norm; /* compute current block length */ if (pwd->use_variable_block_len) { @@ -731,10 +880,10 @@ static int wma_decode_block(struct private_wmadec_data *pwd) return -E_INCOHERENT_BLOCK_LEN; if (pwd->ahi.channels == 2) - pwd->ms_stereo = get_bits1(&pwd->gb); + pwd->ms_stereo = get_bit(&pwd->gb); v = 0; for (ch = 0; ch < pwd->ahi.channels; ch++) { - int a = get_bits1(&pwd->gb); + int a = get_bit(&pwd->gb); pwd->channel_coded[ch] = a; v |= a; } @@ -763,58 +912,11 @@ static int wma_decode_block(struct private_wmadec_data *pwd) for (ch = 0; ch < pwd->ahi.channels; ch++) nb_coefs[ch] = n; - /* complex coding */ - if (pwd->use_noise_coding) { - for (ch = 0; ch < pwd->ahi.channels; ch++) { - if (pwd->channel_coded[ch]) { - int i, m, a; - m = pwd->exponent_high_sizes[bsize]; - for (i = 0; i < m; i++) { - a = get_bits1(&pwd->gb); - pwd->high_band_coded[ch][i] = a; - /* if noise coding, the coefficients are not transmitted */ - if (a) - nb_coefs[ch] -= - pwd-> - exponent_high_bands[bsize] - [i]; - } - } - } - for (ch = 0; ch < pwd->ahi.channels; ch++) { - if (pwd->channel_coded[ch]) { - int i, val; - - n = pwd->exponent_high_sizes[bsize]; - val = (int) 0x80000000; - for (i = 0; i < n; i++) { - if (pwd->high_band_coded[ch][i]) { - if (val == (int) 0x80000000) { - val = - get_bits(&pwd->gb, - 7) - 19; - } else { - code = - get_vlc(&pwd->gb, - pwd-> - hgain_vlc. - table, - HGAINVLCBITS, - HGAINMAX); - if (code < 0) - return -1; - val += code - 18; - } - pwd->high_band_values[ch][i] = - val; - } - } - } - } - } + if (compute_high_band_values(pwd, bsize, nb_coefs) < 0) + return -1; /* exponents can be reused in short blocks. */ - if ((pwd->block_len_bits == pwd->frame_len_bits) || get_bits1(&pwd->gb)) { + if ((pwd->block_len_bits == pwd->frame_len_bits) || get_bit(&pwd->gb)) { for (ch = 0; ch < pwd->ahi.channels; ch++) { if (pwd->channel_coded[ch]) { if (pwd->use_exp_vlc) { @@ -830,220 +932,55 @@ static int wma_decode_block(struct private_wmadec_data *pwd) /* parse spectral coefficients : just RLE encoding */ for (ch = 0; ch < pwd->ahi.channels; ch++) { - if (pwd->channel_coded[ch]) { - struct vlc *coef_vlc; - int level, run, sign, tindex; - int16_t *ptr, *eptr; - const uint16_t *level_table, *run_table; - - /* special VLC tables are used for ms stereo because - there is potentially less energy there */ - tindex = (ch == 1 && pwd->ms_stereo); - coef_vlc = &pwd->coef_vlc[tindex]; - run_table = pwd->run_table[tindex]; - level_table = pwd->level_table[tindex]; - /* XXX: optimize */ - ptr = &pwd->coefs1[ch][0]; - eptr = ptr + nb_coefs[ch]; - memset(ptr, 0, pwd->block_len * sizeof(int16_t)); - for (;;) { - code = - get_vlc(&pwd->gb, coef_vlc->table, VLCBITS, - VLCMAX); - if (code < 0) - return -1; - if (code == 1) { - /* EOB */ - break; - } else if (code == 0) { - /* escape */ - level = get_bits(&pwd->gb, coef_nb_bits); - /* NOTE: this is rather suboptimal. reading - block_len_bits would be better */ - run = - get_bits(&pwd->gb, pwd->frame_len_bits); - } else { - /* normal code */ - run = run_table[code]; - level = level_table[code]; - } - sign = get_bits1(&pwd->gb); - if (!sign) - level = -level; - ptr += run; - if (ptr >= eptr) { - PARA_ERROR_LOG("overflow in spectral RLE, ignoring\n"); - break; - } - *ptr++ = level; - /* NOTE: EOB can be omitted */ - if (ptr >= eptr) - break; - } - } - } - - /* normalize */ - { - int n4 = pwd->block_len / 2; - mdct_norm = 1.0 / (float) n4; - } - - /* finally compute the MDCT coefficients */ - 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, 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); - } + struct vlc *coef_vlc; + int level, run, tindex; + int16_t *ptr, *eptr; + const uint16_t *level_table, *run_table; - 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; - } - - /* 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; - } - } - - /* 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); - } - } else { - /* XXX: optimize more */ - for (i = 0; i < pwd->coefs_start; i++) - *coefs++ = 0.0; - 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; + if (!pwd->channel_coded[ch]) + continue; + /* + * special VLC tables are used for ms stereo because there is + * potentially less energy there + */ + tindex = (ch == 1 && pwd->ms_stereo); + coef_vlc = &pwd->coef_vlc[tindex]; + run_table = pwd->run_table[tindex]; + level_table = pwd->level_table[tindex]; + /* XXX: optimize */ + ptr = &pwd->coefs1[ch][0]; + eptr = ptr + nb_coefs[ch]; + memset(ptr, 0, pwd->block_len * sizeof(int16_t)); + for (;;) { + code = get_vlc(&pwd->gb, coef_vlc->table, + VLCBITS, VLCMAX); + if (code < 0) + return -1; + if (code == 1) /* EOB */ + break; + if (code == 0) { /* escape */ + level = get_bits(&pwd->gb, coef_nb_bits); + /* reading block_len_bits would be better */ + run = get_bits(&pwd->gb, pwd->frame_len_bits); + } else { /* normal code */ + run = run_table[code]; + level = level_table[code]; + } + if (!get_bit(&pwd->gb)) + level = -level; + ptr += run; + if (ptr >= eptr) { + PARA_ERROR_LOG("overflow in spectral RLE, ignoring\n"); + break; } + *ptr++ = level; + if (ptr >= eptr) /* EOB can be omitted */ + break; } } + compute_mdct_coefficients(pwd, bsize, total_gain, nb_coefs); + if (pwd->ms_stereo && pwd->channel_coded[1]) { float a, b; int i; @@ -1144,8 +1081,7 @@ static int wma_decode_frame(struct private_wmadec_data *pwd, int16_t *samples) static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data, int *data_size, const uint8_t *buf, int buf_size) { - int ret, nb_frames, bit_offset, i, pos, len; - uint8_t *q; + int ret; int16_t *samples; static int frame_count; @@ -1157,8 +1093,11 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data, return 0; buf_size = pwd->ahi.block_align; samples = data; - init_get_bits(&pwd->gb, buf, buf_size * 8); + init_get_bits(&pwd->gb, buf, buf_size); if (pwd->use_bit_reservoir) { + int i, nb_frames, bit_offset, pos, len; + uint8_t *q; + /* read super frame header */ skip_bits(&pwd->gb, 4); /* super frame index */ nb_frames = get_bits(&pwd->gb, 4) - 1; @@ -1187,7 +1126,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data, /* XXX: bit_offset bits into last frame */ init_get_bits(&pwd->gb, pwd->last_superframe, - MAX_CODED_SUPERFRAME_SIZE * 8); + MAX_CODED_SUPERFRAME_SIZE); /* skip unused bits */ if (pwd->last_bitoffset > 0) skip_bits(&pwd->gb, pwd->last_bitoffset); @@ -1205,7 +1144,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data, /* read each frame starting from bit_offset */ pos = bit_offset + 4 + 4 + pwd->byte_offset_bits + 3; init_get_bits(&pwd->gb, buf + (pos >> 3), - (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3)) * 8); + (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))); len = pos & 7; if (len > 0) skip_bits(&pwd->gb, len); @@ -1243,7 +1182,7 @@ static int wma_decode_superframe(struct private_wmadec_data *pwd, void *data, samples += pwd->ahi.channels * pwd->frame_len; } PARA_DEBUG_LOG("frame_count: %d frame_len: %d, block_len: %d, " - "outbytes: %d, eaten: %d\n", + "outbytes: %zd, eaten: %d\n", frame_count, pwd->frame_len, pwd->block_len, (int8_t *) samples - (int8_t *) data, pwd->ahi.block_align); *data_size = (int8_t *)samples - (int8_t *)data; @@ -1262,6 +1201,8 @@ static ssize_t wmadec_convert(char *inbuffer, size_t len, if (out_size < 128 * 1024) return 0; + if (len <= WMA_FRAME_SKIP) + return 0; if (!pwd) { ret = wma_decode_init(inbuffer, len, &pwd); if (ret <= 0)