예제 #1
0
        public void Setup(WWFlacRWCS.Metadata metaW, byte[] picture)
        {
            mDsfW = new WWDsfRW.WWDsfWriter();
            mDsfW.EncodeInit(metaW);
            if (picture != null)
            {
                mDsfW.EncodeSetPicture(picture);
            }

            // サンプルデータ置き場。
            mSampleData = new SampleData1ch[metaW.channels];
            for (int ch = 0; ch < metaW.channels; ++ch)
            {
                mSampleData[ch] = new SampleData1ch((metaW.totalSamples + 7) / 8);
            }

            // ノイズシェイピングフィルターmLoopFiltersを作る。
            mLoopFilter.Design(FILTER_ORDER, metaW.channels);

            if (FILTER_ORDER == 5)
            {
                mLoopFilter.SetDelayValues(
                    new double[] {
                    1.43681852625616E-06,
                    -9.4526383335642E-05,
                    -0.00124416475447812,
                    -0.00212062453327017,
                    0.0391562027012161,
                }
                    );
            }
        }
예제 #2
0
        private long FlacWriteConvertTo24bitPcm(double [] y, WWFlacRWCS.Metadata metaW, LargeArray <byte> pcmW, long posY)
        {
            var yPcm = ConvertToIntegerPcm(y, metaW.BytesPerSample);

            pcmW.CopyFrom(yPcm, 0, posY, yPcm.Length);
            posY += yPcm.Length;
            return(posY);
        }
예제 #3
0
 public void Setup(WWFlacRWCS.Metadata metaW, byte[] picture)
 {
     mFlacW = new WWFlacRWCS.FlacRW();
     mFlacW.EncodeInit(metaW);
     if (picture != null)
     {
         mFlacW.EncodeSetPicture(picture);
     }
 }
예제 #4
0
        // FLACからPCMのバイト列を取得し、最大値1のdouble型のサンプル値の配列を作る。
        private double[] InputSamples(WWFlacRWCS.FlacRW flacR, WWFlacRWCS.Metadata meta,
                                      int ch, long posSamples, int nSamples)
        {
            // 1ch分のnサンプルのPCMデータ。
            int nBytes = nSamples * meta.BytesPerSample;
            var pcm    = new byte[nBytes];

            nSamples = flacR.GetPcmOfChannel(ch, posSamples, ref pcm, nSamples);
            if (nSamples <= 0)
            {
                return(new double[0]);
            }
            double[] result = new double[nSamples];
            switch (meta.bitsPerSample)
            {
            case 16:
                for (int i = 0; i < nSamples; ++i)
                {
                    short v = (short)(pcm[i * 2] + (pcm[i * 2 + 1] << 8));
                    result[i] = v / 32768.0;
                }
                break;

            case 20:
            case 24:
                for (int i = 0; i < nSamples; ++i)
                {
                    int v = (int)((pcm[i * 3] << 8) + (pcm[i * 3 + 1] << 16) + (pcm[i * 3 + 2] << 24));
                    result[i] = v / 2147483648.0;
                }
                break;

            default:
                throw new NotSupportedException();
            }
            return(result);
        }
 public int EncodeInit(WWFlacRWCS.Metadata meta)
 {
     mMeta = meta;
     mDsdData = new List<byte[]>();
     return 0;
 }
 public void EncodeEnd()
 {
     mDsdData = null;
     mPictureData = null;
     mMeta = null;
 }
예제 #7
0
        public RunWorkerCompletedResult BackgroundDoWorkImpl(DoWorkEventArgs e, string rootPath, bool background)
        {
            mContentList.Clear();

            var result = new RunWorkerCompletedResult();

            result.fileCount = 0;
            result.path      = rootPath;

            if (background)
            {
                mBw.ReportProgress(0, new ReportProgressArgs(string.Format(Properties.Resources.LogCountingFiles, rootPath)));
            }

            var flacList = WWUtil.DirectoryUtil.CollectFilesOnFolder(rootPath, ".FLAC");

            if (background)
            {
                mBw.ReportProgress(0, new ReportProgressArgs(string.Format(Properties.Resources.LogReportCount, flacList.Length)));
            }

            if (mBw.CancellationPending)
            {
                Console.WriteLine("D: BackgroundContentListBuilder::BackgroundDoWorkImpl() canceled 1");
                e.Cancel = true;
                return(result);
            }

            int finished = 0;

            mStopWatch.Start();

            // Parallel.Forにした時はforの中に持っていく必要あり。
            if (background)
            {
                System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest;
            }

            try {
                for (int i = 0; i < flacList.Length; ++i)
                {
                    if (mBw.CancellationPending)
                    {
                        Console.WriteLine("D: BackgroundContentListBuilder::BackgroundDoWorkImpl() canceled 2");
                        e.Cancel = true;
                        return(result);
                    }

                    string path   = flacList[i];
                    var    flacrw = new WWFlacRWCS.FlacRW();
                    int    ercd   = flacrw.DecodeHeader(path);
                    lock (mBw) {
                        if (0 <= ercd)
                        {
                            ++result.fileCount;
                            var m = new WWFlacRWCS.Metadata();
                            flacrw.GetDecodedMetadata(out m);
                            var pic = new byte[0];
                            if (0 < m.pictureBytes)
                            {
                                pic = new byte[m.pictureBytes];
                                flacrw.GetDecodedPicture(out pic, m.pictureBytes);
                            }
                            mContentList.Add(path, m.titleStr, 1, m.albumStr, m.artistStr, pic,
                                             m.channels, m.bitsPerSample, m.sampleRate, m.PcmBytes / (m.channels * m.bitsPerSample / 8));
                        }
                        else
                        {
                            Console.WriteLine("FLAC decode failed {0} {1}", WWFlacRWCS.FlacRW.ErrorCodeToStr(ercd), path);
                        }
                        flacrw.DecodeEnd();

                        ++finished;

                        if (1000 < mStopWatch.ElapsedMilliseconds)
                        {
                            if (background)
                            {
                                var text = string.Format(Properties.Resources.LogCreatingMusicList,
                                                         100 * finished / flacList.Length);
                                mBw.ReportProgress((int)(1000000L * finished / flacList.Length),
                                                   new ReportProgressArgs(text));
                            }

                            mStopWatch.Restart();
                        }
                    }
                }
            } catch (System.IO.IOException ex) {
                //Console.WriteLine(ex);
            } catch (System.Exception ex) {
                Console.WriteLine(ex);
            }

            mStopWatch.Stop();
            return(result);
        }
예제 #8
0
 public void EncodeEnd()
 {
     mSdmData     = null;
     mPictureData = null;
     mMeta        = null;
 }
예제 #9
0
 public int EncodeInit(WWFlacRWCS.Metadata meta)
 {
     mMeta    = meta;
     mSdmData = new List <WWUtil.LargeArray <byte> >();
     return(0);
 }
예제 #10
0
 public int EncodeInit(WWFlacRWCS.Metadata meta)
 {
     mMeta    = meta;
     mDsdData = new List <byte[]>();
     return(0);
 }
예제 #11
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