static int parse_dmix_coeffs(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; int m, n; if (chs->primary_chset) { m = dmix_primary_nch[chs->dmix_type]; n = chs->nchannels; } else { m = chs->dmix_m; n = chs->nchannels + 2; // Two extra columns for scales } // Reallocate downmix coefficients matrix if (ta_zalloc_fast(xll->chset, &chs->dmix_coeff, m * n, sizeof(int)) < 0) return -DCADEC_ENOMEM; if (chs->primary_chset) { chs->dmix_scale = NULL; chs->dmix_scale_inv = NULL; } else { chs->dmix_scale = chs->dmix_coeff + m * chs->nchannels; chs->dmix_scale_inv = chs->dmix_coeff + m * (chs->nchannels + 1); } int *coeff_ptr = chs->dmix_coeff; for (int i = 0; i < m; i++) { int scale_inv = 0; // Downmix scale // Only for non-primary channel sets if (!chs->primary_chset) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; enforce(index >= 40 && index < dca_countof(dmix_table), "Invalid downmix scale index"); int scale = dmix_table[index]; scale_inv = dmix_table_inv[index - 40]; chs->dmix_scale[i] = (scale ^ sign) - sign; chs->dmix_scale_inv[i] = (scale_inv ^ sign) - sign; } else { chs->dmix_scale[i] = 0; chs->dmix_scale_inv[i] = 0; } } // Downmix coefficients for (int j = 0; j < chs->nchannels; j++) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; enforce(index < dca_countof(dmix_table), "Invalid downmix coefficient index"); int coeff = dmix_table[index]; if (!chs->primary_chset) // Multiply by |InvDmixScale| to get |UndoDmixScale| coeff = mul16(scale_inv, coeff); // Convert sign *coeff_ptr++ = (coeff ^ sign) - sign; } else { *coeff_ptr++ = 0; } } }
static int parse_dmix_coeffs(struct xll_chset *chs) { struct xll_decoder *xll = chs->decoder; int m, n; if (chs->primary_chset) { m = dmix_primary_nch[chs->dmix_type]; n = chs->nchannels; } else { m = chs->dmix_m; n = chs->nchannels + 2; // Two extra columns for scales } // Reallocate downmix coefficients buffer if (ta_zalloc_fast(xll->chset, &chs->dmix_coeff, m * n * 2, sizeof(int)) < 0) return -DCADEC_ENOMEM; // Setup buffer pointers for current and previous frame bool valid = (chs->dmix_coeffs_signature == XLL_DMIX_SIGNATURE(chs)); chs->dmix_coeff_cur = chs->dmix_coeff + m * n * chs->dmix_coeffs_parity; chs->dmix_coeff_pre = chs->dmix_coeff + m * n * (chs->dmix_coeffs_parity ^ valid); if (chs->primary_chset) { chs->dmix_scale_cur = chs->dmix_scale_pre = NULL; chs->dmix_scale_inv_cur = chs->dmix_scale_inv_pre = NULL; } else { chs->dmix_scale_cur = chs->dmix_coeff_cur + m * chs->nchannels; chs->dmix_scale_pre = chs->dmix_coeff_pre + m * chs->nchannels; chs->dmix_scale_inv_cur = chs->dmix_coeff_cur + m * (chs->nchannels + 1); chs->dmix_scale_inv_pre = chs->dmix_coeff_pre + m * (chs->nchannels + 1); } int *coeff_ptr = chs->dmix_coeff_cur; for (int i = 0; i < m; i++) { int scale_inv = 0; // Downmix scale // Only for non-primary channel sets if (!chs->primary_chset) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; if (index < 40 || index >= dca_countof(dmix_table)) { xll_err("Invalid downmix scale index"); return -DCADEC_EBADDATA; } int scale = dmix_table[index]; scale_inv = dmix_table_inv[index - 40]; chs->dmix_scale_cur[i] = (scale ^ sign) - sign; chs->dmix_scale_inv_cur[i] = (scale_inv ^ sign) - sign; } else { chs->dmix_scale_cur[i] = 0; chs->dmix_scale_inv_cur[i] = 0; } } // Downmix coefficients for (int j = 0; j < chs->nchannels; j++) { int code = bits_get(&xll->bits, 9); int sign = (code >> 8) - 1; code &= 0xff; if (code > 0) { unsigned int index = code - 1; if (index >= dca_countof(dmix_table)) { xll_err("Invalid downmix coefficient index"); return -DCADEC_EBADDATA; } int coeff = dmix_table[index]; if (!chs->primary_chset) // Multiply by |InvDmixScale| to get |UndoDmixScale| coeff = mul16(scale_inv, coeff); // Convert sign *coeff_ptr++ = (coeff ^ sign) - sign; } else { *coeff_ptr++ = 0; } } }