private int GpuUpsample(USWorkerArgs args, PcmData pcmDataIn, PcmData pcmDataOut)
        {
            int hr = 0;

            int sampleTotalTo = (int)pcmDataOut.NumFrames;

            float[] sampleData = new float[pcmDataIn.NumFrames];
            for (int ch = 0; ch < pcmDataIn.NumChannels; ++ch) {
                for (int i = 0; i < pcmDataIn.NumFrames; ++i) {
                    sampleData[i] = pcmDataIn.GetSampleValueInFloat(ch, i);
                }

                WWUpsampleGpu us = new WWUpsampleGpu();
                if (args.addJitter) {
                    hr = us.Init(args.convolutionN, sampleData, (int)pcmDataIn.NumFrames, pcmDataIn.SampleRate,
                        args.resampleFrequency, sampleTotalTo, args.resamplePosArray, args.fractionArray);
                } else {
                    hr = us.Init(args.convolutionN, sampleData, (int)pcmDataIn.NumFrames, pcmDataIn.SampleRate,
                        args.resampleFrequency, sampleTotalTo);
                }
                if (hr < 0) {
                    us.Term();
                    return hr;
                }

                int sampleRemain = sampleTotalTo;
                int offs = 0;
                while (0 < sampleRemain) {
                    int sample1 = args.sampleSlice;
                    if (sampleRemain < sample1) {
                        sample1 = sampleRemain;
                    }
                    hr = us.ProcessPortion(offs, sample1);
                    if (hr < 0) {
                        break;
                    }
                    if (m_USAQworker.CancellationPending) {
                        us.Term();
                        return -1;
                    }

                    sampleRemain -= sample1;
                    offs += sample1;

                    // 10%~99%
                    m_USAQworker.ReportProgress(
                        10 + (int)(89L * offs / sampleTotalTo + 89L * ch) / pcmDataIn.NumChannels);
                }

                if (0 <= hr) {
                    float[] output = new float[sampleTotalTo];
                    hr = us.GetResultFromGpuMemory(ref output, sampleTotalTo);
                    if (0 <= hr) {
                        // すべて成功。
                        for (int i = 0; i < pcmDataOut.NumFrames; ++i) {
                            pcmDataOut.SetSampleValueInFloat(ch, i, output[i]);
                        }
                    }
                    output = null;
                }
                us.Term();

                if (hr < 0) {
                    break;
                }
            }
            sampleData = null;

            return hr;
        }
        ////////////////////////////////////////////////////////////////////
        // US AQ共用ワーカースレッド
        private int CpuUpsample(USWorkerArgs args, PcmData pcmDataIn, PcmData pcmDataOut)
        {
            int hr = 0;

            int sampleTotalTo = (int)pcmDataOut.NumFrames;

            float[] sampleData = new float[pcmDataIn.NumFrames];
            for (int ch = 0; ch < pcmDataIn.NumChannels; ++ch) {
                for (int i = 0; i < pcmDataIn.NumFrames; ++i) {
                    sampleData[i] = pcmDataIn.GetSampleValueInFloat(ch, i);
                }

                WWUpsampleCpu us = new WWUpsampleCpu();
                if (args.addJitter) {
                    hr = us.Setup(args.convolutionN, sampleData, sampleData.Length,
                        pcmDataIn.SampleRate, pcmDataOut.SampleRate, sampleTotalTo,
                        args.resamplePosArray, args.fractionArray);
                } else {
                    hr = us.Setup(args.convolutionN, sampleData, sampleData.Length,
                        pcmDataIn.SampleRate, pcmDataOut.SampleRate, sampleTotalTo);
                }
                if (hr < 0) {
                    break;
                }

                for (int offs = 0; offs < sampleTotalTo; offs += args.sampleSlice) {
                    int sample1 = args.sampleSlice;
                    if (sampleTotalTo - offs < sample1) {
                        sample1 = sampleTotalTo - offs;
                    }
                    if (sample1 < 1) {
                        break;
                    }

                    float[] outFragment = new float[sample1];
                    hr = us.Do(offs, sample1, outFragment);
                    if (hr < 0) {
                        // ここからbreakしても外のfor文までしか行かない
                        us.Unsetup();
                        sampleData = null;
                        break;
                    }
                    if (m_USAQworker.CancellationPending) {
                        // ここからbreakしても外のfor文までしか行かない
                        us.Unsetup();
                        sampleData = null;
                        hr = -1;
                        break;
                    }
                    if (0 <= hr) {
                        // 成功。出てきたデータをpcmDataOutに詰める。
                        for (int j = 0; j < sample1; ++j) {
                            pcmDataOut.SetSampleValueInFloat(ch, offs + j, outFragment[j]);
                        }
                    }
                    outFragment = null;

                    // 10%~99%
                    m_USAQworker.ReportProgress(
                        10 + (int)(89L * offs / sampleTotalTo + 89L * ch) / pcmDataIn.NumChannels);
                }

                if (m_USAQworker.CancellationPending) {
                    break;
                }
                if (hr < 0) {
                    break;
                }

                us.Unsetup();
            }

            sampleData = null;

            return hr;
        }