Пример #1
0
		public CDRepair(int finalSampleCount, int stride, int npar)
		{			
			this.npar = npar;
			this.stride = stride;
			this.finalSampleCount = finalSampleCount;
			sampleCount = 0;
			galois = Galois16.instance;
			rs = new RsDecode16(npar, galois);
			//crc32 = new Crc32();
			//crc = 0xffffffff;
			encodeGx = galois.makeEncodeGxLog(npar);
			laststride = stride + (finalSampleCount * 2) % stride;
			stridecount = (finalSampleCount * 2) / stride - 2; // minus one for leadin and one for leadout
			if ((finalSampleCount * 2 + stride - 1) / stride + npar > galois.Max)
				throw new Exception("invalid stride");
		}
Пример #2
0
        /**
         * チェン探索により誤り位置を求める
         *		σ(z) = 0の解を探索する
         *		ただし、探索はデータ長以内の解のみで
         *		jisu個の解が見つからなければ、エラーとする
         * @param pos int[]
         *      誤り位置格納用配列、jisu個の領域が必要
         * @param n int
         *      データ長
         * @param jisu int
         *      σの次数
         * @param sigma int[]
         *      σ0,σ1,σ2, ... σ<jisu>
         * @return int
         *		0: 正常終了
         *		< 0: エラー
         */
        public unsafe bool chienSearch(int *pos, int n, int jisu, int *sigma)
        {
            /*
             * σ(z) = (1-α^i*z)(1-α^j*z)(1-α^k*z)
             *       = 1 + σ1z + σ2z^2 +...
             * σ1 = α^i + α^j + α^k
             * つまりσ1は全ての解の合計となっている。上記の性質を利用して、プチ最適化
             * last = σ1から、見つけた解を次々と引いていくことにより、最後の解はlastとなる
             */
            int last = sigma[1];

            if (jisu == 1)
            {
                // 次数が1ならばlastがその解である
                return(setLastErrorPos(pos, n, last));
            }
            int *sg = stackalloc int[jisu + 1];

            for (int j = 1; j <= jisu; j++)
            {
                sg[j] = sigma[j];
            }
            int posIdx = jisu - 1;                      // 誤り位置格納用インデックス

            bool haveZeroes = false;

            // haveZeroes = true;
            for (int j = 1; j <= jisu; j++)
            {
                haveZeroes |= sg[j] == 0;
            }
            if (!haveZeroes && this.galois.Max == 0xffff)
            {
                const int himax = 0x11000;
                fixed(ushort *exp = this.galois.ExpTbl, log = this.galois.LogTbl)
                {
                    for (int j = 1; j <= jisu; j++)
                    {
                        sg[j] = log[sg[j]] - ((j * n) % 0xffff) + 0xffff;
                        sg[j] = (sg[j] & 0xffff) + (sg[j] >> 16);
                    }
                    int i = n;

                    while (i > 0)
                    {
                        int cnt = i;
                        for (int j = 1; j <= jisu; j++)
                        {
                            sg[j] = (sg[j] & 0xffff) + (sg[j] >> 16);
                            cnt   = Math.Min(cnt, (himax - sg[j]) / j);
                        }
                        i -= RsDecode.chienFast(sg, exp, cnt, jisu);
                        int wk = 1;
                        for (int j = 1; j <= jisu; j++)
                        {
                            wk ^= exp[sg[j]];
                        }
                        if (wk == 0)
                        {
                            last ^= pos[posIdx--] = exp[i];
                            if (posIdx == 0)
                            {
                                pos[0] = last;
                                return(log[last] < n);
                            }
                        }
                    }
                }

                return(false);
            }

            for (int i = 0; i < n; i++)
            {
                /*
                 * σ(z)の計算
                 * w を1(0乗の項)に初期化した後、残りの項<1..jisu>を加算
                 * z = 1/α^i = α^Iとすると
                 * σ(z) = 1 + σ1α^I + σ2(α^I)^2 + σ3(α^I)^3 + ... + σ<jisu>/(α^I)^<jisu>
                 *      = 1 + σ1α^I + σ2α^(I*2) + σ3α^(I*3) + ... + σ<jisu>α^(I*<jisu>)
                 */
                int wk = 1;
                for (int j = 1; j <= jisu; j++)
                {
                    wk ^= sg[j];
                }
                for (int j = 1; j <= jisu; j++)
                {
                    sg[j] = galois.divExp(sg[j], j);
                }
                if (wk == 0)
                {
                    int pv = galois.toExp(i);                                   // σ(z) = 0の解
                    last         ^= pv;                                         // lastから今見つかった解を引く
                    pos[posIdx--] = pv;
                    if (posIdx == 0)
                    {
                        // 残りが一つならば、lastがその解である
                        return(setLastErrorPos(pos, n, last));
                    }
                }
            }
            // 探索によりデータ長以内に、jisu個の解が見つからなかった
            return(false);
        }