示例#1
0
        public PcmData MonoToStereo()
        {
            System.Diagnostics.Debug.Assert(NumChannels == 1);

            // サンプルあたりビット数が8の倍数でないとこのアルゴリズムは使えない
            System.Diagnostics.Debug.Assert((BitsPerSample & 7) == 0);

            var newSampleArray = new WWUtil.LargeArray <byte>(mSampleLargeArray.LongLength * 2);

            {
                int bytesPerSample = BitsPerSample / 8;

                // sampleArrayのフレーム数はこれよりも少ないことがある。
                // 実際に存在するサンプル数sampleFramesだけ処理する。
                long sampleFrames = mSampleLargeArray.LongLength / bytesPerSample; // NumChannels==1なので。
                long fromPosBytes = 0;
                for (long frame = 0; frame < sampleFrames; ++frame)
                {
                    for (int offs = 0; offs < bytesPerSample; ++offs)
                    {
                        byte b = mSampleLargeArray.At(fromPosBytes + offs);
                        newSampleArray.Set(fromPosBytes * 2 + offs, b);
                        newSampleArray.Set(fromPosBytes * 2 + bytesPerSample + offs, b);
                    }
                    fromPosBytes += bytesPerSample;
                }
            }
            PcmData newPcmData = new PcmData();

            newPcmData.CopyHeaderInfoFrom(this);
            newPcmData.SetFormat(2, BitsPerSample, ValidBitsPerSample, SampleRate, SampleValueRepresentationType, NumFrames);
            newPcmData.SetSampleLargeArray(newSampleArray);

            return(newPcmData);
        }
示例#2
0
        public PcmData ConvertChannelCount(int newCh)
        {
            if (NumChannels == newCh)
            {
                // 既に希望のチャンネル数である。
                return(this);
            }

            // サンプルあたりビット数が8の倍数でないとこのアルゴリズムは使えない
            System.Diagnostics.Debug.Assert((BitsPerSample & 7) == 0);

            // 新しいサンプルサイズ
            // NumFramesは総フレーム数。sampleArrayのフレーム数はこれよりも少ないことがある。
            // 実際に存在するサンプル数sampleFramesだけ処理する。
            int  bytesPerSample = BitsPerSample / 8;
            long sampleFrames   = mSampleLargeArray.LongLength / (BitsPerFrame / 8);
            var  newSampleArray = new WWUtil.LargeArray <byte>((long)newCh * bytesPerSample * sampleFrames);

            for (long frame = 0; frame < sampleFrames; ++frame)
            {
                int copyBytes = NumChannels * bytesPerSample;
                if (newCh < NumChannels)
                {
                    // チャンネル数が減る場合。
                    copyBytes = newCh * bytesPerSample;
                }

                newSampleArray.CopyFrom(mSampleLargeArray, (long)NumChannels * bytesPerSample * frame,
                                        (long)newCh * bytesPerSample * frame, copyBytes);

                if (SampleDataType == DataType.DoP &&
                    NumChannels < newCh)
                {
                    // 追加したチャンネルにDSD無音をセットする。
                    switch (bytesPerSample)
                    {
                    case 3:
                        for (int ch = NumChannels; ch < newCh; ++ch)
                        {
                            newSampleArray.Set((frame * newCh + ch) * bytesPerSample + 0, 0x69);
                            newSampleArray.Set((frame * newCh + ch) * bytesPerSample + 1, 0x69);
                            newSampleArray.Set((frame * newCh + ch) * bytesPerSample + 2, (byte)((frame & 1) == 1 ? 0xfa : 0x05));
                        }
                        break;

                    case 4:
                        for (int ch = NumChannels; ch < newCh; ++ch)
                        {
                            newSampleArray.Set((frame * newCh + ch) * bytesPerSample + 1, 0x69);
                            newSampleArray.Set((frame * newCh + ch) * bytesPerSample + 2, 0x69);
                            newSampleArray.Set((frame * newCh + ch) * bytesPerSample + 3, (byte)((frame & 1) == 1 ? 0xfa : 0x05));
                        }
                        break;
                    }
                }
            }

            PcmData newPcmData = new PcmData();

            newPcmData.CopyHeaderInfoFrom(this);
            newPcmData.SetFormat(newCh, BitsPerSample, ValidBitsPerSample, SampleRate, SampleValueRepresentationType, NumFrames);
            newPcmData.SetSampleLargeArray(newSampleArray);

            return(newPcmData);
        }
        public PcmData MonoToStereo()
        {
            System.Diagnostics.Debug.Assert(NumChannels == 1);

            // サンプルあたりビット数が8の倍数でないとこのアルゴリズムは使えない
            System.Diagnostics.Debug.Assert((BitsPerSample & 7) == 0);

            byte [] newSampleArray = new byte[mSampleArray.LongLength * 2];

            {
                int bytesPerSample = BitsPerSample / 8;

                // NumFramesは総フレーム数。sampleArrayのフレーム数はこれよりも少ないことがある。
                // 実際に存在するサンプル数sampleFramesだけ処理する。
                long sampleFrames = mSampleArray.LongLength / bytesPerSample;
                long fromPosBytes = 0;
                for (long frame = 0; frame < sampleFrames; ++frame) {
                    for (int offs = 0; offs < bytesPerSample; ++offs) {
                        newSampleArray[fromPosBytes * 2 + offs] = mSampleArray[fromPosBytes + offs];
                        newSampleArray[fromPosBytes * 2 + bytesPerSample + offs] = mSampleArray[fromPosBytes + offs];
                    }
                    fromPosBytes += bytesPerSample;
                }
            }
            PcmData newPcmData = new PcmData();
            newPcmData.CopyHeaderInfoFrom(this);
            newPcmData.SetFormat(2, BitsPerSample, ValidBitsPerSample, SampleRate, SampleValueRepresentationType, NumFrames);
            newPcmData.SetSampleArray(newSampleArray);

            return newPcmData;
        }
        /// <summary>
        /// Converts sample format to toFormat and returns new instance of PcmData.
        /// pcmFrom is not changed.
        /// </summary>
        /// <param name="toFormat">sample format to convert</param>
        /// <returns>Newly instanciated PcmData</returns>
        public PcmData Convert(PcmData pcmFrom, WasapiCS.SampleFormatType toFormat, BitsPerSampleConvArgs args)
        {
            if (args == null) {
                args = new BitsPerSampleConvArgs(NoiseShapingType.None);
            }

            var fromFormat = WasapiCS.BitAndFormatToSampleFormatType(pcmFrom.BitsPerSample, pcmFrom.ValidBitsPerSample,
                    SampleFormatInfo.VrtToBft(pcmFrom.SampleValueRepresentationType));

            if (fromFormat == WasapiCS.SampleFormatType.Unknown ||
                    toFormat == WasapiCS.SampleFormatType.Unknown) {
                return null;
            }

            var newSampleArray = mConvert[(int)fromFormat][(int)toFormat](pcmFrom, toFormat, args);

            PcmData newPcmData = new PcmData();
            newPcmData.CopyHeaderInfoFrom(pcmFrom);
            newPcmData.SetFormat(pcmFrom.NumChannels,
                    WasapiCS.SampleFormatTypeToUseBitsPerSample(toFormat),
                    WasapiCS.SampleFormatTypeToValidBitsPerSample(toFormat), pcmFrom.SampleRate,
                    SampleFormatInfo.BftToVrt(WasapiCS.SampleFormatTypeToBitFormatType(toFormat)), pcmFrom.NumFrames);
            newPcmData.SetSampleArray(newSampleArray);

            return newPcmData;
        }
示例#5
0
        public PcmData ConvertChannelCount(int newCh)
        {
            if (NumChannels == newCh) {
                // 既に希望のチャンネル数である。
                return this;
            }

            // サンプルあたりビット数が8の倍数でないとこのアルゴリズムは使えない
            System.Diagnostics.Debug.Assert((BitsPerSample & 7) == 0);

            // 新しいサンプルサイズ
            // NumFramesは総フレーム数。sampleArrayのフレーム数はこれよりも少ないことがある。
            // 実際に存在するサンプル数sampleFramesだけ処理する。
            int bytesPerSample = BitsPerSample / 8;
            long sampleFrames = mSampleArray.LongLength / (BitsPerFrame / 8);
            var newSampleArray = new byte[newCh * bytesPerSample * sampleFrames];

            for (long frame = 0; frame < sampleFrames; ++frame) {
                int copyBytes = NumChannels * bytesPerSample;
                if (newCh < NumChannels) {
                    // チャンネル数が減る場合。
                    copyBytes = newCh * bytesPerSample;
                }

                Array.Copy(mSampleArray, NumChannels * bytesPerSample * frame,
                    newSampleArray, newCh * bytesPerSample * frame,
                    copyBytes);
                if (SampleDataType == DataType.DoP
                        && NumChannels < newCh) {
                    // 追加したチャンネルにDSD無音をセットする。
                    switch (bytesPerSample) {
                    case 3:
                        for (int ch = NumChannels; ch < newCh; ++ch) {
                            newSampleArray[(frame * newCh + ch) * bytesPerSample + 0] = 0x69;
                            newSampleArray[(frame * newCh + ch) * bytesPerSample + 1] = 0x69;
                            newSampleArray[(frame * newCh + ch) * bytesPerSample + 2] = (byte)((frame & 1) == 1 ? 0xfa : 0x05);
                        }
                        break;
                    case 4:
                        for (int ch = NumChannels; ch < newCh; ++ch) {
                            newSampleArray[(frame * newCh + ch) * bytesPerSample + 1] = 0x69;
                            newSampleArray[(frame * newCh + ch) * bytesPerSample + 2] = 0x69;
                            newSampleArray[(frame * newCh + ch) * bytesPerSample + 3] = (byte)((frame & 1) == 1 ? 0xfa : 0x05);
                        }
                        break;
                    }
                }
            }

            PcmData newPcmData = new PcmData();
            newPcmData.CopyHeaderInfoFrom(this);
            newPcmData.SetFormat(newCh, BitsPerSample, ValidBitsPerSample, SampleRate, SampleValueRepresentationType, NumFrames);
            newPcmData.SetSampleArray(newSampleArray);

            return newPcmData;
        }