📄 atrac3.c
字号:
/* Get the VLC selector table for the subbands, 0 means not coded. */ for (cnt = 0; cnt <= numSubbands; cnt++) subband_vlc_index[cnt] = get_bits(gb, 3); /* Read the scale factor indexes from the stream. */ for (cnt = 0; cnt <= numSubbands; cnt++) { if (subband_vlc_index[cnt] != 0) SF_idxs[cnt] = get_bits(gb, 6); } for (cnt = 0; cnt <= numSubbands; cnt++) { first = subbandTab[cnt]; last = subbandTab[cnt+1]; subbWidth = last - first; if (subband_vlc_index[cnt] != 0) { /* Decode spectral coefficients for this subband. */ /* TODO: This can be done faster is several blocks share the * same VLC selector (subband_vlc_index) */ readQuantSpectralCoeffs (gb, subband_vlc_index[cnt], codingMode, mantissas, subbWidth); /* Decode the scale factor for this subband. */ SF = SFTable[SF_idxs[cnt]] * iMaxQuant[subband_vlc_index[cnt]]; /* Inverse quantize the coefficients. */ for (pIn=mantissas ; first<last; first++, pIn++) pOut[first] = *pIn * SF; } else { /* This subband was not coded, so zero the entire subband. */ memset(pOut+first, 0, subbWidth*sizeof(float)); } } /* Clear the subbands that were not coded. */ first = subbandTab[cnt]; memset(pOut+first, 0, (1024 - first) * sizeof(float)); return numSubbands;}/** * Restore the quantized tonal components * * @param gb the GetBit context * @param pComponent tone component * @param numBands amount of coded bands */static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent, int numBands){ int i,j,k,cnt; int components, coding_mode_selector, coding_mode, coded_values_per_component; int sfIndx, coded_values, max_coded_values, quant_step_index, coded_components; int band_flags[4], mantissa[8]; float *pCoef; float scalefactor; int component_count = 0; components = get_bits(gb,5); /* no tonal components */ if (components == 0) return 0; coding_mode_selector = get_bits(gb,2); if (coding_mode_selector == 2) return -1; coding_mode = coding_mode_selector & 1; for (i = 0; i < components; i++) { for (cnt = 0; cnt <= numBands; cnt++) band_flags[cnt] = get_bits1(gb); coded_values_per_component = get_bits(gb,3); quant_step_index = get_bits(gb,3); if (quant_step_index <= 1) return -1; if (coding_mode_selector == 3) coding_mode = get_bits1(gb); for (j = 0; j < (numBands + 1) * 4; j++) { if (band_flags[j >> 2] == 0) continue; coded_components = get_bits(gb,3); for (k=0; k<coded_components; k++) { sfIndx = get_bits(gb,6); pComponent[component_count].pos = j * 64 + (get_bits(gb,6)); max_coded_values = 1024 - pComponent[component_count].pos; coded_values = coded_values_per_component + 1; coded_values = FFMIN(max_coded_values,coded_values); scalefactor = SFTable[sfIndx] * iMaxQuant[quant_step_index]; readQuantSpectralCoeffs(gb, quant_step_index, coding_mode, mantissa, coded_values); pComponent[component_count].numCoefs = coded_values; /* inverse quant */ pCoef = pComponent[component_count].coef; for (cnt = 0; cnt < coded_values; cnt++) pCoef[cnt] = mantissa[cnt] * scalefactor; component_count++; } } } return component_count;}/** * Decode gain parameters for the coded bands * * @param gb the GetBit context * @param pGb the gainblock for the current band * @param numBands amount of coded bands */static int decodeGainControl (GetBitContext *gb, gain_block *pGb, int numBands){ int i, cf, numData; int *pLevel, *pLoc; gain_info *pGain = pGb->gBlock; for (i=0 ; i<=numBands; i++) { numData = get_bits(gb,3); pGain[i].num_gain_data = numData; pLevel = pGain[i].levcode; pLoc = pGain[i].loccode; for (cf = 0; cf < numData; cf++){ pLevel[cf]= get_bits(gb,4); pLoc [cf]= get_bits(gb,5); if(cf && pLoc[cf] <= pLoc[cf-1]) return -1; } } /* Clear the unused blocks. */ for (; i<4 ; i++) pGain[i].num_gain_data = 0; return 0;}/** * Apply gain parameters and perform the MDCT overlapping part * * @param pIn input float buffer * @param pPrev previous float buffer to perform overlap against * @param pOut output float buffer * @param pGain1 current band gain info * @param pGain2 next band gain info */static void gainCompensateAndOverlap (float *pIn, float *pPrev, float *pOut, gain_info *pGain1, gain_info *pGain2){ /* gain compensation function */ float gain1, gain2, gain_inc; int cnt, numdata, nsample, startLoc, endLoc; if (pGain2->num_gain_data == 0) gain1 = 1.0; else gain1 = gain_tab1[pGain2->levcode[0]]; if (pGain1->num_gain_data == 0) { for (cnt = 0; cnt < 256; cnt++) pOut[cnt] = pIn[cnt] * gain1 + pPrev[cnt]; } else { numdata = pGain1->num_gain_data; pGain1->loccode[numdata] = 32; pGain1->levcode[numdata] = 4; nsample = 0; // current sample = 0 for (cnt = 0; cnt < numdata; cnt++) { startLoc = pGain1->loccode[cnt] * 8; endLoc = startLoc + 8; gain2 = gain_tab1[pGain1->levcode[cnt]]; gain_inc = gain_tab2[(pGain1->levcode[cnt+1] - pGain1->levcode[cnt])+15]; /* interpolate */ for (; nsample < startLoc; nsample++) pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; /* interpolation is done over eight samples */ for (; nsample < endLoc; nsample++) { pOut[nsample] = (pIn[nsample] * gain1 + pPrev[nsample]) * gain2; gain2 *= gain_inc; } } for (; nsample < 256; nsample++) pOut[nsample] = (pIn[nsample] * gain1) + pPrev[nsample]; } /* Delay for the overlapping part. */ memcpy(pPrev, &pIn[256], 256*sizeof(float));}/** * Combine the tonal band spectrum and regular band spectrum * Return position of the last tonal coefficient * * @param pSpectrum output spectrum buffer * @param numComponents amount of tonal components * @param pComponent tonal components for this band */static int addTonalComponents (float *pSpectrum, int numComponents, tonal_component *pComponent){ int cnt, i, lastPos = -1; float *pIn, *pOut; for (cnt = 0; cnt < numComponents; cnt++){ lastPos = FFMAX(pComponent[cnt].pos + pComponent[cnt].numCoefs, lastPos); pIn = pComponent[cnt].coef; pOut = &(pSpectrum[pComponent[cnt].pos]); for (i=0 ; i<pComponent[cnt].numCoefs ; i++) pOut[i] += pIn[i]; } return lastPos;}#define INTERPOLATE(old,new,nsample) ((old) + (nsample)*0.125*((new)-(old)))static void reverseMatrixing(float *su1, float *su2, int *pPrevCode, int *pCurrCode){ int i, band, nsample, s1, s2; float c1, c2; float mc1_l, mc1_r, mc2_l, mc2_r; for (i=0,band = 0; band < 4*256; band+=256,i++) { s1 = pPrevCode[i]; s2 = pCurrCode[i]; nsample = 0; if (s1 != s2) { /* Selector value changed, interpolation needed. */ mc1_l = matrixCoeffs[s1*2]; mc1_r = matrixCoeffs[s1*2+1]; mc2_l = matrixCoeffs[s2*2]; mc2_r = matrixCoeffs[s2*2+1]; /* Interpolation is done over the first eight samples. */ for(; nsample < 8; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; c2 = c1 * INTERPOLATE(mc1_l,mc2_l,nsample) + c2 * INTERPOLATE(mc1_r,mc2_r,nsample); su1[band+nsample] = c2; su2[band+nsample] = c1 * 2.0 - c2; } } /* Apply the matrix without interpolation. */ switch (s2) { case 0: /* M/S decoding */ for (; nsample < 256; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; su1[band+nsample] = c2 * 2.0; su2[band+nsample] = (c1 - c2) * 2.0; } break; case 1: for (; nsample < 256; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; su1[band+nsample] = (c1 + c2) * 2.0; su2[band+nsample] = c2 * -2.0; } break; case 2: case 3: for (; nsample < 256; nsample++) { c1 = su1[band+nsample]; c2 = su2[band+nsample]; su1[band+nsample] = c1 + c2; su2[band+nsample] = c1 - c2; } break; default: assert(0); } }}static void getChannelWeights (int indx, int flag, float ch[2]){ if (indx == 7) { ch[0] = 1.0; ch[1] = 1.0; } else { ch[0] = (float)(indx & 7) / 7.0; ch[1] = sqrt(2 - ch[0]*ch[0]); if(flag) FFSWAP(float, ch[0], ch[1]); }}static void channelWeighting (float *su1, float *su2, int *p3){ int band, nsample; /* w[x][y] y=0 is left y=1 is right */ float w[2][2]; if (p3[1] != 7 || p3[3] != 7){ getChannelWeights(p3[1], p3[0], w[0]); getChannelWeights(p3[3], p3[2], w[1]); for(band = 1; band < 4; band++) { /* scale the channels by the weights */ for(nsample = 0; nsample < 8; nsample++) { su1[band*256+nsample] *= INTERPOLATE(w[0][0], w[0][1], nsample); su2[band*256+nsample] *= INTERPOLATE(w[1][0], w[1][1], nsample); } for(; nsample < 256; nsample++) { su1[band*256+nsample] *= w[1][0]; su2[band*256+nsample] *= w[1][1]; } } }}/** * Decode a Sound Unit * * @param gb the GetBit context * @param pSnd the channel unit to be used * @param pOut the decoded samples before IQMF in float representation * @param channelNum channel number * @param codingMode the coding mode (JOINT_STEREO or regular stereo/mono) */static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_unit *pSnd, float *pOut, int channelNum, int codingMode){ int band, result=0, numSubbands, lastTonal, numBands; if (codingMode == JOINT_STEREO && channelNum == 1) { if (get_bits(gb,2) != 3) { av_log(NULL,AV_LOG_ERROR,"JS mono Sound Unit id != 3.\n"); return -1; } } else { if (get_bits(gb,6) != 0x28) { av_log(NULL,AV_LOG_ERROR,"Sound Unit id != 0x28.\n"); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -