示例#1
0
 public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcm)
 {
     WWUtil.LargeArray <double> outPcm = new WWUtil.LargeArray <double>(inPcm.LongLength);
     for (long i = 0; i < outPcm.LongLength; ++i)
     {
         outPcm.Set(i, inPcm.At(inPcm.LongLength - i - 1));
     }
     return(outPcm);
 }
示例#2
0
        /// <summary>
        /// Returns jitter added resample position
        /// retval unit is sample, difference from the ideal resample position of no jitter
        /// </summary>
        private double GenerateJitter2()
        {
            // 以下のsineJitterの計算、offsを掛けるのではなくて、前回の計算結果にcoeffを足してから
            // -π ≦ mSineArg < +π にする。

            double sineJitter        = mSineJitterAmp * Math.Sin(mSineArg);
            double tpdfJitter        = 0.0;
            double rpdfJitter        = 0.0;
            double timingErrFromFile = 0.0;

            if (0.0 < mTpdfJitterAmp)
            {
                double r = GenRandom0to1(mRand) + GenRandom0to1(mRand) - 1.0;
                tpdfJitter = mTpdfJitterAmp * r;
            }
            if (0.0 < mRpdfJitterAmp)
            {
                rpdfJitter = mRpdfJitterAmp * (GenRandom0to1(mRand) * 2.0 - 1.0);
            }

            if (mTimingErrorFromAudioFile != null)
            {
                timingErrFromFile = 1.0e-9 * TimingErrorFileNanosec * mSampleRate * mTimingErrorFromAudioFile.At(mOffs);
            }

            double jitter = sineJitter + tpdfJitter + rpdfJitter + timingErrFromFile;

            mSineArg += mSineJitterThetaCoefficient;
            while (Math.PI < mSineArg)
            {
                mSineArg -= 2.0 * Math.PI;
            }

            ++mOffs;

            return(jitter);
        }
示例#3
0
        Add(WWUtil.LargeArray <double> a, WWUtil.LargeArray <double> b)
        {
            if (a.LongLength != b.LongLength)
            {
                return(null);
            }

            var result = new WWUtil.LargeArray <double>(a.LongLength);

            for (long i = 0; i < a.LongLength; ++i)
            {
                result.Set(i, a.At(i) + b.At(i));
            }

            return(result);
        }
示例#4
0
        Mul(WWUtil.LargeArray <WWComplex> a, WWUtil.LargeArray <WWComplex> b)
        {
            if (a.LongLength != b.LongLength)
            {
                return(null);
            }

            var result = new WWUtil.LargeArray <WWComplex>(a.LongLength);

            for (long i = 0; i < a.LongLength; ++i)
            {
                var t = a.At(i);
                result.Set(i, WWComplex.Mul(t, b.At(i)));
            }

            return(result);
        }
示例#5
0
        public override WWUtil.LargeArray<double> FilterDo(WWUtil.LargeArray<double> inPcmLA) {
            System.Diagnostics.Debug.Assert(inPcmLA.LongLength == NumOfSamplesNeeded());
            var inPcm = inPcmLA.ToArray();

            int inputSamples = (int)((UpsampledWindowLen + 1) / Factor + PROCESS_SLICE);

            if (mFirst) {
                var silence = new double[(UpsampledWindowLen + 1) / Factor / 2];
                mInputDelay.AddRange(silence);
            }

            mInputDelay.AddRange(inPcm);
            if (inputSamples < mInputDelay.Count) {
                int count = mInputDelay.Count - inputSamples;
                mInputDelay.RemoveRange(0, count);
            }

            var fromPcm = mInputDelay.ToArray();
            var toPcm = new double[PROCESS_SLICE * Factor];

#if false
            for (int i=0; i<PROCESS_SLICE; ++i) {
#else
            Parallel.For(0, PROCESS_SLICE, i => {
#endif
                for (int f = 0; f < Factor; ++f) {
                    double sampleValue = 0;
                    for (long offs = 0; offs + Factor - f < mCoeffs.LongLength; offs += Factor) {
                        double input = mInputDelay[(int)(offs / Factor + i)];
                        if (input != 0.0) {
                            sampleValue += mCoeffs.At(offs + Factor - f) * input;
                        }
                    }
                    toPcm[i * Factor + f] = sampleValue;
                } 
#if false
            }
#else
            });
#endif

            mFirst = false;
            return new WWUtil.LargeArray<double>(toPcm);
        }
    }
示例#6
0
        private WWUtil.LargeArray <double> FFTFir(WWUtil.LargeArray <double> inPcm,
                                                  double[] coef, long fftLength)
        {
            var fft    = new WWMath.WWRadix2FftLargeArray(fftLength);
            var inTime = new WWUtil.LargeArray <WWComplex>(fftLength);

            for (long i = 0; i < mNumSamples; ++i)
            {
                inTime.Set(i, new WWComplex(inPcm.At(i), 0));
            }

            var inFreq = fft.ForwardFft(inTime);

            inTime = null;

            var coefTime = new WWUtil.LargeArray <WWComplex>(fftLength);

            for (long i = 0; i < mCoeffs[mChannelId * 2].Length; ++i)
            {
                coefTime.Set(i, new WWComplex(coef[i], 0));
            }

            var coefFreq = fft.ForwardFft(coefTime);

            coefTime = null;

            var mulFreq = Mul(inFreq, coefFreq);

            inFreq   = null;
            coefFreq = null;

            var mulTime = fft.InverseFft(mulFreq);

            mulFreq = null;

            var result = new WWUtil.LargeArray <double>(inPcm.LongLength);

            for (int i = 0; i < inPcm.LongLength; ++i)
            {
                result.Set(i, mulTime.At(i).real);
            }
            mulTime = null;

            return(result);
        }
示例#7
0
        public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcmLA)
        {
            var y = new WWUtil.LargeArray <double>(inPcmLA.LongLength);

            for (long pos = 0; pos < inPcmLA.LongLength; ++pos)
            {
                double x = inPcmLA.At(pos);

                x = mScale * x;

                foreach (var f in mF)
                {
                    x = f.Filter(x);
                }

                y.Set(pos, x);
            }

            return(y);
        }
示例#8
0
        private void SetupCoeffs() {
            var window = WWMath.WWWindowFunc.BlackmanWindow(UpsampledWindowLen);

            // ループ処理を簡単にするため最初と最後に0を置く。
            mCoeffs = new WWUtil.LargeArray<double>(1 + UpsampledWindowLen + 1);
            long center = UpsampledWindowLen / 2;

            for (long i = 0; i < UpsampledWindowLen / 2 + 1; ++i) {
                long numerator = i;
                int denominator = Factor;
                int numeratorReminder = (int)(numerator % (denominator*2));
                if (numerator == 0) {
                    mCoeffs.Set(1 + center + i, 1.0f);
                } else if (numerator % denominator == 0) {
                    // sinc(180 deg) == 0, sinc(360 deg) == 0, ...
                    mCoeffs.Set(1 + center + i, 0.0f);
                } else {
                    mCoeffs.Set(1 + center + i, Math.Sin(Math.PI * numeratorReminder / denominator)
                        / (Math.PI * numerator / denominator)
                        * window.At(center + i));
                }
                mCoeffs.Set(1 + center - i, mCoeffs.At(1 + center + i));
            }
        }
示例#9
0
        public int GetSampleValueInInt32(int ch, long pos)
        {
            Debug.Assert(0 <= ch && ch < NumChannels);
            if (pos < 0 || NumFrames <= pos)
            {
                return(0);
            }

            long offset = pos * BitsPerFrame / 8 + ch * BitsPerSample / 8;

            switch (BitsPerSample)
            {
            case 16:
                return((mSampleLargeArray.At(offset) << 16)
                       + (mSampleLargeArray.At(offset + 1) << 24));

            case 24:
                return((mSampleLargeArray.At(offset) << 8)
                       + (mSampleLargeArray.At(offset + 1) << 16)
                       + (mSampleLargeArray.At(offset + 2) << 24));

            case 32:
                if (SampleValueRepresentationType == PcmDataLib.PcmData.ValueRepresentationType.SFloat)
                {
                    var buff = new byte[4];
                    buff[0] = mSampleLargeArray.At(offset + 0);
                    buff[1] = mSampleLargeArray.At(offset + 1);
                    buff[2] = mSampleLargeArray.At(offset + 2);
                    buff[3] = mSampleLargeArray.At(offset + 3);
                    float f = BitConverter.ToSingle(buff, 0);
                    int   v = (int)(f * 0x80000000L);
                    return(v);
                }

                switch (ValidBitsPerSample)
                {
                case 24:
                    return((mSampleLargeArray.At(offset + 1) << 8)
                           + (mSampleLargeArray.At(offset + 2) << 16)
                           + (mSampleLargeArray.At(offset + 3) << 24));

                case 32:
                    return((mSampleLargeArray.At(offset))
                           + (mSampleLargeArray.At(offset + 1) << 8)
                           + (mSampleLargeArray.At(offset + 2) << 16)
                           + (mSampleLargeArray.At(offset + 3) << 24));

                default:
                    System.Diagnostics.Debug.Assert(false);
                    return(0);
                }

            default:
                System.Diagnostics.Debug.Assert(false);
                return(0);
            }
        }
        /// <summary>
        /// double[]を戻すバージョン。
        /// </summary>
        /// <param name="count">取得する要素数。範囲外の領域は0が入る。</param>
        /// <returns></returns>
        public double[] GetPcmInDoublePcm(int count)
        {
            // 確保するサイズはcount個。
            if (mTotalSamples <= mOffsBytes / (mBitsPerSample / 8) || count == 0)
            {
                // 完全に範囲外。
                return(new double[count]);
            }

            var result = new double[count];

            // コピーするデータの個数はcount個よりも少ないことがある。
            int copyCount = result.Length;

            if (mTotalSamples < mOffsBytes / (mBitsPerSample / 8) + copyCount)
            {
                copyCount = (int)(mTotalSamples - mOffsBytes / (mBitsPerSample / 8));
            }

            switch (mBitsPerSample)
            {
            case 16:
                for (int i = 0; i < copyCount; ++i)
                {
                    short v = (short)((mData.At(mOffsBytes)) + (mData.At(mOffsBytes + 1) << 8));
                    result[i]   = v * (1.0 / 32768.0);
                    mOffsBytes += 2;
                }
                break;

            case 24:
                for (int i = 0; i < copyCount; ++i)
                {
                    int v = (int)((mData.At(mOffsBytes) << 8) + (mData.At(mOffsBytes + 1) << 16)
                                  + (mData.At(mOffsBytes + 2) << 24));
                    result[i]   = v * (1.0 / 2147483648.0);
                    mOffsBytes += 3;
                }
                break;

            case 32:
                switch (mValueRepresentationType)
                {
                case PcmData.ValueRepresentationType.SInt:
                    for (int i = 0; i < copyCount; ++i)
                    {
                        // 32bit int.
                        int v = (int)(
                            (mData.At(mOffsBytes + 0) << 0)
                            + (mData.At(mOffsBytes + 1) << 8)
                            + (mData.At(mOffsBytes + 2) << 16)
                            + (mData.At(mOffsBytes + 3) << 24));
                        result[i]   = v * (1.0 / 2147483648.0);
                        mOffsBytes += 4;
                    }
                    break;

                case PcmData.ValueRepresentationType.SFloat:
                    for (int i = 0; i < copyCount; ++i)
                    {
                        // 32bit float.
                        byte [] buff = new byte[4];
                        for (int j = 0; j < 4; ++j)
                        {
                            buff[j] = mData.At(mOffsBytes + j);
                        }
                        float v = BitConverter.ToSingle(buff, 0);
                        result[i]   = v;
                        mOffsBytes += 4;
                    }
                    break;
                }
                break;

            case 64:
                switch (mValueRepresentationType)
                {
                case PcmData.ValueRepresentationType.SInt:
                    for (int i = 0; i < copyCount; ++i)
                    {
                        // 16.48 fixed point number
                        long v = (long)(
                            ((ulong)mData.At(mOffsBytes + 0) << 0)
                            + ((ulong)mData.At(mOffsBytes + 1) << 8)
                            + ((ulong)mData.At(mOffsBytes + 2) << 16)
                            + ((ulong)mData.At(mOffsBytes + 3) << 24)
                            + ((ulong)mData.At(mOffsBytes + 4) << 32)
                            + ((ulong)mData.At(mOffsBytes + 5) << 40)
                            + ((ulong)mData.At(mOffsBytes + 6) << 48)
                            + ((ulong)mData.At(mOffsBytes + 7) << 56));
                        result[i]   = v * (1.0 / 65536.0 / 65536.0 / 65536.0);
                        mOffsBytes += 8;
                    }
                    break;

                case PcmData.ValueRepresentationType.SFloat:
                    for (int i = 0; i < copyCount; ++i)
                    {
                        // 64bit float.
                        byte[] buff = new byte[8];
                        for (int j = 0; j < 8; ++j)
                        {
                            buff[j] = mData.At(mOffsBytes + j);
                        }
                        double v = BitConverter.ToDouble(buff, 0);
                        result[i]   = v;
                        mOffsBytes += 8;
                    }
                    break;
                }
                break;

            default:
                System.Diagnostics.Debug.Assert(false);
                break;
            }
            return(result);
        }