예제 #1
0
        public int EncodeAddPcm(int channel, WWUtil.LargeArray <byte> pcmData)
        {
            long pos = 0;

            for (long remain = pcmData.LongLength; 0 < remain;)
            {
                int fragmentBytes = WWUtil.LargeArray <byte> .ARRAY_FRAGMENT_LENGTH_NUM;
                if (remain < fragmentBytes)
                {
                    fragmentBytes = (int)remain;
                }

                var fragment = new byte[fragmentBytes];
                pcmData.CopyTo(pos, ref fragment, 0, fragmentBytes);

                int rv = NativeMethods.WWFlacRW_EncodeSetPcmFragment(mId, channel, pos, fragment, fragmentBytes);
                if (rv < 0)
                {
                    return(rv);
                }

                pos    += fragmentBytes;
                remain -= fragmentBytes;
            }
            return(0);
        }
        public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcmLA)
        {
            var inPcm = inPcmLA.ToArray();

            double [] outPcm = new double[inPcm.Length];

            for (long i = 0; i < outPcm.Length; ++i)
            {
                mDelay.Filter(inPcm[i]);
                outPcm[i] = Convolution();
            }
            return(new WWUtil.LargeArray <double>(outPcm));
        }
예제 #3
0
        public override WWUtil.LargeArray <double> FilterDo(WWUtil.LargeArray <double> inPcmLA)
        {
            var inPcm  = inPcmLA.ToArray();
            var outPcm = new double[inPcm.Length];

            for (int i = 0; i < inPcm.Length; ++i)
            {
                double x = inPcm[i];

                double delayedY = mDelayX.Filter(x);

                for (int j = 0; j < MOVING_AVERAGER_NUM; ++j)
                {
                    x = mMovingAveragerList[j].Filter(x);
                }

                double y = delayedY - x;
                outPcm[i] = y;
            }

            if (0 < mDiscardSamples)
            {
                if (outPcm.Length < mDiscardSamples)
                {
                    mDiscardSamples -= outPcm.Length;
                    return(new WWUtil.LargeArray <double>(0));
                }
                else
                {
                    var outPcm2 = new double[outPcm.Length - mDiscardSamples];
                    Array.Copy(outPcm, mDiscardSamples, outPcm2, 0, outPcm2.Length);

                    mDiscardSamples = 0;
                    return(new WWUtil.LargeArray <double>(outPcm2));
                }
            }

            return(new WWUtil.LargeArray <double>(outPcm));
        }
예제 #4
0
        public BWCompletedParam DoWork(BWStartParams param, ProgressReportDelegate ReportProgress)
        {
            int rv = 0;

            var flacR = new WWFlacRWCS.FlacRW();

            do
            {
                // FLACファイルからメタデータ、画像、音声を取り出す。
                WWFlacRWCS.Metadata metaR;
                rv = flacR.DecodeAll(param.inputFile);
                if (rv < 0)
                {
                    // do-whileを抜けたところでflacR.DecodeEndする。
                    break;
                }

                flacR.GetDecodedMetadata(out metaR);

                byte[] picture = null;
                if (0 < metaR.pictureBytes)
                {
                    rv = flacR.GetDecodedPicture(out picture, metaR.pictureBytes);
                    if (rv < 0)
                    {
                        // do-whileを抜けたところでflacR.DecodeEndする。
                        break;
                    }
                }

                // flacRはまだ使用するのでここではDecodeEndしない。

                long lcm             = WWMath.Functions.LCM(metaR.sampleRate, param.targetSampleRate);
                int  upsampleScale   = (int)(lcm / metaR.sampleRate);
                int  downsampleScale = (int)(lcm / param.targetSampleRate);

                // IIRフィルターを設計。

                // ストップバンド最小周波数fs。
                double fs = metaR.sampleRate / 2 * STOPBAND_FREQ_RATIO;
                if (param.targetSampleRate / 2 * STOPBAND_FREQ_RATIO < fs)
                {
                    fs = param.targetSampleRate / 2 * STOPBAND_FREQ_RATIO;
                }

                // カットオフ周波数fc。
                double fc = CUTOFF_STOPBAND_RATIO * fs;

                mIIRFilterDesign = new IIRFilterDesign();
                mIIRFilterDesign.Design(fc, fs, lcm, param.method);

                ReportProgress(CONVERT_START_PERCENT, new BWProgressParam(State.FilterDesigned,
                                                                          string.Format("Read FLAC completed.\nSource sample rate = {0}kHz.\nTarget sample rate = {1}kHz. ratio={2}/{3}\n",
                                                                                        metaR.sampleRate / 1000.0, param.targetSampleRate / 1000.0,
                                                                                        lcm / metaR.sampleRate, lcm / param.targetSampleRate)));

                double RESAMPLE_RATIO = param.targetSampleRate / metaR.sampleRate;

                mSw.Restart();

                // 書き込み準備。
                WWFlacRWCS.Metadata metaW = new WWFlacRWCS.Metadata(metaR);
                metaW.sampleRate    = param.targetSampleRate;
                metaW.pictureBytes  = metaR.pictureBytes;
                metaW.bitsPerSample = 24;
                metaW.totalSamples  = metaR.totalSamples * upsampleScale / downsampleScale;

                if (param.isTargetPcm)
                {
                    mFlacWrite = new FlacWrite();
                    mFlacWrite.Setup(metaW, picture);
                }
                else
                {
                    mDsfWrite = new DsfWrite();
                    mDsfWrite.Setup(metaW, picture);
                }

                var  stat = new SampleValueStatistics();
                long totalSamplesOfAllChannels = metaR.totalSamples * metaR.channels;
                long processedSamples          = 0;

                // Mathematica用の設定。
                WWComplex.imaginaryUnit = "I";

                // 変換する
                for (int ch = 0; ch < metaR.channels; ++ch)
                {
                    //Parallel.For(0, metaR.channels, (int ch) => {
                    var pcmW = new WWUtil.LargeArray <byte>(metaW.totalSamples * metaW.BytesPerSample);

#if USE_ZOH_UPSAMPLE
                    // 零次ホールドのハイ落ち補償フィルター。
# if USE_CPP
                    var zohCompensation = new WWFilterCpp();
                    zohCompensation.BuildZohCompensation();
# else
                    var zohCompensation = new WWIIRFilterDesign.ZohNosdacCompensation(33);
# endif