private bool DecodeHuffmanCode(int ch, int gr, int endpos) { int idx = 0; // Reading and decoding BigValue. int Region1Start, Region2Start; GranuleInfo f_granule = frame.granule[ch, gr]; if (f_granule.BlockType == 0) { Region1Start = ScfBandIndex[frame.FrequencyIndex]. LongBlock[f_granule.Region0Count + 1]; Region2Start = ScfBandIndex[frame.FrequencyIndex]. LongBlock[f_granule.Region0Count + f_granule.Region1Count + 2]; } else { Region1Start = 36; Region2Start = 576; } for (; idx <= 576 - 2 && idx < f_granule.BigValues * 2 ; idx += 2) { int tbl; // Region0 if (idx < Region1Start) { tbl = f_granule.GetTableSelect(0); } // Region1 else if (idx < Region2Start) { tbl = f_granule.GetTableSelect(1); } // Region2 else { tbl = f_granule.GetTableSelect(2); } LookupHuffman(ch, tbl, idx); } // Reading and decoding Count1 for ( ; (idx <= 576 - 4) && (bs.PositionBit < endpos); idx += 4) { LookupHuffmanQ(ch, f_granule.Count1TableSelect, idx); } for (; idx < 576; idx++) { _is[ch, idx] = 0; } return(true); }
public ToyMP3Frame() { // initialize CRC_check = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { granule[i, j] = new GranuleInfo(); } } }
private void Dequantize(int ch, int gr) { GranuleInfo _gr = frame.granule[ch, gr]; double Gain = 0.25 * (_gr.GlobalGain - 210.0); for (int i = 0; i < 576; i++) { if (SampleMap[ch, i].BlockType == BLOCK_SHORT) { Gain -= -2.0 * _gr.GetSubblockGain(SampleMap[ch, i].Subblock); } xr[ch, SampleMap[ch, i].OrderIndex] = _is[ch, i] * Math.Pow(Math.Abs(_is[ch, i]), 1.0 / 3.0) * Math.Pow(2.0, Gain - SampleMap[ch, i].Scale); } }
private void Antialias(int ch, int gr) { if (!AntialiasInitializedFlag) { InitAntialias(); AntialiasInitializedFlag = true; } GranuleInfo _gr = frame.granule[ch, gr]; if (_gr.IsShortBlock) { return; } int nl; if (_gr.IsLongBlock) { nl = 31; } else { nl = 1; } for (int k = 0; k < nl; k++) { for (int i = 0; i < 8; i++) { double a0 = xr[ch, (k * 18) + 18 + i]; double b0 = xr[ch, (k * 18) + 17 - i]; xr[ch, (k * 18) + 18 + i] = a0 * g_cs[i] + b0 * g_ca[i]; xr[ch, (k * 18) + 17 - i] = b0 * g_cs[i] - a0 * g_ca[i]; } } }
private void InverseMDCTSynthesys(int ch, int gr) { // Initialize if (!InversedMDCTInitializedFlag) { InitIMDCT(); InversedMDCTInitializedFlag = true; } GranuleInfo _gr = frame.granule[ch, gr]; int LongSubbandNum = 0; int WindowTypeLong = 0; if (_gr.IsLongBlock) { LongSubbandNum = 32; WindowTypeLong = _gr.BlockType; } else if (_gr.IsShortBlock) { LongSubbandNum = 0; WindowTypeLong = -1; } else if (_gr.IsMixedBlock) { LongSubbandNum = 2; WindowTypeLong = 0; } int _Subband = 0; int _Index = 0; // Long (and mixed) Block for (_Subband = 0; _Subband < LongSubbandNum; _Subband++) { double[] Rawout = new double[36]; for (int i = 0; i < 36; i++) { double _Sum = 0.0; for (int j = 0; j < 18; j++) { _Sum += xr[ch, j + _Subband * 18] * Math.Cos ( Math.PI / 72.0 * (2.0 * i + 19.0) * (2.0 * j + 1.0) ); } Rawout[i] = _Sum * SineWindow[WindowTypeLong, i]; } // Combine width last granule and saving; for (int ss = 0; ss < 18; ss++) { // First half of data + Second half of prev data. pfb[ch, _Index] = Rawout[ss] + ImdctPrevRawout[ch, _Index]; // Keep second half of data for next granule. ImdctPrevRawout[ch, _Index] = Rawout[ss + 18]; _Index++; } } // ShortBlock for (; _Subband < 32; _Subband++) { double[] Rawout = new double[36]; for (int _Subblock = 0; _Subblock < 3; _Subblock++) { double[] RawoutTmp = new double[12]; for (int i = 0; i < 12; i++) { double _Sum = 0; for (int j = 0; j < 6; j++) { _Sum += xr[ch, _Subband *18 + j * 3 + _Subblock] * Math.Cos(Math.PI / 24.0 * (2.0 * i + 7.0) * (2.0 * j + 1.0)); } RawoutTmp[i] = _Sum * SineWindow[2, i]; } for (int i = 0; i < 12; i++) { Rawout[6 * _Subblock + i + 6] += RawoutTmp[i]; } } for (int ss = 0; ss < 18; ss++) { pfb[ch, _Index] = Rawout[ss] + ImdctPrevRawout[ch, _Index]; ImdctPrevRawout[ch, _Index] = Rawout[ss + 18]; _Index++; } } }
private void CreateSampleMap(int ch, int gr) { int idx = 0; GranuleInfo _gr = frame.granule[ch, gr]; // Short Block if (_gr.IsShortBlock) { int[] ScfbIdx = ScfBandIndex[frame.FrequencyIndex].ShortBlock; for (int _sbi = 0; _sbi < 13; _sbi++) { int idx_s = idx; for (int _sub = 0; _sub < 3; _sub++) { int CriticalBandWidth = ScfbIdx[_sbi + 1] - ScfbIdx[_sbi]; for (int i = 0; i < CriticalBandWidth; i++) { SampleMap[ch, idx] = new Sample(); SampleMap[ch, idx].BlockType = BLOCK_SHORT; SampleMap[ch, idx].Subblock = _sub; SampleMap[ch, idx].Scale = 0.5 * (_gr.ScalefacScale + 1.0) * Scf[ch, gr].ShortBlock[_sub, _sbi]; SampleMap[ch, idx].OrderIndex = 3 * ((idx - idx_s) % CriticalBandWidth) + (idx - idx_s) / CriticalBandWidth + idx_s; idx++; } } } } // Long Block else if (_gr.IsLongBlock) { int[] ScfbIdx = ScfBandIndex[frame.FrequencyIndex].LongBlock; int Scfb = 0; for (int i = 0; i < 576; i++) { SampleMap[ch, idx] = new Sample(); SampleMap[ch, idx].BlockType = BLOCK_LONG; SampleMap[ch, idx].Subblock = 0; SampleMap[ch, idx].OrderIndex = idx; if (idx >= ScfbIdx[Scfb + 1]) { Scfb++; } int _Scf = Scf[ch, gr].LongBlock[Scfb]; if (_gr.PreFlag == 1) { _Scf += PreemphasisTable[Scfb]; } SampleMap[ch, idx].Scale = 0.5 * (_gr.ScalefacScale + 1.0) * _Scf; idx++; } } // MixedBlock else { // LongBlock sample int[] ScfbIdx = ScfBandIndex[frame.FrequencyIndex].LongBlock; int Scfb = 0; for (int i = 0; i < 36; i++) { SampleMap[ch, idx] = new Sample(); SampleMap[ch, idx].BlockType = BLOCK_LONG; SampleMap[ch, idx].Subblock = 0; SampleMap[ch, idx].OrderIndex = idx; if (idx >= ScfbIdx[Scfb + 1]) { Scfb++; } int _Scf = Scf[ch, gr].LongBlock[Scfb]; if (_gr.PreFlag == 1) { _Scf += PreemphasisTable[Scfb]; } SampleMap[ch, idx].Scale = 0.5 * (_gr.ScalefacScale + 1.0) * _Scf; idx++; } // Short Block Samples ScfbIdx = ScfBandIndex[frame.FrequencyIndex].ShortBlock; for (Scfb = 3; Scfb < 13; Scfb++) { int idx_s = idx; for (int _sub = 0; _sub < 3; _sub++) { int CriticalBandWidth = ScfbIdx[Scfb + 1] - ScfbIdx[Scfb]; for (int i = 0; i < CriticalBandWidth; i++) { SampleMap[ch, idx].BlockType = BLOCK_SHORT; SampleMap[ch, idx].Subblock = _sub; int _Scf = Scf[ch, gr].ShortBlock[_sub, Scfb]; SampleMap[ch, idx].Scale = 0.5 * (_gr.ScalefacScale + 1.0) * _Scf; SampleMap[ch, idx].OrderIndex = 3 * ((idx - idx_s) % CriticalBandWidth) + (idx - idx_s) / CriticalBandWidth + idx_s; idx++; } } } } }
private void DecodeScalefactor(GranuleInfo granule, int ch, int gr) { int Slen1 = granule.Slen[0]; int Slen2 = granule.Slen[1]; // Mixed Block if (granule.IsMixedBlock) { for (int sfb = 0; sfb < 8; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen1); } for (int sfb = 3; sfb < 6; sfb++) { for (int w = 0; w < 3; w++) { Scf[ch, gr].ShortBlock[w, sfb] = bs.GetByInt(Slen1); } } for (int sfb = 6; sfb < 12; sfb++) { for (int w = 0; w < 3; w++) { Scf[ch, gr].ShortBlock[w, sfb] = bs.GetByInt(Slen2); } } } // Short Block else if (granule.IsShortBlock) { for (int sfb = 0; sfb < 6; sfb++) { for (int w = 0; w < 3; w++) { Scf[ch, gr].ShortBlock[w, sfb] = bs.GetByInt(Slen1); } } for (int sfb = 6; sfb < 12; sfb++) { for (int w = 0; w < 3; w++) { Scf[ch, gr].ShortBlock[w, sfb] = bs.GetByInt(Slen2); } } } // Long Block else if (granule.IsLongBlock) { // In case granule0, // without exception, data should be taken from bitstream. if (gr == 0) { for (int sfb = 0; sfb < 11; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen1); } for (int sfb = 11; sfb < 21; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen2); } } else { // When processing granule1 and SCFSI is 1, // sdalefactor will shared with granule0. // Else, scalefactor should be got from bitstream. if (frame.GetScfsi(ch, 0) == 1) { for (int sfb = 0; sfb < 6; sfb++) { Scf[ch, gr].LongBlock[sfb] = Scf[ch, 0].LongBlock[sfb]; } } else { for (int sfb = 0; sfb < 6; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen1); } } if (frame.GetScfsi(ch, 1) == 1) { for (int sfb = 6; sfb < 11; sfb++) { Scf[ch, gr].LongBlock[sfb] = Scf[ch, 0].LongBlock[sfb]; } } else { for (int sfb = 6; sfb < 11; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen1); } } if (frame.GetScfsi(ch, 2) == 1) { for (int sfb = 11; sfb < 16; sfb++) { Scf[ch, gr].LongBlock[sfb] = Scf[ch, 0].LongBlock[sfb]; } } else { for (int sfb = 11; sfb < 16; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen2); } } if (frame.GetScfsi(ch, 3) == 1) { for (int sfb = 16; sfb < 21; sfb++) { Scf[ch, gr].LongBlock[sfb] = Scf[ch, 0].LongBlock[sfb]; } } else { for (int sfb = 16; sfb < 21; sfb++) { Scf[ch, gr].LongBlock[sfb] = bs.GetByInt(Slen2); } } } } }