示例#1
0
        public byte[] WriteToBitStream(int bitsPerFrame, ref FrameParams fr_ps, int[][][] l3_enc, ref SideInfo l3_side, int[][][] scalefact_l, int[][][][] scalefact_s, double[][][] xr, byte[] ancillary, int ancillary_bits)
        {
            OutputBit = 8;
            int mode_gr = 2;


            for (int gr = 0; gr < mode_gr; gr++)
            {
                for (int ch = 0; ch < fr_ps.Chn; ch++)
                {
                    for (int i = 0; i < 576; i++)
                    {
                        if ((xr[ch][gr][i] < 0) && (l3_enc[ch][gr][i] > 0))
                        {
                            l3_enc[ch][gr][i] *= -1;
                        }
                    }
                }
            }

            EncodeSideInfo(ref l3_side, ref fr_ps);
            EncodeMainData(l3_enc, ref l3_side, ref fr_ps, scalefact_l, scalefact_s);
            WriteAncillaryData(ancillary, ancillary_bits);

            if (l3_side.ResvDrain != 0)
            {
                DrainIntoAncillaryData(l3_side.ResvDrain);
            }
            SFrameData    = new FrameData(bitsPerFrame, mode_gr, fr_ps.Chn, headerPH, frameSIPH, channelSIPH, spectrumSIPH, scaleFactorsPH, codedDataPH, userSpectrumPH, userFrameDataPH);
            sFrameResults = new FrameResults();
            WriteFrame(ref SFrameData, ref sFrameResults);

            l3_side.MainDataBegin = sFrameResults.NextBackPtr;
            return(EncodedOutput);
        }
示例#2
0
        public void ResvFrameBegin(ref FrameParams fr_ps, ref SideInfo l3_side, int mean_bits, int frameLength)
        {
            Layer info;
            int   fullFrameBits, mode_gr;
            int   expectedResvSize, resvLimit;

            info             = fr_ps.Header;
            mode_gr          = 2;
            resvLimit        = 4088;
            expectedResvSize = l3_side.MainDataBegin * 8;

            fullFrameBits = mean_bits * mode_gr;

            if (frameLength > 7680)
            {
                ResvMax = 0;
            }
            else
            {
                ResvMax = 7680 - frameLength;
            }

            if (ResvMax > resvLimit)
            {
                ResvMax = resvLimit;
            }
        }
示例#3
0
        public int ResvMaxBits(ref FrameParams fr_ps, ref SideInfo l3_side, ref double pe, int mean_bits)
        {
            int more_bits, max_bits, add_bits, over_bits;

            mean_bits /= fr_ps.Chn;
            max_bits   = mean_bits;

            if (max_bits > 4095)
            {
                max_bits = 4095;
            }

            if (ResvMax == 0)
            {
                return(max_bits);
            }

            more_bits = (int)(pe * 3.1 - mean_bits);
            add_bits  = 0;
            if (more_bits > 100)
            {
                int frac = (ResvSize * 6) / 10;

                if (frac < more_bits)
                {
                    add_bits = frac;
                }
                else
                {
                    add_bits = more_bits;
                }
            }
            over_bits = ResvSize - ((ResvMax * 8) / 10) - add_bits;
            if (over_bits > 0)
            {
                add_bits += over_bits;
            }

            max_bits += add_bits;
            if (max_bits > 4095)
            {
                max_bits = 4095;
            }
            return(max_bits);
        }
示例#4
0
        public void ResvFrameEnd(ref FrameParams fr_ps, ref SideInfo l3_side, int mean_bits)
        {
            int mode_gr, gr, ch, chn, ancillary_pad, stuffingBits;
            int over_bits;

            chn           = fr_ps.Chn;
            mode_gr       = 2;
            ancillary_pad = 0;

            if ((chn == 2) && ((mean_bits & 1) != 0))
            {
                ResvSize += 1;
            }
            over_bits = ResvSize - ResvMax;
            if (over_bits < 0)
            {
                over_bits = 0;
            }
            ResvSize    -= over_bits;
            stuffingBits = over_bits + ancillary_pad;

            if ((over_bits = ResvSize % 8) != 0)
            {
                stuffingBits += over_bits;
                ResvSize     -= over_bits;
            }

            if (stuffingBits != 0)
            {
                if (l3_side.TT[0, 0].Part23Length + stuffingBits < 4095)
                {
                    l3_side.TT[0, 0].Part23Length += stuffingBits;
                }
                else
                {
                    for (gr = 0; gr < mode_gr; gr++)
                    {
                        for (ch = 0; ch < chn; ch++)
                        {
                            int extraBits, bitsThisGr;

                            if (stuffingBits == 0)
                            {
                                break;
                            }
                            extraBits = 4095 - l3_side.TT[ch, gr].Part23Length;
                            if (extraBits < stuffingBits)
                            {
                                bitsThisGr = extraBits;
                            }
                            else
                            {
                                bitsThisGr = stuffingBits;
                            }
                            l3_side.TT[0, 0].Part23Length += bitsThisGr;
                            stuffingBits -= bitsThisGr;
                        }
                    }

                    l3_side.ResvDrain = stuffingBits;
                }
            }
        }
示例#5
0
 public void ResvAdjust(ref FrameParams fr_ps, ref GrInfo gi, ref SideInfo l3_side, int mean_bits)
 {
     ResvSize += (mean_bits / fr_ps.Chn) - gi.Part23Length;
 }
示例#6
0
        static private int Part2Length(int[][][] scalefact_l, int[][][][] scalefact_s, ref FrameParams fr_ps, int gr, int ch, ref SideInfo si)
        {
            int slen1, slen2, bits;

            bits = 0;

            slen1 = Tables.Slen1Tab[si.TT[ch, gr].ScalefacCompress];
            slen2 = Tables.Slen2Tab[si.TT[ch, gr].ScalefacCompress];

            if ((si.TT[ch, gr].WindowSwitchingFlag == 1) && (si.TT[ch, gr].BlockType == 2))
            {
                if (si.TT[ch, gr].MixedBlockFlag != 0)
                {
                    bits += (8 * slen1) + (9 * slen1) + (18 * slen2);
                }
                else
                {
                    bits += (18 * slen1) + (18 * slen2);
                }
            }
            else
            {
                if ((gr == 0) || (si.Scfsi[ch, 0] == 0))
                {
                    bits += (6 * slen1);
                }
                if ((gr == 0) || (si.Scfsi[ch, 1] == 0))
                {
                    bits += (5 * slen1);
                }
                if ((gr == 0) || (si.Scfsi[ch, 2] == 0))
                {
                    bits += (5 * slen2);
                }
                if ((gr == 0) || (si.Scfsi[ch, 3] == 0))
                {
                    bits += (5 * slen2);
                }
            }
            return(bits);
        }
示例#7
0
        private int OuterLoop(double[] abs_xr, int max_bits, double[,,] xmin_l, double[,,,] xmin_s, int[] abs_ix, ref FrameParams fr_ps, int[][][] scalefact_l, int[][][][] scalefact_s, int gr, int ch, ref SideInfo l3_side)
        {
            double[,] xfsf = new double[4, 21];
            int[] scalesave_l = new int[21];
            int[,] scalesave_s = new int[12, 3];
            int bits, huff_bits, save_preflag, save_compress;
            int sfb, b, over, iteration = 0;

            do
            {
                iteration++;

                l3_side.TT[ch, gr].Part2Length = Part2Length(scalefact_l, scalefact_s, ref fr_ps, gr, ch, ref l3_side);

                huff_bits = max_bits - l3_side.TT[ch, gr].Part2Length;

                if (iteration == 1)
                {
                    BinSearchStepSize(max_bits, l3_side.TT[ch, gr].QuantizerStepSize, abs_ix, abs_xr, ref l3_side.TT[ch, gr]);  /* speeds things up a bit */
                }

                bits = InnerLoop(abs_xr, abs_ix, huff_bits, ref l3_side.TT[ch, gr]);
                CalcNoise(abs_xr, abs_ix, ref l3_side.TT[ch, gr], xfsf);

                for (sfb = 0; sfb < 21; sfb++)
                {
                    scalesave_l[sfb] = scalefact_l[ch][gr][sfb];
                }

                for (sfb = 0; sfb < 12; sfb++)
                {
                    for (b = 0; b < 3; b++)
                    {
                        scalesave_s[sfb, b] = scalefact_s[ch][gr][sfb][b];
                    }
                }
                save_preflag  = l3_side.TT[ch, gr].Preflag;
                save_compress = l3_side.TT[ch, gr].ScalefacCompress;

                Preemphasis(abs_xr, xfsf, xmin_l, xmin_s, gr, ch, ref l3_side);

                over = AmpScalefacBands(abs_xr, xfsf, xmin_l, xmin_s, ref l3_side, scalefact_l, scalefact_s, gr, ch, iteration);

                if (LoopBreak(scalefact_l, scalefact_s, ref l3_side.TT[ch, gr], gr, ch))
                {
                    break;
                }
                if (ScaleBitcount(scalefact_l, scalefact_s, ref l3_side.TT[ch, gr], gr, ch) != 0)
                {
                    break;
                }
            }while (over > 0);

            l3_side.TT[ch, gr].Preflag          = save_preflag;
            l3_side.TT[ch, gr].ScalefacCompress = save_compress;

            for (sfb = 0; sfb < 21; sfb++)
            {
                scalefact_l[ch][gr][sfb] = scalesave_l[sfb];
            }

            for (sfb = 0; sfb < 12; sfb++)
            {
                for (b = 0; b < 3; b++)
                {
                    scalefact_s[ch][gr][sfb][b] = scalesave_s[sfb, b];
                }
            }

            l3_side.TT[ch, gr].Part2Length  = Part2Length(scalefact_l, scalefact_s, ref fr_ps, gr, ch, ref l3_side);
            l3_side.TT[ch, gr].Part23Length = l3_side.TT[ch, gr].Part2Length + bits;

            return(l3_side.TT[ch, gr].Part23Length);
        }
示例#8
0
        public void Loop(double[,] pe, double[][][] xr_org, double[,,,] ratio_s, double[,,] ratio_l, ref SideInfo l3_side, int[][][] l3_enc, int mean_bits, int chn, double[][][] xr_dec, int[][][] scalefact_l, int[][][][] scalefact_s, ref FrameParams fr_ps, int ancillary_pad, int bitsPerFrame)
        {
            int    max_bits;
            int    ch, gr, i, sfb, b, scfsi_band;
            int    mode_gr;
            int    start, end;
            double sum1, sum2, temp, x;
            double log2;


            double[,,] xmin_l  = new double[2, 2, 21];
            double[,,,] xmin_s = new double[2, 2, 12, 3];
            double[] abs_xr   = new double[576];
            double[] energy_l = new double[22];
            double[,] en_tot = new double[2, 2];
            double[,,] en    = new double[2, 2, 21];
            double[,,] xm    = new double[2, 2, 21];
            int[,] xrAllZero = new int[2, 2];



            int en_tot_krit        = 10;
            int en_dif_krit        = 100;
            int en_scfsi_band_krit = 10;
            int xm_scfsi_band_krit = 10;



            log2 = Math.Log(2.0);
            l3_side.ResvDrain = 0;

            if (fInit_iteration_loop == 0)
            {
                l3_side.MainDataBegin = 0;
                fInit_iteration_loop  = 1;
            }
            mode_gr = 2;

            scalefac_band_long  = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][0];
            scalefac_band_short = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][1];

            reserv.ResvFrameBegin(ref fr_ps, ref l3_side, mean_bits, bitsPerFrame);

            for (gr = 0; gr < mode_gr; gr++)
            {
                for (ch = 0; ch < chn; ch++)
                {
                    for (i = 0; i < 576; i++)
                    {
                        abs_xr[i] = Math.Abs(xr_org[ch][gr][i]);
                    }

                    if (l3_side.TT[ch, gr].WindowSwitchingFlag != 0 && l3_side.TT[ch, gr].BlockType == 2)
                    {
                        if (l3_side.TT[ch, gr].MixedBlockFlag != 0)
                        {
                            l3_side.TT[ch, gr].SfbLmax = 8;
                            l3_side.TT[ch, gr].SfbSmax = 3;
                        }
                        else
                        {
                            l3_side.TT[ch, gr].SfbLmax = 0;
                            l3_side.TT[ch, gr].SfbSmax = 0;
                        }
                    }
                    else
                    {
                        l3_side.TT[ch, gr].SfbLmax = 21;
                        l3_side.TT[ch, gr].SfbSmax = 12;
                    }

                    sum1 = 0;
                    sum2 = 0;
                    for (sfb = 0; sfb < 22; sfb++)
                    {
                        start = scalefac_band_long[sfb];
                        end   = scalefac_band_long[sfb + 1];
                        temp  = 0;
                        for (i = start; i < end; i++)
                        {
                            if ((x = abs_xr[i]) != 0)
                            {
                                temp += x * x;
                                sum1 += Math.Log(x);
                            }
                        }

                        sum2 += energy_l[sfb] = temp;

                        if (sfb < l3_side.TT[ch, gr].SfbLmax)
                        {
                            xmin_l[ch, gr, sfb] = ratio_l[ch, gr, sfb] * temp / (end - start);
                        }
                    }

                    for (sfb = l3_side.TT[ch, gr].SfbSmax; sfb < 12; sfb++)
                    {
                        start = scalefac_band_short[sfb];
                        end   = scalefac_band_short[sfb + 1];
                        for (b = 0; b < 3; b++)
                        {
                            temp = 0.0;
                            for (i = start; i < end; i++)
                            {
                                temp += abs_xr[i * 3 + b] * abs_xr[i * 3 + b];
                            }
                            xmin_s[ch, gr, sfb, b] = ratio_s[ch, gr, sfb, b] * temp / (end - start);
                        }
                    }

                    xrAllZero[ch, gr] = 1;

                    if (l3_side.TT[ch, gr].WindowSwitchingFlag == 0 || (l3_side.TT[ch, gr].BlockType != 2))
                    {
                        for (sfb = 0; sfb < 21; sfb++)
                        {
                            if (xmin_l[ch, gr, sfb] == 0)
                            {
                                xm[ch, gr, sfb] = 0;
                            }
                            else
                            {
                                xm[ch, gr, sfb] = Math.Log(xmin_l[ch, gr, sfb]) / log2;
                            }
                        }

                        if (gr == 1)
                        {
                            for (scfsi_band = 0; scfsi_band < 4; scfsi_band++)
                            {
                                l3_side.Scfsi[ch, scfsi_band] = 0;
                            }

                            if (xrAllZero[ch, 0] == 0 || xrAllZero[ch, 1] == 0)
                            {
                                if (Math.Abs(en_tot[ch, 0] - en_tot[ch, 1]) < en_tot_krit)
                                {
                                    temp = 0.0;
                                    for (sfb = 0; sfb < 21; sfb++)
                                    {
                                        temp += Math.Abs(en[ch, 0, sfb] - en[ch, 1, sfb]);
                                    }
                                    if (temp < en_dif_krit)
                                    {
                                        for (scfsi_band = 0; scfsi_band < 4; scfsi_band++)
                                        {
                                            sum1 = 0;
                                            sum2 = 0;

                                            start = scfsi_band_long[scfsi_band];
                                            end   = scfsi_band_long[scfsi_band + 1];
                                            for (sfb = start; sfb < end; sfb++)
                                            {
                                                sum1 += Math.Abs(en[ch, 0, sfb] - en[ch, 1, sfb]);
                                                sum2 += Math.Abs(xm[ch, 0, sfb] - xm[ch, 1, sfb]);
                                            }

                                            if (sum1 < en_scfsi_band_krit && sum2 < xm_scfsi_band_krit)
                                            {
                                                l3_side.Scfsi[ch, scfsi_band] = 1;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    max_bits = reserv.ResvMaxBits(ref fr_ps, ref l3_side, ref pe[ch, gr], mean_bits);

                    for (sfb = 0; sfb < 21; sfb++)
                    {
                        scalefact_l[ch][gr][sfb] = 0;
                    }
                    for (sfb = 0; sfb < 12; sfb++)
                    {
                        for (b = 0; b < 3; b++)
                        {
                            scalefact_s[ch][gr][sfb][b] = 0;
                        }
                    }

                    for (scfsi_band = 0; scfsi_band < 4; scfsi_band++)
                    {
                        l3_side.TT[ch, gr].Slen[scfsi_band] = 0;
                    }

                    l3_side.TT[ch, gr].SfbPartitionTable = nr_of_sfb_block;
                    l3_side.TT[ch, gr].Part23Length      = 0;
                    l3_side.TT[ch, gr].BigValues         = 0;
                    l3_side.TT[ch, gr].Count1            = 0;
                    l3_side.TT[ch, gr].ScalefacCompress  = 0;
                    l3_side.TT[ch, gr].TableSelect[0]    = 0;
                    l3_side.TT[ch, gr].TableSelect[1]    = 0;
                    l3_side.TT[ch, gr].TableSelect[2]    = 0;
                    l3_side.TT[ch, gr].SubblockGain[0]   = 0;
                    l3_side.TT[ch, gr].SubblockGain[1]   = 0;
                    l3_side.TT[ch, gr].SubblockGain[2]   = 0;
                    l3_side.TT[ch, gr].Region0Count      = 0;
                    l3_side.TT[ch, gr].Region1Count      = 0;
                    l3_side.TT[ch, gr].Part2Length       = 0;
                    l3_side.TT[ch, gr].Preflag           = 0;
                    l3_side.TT[ch, gr].ScalefacScale     = 0;
                    l3_side.TT[ch, gr].QuantizerStepSize = 0;
                    l3_side.TT[ch, gr].Count1tableSelect = 0;

                    int system_const = 8;
                    int minlimit     = -100;

                    if (sum2 != 0)
                    {
                        temp = Nint(system_const * (sum1 / 288 - Math.Log(sum2 / 576)));
                        if (temp < minlimit)
                        {
                            temp = minlimit;
                        }

                        temp -= 70;
                        l3_side.TT[ch, gr].QuantizerStepSize = temp;
                        l3_side.TT[ch, gr].Part23Length      = OuterLoop(abs_xr, max_bits, xmin_l, xmin_s, l3_enc[ch][gr], ref fr_ps, scalefact_l, scalefact_s, gr, ch, ref l3_side);
                    }

                    reserv.ResvAdjust(ref fr_ps, ref l3_side.TT[ch, gr], ref l3_side, mean_bits);

                    l3_side.TT[ch, gr].GlobalGain = Nint(l3_side.TT[ch, gr].QuantizerStepSize + 210.0);
                }
            }
            reserv.ResvFrameEnd(ref fr_ps, ref l3_side, mean_bits);
        }
示例#9
0
        private void EncodeSideInfo(ref SideInfo l3_side, ref FrameParams fr_ps)
        {
            int bits_sent, mode_gr = 2;

            headerPH.Position = 0;

            headerPH.Add(4095, 12);
            headerPH.Add(1, 1);
            headerPH.Add(1, 2);
            headerPH.Add(fr_ps.Header.ErrorProtection, 1);
            headerPH.Add(fr_ps.Header.BitrateIndex, 4);
            headerPH.Add(fr_ps.Header.SamplingFrequency, 2);
            headerPH.Add(fr_ps.Header.Padding, 1);
            headerPH.Add(fr_ps.Header.Extension, 1);
            headerPH.Add(fr_ps.Header.Mode, 2);
            headerPH.Add(fr_ps.Header.ModeExt, 2);
            headerPH.Add(fr_ps.Header.Copyright, 1);
            headerPH.Add(fr_ps.Header.Original, 1);
            headerPH.Add(fr_ps.Header.Emphasis, 2);

            bits_sent = 32;

            frameSIPH.Position = 0;

            for (int ch = 0; ch < fr_ps.Chn; ch++)
            {
                channelSIPH[ch].Position = 0;
            }

            for (int gr = 0; gr < 2; gr++)
            {
                for (int ch = 0; ch < fr_ps.Chn; ch++)
                {
                    spectrumSIPH[ch, gr].Position = 0;
                }
            }

            if (fr_ps.Header.ErrorProtection == 0)
            {
                headerPH.Add(0, 16);
                bits_sent += 16;
            }

            frameSIPH.Add(l3_side.MainDataBegin, 9);

            if (fr_ps.Chn == 2)
            {
                frameSIPH.Add(l3_side.PrivateBits, 3);
            }
            else
            {
                frameSIPH.Add(l3_side.PrivateBits, 5);
            }

            for (int ch = 0; ch < fr_ps.Chn; ch++)
            {
                for (int scfsi_band = 0; scfsi_band < 4; scfsi_band++)
                {
                    channelSIPH[ch].Add(l3_side.Scfsi[ch, scfsi_band], 1);
                }
            }
            for (int gr = 0; gr < mode_gr; gr++)
            {
                for (int ch = 0; ch < fr_ps.Chn; ch++)
                {
                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].Part23Length, 12);

                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].BigValues, 9);
                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].GlobalGain, 8);
                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].ScalefacCompress, 4);
                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].WindowSwitchingFlag, 1);

                    if (l3_side.TT[ch, gr].WindowSwitchingFlag != 0)
                    {
                        spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].BlockType, 2);
                        spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].MixedBlockFlag, 1);

                        for (int region = 0; region < 2; region++)
                        {
                            spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].TableSelect[region], 5);
                        }
                        for (int window = 0; window < 3; window++)
                        {
                            spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].SubblockGain[window], 3);
                        }
                    }
                    else
                    {
                        for (int region = 0; region < 3; region++)
                        {
                            spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].TableSelect[region], 5);
                        }

                        spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].Region0Count, 4);
                        spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].Region1Count, 3);
                    }

                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].Preflag, 1);
                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].ScalefacScale, 1);
                    spectrumSIPH[ch, gr].Add(l3_side.TT[ch, gr].Count1tableSelect, 1);
                }
            }


            if (fr_ps.Chn == 2)
            {
                bits_sent += 256;
            }
            else
            {
                bits_sent += 136;
            }
        }
示例#10
0
        private void HuffmanCodeBits(int ch, int gr, int[] ix, ref GrInfo gi, ref FrameParams fr_ps)
        {
            int         region1Start;
            int         region2Start;
            int         bigvalues, count1End;
            int         v, w, x, y, bits, stuffingBits;
            HuffCodeTab ht;

            int bvbits, c1bits, cbits = 0, xbits = 0, code = 0, ext = 0, tablezeros = 0, r0 = 0, r1 = 0, r2 = 0, rt, pr;
            int bitsWritten = 0;



            bigvalues = gi.BigValues * 2;
            if (bigvalues != 0)
            {
                if (gi.MixedBlockFlag == 0 && gi.WindowSwitchingFlag != 0 && gi.BlockType == 2)
                {
                    int sfb, window, line, start, end;

                    region1Start = 12;
                    region2Start = 576;

                    for (sfb = 0; sfb < 13; sfb++)
                    {
                        int tableindex = 100;
                        start = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][1][sfb]; //scalefac[sfb];
                        end   = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][1][sfb + 1];

                        if (start < region1Start)
                        {
                            tableindex = gi.TableSelect[0];
                        }
                        else
                        {
                            tableindex = gi.TableSelect[1];
                        }

                        for (window = 0; window < 3; window++)
                        {
                            for (line = start; line < end; line += 2)
                            {
                                x    = ix[line * 3 + window];
                                y    = ix[(line + 1) * 3 + window];
                                bits = HuffmanCode(tableindex, x, y, ref code, ref ext, ref cbits, ref xbits);
                                codedDataPH[ch, gr].Add(code, cbits);
                                codedDataPH[ch, gr].Add(ext, xbits);
                                bitsWritten += bits;
                            }
                        }
                    }
                }
                else if (gi.MixedBlockFlag != 0 && gi.BlockType == 2)
                {
                    int sfb, window, line, start, end, tableindex;

                    tableindex = gi.TableSelect[0];
                    if (tableindex != 0)
                    {
                        for (int i = 0; i < 36; i += 2)
                        {
                            x = ix[i];
                            y = ix[i + 1];

                            bits = HuffmanCode(tableindex, x, y, ref code, ref ext, ref cbits, ref xbits);

                            codedDataPH[ch, gr].Add(code, cbits);
                            codedDataPH[ch, gr].Add(ext, xbits);
                            bitsWritten += bits;
                        }
                    }
                    tableindex = gi.TableSelect[1];


                    for (sfb = 3; sfb < 13; sfb++)
                    {
                        start = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][1][sfb];
                        end   = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][1][sfb + 1];

                        for (window = 0; window < 3; window++)
                        {
                            for (line = start; line < end; line += 2)
                            {
                                x = ix[line * 3 + window];
                                y = ix[(line + 1) * 3 + window];

                                bits = HuffmanCode(tableindex, x, y, ref code, ref ext, ref cbits, ref xbits);

                                codedDataPH[ch, gr].Add(code, cbits);
                                codedDataPH[ch, gr].Add(ext, xbits);
                                bitsWritten += bits;
                            }
                        }
                    }
                }
                else
                {
                    int scalefac_index = 100;

                    if (gi.MixedBlockFlag != 0)
                    {
                        region1Start = 36;
                        region2Start = 576;
                    }
                    else
                    {
                        scalefac_index  = gi.Region0Count + 1;
                        region1Start    = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][0][scalefac_index];
                        scalefac_index += gi.Region1Count + 1;
                        region2Start    = Tables.SfBandIndex[fr_ps.Header.SamplingFrequency][0][scalefac_index];
                    }
                    for (int i = 0; i < bigvalues; i += 2)
                    {
                        int tableindex = 100;

                        if (i < region1Start)
                        {
                            tableindex = gi.TableSelect[0];
                            pr         = 0;
                        }
                        else if (i < region2Start)
                        {
                            tableindex = gi.TableSelect[1];
                            pr         = 1;
                        }
                        else
                        {
                            tableindex = gi.TableSelect[2];
                            pr         = 2;
                        }

                        ht = huf.HT[tableindex];
                        x  = ix[i];
                        y  = ix[i + 1];

                        if (tableindex != 0)
                        {
                            bits = HuffmanCode(tableindex, x, y, ref code, ref ext, ref cbits, ref xbits);

                            codedDataPH[ch, gr].Add(code, cbits);
                            codedDataPH[ch, gr].Add(ext, xbits);
                            rt           = bits;
                            bitsWritten += rt;

                            switch (pr)
                            {
                            case 0:
                                r0 += rt;
                                break;

                            case 1:
                                r1 += rt;
                                break;

                            case 2:
                                r2 += rt;
                                break;
                            }
                        }
                        else
                        {
                            tablezeros += 1;
                            switch (pr)
                            {
                            case 0:
                                r0 = 0;
                                break;

                            case 1:
                                r1 = 0;
                                break;

                            case 2:
                                r2 = 0;
                                break;
                            }
                        }
                    }
                }
            }
            bvbits = bitsWritten;


            ht        = huf.HT[gi.Count1tableSelect + 32];
            count1End = bigvalues + (gi.Count1 * 4);

            for (int i = bigvalues; i < count1End; i += 4)
            {
                v            = ix[i];
                w            = ix[i + 1];
                x            = ix[i + 2];
                y            = ix[i + 3];
                bitsWritten += HuffmanCoderCount1(ch, gr, ht, v, w, x, y);
            }

            c1bits       = bitsWritten - bvbits;
            stuffingBits = gi.Part23Length - gi.Part2Length - bitsWritten;

            if (stuffingBits != 0)
            {
                int stuffingWords = stuffingBits / 32;
                int remainingBits = stuffingBits % 32;

                for (; stuffingWords > 0; stuffingWords--)
                {
                    codedDataPH[ch, gr].Add(-1, 32);
                }

                if (remainingBits != 0)
                {
                    codedDataPH[ch, gr].Add(-1, remainingBits);
                }
                bitsWritten += stuffingBits;
            }
        }
示例#11
0
        private void EncodeMainData(int[][][] l3_enc, ref SideInfo l3_side, ref FrameParams fr_ps, int[][][] scalefact_l, int[][][][] scalefact_s)
        {
            int slen1, slen2, mode_gr = 2;

            for (int gr = 0; gr < mode_gr; gr++)
            {
                for (int ch = 0; ch < fr_ps.Chn; ch++)
                {
                    scaleFactorsPH[ch, gr].Position = 0;
                }
            }

            for (int gr = 0; gr < mode_gr; gr++)
            {
                for (int ch = 0; ch < fr_ps.Chn; ch++)
                {
                    codedDataPH[ch, gr].Position = 0;
                }
            }

            for (int gr = 0; gr < mode_gr; gr++)
            {
                for (int ch = 0; ch < fr_ps.Chn; ch++)
                {
                    slen1 = Tables.Slen1Tab[l3_side.TT[ch, gr].ScalefacCompress];
                    slen2 = Tables.Slen2Tab[l3_side.TT[ch, gr].ScalefacCompress];

                    if ((l3_side.TT[ch, gr].WindowSwitchingFlag == 1) && (l3_side.TT[ch, gr].BlockType == 2))
                    {
                        if (l3_side.TT[ch, gr].MixedBlockFlag != 0)
                        {
                            for (int sfb = 0; sfb < 8; sfb++)
                            {
                                scaleFactorsPH[ch, gr].Add(scalefact_l[ch][gr][sfb], slen1);
                            }

                            for (int sfb = 3; sfb < 6; sfb++)
                            {
                                for (int window = 0; window < 3; window++)
                                {
                                    scaleFactorsPH[ch, gr].Add(scalefact_s[ch][gr][sfb][window], slen1);
                                }
                            }
                            for (int sfb = 6; sfb < 12; sfb++)
                            {
                                for (int window = 0; window < 3; window++)
                                {
                                    scaleFactorsPH[ch, gr].Add(scalefact_s[ch][gr][sfb][window], slen2);
                                }
                            }
                        }
                        else
                        {
                            for (int sfb = 0; sfb < 6; sfb++)
                            {
                                for (int window = 0; window < 3; window++)
                                {
                                    scaleFactorsPH[ch, gr].Add(scalefact_s[gr][ch][sfb][window], slen1);
                                }
                            }
                            for (int sfb = 6; sfb < 12; sfb++)
                            {
                                for (int window = 0; window < 3; window++)
                                {
                                    scaleFactorsPH[ch, gr].Add(scalefact_s[ch][gr][sfb][window], slen2);
                                }
                            }
                        }
                    }
                    else
                    {
                        if ((gr == 0) || (l3_side.Scfsi[ch, 0] == 0))
                        {
                            for (int sfb = 0; sfb < 6; sfb++)
                            {
                                scaleFactorsPH[ch, gr].Add(scalefact_l[ch][gr][sfb], slen1);
                            }
                        }
                        if ((gr == 0) || (l3_side.Scfsi[ch, 1] == 0))
                        {
                            for (int sfb = 6; sfb < 11; sfb++)
                            {
                                scaleFactorsPH[ch, gr].Add(scalefact_l[ch][gr][sfb], slen1);
                            }
                        }
                        if ((gr == 0) || (l3_side.Scfsi[ch, 2] == 0))
                        {
                            for (int sfb = 11; sfb < 16; sfb++)
                            {
                                scaleFactorsPH[ch, gr].Add(scalefact_l[ch][gr][sfb], slen2);
                            }
                        }
                        if ((gr == 0) || (l3_side.Scfsi[ch, 3] == 0))
                        {
                            for (int sfb = 16; sfb < 21; sfb++)
                            {
                                scaleFactorsPH[ch, gr].Add(scalefact_l[ch][gr][sfb], slen2);
                            }
                        }
                    }
                    HuffmanCodeBits(ch, gr, l3_enc[ch][gr], ref l3_side.TT[ch, gr], ref fr_ps);
                }
            }
        }
示例#12
0
        public static string Encode(string path, int bitrate, string title, string artist, string album, string year, string comment, byte zero, byte num, byte genre, System.ComponentModel.BackgroundWorker backgroundWorker)
        {
            int[,] savebuf = new int[2, 1344];
            int[,] buf     = new int[2, 1152];
            int[,,] grbuf  = new int[2, 2, 576];
            double[][][][] xr;
            double[][][]   xr1;
            int[][][]      l3_enc = new int[2][][];

            for (int i1 = 0; i1 < 2; i1++)
            {
                l3_enc[i1] = new int[2][];
                for (int i2 = 0; i2 < 2; i2++)
                {
                    l3_enc[i1][i2] = new int[576];
                }
            }


            double[][][] xr_dec = new double[2][][];
            for (int i1 = 0; i1 < 2; i1++)
            {
                xr_dec[i1] = new double[2][];
                for (int i2 = 0; i2 < 2; i2++)
                {
                    xr_dec[i1][i2] = new double[576];
                }
            }

            int[][][] scalefact_l = new int[2][][];
            for (int i1 = 0; i1 < 2; i1++)
            {
                scalefact_l[i1] = new int[2][];
                for (int i2 = 0; i2 < 2; i2++)
                {
                    scalefact_l[i1][i2] = new int[21];
                }
            }

            int[][][][] scalefact_s = new int[2][][][];
            for (int i1 = 0; i1 < 2; i1++)
            {
                scalefact_s[i1] = new int[2][][];
                for (int i2 = 0; i2 < 2; i2++)
                {
                    scalefact_s[i1][i2] = new int[12][];
                    for (int i3 = 0; i3 < 12; i3++)
                    {
                        scalefact_s[i1][i2][i3] = new int[3];
                    }
                }
            }

            SideInfo         l3_side = new SideInfo();
            FrameParams      fr_ps   = new FrameParams();
            BitAndNoizeAlloc bna     = new BitAndNoizeAlloc();
            FormatBitStream  fbs     = new FormatBitStream();

            int counter       = 0;
            int ancillary_pad = 0;
            int bitsPerFrame  = 0;
            int meanBits      = 0;

            double[,,] ratio_d   = new double[2, 2, 21];
            double[,,,] ratio_ds = new double[2, 2, 12, 3];
            double[,] pe         = new double[2, 2];
            int[,] sw_fl         = new int[2, 2], bl_fl = new int[2, 2], wintp = new int[2, 2];

            byte[] Song = File.ReadAllBytes(path);          //чтение файла с PCM и запись в массив байтов

            int chn   = BitConverter.ToInt16(Song, 22);     //кол-во каналов
            int smplr = BitConverter.ToInt32(Song, 24);     //частота семплирования
            int bps   = BitConverter.ToInt16(Song, 34) / 8; //размер одного семпла
            int size  = BitConverter.ToInt32(Song, 40);     //размер области с данными

            int[,] s = new int[chn, (Song.Length - 44) / (chn * bps)];
            double[][][][] sb_gr = new double[2][][][];

            if (bps != 2 && bps != 4 && bps != 3)
            {
                throw new Exception("Неподдерживаемое разрешение");
            }

            for (int i1 = 0; i1 < 2; i1++)
            {
                sb_gr[i1] = new double[3][][];
                for (int i2 = 0; i2 < 3; i2++)
                {
                    sb_gr[i1][i2] = new double[18][];
                    for (int i3 = 0; i3 < 18; i3++)
                    {
                        sb_gr[i1][i2][i3] = new double[32];
                    }
                }
            }

            Layer info   = new Layer();
            MDCT  subber = new MDCT();



            switch (smplr)
            {
            case 48000:
                info.SamplingFrequency = 1;
                break;

            case 44100:
                info.SamplingFrequency = 0;
                break;

            case 32000:
                info.SamplingFrequency = 2;
                break;

            default:
                throw new Exception("Неподдерживаемая частота семплирования");
            }


            switch (chn)
            {
            case 0:
                info.Mode    = 0;
                info.ModeExt = 0;
                break;

            case 2:
                info.Mode    = 2;
                info.ModeExt = 0;
                break;

            case 1:
                info.Mode    = 3;
                info.ModeExt = 0;
                break;

            default:
                throw new Exception("Неправильный формат данных");
            }

            int j = 0;

            while (j < 15)
            {
                if (bitratex[1][j] == bitrate)
                {
                    break;
                }
                j++;
            }
            info.BitrateIndex = j;

            info.Version         = 1;
            info.Emphasis        = 0;
            info.Extension       = 0;
            info.Copyright       = 0;
            info.Original        = 1;
            info.ErrorProtection = 1;


            fr_ps.Header     = info;
            fr_ps.Chn        = chn;
            fr_ps.TabNum     = -1;
            fr_ps.Alloc      = null;
            fr_ps.ActualMode = info.Mode;
            fr_ps.Sblimit    = 32;
            fr_ps.Jsbound    = 32;


            double avg_slots_per_frame = (1152 / s_freq[1][info.SamplingFrequency]) * (bitratex[1][info.BitrateIndex] / 8.0);
            int    whole_SpF           = (int)avg_slots_per_frame;
            double frac_SpF            = avg_slots_per_frame - whole_SpF;
            double slot_lag            = -frac_SpF;
            int    extra_slot;

            if (frac_SpF == 0)
            {
                fr_ps.Header.Padding = 0;
            }

            if (frac_SpF != 0)
            {
                if (slot_lag > (frac_SpF - 1.0))
                {
                    slot_lag            -= frac_SpF;
                    extra_slot           = 0;
                    fr_ps.Header.Padding = 0;
                }
                else
                {
                    extra_slot           = 1;
                    fr_ps.Header.Padding = 1;
                    slot_lag            += (1 - frac_SpF);
                }
            }

            int sideinfo_len = 32;

            if (chn == 1)
            {
                sideinfo_len += 136;
            }
            else
            {
                sideinfo_len += 256;
            }

            if (fr_ps.Header.ErrorProtection == 0)
            {
                sideinfo_len += 16;
            }

            bitsPerFrame = 8 * whole_SpF + (fr_ps.Header.Padding * 8);
            meanBits     = (bitsPerFrame - sideinfo_len) / 2;



            PsyAcoustic Obj = new PsyAcoustic(smplr); // инициализация психоакустической модели

            for (int i = 44; i < Song.Length - 44;)   //массив со значениями PCM
            {
                for (int ch = 0; ch < chn; ch++, i += bps)
                {
                    switch (bps)
                    {
                    case 2:
                        s[ch, (i - 44) / (bps * chn)] = BitConverter.ToInt16(Song, i);
                        break;

                    case 3:
                        s[ch, (i - 44) / (bps * chn)] = ToInt24(Song[i], Song[i + 1], Song[i + 2]);
                        break;

                    case 4:
                        s[ch, (i - 44) / (bps * chn)] = BitConverter.ToInt32(Song, i);
                        break;

                    default:
                        throw new ArgumentException();
                    }
                }
            }
            string       outpath = Path.GetDirectoryName(path) + @"\" + Path.GetFileNameWithoutExtension(path) + ".mp3";
            BinaryWriter bw      = new BinaryWriter(File.Open(outpath, FileMode.Create));

            counter = 0;
            double end = Math.Floor((double)(s.GetLength(1)) / 1152);

            for (int k = 0; k < end; k++)
            {
                xr = new double[2][][][];
                for (int i1 = 0; i1 < 2; i1++)
                {
                    xr[i1] = new double[3][][];
                    for (int i2 = 0; i2 < 3; i2++)
                    {
                        xr[i1][i2] = new double[32][];
                        for (int i3 = 0; i3 < 32; i3++)
                        {
                            xr[i1][i2][i3] = new double[18];
                        }
                    }
                }


                grbuf = Granulation(s, ref counter, buf, chn);
                Sub   = new double[2][][];

                for (int gr = 0; gr < 2; gr++)
                {
                    for (int ch = 0; ch < chn; ch++)
                    {
                        Obj.Analize(ch, gr, grbuf, ref savebuf, ref ratio_d, ref ratio_ds, ref pe, ref wintp[ch, gr], ref sw_fl[ch, gr], ref bl_fl[ch, gr]); //применение психоакустической модели
                        l3_side.TT[ch, gr].WindowSwitchingFlag = sw_fl[ch, gr];
                        l3_side.TT[ch, gr].BlockType           = wintp[ch, gr];
                        l3_side.TT[ch, gr].MixedBlockFlag      = bl_fl[ch, gr];
                    }
                }

                for (int ch = 0; ch < chn; ch++)
                {
                    PolyPhase.Subbanding(ch, out Sub[ch], buf); // разделение на 32 подполосы
                }

                for (int ch = 0; ch < chn; ch++)
                {
                    for (int gr = 0, i0 = 0; gr < 2; gr++)
                    {
                        for (int s1 = 0; s1 < 18; s1++, i0++)
                        {
                            for (int band = 0; band < 32; band++)
                            {
                                sb_gr[ch][gr + 1][s1][band] = Sub[ch][i0][band];
                            }
                        }
                    }
                }
                subber.Subbanding(sb_gr, xr, chn, wintp, bl_fl);

                xr1 = new double[2][][];

                for (int ch = 0; ch < chn; ch++)
                {
                    xr1[ch] = new double[2][];
                    for (int gr = 0; gr < 2; gr++)
                    {
                        xr1[ch][gr] = new double[576];
                        for (int i1 = 0, i3 = 0; i1 < 32; i1++)
                        {
                            for (int i2 = 0; i2 < 18; i2++)
                            {
                                xr1[ch][gr][i3++] = xr[ch][gr][i1][i2];
                            }
                        }
                    }
                }



                bna.Loop(pe, xr1, ratio_ds, ratio_d, ref l3_side, l3_enc, meanBits, chn, xr_dec, scalefact_l, scalefact_s, ref fr_ps, ancillary_pad, bitsPerFrame);

                byte[] Arr = fbs.WriteToBitStream(bitsPerFrame, ref fr_ps, l3_enc, ref l3_side, scalefact_l, scalefact_s, xr1, null, 0);


                for (int i = 0; i < fbs.GetLength(); i++)
                {
                    bw.Write(Arr[i]);
                }

                if (backgroundWorker.CancellationPending)
                {
                    bw.Close();
                    return(outpath);
                }

                if (backgroundWorker.WorkerReportsProgress)
                {
                    double pr = (k * 100) / end;
                    backgroundWorker.ReportProgress((int)Math.Round(pr));
                }
            }

            byte[] Tag  = new byte[128];
            byte[] temp = new byte[30];
            Array.Copy(ASCIIEncoding.ASCII.GetBytes("TAG"), 0, Tag, 0, 3);
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(title), 0, temp, 0, title.Length);
            Array.Copy(temp, 0, Tag, 3, 30);
            temp = new byte[30];
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(artist), 0, temp, 0, artist.Length);
            Array.Copy(temp, 0, Tag, 33, 30);
            temp = new byte[30];
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(album), 0, temp, 0, album.Length);
            Array.Copy(temp, 0, Tag, 63, 30);
            temp = new byte[30];
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(year), 0, temp, 0, year.Length);
            Array.Copy(temp, 0, Tag, 93, 30);
            temp = new byte[28];
            Array.Copy(ASCIIEncoding.ASCII.GetBytes(comment), 0, temp, 0, comment.Length);
            Array.Copy(temp, 0, Tag, 97, 28);
            Tag[125] = zero;
            Tag[126] = num;
            Tag[127] = genre;
            bw.Write(Tag);

            bw.Close();
            return(outpath);
        }