/// <summary>
        /// double型のLargeArrayを入力するバージョン。
        /// </summary>
        public void SetPcmInDouble(WWUtil.LargeArray <double> pcm, long toPos)
        {
            long fromPos = 0;

            long copyCount = pcm.LongLength;

            if (mTotalSamples < toPos + pcm.LongLength)
            {
                copyCount = mTotalSamples - toPos;
            }

            for (long remain = copyCount; 0 < remain;)
            {
                int fragmentCount = WWUtil.LargeArray <byte> .ARRAY_FRAGMENT_LENGTH_NUM;
                if (remain < fragmentCount)
                {
                    fragmentCount = (int)(remain);
                }

                var fragment = new double[fragmentCount];
                pcm.CopyTo(fromPos, ref fragment, 0, fragmentCount);
                SetPcmInDouble(fragment, toPos);
                fragment = null;

                fromPos += fragmentCount;
                toPos   += fragmentCount;
                remain  -= fragmentCount;
            }
        }
        public double[] GetPcmInDoubleSdm1bit(int count)
        {
            // サンプル数 / 8 == バイト数。

            System.Diagnostics.Debug.Assert(count % 8 == 0);
            System.Diagnostics.Debug.Assert(count <= WWUtil.LargeArray <byte> .ARRAY_FRAGMENT_LENGTH_NUM);

            var result = new double[count];

            int writePos = 0;

            if (mTotalSamples / 8 <= mOffsBytes || count == 0)
            {
                // 完全に範囲外の時。
            }
            else
            {
                int copySamples = count;
                if (mTotalSamples < mOffsBytes * 8 + copySamples)
                {
                    copySamples = (int)(mTotalSamples - mOffsBytes * 8);
                }

                var bitBuff = new byte[copySamples / 8];
                mData.CopyTo(mOffsBytes, ref bitBuff, 0, copySamples / 8);

                for (long i = 0; i < copySamples / 8; ++i)
                {
                    byte b = bitBuff[i];

                    // 1バイト内のビットの並びはMSBから古い順にデータが詰まっている。
                    for (int bit = 7; 0 <= bit; --bit)
                    {
                        result[writePos++] = ((b >> bit) & 1) == 1 ? 1.0 : -1.0;
                    }
                }

                mOffsBytes += copySamples / 8;
            }

            while (writePos < count)
            {
                byte b = 0x69; // DSD silence

                // 1バイト内のビットの並びはMSBから古い順にデータが詰まっている。
                for (int bit = 7; 0 <= bit; --bit)
                {
                    result[writePos++] = ((b >> bit) & 1) == 1 ? 1.0 : -1.0;
                }
            }

            return(result);
        }
        /// <summary>
        /// data chunk : total size 8 bytes + payload size
        /// </summary>
        public void DataChunkWrite(BinaryWriter bw, bool isDs64, WWUtil.LargeArray <byte> rawData)
        {
            var chunkId = new byte[4];

            chunkId[0] = (byte)'d';
            chunkId[1] = (byte)'a';
            chunkId[2] = (byte)'t';
            chunkId[3] = (byte)'a';
            bw.Write(chunkId);

            if (UInt32.MaxValue < rawData.LongLength && !isDs64)
            {
                throw new ArgumentException("large rawData. needs DS64");
                // RF64形式。別途ds64チャンクを用意して、そこにdata chunkのバイト数を入れる。
                // ChunkSize = UInt32.MaxValue;
            }

            uint chunkSize;

            if (isDs64)
            {
                chunkSize = UInt32.MaxValue;
            }
            else
            {
                chunkSize = (uint)rawData.LongLength;
            }

            bw.Write(chunkSize);

            int fragmentLength = 1048576;

            for (long pos = 0; pos < rawData.LongLength; pos += fragmentLength)
            {
                int count = fragmentLength;
                if (rawData.LongLength - pos < count)
                {
                    count = (int)(rawData.LongLength - pos);
                }
                var buff = new byte[count];
                rawData.CopyTo(pos, ref buff, 0, count);
                bw.Write(buff);
            }

            AddPadIfNecessary(bw, rawData.LongLength);
        }
Example #4
0
        /// <summary>
        /// サンプル値取得。フォーマットがなんであっても使用可能。
        /// </summary>
        /// <param name="ch">チャンネル番号</param>
        /// <param name="pos">サンプル番号</param>
        /// <returns>サンプル値。-1.0~+1.0位</returns>
        public double GetSampleValueInDouble(int ch, long pos)
        {
            Debug.Assert(0 <= ch && ch < NumChannels);

            if (pos < 0 || NumFrames <= pos)
            {
                return(0.0);
            }

            long offset = pos * BitsPerFrame / 8 + ch * BitsPerSample / 8;

            var data = new byte[BitsPerSample / 8];

            mSampleLargeArray.CopyTo(offset, ref data, 0, BitsPerSample / 8);

            switch (BitsPerSample)
            {
            case 16:
                data = ConvI16toF64(data);
                break;

            case 24:
                data = ConvI24toF64(data);
                break;

            case 32:
                switch (SampleValueRepresentationType)
                {
                case ValueRepresentationType.SInt:
                    data = ConvI32toF64(data);
                    break;

                case ValueRepresentationType.SFloat:
                    data = ConvF32toF64(data);
                    break;

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

            case 64:
                switch (SampleValueRepresentationType)
                {
                case ValueRepresentationType.SInt:
                    data = ConvI64toF64(data);
                    break;

                case ValueRepresentationType.SFloat:
                    data = ConvF64toF64(data);
                    break;

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

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

            return(BitConverter.ToDouble(data, 0));
        }