static int parse_tonal(DCALbrDecoder *s, int group) { unsigned int amp[DCA_LBR_CHANNELS_TOTAL]; unsigned int phs[DCA_LBR_CHANNELS_TOTAL]; unsigned int diff, main_amp, shift; int sf, sf_idx, ch, main_ch, freq; int ch_nbits = av_ceil_log2(s->nchannels_total); // Parse subframes for this group for (sf = 0; sf < 1 << group; sf += diff ? 8 : 1) { sf_idx = ((s->framenum << group) + sf) & 31; s->tonal_bounds[group][sf_idx][0] = s->ntones; // Parse tones for this subframe for (freq = 1;; freq++) { if (get_bits_left(&s->gb) < 1) { av_log(s->avctx, AV_LOG_ERROR, "Tonal group chunk too short\n"); return -1; } diff = parse_vlc(&s->gb, &ff_dca_vlc_tnl_grp[group], 2); if (diff >= FF_ARRAY_ELEMS(ff_dca_fst_amp)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid tonal frequency diff\n"); return -1; } diff = get_bitsz(&s->gb, diff >> 2) + ff_dca_fst_amp[diff]; if (diff <= 1) break; // End of subframe freq += diff - 2; if (freq >> (5 - group) > s->nsubbands * 4 - 5) { av_log(s->avctx, AV_LOG_ERROR, "Invalid spectral line offset\n"); return -1; } // Main channel main_ch = get_bitsz(&s->gb, ch_nbits); main_amp = parse_vlc(&s->gb, &ff_dca_vlc_tnl_scf, 2) + s->tonal_scf[ff_dca_freq_to_sb[freq >> (7 - group)]] + s->limited_range - 2; amp[main_ch] = main_amp < AMP_MAX ? main_amp : 0; phs[main_ch] = get_bits(&s->gb, 3); // Secondary channels for (ch = 0; ch < s->nchannels_total; ch++) { if (ch == main_ch) continue; if (get_bits1(&s->gb)) { amp[ch] = amp[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_damp, 1); phs[ch] = phs[main_ch] - parse_vlc(&s->gb, &ff_dca_vlc_dph, 1); } else { amp[ch] = 0; phs[ch] = 0; } } if (amp[main_ch]) { // Allocate new tone DCALbrTone *t = &s->tones[s->ntones]; s->ntones = (s->ntones + 1) & (DCA_LBR_TONES - 1); t->x_freq = freq >> (5 - group); t->f_delt = (freq & ((1 << (5 - group)) - 1)) << group; t->ph_rot = 256 - (t->x_freq & 1) * 128 - t->f_delt * 4; shift = ff_dca_ph0_shift[(t->x_freq & 3) * 2 + (freq & 1)] - ((t->ph_rot << (5 - group)) - t->ph_rot); for (ch = 0; ch < s->nchannels; ch++) { t->amp[ch] = amp[ch] < AMP_MAX ? amp[ch] : 0; t->phs[ch] = 128 - phs[ch] * 32 + shift; } } } s->tonal_bounds[group][sf_idx][1] = s->ntones; } return 0; }