public RunWorkerArgs(string fromPath, string toPath, WWAFUtil.AFSampleFormat sf, bool bDither)
 {
     FromPath     = fromPath;
     ToPath       = toPath;
     SampleFormat = sf;
     Dither       = bDither;
 }
        private FilterBase FinalDither(WWAFUtil.AFSampleFormat outputSampleFormat)
        {
            switch (outputSampleFormat)
            {
            case WWAFUtil.AFSampleFormat.Auto:
            default:
                System.Diagnostics.Debug.Assert(false);
                return(null);

            case WWAFUtil.AFSampleFormat.PcmInt16:
                return(new RandomNoiseFilter(RandomNoiseFilter.NoiseTypeEnum.TPDF, -20.0 * Math.Log10(2) * 13));

            case WWAFUtil.AFSampleFormat.PcmInt24:
                return(new RandomNoiseFilter(RandomNoiseFilter.NoiseTypeEnum.TPDF, -20.0 * Math.Log10(2) * 21));

            case WWAFUtil.AFSampleFormat.PcmInt32:
                return(new RandomNoiseFilter(RandomNoiseFilter.NoiseTypeEnum.TPDF, -20.0 * Math.Log10(2) * 29));

            case WWAFUtil.AFSampleFormat.PcmInt64:
            case WWAFUtil.AFSampleFormat.PcmFloat32:
            case WWAFUtil.AFSampleFormat.PcmFloat64:
                return(null);
            }
        }
        public int Run(string fromPath, List <FilterBase> aFilters,
                       string toPath, WWAFUtil.AFSampleFormat outputSampleFormat,
                       bool dither, ProgressReportCallback Callback)
        {
            AudioData audioDataFrom;
            AudioData audioDataTo;
            int       rv = AudioDataIO.Read(fromPath, out audioDataFrom);

            if (rv < 0)
            {
                return(rv);
            }

            mBarrierReady      = new Barrier(audioDataFrom.meta.channels);
            mBarrierSet        = new Barrier(audioDataFrom.meta.channels);
            mBarrierClearInPcm = new Barrier(audioDataFrom.meta.channels);
            mInPcmArray        = new WWUtil.LargeArray <double> [audioDataFrom.meta.channels];

            Callback(FILE_READ_COMPLETE_PERCENTAGE, new ProgressArgs(Properties.Resources.LogFileReadCompleted, 0));

            var fileFormat = WWAFUtil.FileNameToFileFormatType(toPath);

            rv = SetupResultPcm(audioDataFrom, aFilters, out audioDataTo, fileFormat, outputSampleFormat);
            if (rv < 0)
            {
                return(rv);
            }

            {
                // タグの編集
                var tagData = new TagData();
                tagData.Meta    = new WWFlacRWCS.Metadata(audioDataTo.meta);
                tagData.Picture = audioDataTo.picture;

                foreach (var f in aFilters)
                {
                    tagData = f.TagEdit(tagData);
                }

                audioDataTo.meta    = tagData.Meta;
                audioDataTo.picture = tagData.Picture;
            }

            //for (int ch=0; ch<audioDataFrom.meta.channels; ++ch) {
            Parallel.For(0, audioDataFrom.meta.channels, ch => {
                var filters = new List <FilterBase>();
                foreach (var f in aFilters)
                {
                    filters.Add(f.CreateCopy());
                }

                if (dither)
                {
                    // 最後にディザを加算。
                    FilterBase fb = FinalDither(outputSampleFormat);
                    if (fb != null)
                    {
                        filters.Add(fb);
                    }
                }

                var pRv = FilterSetup(audioDataFrom, ch, filters);
                if (null == pRv)
                {
                    rv = -1;
                    //break;
                    return;
                }

                var from = audioDataFrom.pcm[ch];
                var to   = audioDataTo.pcm[ch];
                rv       = ProcessAudioFile(filters, audioDataFrom.meta.channels, ch, ref from, ref to, Callback);
                if (rv < 0)
                {
                    //break;
                    return;
                }
                audioDataTo.pcm[ch] = to;

                if (audioDataTo.pcm[ch].mOverflow)
                {
                    var s = string.Format(CultureInfo.CurrentCulture, Properties.Resources.ErrorSampleValueClipped,
                                          ch, audioDataTo.pcm[ch].mMaxMagnitude);
                    Callback(-1, new ProgressArgs(s, 0));
                }

                filters = null;
            });

            if (rv < 0)
            {
                return(rv);
            }

            Callback(FILE_PROCESS_COMPLETE_PERCENTAGE, new ProgressArgs(string.Format(CultureInfo.CurrentCulture, Properties.Resources.LogfileWriteStarted, toPath), 0));

            switch (audioDataTo.preferredSaveFormat)
            {
            case WWAFUtil.FileFormatType.FLAC:
                rv = AudioDataIO.WriteFlacFile(ref audioDataTo, toPath);
                break;

            case WWAFUtil.FileFormatType.WAVE:
                rv = AudioDataIO.WriteWavFile(ref audioDataTo, toPath);
                break;

            case WWAFUtil.FileFormatType.DSF:
                try {
                    rv = AudioDataIO.WriteDsfFile(ref audioDataTo, toPath);
                } catch (Exception ex) {
                    Console.WriteLine(ex);
                }
                break;
            }

            return(rv);
        }
        private int SetupResultPcm(AudioData from, List <FilterBase> filters, out AudioData to,
                                   WWAFUtil.FileFormatType toFileFormat, WWAFUtil.AFSampleFormat toSampleFormat)
        {
            to = new AudioData();
            to.preferredSaveFormat = toFileFormat;

            var fmt = FilterSetup(from, 0, filters);

            if (null == fmt)
            {
                return(-1);
            }

            to.meta                     = new WWFlacRWCS.Metadata(from.meta);
            to.meta.sampleRate          = fmt.SampleRate;
            to.meta.totalSamples        = fmt.NumSamples;
            to.meta.channels            = fmt.NumChannels;
            to.writeValueRepresentation = PcmDataLib.PcmData.ValueRepresentationType.SInt;

            switch (toSampleFormat)
            {
            case WWAFUtil.AFSampleFormat.Auto:
                // auto selection.
                switch (toFileFormat)
                {
                case WWAFUtil.FileFormatType.FLAC:
                    to.meta.bitsPerSample = 24;
                    break;

                case WWAFUtil.FileFormatType.WAVE:
                    to.meta.bitsPerSample = 32;
                    break;

                case WWAFUtil.FileFormatType.DSF:
                    to.meta.bitsPerSample = 1;
                    break;
                }
                break;

            case WWAFUtil.AFSampleFormat.PcmInt16:
                to.meta.bitsPerSample = 16;
                break;

            case WWAFUtil.AFSampleFormat.PcmInt24:
                to.meta.bitsPerSample = 24;
                break;

            case WWAFUtil.AFSampleFormat.PcmInt32:
                to.meta.bitsPerSample = 32;
                break;

            case WWAFUtil.AFSampleFormat.PcmFloat32:
                to.meta.bitsPerSample       = 32;
                to.writeValueRepresentation = PcmDataLib.PcmData.ValueRepresentationType.SFloat;
                break;

            case WWAFUtil.AFSampleFormat.PcmInt64:
                to.meta.bitsPerSample = 64;
                break;

            case WWAFUtil.AFSampleFormat.PcmFloat64:
                to.meta.bitsPerSample       = 64;
                to.writeValueRepresentation = PcmDataLib.PcmData.ValueRepresentationType.SFloat;
                break;
            }

            if (from.picture != null)
            {
                to.picture = new byte[from.picture.Length];
                System.Array.Copy(from.picture, to.picture, to.picture.Length);
            }

            // allocate "to" pcm data
            to.pcm = new List <AudioDataPerChannel>();
            for (int ch = 0; ch < to.meta.channels; ++ch)
            {
                WWUtil.LargeArray <byte> data;

                // set silent sample values to output buffer
                switch (toFileFormat)
                {
                case WWAFUtil.FileFormatType.DSF:
                    data = new WWUtil.LargeArray <byte>((to.meta.totalSamples + 7) / 8);
                    for (long i = 0; i < data.LongLength; ++i)
                    {
                        data.Set(i, 0x69);
                    }
                    break;

                case WWAFUtil.FileFormatType.FLAC:
                    if (655350 < to.meta.sampleRate)
                    {
                        return((int)WWFlacRWCS.FlacErrorCode.InvalidSampleRate);
                    }
                    data = new WWUtil.LargeArray <byte>(to.meta.totalSamples * (to.meta.bitsPerSample / 8));
                    break;

                case WWAFUtil.FileFormatType.WAVE:
                    data = new WWUtil.LargeArray <byte>(to.meta.totalSamples * (to.meta.bitsPerSample / 8));
                    break;

                default:
                    System.Diagnostics.Debug.Assert(false);
                    data = null;
                    break;
                }

                var adp = new AudioDataPerChannel();
                adp.mDataFormat              = AudioDataPerChannel.DataFormat.Pcm;
                adp.mData                    = data;
                adp.mBitsPerSample           = to.meta.bitsPerSample;
                adp.mValueRepresentationType = to.writeValueRepresentation;
                adp.mTotalSamples            = to.meta.totalSamples;
                to.pcm.Add(adp);
            }
            return(0);
        }