📄 decoder.c
字号:
#include <windows.h>
#include "decoder.h"
#include "all.h"
#include "block.h"
#include "dolby_def.h"
#include "audio.h"
/* prediction */
static PRED_STATUS *sp_status[Chans];
void
do_init(void)
{
#if (CChans > 0)
init_cc();
#endif
huffbookinit();
predinit();
winmap[0] = win_seq_info[ONLY_LONG_WINDOW];
winmap[1] = win_seq_info[ONLY_LONG_WINDOW];
winmap[2] = win_seq_info[EIGHT_SHORT_WINDOW];
winmap[3] = win_seq_info[ONLY_LONG_WINDOW];
}
void
predinit(void)
{
int i, ch;
for (ch = 0; ch < Chans; ch++) {
for (i = 0; i < LN2; i++) {
init_pred_stat(&sp_status[ch][i],
PRED_ORDER,PRED_ALPHA,PRED_A,PRED_B);
}
}
}
void getfill(void)
{
int i, cnt;
if ((cnt = getbits(LEN_F_CNT)) == (1<<LEN_F_CNT)-1)
cnt += getbits(LEN_F_ESC) - 1;
for (i=0; i<cnt; i++)
getbits(LEN_BYTE);
}
Float *coef[Chans], *data[Chans], *state[Chans];
byte hasmask[Winds], *mask[Winds], *group[Chans],
wnd[Chans], max_sfb[Chans],
*cb_map[Chans];
Wnd_Shape wnd_shape[Chans];
short *factors[Chans];
int *lpflag[Chans], *prstflag[Chans];
TNS_frame_info *tns[Chans];
#if (CChans > 0)
Float *cc_coef[CChans], *cc_gain[CChans][Chans];
byte cc_wnd[CChans];
Wnd_Shape cc_wnd_shape[CChans];
#if (ICChans > 0)
Float *cc_state[ICChans];
#endif
#endif
int i, j, ch, wn, ele_id, d_tag, d_cnt;
int left, right;
Info *info;
MC_Info *mip = &mc_info;
Ch_Info *cip;
void extra_init(void)
{
int i, j;
for(i=0; i<Chans; i++){
// memset(state[i], 0, LN*sizeof(*state[i]));
for (j = 0; j < LN; j++)
state[i][j] = 0;
wnd_shape[i].prev_bk = 0;
}
#if (CChans > 0)
for(i=0; i<CChans; i++){
#if (ICChans > 0)
if (i < ICChans) {
// memset(cc_state[i], 0, LN*sizeof(*cc_state[i]));
for (j = 0; j < LN; j++)
cc_state[i][j] = 0;
cc_wnd_shape[i].prev_bk = 0;
}
#endif
}
#endif
for(i = 0; i < Chans; i++){
wnd_shape[i].prev_bk = 0;
wnd_shape[i].this_bk = 0;
}
}
void aac_decode_init(void)
{
for(i=0; i<Chans; i++){
coef[i] = (Float *)LocalAlloc(LPTR, LN2*sizeof(*coef[0]));
data[i] = (Float *)LocalAlloc(LPTR, LN2*sizeof(*data[0]));
state[i] = (Float *)LocalAlloc(LPTR, LN*sizeof(*state[0]));
factors[i] = (short *)LocalAlloc(LPTR, MAXBANDS*sizeof(*factors[0]));
cb_map[i] = (byte *)LocalAlloc(LPTR, MAXBANDS*sizeof(*cb_map[0]));
group[i] = (byte *)LocalAlloc(LPTR, NSHORT*sizeof(group[0]));
lpflag[i] = (int *)LocalAlloc(LPTR, MAXBANDS*sizeof(*lpflag[0]));
prstflag[i] = (int *)LocalAlloc(LPTR, (LEN_PRED_RSTGRP+1)*sizeof(*prstflag[0]));
tns[i] = (TNS_frame_info *)LocalAlloc(LPTR, sizeof(*tns[0]));
sp_status[i] = (PRED_STATUS *)LocalAlloc(LPTR, LN*sizeof(*sp_status[0]));
}
for(i=0; i<Winds; i++) {
mask[i] = (byte *)LocalAlloc(LPTR, MAXBANDS*sizeof(mask[0]));
}
#if (CChans > 0)
for(i=0; i<CChans; i++){
cc_coef[i] = (Float *)LocalAlloc(LPTR, LN2*sizeof(*cc_coef[0]));
for(j=0; j<Chans; j++)
cc_gain[i][j] = (Float *)LocalAlloc(LPTR, MAXBANDS*sizeof(*cc_gain[0][0]));
#if (ICChans > 0)
if (i < ICChans) {
cc_state[i] = (Float *)LocalAlloc(LPTR, LN*sizeof(*state[0])); /* changed LN4 to LN 1/97 mfd */
}
#endif
}
#endif
}
void aac_decode_free(void)
{
for(i=0; i<Chans; i++){
if (coef[i]) LocalFree(coef[i]);
if (data[i]) LocalFree(data[i]);
if (state[i]) LocalFree(state[i]);
if (factors[i]) LocalFree(factors[i]);
if (cb_map[i]) LocalFree(cb_map[i]);
if (group[i]) LocalFree(group[i]);
if (lpflag[i]) LocalFree(lpflag[i]);
if (prstflag[i]) LocalFree(prstflag[i]);
if (tns[i]) LocalFree(tns[i]);
if (sp_status[i]) LocalFree(sp_status[i]);
}
for(i=0; i<Winds; i++) {
if (mask[i]) LocalFree(mask[i]);
}
#if (CChans > 0)
for(i=0; i<CChans; i++){
if (cc_coef[i]) LocalFree(cc_coef[i]);
for(j=0; j<Chans; j++)
if (cc_gain[i][j]) LocalFree(cc_gain[i][j]);
#if (ICChans > 0)
if (i < ICChans) {
if (cc_state[i]) LocalFree(cc_state[i]);
}
#endif
}
#endif
}
int aac_decode_frame(void)
{
framebits = 0;
byte_align();
reset_mc_info(mip);
while ((ele_id=getbits(LEN_SE_ID)) != ID_END) {
/* get audio syntactic element */
switch (ele_id) {
case ID_SCE: /* single channel */
case ID_CPE: /* channel pair */
case ID_LFE: /* low freq effects channel */
if (huffdecode(ele_id, mip, wnd, wnd_shape,
cb_map, factors,
group, hasmask, mask, max_sfb,
lpflag, prstflag
, tns, coef) < 0)
return 0;
//CommonExit(1,"2022: Error in huffman decoder");
break;
#if (CChans > 0)
case ID_CCE: /* coupling channel */
if (getcc(mip, cc_wnd, cc_wnd_shape, cc_coef, cc_gain) < 0)
return 0;
// CommonExit(1,"2023: Error in coupling channel");
break;
#endif
case ID_PCE: /* program config element */
get_prog_config(&prog_config);
break;
case ID_FIL: /* fill element */
getfill();
break;
default:
// CommonWarning("Element not supported");
return 0;
}
}
check_mc_info(mip, (bno==0 && default_config));
#if (ICChans > 0)
/* transform independently switched coupling channels */
ind_coupling(mip, wnd, wnd_shape, cc_wnd, cc_wnd_shape, cc_coef,
cc_state);
#endif
/* m/s stereo */
for (ch=0; ch<Chans; ch++) {
cip = &mip->ch_info[ch];
if ((cip->present) && (cip->cpe) && (cip->ch_is_left)) {
wn = cip->widx;
if(hasmask[wn]) {
left = ch;
right = cip->paired_ch;
info = winmap[wnd[wn]];
if (hasmask[wn] == 1)
map_mask(info, group[wn], mask[wn], cb_map[right]);
synt(info, group[wn], mask[wn], coef[right], coef[left]);
}
}
}
/* intensity stereo and prediction */
for (ch=0; ch<Chans; ch++) {
if (!(mip->ch_info[ch].present)) continue;
wn = mip->ch_info[ch].widx;
info = winmap[wnd[wn]];
if (adif_header_present)
intensity(mip, info, wn, ch,
group[wn], cb_map[ch], factors[ch],
lpflag[wn], coef);
predict(info, mip->profile,
lpflag[wn], sp_status[ch], coef[ch]);
}
for (ch=0; ch<Chans; ch++) {
if (!(mip->ch_info[ch].present)) continue;
wn = mip->ch_info[ch].widx;
info = winmap[wnd[wn]];
/* predictor reset */
left = ch;
right = left;
if ( (mip->ch_info[ch].cpe) &&
(mip->ch_info[ch].common_window) )
/* prstflag's shared by channel pair */
right = mip->ch_info[ch].paired_ch;
predict_reset(info, prstflag[wn], sp_status, left, right);
#if (CChans > 0)
/* if cc_domain indicates before TNS */
coupling(info, mip, coef, cc_coef, cc_gain, ch, CC_DOM, !CC_IND);
#endif
/* tns */
for (i=j=0; i<tns[ch]->n_subblocks; i++) {
tns_decode_subblock(&coef[ch][j],
max_sfb[wn],
info->sbk_sfb_top[i],
info->islong,
&(tns[ch]->info[i]) );
j += info->bins_per_sbk[i];
}
#if (CChans > 0)
/* if cc_domain indicated after TNS */
coupling(info, mip, coef, cc_coef, cc_gain, ch, CC_DOM, !CC_IND);
#endif
/* inverse transform */
freq2time_adapt (wnd [wn], &wnd_shape [wn], coef [ch], state [ch], data [ch]);
#if (CChans > 0)
/* independently switched coupling */
coupling(info, mip, coef, cc_coef, cc_gain, ch, CC_DOM, CC_IND);
#endif
}
writeout(data, mip);
return framebits;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -