コード例 #1
0
ファイル: Types.cs プロジェクト: haiot4105/MP3Encoder
 public SideInfo()
 {
     TT = new GrInfo[2, 2];
     for (int i1 = 0; i1 < 2; i1++)
     {
         for (int i2 = 0; i2 < 2; i2++)
         {
             TT[i1, i2] = new GrInfo();
         }
     }
     Scfsi = new int[2, 4];
 }
コード例 #2
0
        int InnerLoop(double[] abs_xr, int[] abs_ix, int max_bits, ref GrInfo cod_info)
        {
            int bits;

            cod_info.QuantizerStepSize -= 1.0;
            do
            {
                do
                {
                    cod_info.QuantizerStepSize += 1.0;
                    tjBitOverflow2              = false;
                    QuantizeTj(abs_xr, abs_ix, ref cod_info);
                }while (tjBitOverflow2);

                bits = CountBits(abs_ix, ref cod_info);
            }while (bits > max_bits);

            return(bits);
        }
コード例 #3
0
        void CalcNoise(double[] xr, int[] ix, ref GrInfo cod_info, double[,] xfsf)
        {
            int    start, end, l, i;
            int    sfb;
            double sum, step, bw;

            step = Math.Pow(2.0, (cod_info.QuantizerStepSize) * 0.25);

            for (sfb = 0; sfb < cod_info.SfbLmax; sfb++)
            {
                start = scalefac_band_long[sfb];
                end   = scalefac_band_long[sfb + 1];
                bw    = end - start;

                for (sum = 0.0, l = start; l < end; l++)
                {
                    double temp;
                    temp = xr[l] - noisePowTab[ix[l]] * step;

                    sum += temp * temp;
                }
                xfsf[0, sfb] = sum / bw;
            }

            for (i = 0; i < 3; i++)
            {
                for (sfb = cod_info.SfbSmax; sfb < 12; sfb++)
                {
                    start = scalefac_band_short[sfb];
                    end   = scalefac_band_short[sfb + 1];
                    bw    = end - start;

                    for (sum = 0.0, l = start; l < end; l++)
                    {
                        double temp;
                        temp = xr[l * 3 + i] - noisePowTab[ix[l * 3 + i]] * step;
                        sum += temp * temp;
                    }
                    xfsf[i + 1, sfb] = sum / bw;
                }
            }
        }
コード例 #4
0
        private bool LoopBreak(int[][][] scalefact_l, int[][][][] scalefact_s, ref GrInfo cod_info, int gr, int ch)
        {
            int i, sfb;

            for (sfb = 0; sfb < cod_info.SfbLmax; sfb++)
            {
                if (scalefact_l[ch][gr][sfb] == 0)
                {
                    return(false);
                }
            }

            for (sfb = cod_info.SfbSmax; sfb < 12; sfb++)
            {
                for (i = 0; i < 3; i++)
                {
                    if (scalefact_s[ch][gr][sfb][i] == 0)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
コード例 #5
0
ファイル: Reservoir.cs プロジェクト: haiot4105/MP3Encoder
 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
        private int CountBits(int[] abs_ix, ref GrInfo cod_info)
        {
            int zero_region = 576;
            int bigv_region = 576;

            int bits = 0;
            int sum0 = 0;
            int sum1 = 0;



            if (cod_info.WindowSwitchingFlag == 0 || (cod_info.BlockType != 2))
            {
                int p;

                for (; zero_region > 1; zero_region -= 2)
                {
                    if (abs_ix[zero_region - 1] != 0)
                    {
                        break;
                    }
                    else if (abs_ix[zero_region - 2] != 0)
                    {
                        break;
                    }
                }

                for (bigv_region = zero_region; bigv_region > 3; bigv_region -= 4)
                {
                    if (abs_ix[bigv_region - 1] > 1)
                    {
                        break;
                    }
                    else if (abs_ix[bigv_region - 2] > 1)
                    {
                        break;
                    }
                    else if (abs_ix[bigv_region - 3] > 1)
                    {
                        break;
                    }
                    else if (abs_ix[bigv_region - 4] > 1)
                    {
                        break;
                    }

                    p = 0;
                    if (abs_ix[bigv_region - 1] != 0)
                    {
                        bits++;
                        p |= 8;
                    }
                    if (abs_ix[bigv_region - 2] != 0)
                    {
                        bits++;
                        p |= 4;
                    }
                    if (abs_ix[bigv_region - 3] != 0)
                    {
                        bits++;
                        p |= 2;
                    }
                    if (abs_ix[bigv_region - 4] != 0)
                    {
                        bits++;
                        p |= 1;
                    }

                    sum0 += huf.HT[32].Hlen[p];
                    sum1 += huf.HT[33].Hlen[p];
                }
            }
            cod_info.Count1    = (zero_region - bigv_region) / 4;
            cod_info.BigValues = bigv_region / 2;

            if (sum0 < sum1)
            {
                bits += sum0;
                cod_info.Count1tableSelect = 0;
            }
            else
            {
                bits += sum1;
                cod_info.Count1tableSelect = 1;
            }

            if (bigv_region != 0)
            {
                if (cod_info.WindowSwitchingFlag != 0)
                {
                    if (cod_info.MixedBlockFlag != 0 || (cod_info.BlockType != 2))
                    {
                        cod_info.Region0Count = 7;
                        cod_info.Region1Count = 13;
                        cod_info.Address1     = scalefac_band_long[cod_info.Region0Count + 1];
                    }
                    else
                    {
                        cod_info.Region0Count = 8;
                        cod_info.Region1Count = 36;
                        cod_info.Address1     = 36;
                    }
                    cod_info.Address2 = bigv_region;
                    cod_info.Address3 = 0;
                }
                else
                {
                    int index0, index1;
                    int scfb_anz = 0;

                    while (scalefac_band_long[scfb_anz] < bigv_region)
                    {
                        scfb_anz++;
                    }

                    index0 = (cod_info.Region0Count = subdv_table[scfb_anz][0]) + 1;
                    index1 = (cod_info.Region1Count = subdv_table[scfb_anz][1]) + 1;

                    cod_info.Address1 = scalefac_band_long[index0];
                    cod_info.Address2 = scalefac_band_long[index0 + index1];
                    cod_info.Address3 = bigv_region;
                }
            }
            else
            {
                cod_info.Region0Count = 0;
                cod_info.Region1Count = 0;
            }



            cod_info.TableSelect[0] = 0;
            cod_info.TableSelect[1] = 0;
            cod_info.TableSelect[2] = 0;

            if (cod_info.WindowSwitchingFlag != 0 && (cod_info.BlockType == 2))
            {
                int sfb, window, line, start, end;
                int max1, max2, pmax, tMax;
                int x, y;

                max1 = max2 = 0;

                for (sfb = 0; sfb < 13; sfb++)
                {
                    start = scalefac_band_short[sfb];
                    end   = scalefac_band_short[sfb + 1];

                    if (start < 12)
                    {
                        pmax = max1;
                    }
                    else
                    {
                        pmax = max2;
                    }

                    tMax = pmax;

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

                            y = abs_ix[window + (line + 1) * 3];

                            if (x > tMax)
                            {
                                tMax = x;
                            }
                            if (y > tMax)
                            {
                                tMax = y;
                            }
                        }
                    }

                    if (start < 12)
                    {
                        max1 = tMax;
                    }
                    else
                    {
                        max2 = tMax;
                    }
                }


                cod_info.TableSelect[0] = ChooseTable(max1);
                cod_info.TableSelect[1] = ChooseTable(max2);

                if (cod_info.MixedBlockFlag != 0)
                {
                    if (cod_info.TableSelect[0] != 0)
                    {
                        bits += CountBitTj(abs_ix, 0, cod_info.Address1, cod_info.TableSelect[0]);
                    }
                    sfb = 2;
                }
                else
                {
                    sfb = 0;
                }
                for (; sfb < 13; sfb++)
                {
                    int tableindex;
                    int idx;

                    start = scalefac_band_short[sfb];
                    end   = scalefac_band_short[sfb + 1];

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

                    if (tableindex != 0)
                    {
                        for (window = 0; window < 3; window++)
                        {
                            for (line = start; line < end; line += 2)
                            {
                                int x1 = abs_ix[window + line * 3];
                                int y1 = abs_ix[window + (line + 1) * 3];

                                if (tableindex > 15)
                                {
                                    if (x1 > 14)
                                    {
                                        x1    = 15;
                                        bits += huf.HT[tableindex].LinBits;
                                    }
                                    if (y1 > 14)
                                    {
                                        y1    = 15;
                                        bits += huf.HT[tableindex].LinBits;
                                    }
                                }

                                idx   = (x1 * huf.HT[tableindex].Ylen) + y1;
                                bits += huf.HT[tableindex].Hlen[idx];

                                if (x1 != 0)
                                {
                                    bits++;
                                }
                                if (y1 != 0)
                                {
                                    bits++;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                if (cod_info.Address1 > 0)
                {
                    if ((cod_info.TableSelect[0] = NewChooseTableTj(abs_ix, 0, cod_info.Address1)) > 0)
                    {
                        bits += CountBitTj(abs_ix, 0, cod_info.Address1, cod_info.TableSelect[0]);
                    }
                }
                if (cod_info.Address2 > cod_info.Address1)
                {
                    if ((cod_info.TableSelect[1] = NewChooseTableTj(abs_ix, cod_info.Address1, cod_info.Address2)) > 0)
                    {
                        bits += CountBitTj(abs_ix, cod_info.Address1, cod_info.Address2, cod_info.TableSelect[1]);
                    }
                }
                if (cod_info.BigValues * 2 > cod_info.Address2)
                {
                    if ((cod_info.TableSelect[2] = NewChooseTableTj(abs_ix, cod_info.Address2, cod_info.BigValues * 2)) > 0)
                    {
                        bits += CountBitTj(abs_ix, cod_info.Address2, cod_info.Address3, cod_info.TableSelect[2]);
                    }
                }
            }

            return(bits);
        }
コード例 #7
0
        private int BinSearchStepSize(int desired_rate, double start, int[] abs_ix, double[] abs_xr, ref GrInfo cod_info)
        {
            double top, bot, next, last;
            int    bit;

            top = start;
            bot = 200;

            next = start;
            do
            {
                last = next;
                next = (int)((top + bot) / 2.0);
                cod_info.QuantizerStepSize = next;

                tjBitOverflow1 = false;
                QuantizeTj(abs_xr, abs_ix, ref cod_info);
                if (tjBitOverflow1)
                {
                    bit = 100000;
                }
                else
                {
                    bit = CountBits(abs_ix, ref cod_info);
                }

                if (bit > desired_rate)
                {
                    top = next;
                }
                else
                {
                    bot = next;
                }
            }while ((bit != desired_rate) && (Math.Abs(last - next) > 1.0));

            return((int)next);
        }
コード例 #8
0
        private int ScaleBitcount(int[][][] scalefact_l, int[][][][] scalefact_s, ref GrInfo cod_info, int gr, int ch)
        {
            int i, k, sfb, max_slen1 = 0, max_slen2 = 0, ep = 2;


            int[] slen1 = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };
            int[] slen2 = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };
            int[] pow2  = { 1, 2, 4, 8, 16 };

            if (cod_info.WindowSwitchingFlag != 0 && cod_info.BlockType == 2)
            {
                if (cod_info.MixedBlockFlag == 0)
                {
                    for (i = 0; i < 3; i++)
                    {
                        for (sfb = 0; sfb < 6; sfb++)
                        {
                            if (scalefact_s[ch][gr][sfb][i] > max_slen1)
                            {
                                max_slen1 = scalefact_s[ch][gr][sfb][i];
                            }
                        }
                        for (sfb = 6; sfb < 12; sfb++)
                        {
                            if (scalefact_s[ch][gr][sfb][i] > max_slen2)
                            {
                                max_slen2 = scalefact_s[ch][gr][sfb][i];
                            }
                        }
                    }
                }
                else
                {
                    for (sfb = 0; sfb < 8; sfb++)
                    {
                        if (scalefact_l[ch][gr][sfb] > max_slen1)
                        {
                            max_slen1 = scalefact_l[ch][gr][sfb];
                        }
                    }
                    for (i = 0; i < 3; i++)
                    {
                        for (sfb = 3; sfb < 6; sfb++)
                        {
                            if (scalefact_s[ch][gr][sfb][i] > max_slen1)
                            {
                                max_slen1 = scalefact_s[ch][gr][sfb][i];
                            }
                        }
                        for (sfb = 6; sfb < 12; sfb++)
                        {
                            if (scalefact_s[ch][gr][sfb][i] > max_slen2)
                            {
                                max_slen2 = scalefact_s[ch][gr][sfb][i];
                            }
                        }
                    }
                }
            }
            else
            {
                for (sfb = 0; sfb < 11; sfb++)
                {
                    if (scalefact_l[ch][gr][sfb] > max_slen1)
                    {
                        max_slen1 = scalefact_l[ch][gr][sfb];
                    }
                }
                for (sfb = 11; sfb < 21; sfb++)
                {
                    if (scalefact_l[ch][gr][sfb] > max_slen2)
                    {
                        max_slen2 = scalefact_l[ch][gr][sfb];
                    }
                }
            }

            for (k = 0; k < 16; k++)
            {
                if ((max_slen1 < pow2[slen1[k]]) && (max_slen2 < pow2[slen2[k]]))
                {
                    ep = 0;
                    break;
                }
            }

            if (ep == 0)
            {
                cod_info.ScalefacCompress = k;
            }
            return(ep);
        }
コード例 #9
0
        private void QuantizeTj(double[] abs_xr, int[] abs_ix, ref GrInfo cod_info)
        {
            int    i, b, l_end, s_start;
            double expo, mulVal;

            expo   = -cod_info.QuantizerStepSize * 0.25;
            mulVal = Math.Pow(2, expo);

            if (cod_info.WindowSwitchingFlag != 0 && (cod_info.BlockType == 2))
            {
                if (cod_info.MixedBlockFlag != 0)
                {
                    l_end   = 18 * 2;
                    s_start = 6 * 2;
                }
                else
                {
                    l_end   = 0;
                    s_start = 0;
                }
                for (int bi = l_end; bi < (576 - l_end); bi++)
                {
                    abs_ix[bi] = 0;
                }
            }
            else
            {
                l_end   = 576;
                s_start = 192;
            }

            for (i = 0; i < l_end; i++)
            {
                abs_ix[i] = Nint(Math.Pow(abs_xr[i] * mulVal, 0.75) - 0.0946);

                if (abs_ix[i] > 8192)
                {
                    tjBitOverflow1 = true;
                    if (abs_ix[i] > 8191 + 14)
                    {
                        tjBitOverflow2 = true;
                    }
                }
            }



            if (s_start < 192)
            {
                for (b = 0; b < 3; b++)
                {
                    mulVal = Math.Pow(2.0, expo - (double)(cod_info.SubblockGain[b] * 2));
                    for (i = s_start; i < 192; i++)
                    {
                        abs_ix[i * 3 + b] = Nint(Math.Pow(abs_xr[i * 3 + b] * mulVal, 0.75) - 0.0946);

                        if (abs_ix[i * 3 + b] > 8192)
                        {
                            tjBitOverflow1 = true;
                            if (abs_ix[i * 3 + b] > 8191 + 14)
                            {
                                tjBitOverflow2 = true;
                            }
                        }
                    }
                }
            }
        }
コード例 #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;
            }
        }