private void m_USAQworker_DoWork(object sender, DoWorkEventArgs e)
        {
            // System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.Lowest;

            USWorkerArgs args = (USWorkerArgs)e.Argument;

            PcmData pcmDataIn = ReadWavFile(args.inputPath);
            if (null == pcmDataIn) {
                e.Result = string.Format("WAVファイル 読み込み失敗: {0}", args.inputPath);
                return;
            }

            // ファイル読み込み完了。
            if (args.addJitter) {
                // ジッター負荷の場合、サンプリング周波数は変更しない。
                args.resampleFrequency = pcmDataIn.SampleRate;
            }

            if (args.resampleFrequency < pcmDataIn.SampleRate) {
                e.Result = string.Format("エラー: ダウンサンプルは対応していません {0} from={1} to={2}",
                    args.inputPath, pcmDataIn.SampleRate, args.resampleFrequency);
                return;
            }
            if (0x7fff0000L < pcmDataIn.NumFrames * 4 * pcmDataIn.NumChannels * args.resampleFrequency / pcmDataIn.SampleRate) {
                e.Result = string.Format("エラー: リサンプル後のファイルサイズが2GBを超えそうなので中断しました {0}",
                    args.inputPath);
                return;
            }

            m_USAQworker.ReportProgress(1);

            var conv = new WasapiPcmUtil.PcmFormatConverter(pcmDataIn.NumChannels);
            pcmDataIn = conv.Convert(pcmDataIn, WasapiCS.BitAndFormatToSampleFormatType(32, 32, WasapiCS.BitFormatType.SFloat), null);
            PcmData pcmDataOut = new PcmData();
            pcmDataOut.CopyFrom(pcmDataIn);
            int sampleTotalTo = (int)(args.resampleFrequency * pcmDataIn.NumFrames / pcmDataIn.SampleRate);
            {   // PcmDataOutのサンプルレートとサンプル数を更新する。
                byte[] outSampleArray = new byte[(long)sampleTotalTo * pcmDataOut.NumChannels * 4];
                pcmDataOut.SetSampleArray(sampleTotalTo, outSampleArray);
                pcmDataOut.SampleRate = args.resampleFrequency;
                outSampleArray = null;
            }

            // 再サンプルテーブル作成
            args.resamplePosArray = null;
            args.fractionArray = null;
            if (args.addJitter) {
                // ジッター付加の場合、サンプルレートは変更しない。
                args.resamplePosArray = new int[pcmDataIn.NumFrames];
                args.fractionArray = new double[pcmDataIn.NumFrames];
                /*
                 sampleRate        == 96000 Hz
                 jitterFrequency   == 50 Hz
                 jitterPicoseconds == 1 ps の場合

                 サンプル位置posのθ= 2 * PI * pos * 50 / 96000 (ラジアン)

                 サンプル間隔= 1/96000秒 = 10.4 μs

                 1ms = 10^-3秒
                 1μs= 10^-6秒
                 1ns = 10^-9秒
                 1ps = 10^-12秒

                  1psのずれ                     x サンプルのずれ
                 ───────────── = ─────────
                  10.4 μs(1/96000)sのずれ      1 サンプルのずれ

                 1psのサンプルずれA = 10^-12 ÷ (1/96000) (サンプルのずれ)

                 サンプルを採取する位置= pos + Asin(θ)

                 */

                args.thetaCoefficientSeqJitter = 2.0 * Math.PI * args.sequentialJitterFrequency / pcmDataIn.SampleRate;
                args.ampSeqJitter = 1.0e-12 * pcmDataIn.SampleRate * args.sequentialJitterPicoseconds;
                args.ampTpdfJitter = 1.0e-12 * pcmDataIn.SampleRate * args.tpdfJitterPicoseconds;
                args.ampRpdfJitter = 1.0e-12 * pcmDataIn.SampleRate * args.rpdfJitterPicoseconds;

                PrepareResamplePosArray(
                    args, pcmDataIn.SampleRate, pcmDataOut.SampleRate,
                    (int)pcmDataIn.NumFrames, sampleTotalTo,
                    args.resamplePosArray, args.fractionArray);
            }

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            int hr = 0;
            if (args.device == ProcessDevice.Gpu) {
                hr = GpuUpsample(args, pcmDataIn, pcmDataOut);
            } else {
                hr = CpuUpsample(args, pcmDataIn, pcmDataOut);
            }

            // args.resamplePosArrayは中でコピーされるのでここで不要になる。
            args.resamplePosArray = null;
            args.fractionArray = null;

            if (m_USAQworker.CancellationPending) {
                e.Result = string.Format("キャンセル完了。");
                e.Cancel = true;
                return;
            }
            if (hr < 0) {
                e.Result = string.Format("Upsample エラー 0x{0:X8}", hr);
                return;
            }
            sw.Stop();

            // 成功した。レベル制限する。
            float scale = pcmDataOut.LimitLevelOnFloatRange();

            if (args.outputVRT != PcmData.ValueRepresentationType.SFloat) {
                // ビットフォーマット変更。
                var formatConv = new WasapiPcmUtil.PcmFormatConverter(pcmDataOut.NumChannels);
                pcmDataOut = formatConv.Convert(pcmDataOut,
                        WasapiCS.BitAndFormatToSampleFormatType(args.outputBitsPerSample, args.outputBitsPerSample, (WasapiCS.BitFormatType)args.outputVRT), null);
            }

            try {
                WriteWavFile(pcmDataOut, args.outputPath);
            } catch (IOException ex) {
                // 書き込みエラー。
                e.Result = ex.ToString();
                return;
            }

            e.Result = string.Format("書き込み成功。処理時間 {0}秒\r\n",
                sw.ElapsedMilliseconds * 0.001);
            if (scale < 1.0f) {
                e.Result = string.Format("書き込み成功。処理時間 {0}秒。" +
                    "レベルオーバーのため音量調整{1}dB({2}倍)しました。\r\n",
                    sw.ElapsedMilliseconds * 0.001,
                    20.0 * Math.Log10(scale), scale);
            }
            m_USAQworker.ReportProgress(100);
        }