Example #1
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 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;
            }
        }
    }
Example #2
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;
            }
        }
    }