Esempio n. 1
0
 public int DecodeStreamStart(string path)
 {
     mDecodedMetadata = null;
     mPcmAllBuffer    = null;
     mId = NativeMethods.WWFlacRW_Decode(NativeMethods.WWFLAC_FRDT_STREAM_ONE, path);
     return(mId);
 }
        public LargeArray <WWComplex> InverseFft(LargeArray <WWComplex> aFrom,
                                                 double?compensation = null)
        {
            for (int i = 0; i < aFrom.LongLength; ++i)
            {
                var t = new WWComplex(aFrom.At(i).real, -aFrom.At(i).imaginary);
                aFrom.Set(i, t);
            }

            var aTo = ForwardFft(aFrom);

            double c = 1.0 / mNumPoints;

            if (compensation != null)
            {
                c = (double)compensation;
            }

            for (int i = 0; i < aTo.LongLength; ++i)
            {
                var t = new WWComplex(aTo.At(i).real *c, -aTo.At(i).imaginary *c);
                aTo.Set(i, t);
            }

            return(aTo);
        }
Esempio n. 3
0
        /// <summary>
        /// ヘッダと全PCMデータを抽出する。
        /// この関数呼び出し後
        /// ・GetDecodedMetadata()でメタデータを取り出す。
        /// ・GetDecodedCuesheet()でキューシートを取り出す。
        /// ・GetDecodedPicture()でアルバムカバー画像を取り出す。
        /// ・GetDecodedPcmBytes()でPCMデータを取り出す。
        /// ・DecodeEnd()で後片付けする。
        ///
        /// DecodeAll()が中で呼んでいる関数を個別に呼び出しても良い。
        /// </summary>
        /// <param name="path">FLACのファイル名</param>
        /// <returns>0以上のとき成功。負のときFlacErrorCode</returns>
        public int DecodeAll(string path)
        {
            int rv = 0;

            rv = DecodeStreamStart(path);
            if (rv < 0)
            {
                return(rv);
            }

            rv = GetDecodedMetadata(out mDecodedMetadata);
            if (rv < 0)
            {
                return(rv);
            }

            mPcmAllBuffer = new LargeArray <byte>(mDecodedMetadata.PcmBytes);
            long pos = 0;

            while (pos < mDecodedMetadata.PcmBytes)
            {
                byte[] fragment;
                rv = DecodeStreamOne(out fragment);
                if (rv < 0)
                {
                    return(rv);
                }
                mPcmAllBuffer.CopyFrom(fragment, 0, pos, fragment.Length);
                pos += fragment.Length;
            }

            // mPcmAllBufferから取り出す。

            return(0);
        }
Esempio n. 4
0
 /// <summary>
 /// FLACファイルのヘッダー部分を読み込んでメタデータを取り出す。
 /// この関数呼び出し後
 /// ・GetDecodedMetadata()でメタデータを取り出す。
 /// ・GetDecodedCuesheet()でキューシートを取り出す。
 /// ・GetDecodedPicture()でアルバムカバー画像を取り出す。
 /// </summary>
 /// <param name="path">FLACファイルのパス</param>
 /// <returns>0以上のとき成功。負のときFlacErrorCode</returns>
 public int DecodeHeader(string path)
 {
     mDecodedMetadata = null;
     mPcmAllBuffer    = null;
     mId = NativeMethods.WWFlacRW_Decode(NativeMethods.WWFLAC_FRDT_HEADER, path);
     return(mId);
 }
        public WWRadix2FftLargeArray(long numPoints)
        {
            if (!Functions.IsPowerOfTwo(numPoints) || numPoints < 2)
            {
                throw new ArgumentException("numPoints must be power of two integer and larger than 2");
            }
            mNumPoints = numPoints;

            mWn = new LargeArray <WWComplex>(mNumPoints);
            for (long i = 0; i < mNumPoints; ++i)
            {
                double angle = -2.0 * Math.PI * i / mNumPoints;
                mWn.Set(i, new WWComplex(Math.Cos(angle), Math.Sin(angle)));
            }

            // mNumStage == log_2(mNumPoints)
            long t = mNumPoints;

            for (int i = 0; 0 < t; ++i)
            {
                t       >>= 1;
                mNumStage = i;
            }

            mBitReversalTable = new LargeArray <ulong>(mNumPoints);
            for (long i = 0; i < mNumPoints; ++i)
            {
                mBitReversalTable.Set(i, BitReversal(mNumStage, (ulong)i));
            }
        }
        public LargeArray <WWComplex> ForwardFft(LargeArray <WWComplex> aFrom)
        {
            if (aFrom == null || aFrom.LongLength != mNumPoints)
            {
                throw new ArgumentOutOfRangeException("aFrom");
            }
            var aTo = new LargeArray <WWComplex>(aFrom.LongLength);

            var aTmp0 = new LargeArray <WWComplex>(mNumPoints);

            for (int i = 0; i < aTmp0.LongLength; ++i)
            {
                aTmp0.Set(i, aFrom.At((long)mBitReversalTable.At(i)));
            }
            var aTmp1 = new LargeArray <WWComplex>(mNumPoints);

            for (int i = 0; i < aTmp1.LongLength; ++i)
            {
                aTmp1.Set(i, WWComplex.Zero());
            }

            var aTmps = new LargeArray <WWComplex> [2];

            aTmps[0] = aTmp0;
            aTmps[1] = aTmp1;

            for (int i = 0; i < mNumStage - 1; ++i)
            {
                FftStageN(i, aTmps[((i & 1) == 1) ? 1 : 0], aTmps[((i & 1) == 0) ? 1 : 0]);
            }
            FftStageN(mNumStage - 1, aTmps[(((mNumStage - 1) & 1) == 1) ? 1 : 0], aTo);

            return(aTo);
        }
        public void Chunks()
        {
            var source = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };

            var actuals = LargeArray.Chunk(source, 4).ToList();

            Assert.Equal(4, actuals.Count);
            Assert.Equal(4, actuals[0].Length);
            Assert.Equal(4, actuals[1].Length);
            Assert.Equal(4, actuals[2].Length);
            Assert.Equal(2, actuals[3].Length);

            Assert.Equal(1, actuals[0][0]);
            Assert.Equal(2, actuals[0][1]);
            Assert.Equal(3, actuals[0][2]);
            Assert.Equal(4, actuals[0][3]);

            Assert.Equal(5, actuals[1][0]);
            Assert.Equal(6, actuals[1][1]);
            Assert.Equal(7, actuals[1][2]);
            Assert.Equal(8, actuals[1][3]);

            Assert.Equal(9, actuals[2][0]);
            Assert.Equal(10, actuals[2][1]);
            Assert.Equal(11, actuals[2][2]);
            Assert.Equal(12, actuals[2][3]);

            Assert.Equal(13, actuals[3][0]);
            Assert.Equal(14, actuals[3][1]);
        }
Esempio n. 8
0
        public int AddPcm(int ch, LargeArray <byte> pcmW)
        {
            int rv;

            rv = mFlacW.EncodeAddPcm(ch, pcmW);
            return(rv);
        }
Esempio n. 9
0
        /// <summary>
        /// dataにcoeffsを畳み込む。
        /// </summary>
        public LargeArray <float> Convolution(LargeArray <float> data, float[] coeffs)
        {
            mMaxMagnitude = 0;

            var r = new LargeArray <float>(data.LongLength);

            // rIdx: 出力サンプル列rの書き込みidx。1づつ増える。
            for (long rIdx = 0; rIdx < data.LongLength; ++rIdx)
            {
                // v: 畳み込み結果。
                float v = 0;

                // dIdx: dataの読み出し要素番号。
                long dIdx = rIdx - coeffs.Length / 2;

                // cIdx: coeffsの読み出し要素番号。1づつ減る。
                for (int cIdx = coeffs.Length - 1; 0 <= cIdx; --cIdx)
                {
                    // dataの範囲外を読まないようにする。
                    if (0 <= dIdx && dIdx < data.LongLength)
                    {
                        v += data.At(dIdx++) * coeffs[cIdx];
                    }
                }

                if (mMaxMagnitude < Math.Abs(v))
                {
                    mMaxMagnitude = v;
                }

                r.Set(rIdx, v);
            }

            return(r);
        }
Esempio n. 10
0
        public static int ReadHeaderAndData(
            string sourceFile,
            out Metadata meta_return,
            out LargeArray <byte> data)
        {
            int hr = 0;

            data = new LargeArray <byte>(0);

            hr = ReadHeader(sourceFile, out meta_return);
            if (hr < 0)
            {
                return(hr);
            }

            // データのバイト数はこの時点で不明。
            // 全て読んでから数える。

            hr = NativeMethods.WWMFReaderIFReadDataStart(sourceFile);
            if (hr < 0)
            {
                return(hr);
            }

            int instanceId = hr;

            long bufTotalBytes = 0;
            var  buf           = new byte[1024 * 1024];
            var  bufList       = new List <byte[]>();

            while (true)
            {
                long bufBytes = buf.Length;
                hr = NativeMethods.WWMFReaderIFReadDataFragment(instanceId, buf, ref bufBytes);
                if (hr < 0)
                {
                    break;
                }

                if (bufBytes == 0)
                {
                    break;
                }

                var bufTrim = new byte[bufBytes];
                Array.Copy(buf, 0, bufTrim, 0, bufBytes);
                bufList.Add(bufTrim);
                bufTotalBytes += bufBytes;
            }

            NativeMethods.WWMFReaderIFReadDataEnd(instanceId);

            // データのバイト数が確定。
            data = WWUtil.ListUtils <byte> .GetLargeArrayFragment(bufList, 0, bufTotalBytes);

            meta_return.numExactFrames = data.LongLength / (meta_return.numChannels * meta_return.bitsPerSample / 8);

            return(hr);
        }
Esempio n. 11
0
        /// <summary>
        /// 指定チャンネルのPCMデータを取得。
        /// </summary>
        /// <param name="ch">チャンネル番号 0から始まる。</param>
        /// <param name="posSamples">取得開始サンプル番号。</param>
        /// <param name="copySamples">取得するサンプル数。</param>
        /// <returns>float型のPCMデータ。-1 ≦ v < +1</returns>
        public LargeArray <float> GetFloatPcmOfChannel(int ch, long posSamples, long copySamples)
        {
            System.Diagnostics.Debug.Assert(mDecodedMetadata != null);
            System.Diagnostics.Debug.Assert(mPcmAllBuffer != null);
            System.Diagnostics.Debug.Assert(0 <= ch && ch < mDecodedMetadata.channels);

            int bpf = mDecodedMetadata.BytesPerFrame;
            int bps = mDecodedMetadata.BytesPerSample;

            // copySamplesを決定します。
            long totalSamples = mPcmAllBuffer.LongLength / bpf;

            if (totalSamples < posSamples + copySamples)
            {
                copySamples = (int)(totalSamples - posSamples);
            }
            if (copySamples < 0)
            {
                copySamples = 0;
            }

            var  samples = new LargeArray <float>(copySamples);
            long toIdx   = 0;

            switch (bps)
            {
            case 2:
                for (long pos = posSamples; pos < posSamples + copySamples; ++pos)
                {
                    long  idx = bpf * pos + ch * bps;
                    short vS  = (short)(mPcmAllBuffer.At(idx) + (mPcmAllBuffer.At(idx + 1) << 8));
                    float vF  = vS / 32768.0f;
                    samples.Set(toIdx++, vF);
                    //Console.WriteLine("{0:+00000;-00000}", vS);
                }
                break;

            case 3:
                for (long pos = posSamples; pos < posSamples + copySamples; ++pos)
                {
                    long idx = bpf * pos + ch * bps;
                    int  vI  = (int)((mPcmAllBuffer.At(idx + 0) << 8)
                                     + (mPcmAllBuffer.At(idx + 1) << 16)
                                     + (mPcmAllBuffer.At(idx + 2) << 24));

                    //Console.WriteLine("{0:+00000000;-00000000}", vI);

                    float vF = vI / 2147483648.0f;
                    samples.Set(toIdx++, vF);
                }
                break;

            default:
                throw new ArgumentException(string.Format("Unexpected BytesPerSample {0}", bps));
            }

            return(samples);
        }
Esempio n. 12
0
        public void DecodeEnd()
        {
            NativeMethods.WWFlacRW_DecodeEnd(mId);

            mDecodedMetadata = null;
            mPcmAllBuffer    = null;

            mId = (int)FlacErrorCode.IdNotFound;
        }
Esempio n. 13
0
            /// <summary>
            /// PCMデータを無加工で読み出す。
            /// </summary>
            /// <param name="startFrame">0を指定すると最初から。</param>
            /// <param name="endFrame">負の値を指定するとファイルの最後まで。</param>
            /// <returns>false: ファイルの読み込みエラーなど</returns>
            public bool ReadDataChunkData(BinaryReader br, int numChannels, int bitsPerSample,
                                          long startFrame, long endFrame)
            {
                br.BaseStream.Seek(Offset, SeekOrigin.Begin);

                // endBytesがファイルの終わり指定(負の値)の場合の具体的位置を設定する。
                // startBytesとendBytesがファイルの終わり以降を指していたら修正する。
                // ・endBytesがファイルの終わり以降…ファイルの終わりを指す。
                // ・startBytesがファイルの終わり以降…サイズ0バイトのWAVファイルにする。

                int  frameBytes = bitsPerSample / 8 * numChannels;
                long startBytes = startFrame * frameBytes;
                long endBytes   = endFrame * frameBytes;

                System.Diagnostics.Debug.Assert(0 <= startBytes);

                if (endBytes < 0 ||
                    (NumFrames * frameBytes) < endBytes)
                {
                    // 終了位置はファイルの終わり。
                    endBytes = NumFrames * frameBytes;
                }

                long newNumFrames = (endBytes - startBytes) / frameBytes;

                if (newNumFrames <= 0 ||
                    NumFrames * frameBytes <= startBytes ||
                    endBytes <= startBytes)
                {
                    // サイズが0バイトのWAV。
                    mRawData  = null;
                    NumFrames = 0;
                    return(true);
                }

                if (0 < startBytes)
                {
                    PcmDataLib.PcmDataUtil.BinaryReaderSkip(br, startBytes);
                }

                mRawData = new LargeArray <byte>(newNumFrames * frameBytes);
                int fragmentBytes = 1048576;

                for (long pos = 0; pos < mRawData.LongLength; pos += fragmentBytes)
                {
                    int bytes = fragmentBytes;
                    if (mRawData.LongLength - pos < bytes)
                    {
                        bytes = (int)(mRawData.LongLength - pos);
                    }
                    var buff = br.ReadBytes(bytes);
                    mRawData.CopyFrom(buff, 0, pos, bytes);
                }
                NumFrames = newNumFrames;
                return(true);
            }
Esempio n. 14
0
            public SampleData1ch(long size)
            {
                sdmData = new LargeArray <byte>(size);
                pos     = 0;

                // 念のため無音をセットする。
                for (long i = 0; i < size; ++i)
                {
                    sdmData.Set(i, 0x69);
                }
            }
Esempio n. 15
0
        private float[] PrepareSampleDataForFFT(LargeArray <float> from, long fromPos, float[] w)
        {
            var r = new float[w.Length];

            for (int i = 0; i < r.Length; ++i)
            {
                float v = from.At(fromPos + i);
                r[i] = v * w[i];
            }

            return(r);
        }
Esempio n. 16
0
        private static void Main(string[] args)
        {
            //var summary = BenchmarkRunner.Run<PEFileMagic>();
            #if RELEASE
            var summary = BenchmarkRunner.Run <LargeArray>();
            #else
            var la = new LargeArray {
                size = 1
            };

            la.TraditionalTest();
            #endif
        }
Esempio n. 17
0
        public bool AllocateCaptureMemory(long bytes)
        {
            try {
                mCapturedPcmData = null;
                mCapturedPcmData = new LargeArray <byte>(bytes);
            } catch (Exception ex) {
                Console.WriteLine(ex);
                return(false);
            }

            mNextWritePos = 0;
            return(true);
        }
        public void Combines()
        {
            var source = new[]
            {
                new byte[] { 1, 2, 3, 4 },
                new byte[] { 5, 6, 7, 8 },
                new byte[] { 9, 10 },
            };

            var expected = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            var actual = LargeArray.Combine(source);

            Assert.Equal(expected, actual);
        }
Esempio n. 19
0
        private LargeArray <float> StereoToMono(LargeArray <byte> v)
        {
            var m = new LargeArray <float>(v.LongLength / 4);

            for (long i = 0; i < v.LongLength / 4; ++i)
            {
                short l = (short)((int)v.At(i * 4 + 0) + 256 * v.At(i * 4 + 1));
                short r = (short)((int)v.At(i * 4 + 2) + 256 * v.At(i * 4 + 3));

                short mix = (short)((l + r) / 2);
                m.Set(i, mix / 32768.0f);
            }

            return(m);
        }
Esempio n. 20
0
        //[Test]
        //public unsafe void TestLargeUnmanagedArray()
        //{
        //    Assert.AreEqual(Globals.MemoryPool.AllocatedBytes, 0);
        //    using (LargeUnmanagedArray<int> array = new LargeUnmanagedArray<int>(4, Globals.MemoryPool, ptr => *(int*)ptr, (ptr, v) => *(int*)ptr = v))
        //    {
        //        TestArray(array);
        //    }
        //    Assert.AreEqual(Globals.MemoryPool.AllocatedBytes, 0);
        //}

        public void TestArray(LargeArray <int> array)
        {
            for (int x = 0; x < 250000; x++)
            {
                if (x >= array.Capacity)
                {
                    HelperFunctions.ExpectError(() => array[x] = x);
                    array.SetCapacity(array.Capacity + 1);
                }
                array[x] = x;
            }

            for (int x = 0; x < 250000; x++)
            {
                Assert.AreEqual(array[x], x);
            }
        }
        //[Test]
        //public unsafe void TestLargeUnmanagedArray()
        //{
        //    Assert.AreEqual(Globals.MemoryPool.AllocatedBytes, 0);
        //    using (LargeUnmanagedArray<int> array = new LargeUnmanagedArray<int>(4, Globals.MemoryPool, ptr => *(int*)ptr, (ptr, v) => *(int*)ptr = v))
        //    {
        //        TestArray(array);
        //    }
        //    Assert.AreEqual(Globals.MemoryPool.AllocatedBytes, 0);
        //}

        public void TestArray(LargeArray<int> array)
        {
            for (int x = 0; x < 250000; x++)
            {
                if (x >= array.Capacity)
                {
                    HelperFunctions.ExpectError(() => array[x] = x);
                    array.SetCapacity(array.Capacity + 1);
                }
                array[x] = x;
            }

            for (int x = 0; x < 250000; x++)
            {
                Assert.AreEqual(array[x], x);
            }
        }
Esempio n. 22
0
        private LargeArray <byte> CreatePcmSamples(double[] mls, WasapiCS.SampleFormatType sft, int numCh, int playCh)
        {
            int  sampleBytes = (WasapiCS.SampleFormatTypeToUseBitsPerSample(sft) / 8);
            int  frameBytes  = sampleBytes * numCh;
            long bytes       = (long)mls.Length * frameBytes;
            var  r           = new LargeArray <byte>(bytes);

            long writePos = 0;

            for (long i = 0; i < mls.Length; ++i)
            {
                for (int ch = 0; ch < numCh; ++ch)
                {
                    if (ch != playCh)
                    {
                        for (int c = 0; c < sampleBytes; ++c)
                        {
                            r.Set(writePos++, 0);
                        }
                    }
                    else
                    {
                        int v = 0x7fffffff;

                        // -6dBする。
                        v /= 2;

                        if (mls[i] < 0)
                        {
                            v = -v;
                        }

                        uint uV = (uint)v;

                        for (int c = 0; c < sampleBytes; ++c)
                        {
                            byte b = (byte)(uV >> (8 * (4 - sampleBytes + c)));
                            r.Set(writePos++, b);
                        }
                    }
                }
            }
            return(r);
        }
Esempio n. 23
0
            /// <summary>
            /// dataチャンクのヘッダ部分だけを読む。
            /// 4バイトしか進まない。
            /// </summary>
            public long ReadDataChunkHeader(BinaryReader br, long offset, byte[] fourcc, int numChannels, int bitsPerSample)
            {
                if (!PcmDataLib.PcmDataUtil.FourCCHeaderIs(fourcc, 0, "data"))
                {
                    System.Diagnostics.Debug.Assert(false);
                    return(0);
                }

                ChunkSize = br.ReadUInt32();

                Offset = offset + 4;

                int frameBytes = bitsPerSample / 8 * numChannels;

                NumFrames = ChunkSize / frameBytes;

                mRawData = null;
                return(4);
            }
Esempio n. 24
0
        public static LargeArray <double> BlackmanWindow(long length)
        {
            // nは奇数
            System.Diagnostics.Debug.Assert((length & 1) == 1);

            var window = new LargeArray <double>(length);

            // 教科書通りに計算すると両端の値が0.0になって
            // せっかくのデータが0にされて勿体無いので両端(pos==0とpos==length-1)の値はカットし、両端を1ずつ広げる
            long m = length + 1;

            for (long i = 0; i < length; ++i)
            {
                long   pos = i + 1;
                double v   = 0.42 - 0.5 * Math.Cos(2.0 * Math.PI * pos / m) + 0.08 * Math.Cos(4.0 * Math.PI * pos / m);
                window.Set(i, v);
            }

            return(window);
        }
Esempio n. 25
0
        private void PreparePcmData(StartTestingArgs args)
        {
            mMLSDecon = new MLSDeconvolution(args.order);
            var seq = mMLSDecon.MLSSequence();

            var sampleData = CreatePcmSamples(seq, mPref.PlaySampleFormat, args.numChannels, args.testChannel);

            // mPcmPlay : テストデータ。このPCMデータを再生し、インパルス応答特性を調べる。
            mPcmPlay = new PcmDataLib.PcmData();
            mPcmPlay.SetFormat(args.numChannels,
                               WasapiCS.SampleFormatTypeToUseBitsPerSample(mPref.PlaySampleFormat),
                               WasapiCS.SampleFormatTypeToValidBitsPerSample(mPref.PlaySampleFormat),
                               mPref.SampleRate,
                               PcmDataLib.PcmData.ValueRepresentationType.SInt, seq.Length);
            mPcmPlay.SetSampleLargeArray(sampleData);

            // 録音データ置き場。Maximum Length Seqneuceのサイズよりも1サンプル多くしておく。
            int recBytesPerSample = WasapiCS.SampleFormatTypeToUseBitsPerSample(mPref.RecSampleFormat) / 8;

            mCapturedPcmData = new LargeArray <byte>((long)recBytesPerSample * args.numChannels * (seq.Length + 1));
        }
Esempio n. 26
0
        private void LoadPcm_DoWork(object sender, DoWorkEventArgs e)
        {
            string path = (string)e.Argument;
            var    r    = new LoadPcmResult();

            r.path    = path;
            r.result  = false;
            r.pcmData = null;

            mPlayPcmData = null;
            try {
                using (var br = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))) {
                    var reader = new WavRWLib2.WavReader();
                    if (reader.ReadHeaderAndSamples(br, 0, -1) &&
                        reader.NumChannels == NUM_CHANNELS)
                    {
                        var b = reader.GetSampleLargeArray();
                        r.pcmData = new PcmDataLib.PcmData();
                        r.pcmData.SetFormat(NUM_CHANNELS, reader.BitsPerSample, reader.ValidBitsPerSample,
                                            reader.SampleRate, reader.SampleValueRepresentationType, reader.NumFrames);
                        r.pcmData.SetSampleLargeArray(b);
                    }
                }
            } catch (Exception ex) {
                Console.WriteLine(ex);
                r.pcmData = null;
            }

            if (r.pcmData == null)
            {
                try {
                    var flacRW = new WWFlacRWCS.FlacRW();
                    int rv     = flacRW.DecodeAll(r.path);
                    if (0 <= rv)
                    {
                        WWFlacRWCS.Metadata metaData;
                        flacRW.GetDecodedMetadata(out metaData);
                        if (metaData.channels == NUM_CHANNELS)
                        {
                            var pcmBytes = new LargeArray <byte>(metaData.PcmBytes);

                            int bytesPerSample = metaData.bitsPerSample / 8;
                            var fragment       = new byte[bytesPerSample];
                            for (long pos = 0; pos < metaData.totalSamples; ++pos)
                            {
                                for (int ch = 0; ch < NUM_CHANNELS; ++ch)
                                {
                                    flacRW.GetDecodedPcmBytes(ch, pos * bytesPerSample, out fragment, bytesPerSample);
                                    pcmBytes.CopyFrom(fragment, 0, (long)bytesPerSample * (NUM_CHANNELS * pos + ch), bytesPerSample);
                                }
                            }

                            r.pcmData = new PcmDataLib.PcmData();
                            r.pcmData.SetFormat(NUM_CHANNELS, metaData.bitsPerSample, metaData.bitsPerSample,
                                                metaData.sampleRate, PcmDataLib.PcmData.ValueRepresentationType.SInt, metaData.totalSamples);
                            r.pcmData.SetSampleLargeArray(pcmBytes);
                        }
                    }
                    flacRW.DecodeEnd();
                } catch (Exception ex) {
                    Console.WriteLine(ex);
                    r.pcmData = null;
                }
            }

            if (r.pcmData != null)
            {
                r.result = true;
            }
            else
            {
                r.result = false;
            }

            e.Result = r;
        }
        private void FftStageN(int stageNr, LargeArray <WWComplex> x, LargeArray <WWComplex> y)
        {
            /*
             * stage0: 2つの入力データにバタフライ演算 (length=8の時) 4回 (nRepeat=4, nSubRepeat=2)
             * y[0] = x[0] + w_n^(0*4) * x[1]
             * y[1] = x[0] + w_n^(1*4) * x[1]
             *
             * y[2] = x[2] + w_n^(0*4) * x[3]
             * y[3] = x[2] + w_n^(1*4) * x[3]
             *
             * y[4] = x[4] + w_n^(0*4) * x[5]
             * y[5] = x[4] + w_n^(1*4) * x[5]
             *
             * y[6] = x[6] + w_n^(0*4) * x[7]
             * y[7] = x[6] + w_n^(1*4) * x[7]
             */

            /*
             * stage1: 4つの入力データにバタフライ演算 (length=8の時) 2回 (nRepeat=2, nSubRepeat=4)
             * y[0] = x[0] + w_n^(0*2) * x[2]
             * y[1] = x[1] + w_n^(1*2) * x[3]
             * y[2] = x[0] + w_n^(2*2) * x[2]
             * y[3] = x[1] + w_n^(3*2) * x[3]
             *
             * y[4] = x[4] + w_n^(0*2) * x[6]
             * y[5] = x[5] + w_n^(1*2) * x[7]
             * y[6] = x[4] + w_n^(2*2) * x[6]
             * y[7] = x[5] + w_n^(3*2) * x[7]
             */

            /*
             * stage2: 8つの入力データにバタフライ演算 (length=8の時) 1回 (nRepeat=1, nSubRepeat=8)
             * y[0] = x[0] + w_n^(0*1) * x[4]
             * y[1] = x[1] + w_n^(1*1) * x[5]
             * y[2] = x[2] + w_n^(2*1) * x[6]
             * y[3] = x[3] + w_n^(3*1) * x[7]
             * y[4] = x[0] + w_n^(4*1) * x[4]
             * y[5] = x[1] + w_n^(5*1) * x[5]
             * y[6] = x[2] + w_n^(6*1) * x[6]
             * y[7] = x[3] + w_n^(7*1) * x[7]
             */

            /*
             * stageN:
             */

            long nRepeat    = Pow2(mNumStage - stageNr - 1);
            long nSubRepeat = mNumPoints / nRepeat;

            for (long i = 0; i < nRepeat; ++i)
            {
                long offsBase = i * nSubRepeat;

                bool allZero = true;
                for (long j = 0; j < nSubRepeat / 2; ++j)
                {
                    long offs = offsBase + (j % (nSubRepeat / 2));
                    if (Double.Epsilon < x.At(offs).Magnitude())
                    {
                        allZero = false;
                        break;
                    }
                    if (Double.Epsilon < x.At(offs + nSubRepeat / 2).Magnitude())
                    {
                        allZero = false;
                        break;
                    }
                }

                if (allZero)
                {
                    for (long j = 0; j < nSubRepeat; ++j)
                    {
                        y.Set(j + offsBase, WWComplex.Zero());
                    }
                }
                else
                {
                    for (long j = 0; j < nSubRepeat; ++j)
                    {
                        long offs = offsBase + (j % (nSubRepeat / 2));
                        var  t    = x.At(offs);

                        var t2 = WWComplex.Mul(mWn.At(j * nRepeat), x.At(offs + nSubRepeat / 2));
                        var t3 = WWComplex.Add(t, t2);

                        y.Set(j + offsBase, t3);
                    }
                }
            }
        }
Esempio n. 28
0
        private void PreparePcmData()
        {
            // mPcmSync : 長さ2秒、同期をするために頭に1回小さいクリック音を入れる。これを連続再生する。
            // mPcmReady : 長さ2秒、頭に小さいクリック音がある。このPCMの直後にテストデータを再生する。

            const int SYNC_PCM_SECONDS = 1;

            {
                mPcmSync = new PcmDataLib.PcmData();
                mPcmSync.SetFormat(NUM_CHANNELS,
                                   WasapiCS.SampleFormatTypeToUseBitsPerSample(mPlaySampleFormat),
                                   WasapiCS.SampleFormatTypeToValidBitsPerSample(mPlaySampleFormat),
                                   mSampleRate,
                                   PcmDataLib.PcmData.ValueRepresentationType.SInt, SYNC_PCM_SECONDS * mSampleRate);
                var syncData = new LargeArray <byte>((WasapiCS.SampleFormatTypeToUseBitsPerSample(mPlaySampleFormat) / 8) * NUM_CHANNELS * mPcmSync.NumFrames);
                mPcmSync.SetSampleLargeArray(syncData);
            }

            {
                mPcmReady = new PcmDataLib.PcmData();
                mPcmReady.CopyFrom(mPcmSync);
                var readyData = new LargeArray <byte>((WasapiCS.SampleFormatTypeToUseBitsPerSample(mPlaySampleFormat) / 8) * NUM_CHANNELS * mPcmSync.NumFrames);
                mPcmReady.SetSampleLargeArray(readyData);
            }

            switch (mPlaySampleFormat)
            {
            case WasapiCS.SampleFormatType.Sint16:
                mPcmSync.SetSampleValueInInt32(0, 0, 0x00040000);
                mPcmReady.SetSampleValueInInt32(0, 0, 0x00030000);
                break;

            case WasapiCS.SampleFormatType.Sint24:
            case WasapiCS.SampleFormatType.Sint32V24:
                mPcmSync.SetSampleValueInInt32(0, 0, 0x00000400);
                mPcmReady.SetSampleValueInInt32(0, 0, 0x00000300);
                break;

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

            // mPcmTest : テストデータ。このPCMデータを再生し、再生データと録音データが一致するかどうかを調べる。
            if (mUseFile)
            {
                var conv = new WasapiPcmUtil.PcmFormatConverter(NUM_CHANNELS);
                mPcmTest = conv.Convert(mPlayPcmData, mPlaySampleFormat,
                                        new WasapiPcmUtil.PcmFormatConverter.BitsPerSampleConvArgs(WasapiPcmUtil.NoiseShapingType.None));
                mNumTestFrames = mPcmTest.NumFrames;
            }
            else
            {
                mPcmTest = new PcmDataLib.PcmData();
                mPcmTest.CopyHeaderInfoFrom(mPcmSync);
                var randData = new LargeArray <byte>((long)(WasapiCS.SampleFormatTypeToUseBitsPerSample(mPlaySampleFormat) / 8) * NUM_CHANNELS * mNumTestFrames);
                var fragment = new byte[4096];

                for (long i = 0; i < randData.LongLength; i += fragment.Length)
                {
                    long count = fragment.Length;
                    if (randData.LongLength < i + count)
                    {
                        count = randData.LongLength - i;
                    }

                    mRand.NextBytes(fragment);
                    randData.CopyFrom(fragment, 0, i, (int)count);
                }
                mPcmTest.SetSampleLargeArray(mNumTestFrames, randData);
            }

            // 録音データ置き場。
            mCapturedPcmData = new LargeArray <byte>((long)(WasapiCS.SampleFormatTypeToUseBitsPerSample(mRecSampleFormat) / 8)
                                                     * NUM_CHANNELS * (mNumTestFrames + (4 * SYNC_PCM_SECONDS) * mSampleRate));
        }
Esempio n. 29
0
        /// <summary>
        /// float配列のPCMデータを指定ビットデプスのbyte配列PCMデータにする。
        /// </summary>
        public static LargeArray <byte> ConvertToByteArrayPCM(LargeArray <float> from, int bytesPerSample)
        {
            var  w    = new LargeArray <byte>(from.LongLength * bytesPerSample);
            long wIdx = 0;

            switch (bytesPerSample)
            {
            case 2:
                for (long pos = 0; pos < from.LongLength; ++pos)
                {
                    // 値vを取得。
                    float vF = from.At(pos);
                    if (vF < -1.0f)
                    {
                        vF = -1.0f;
                    }
                    if (32767.0f / 32768.0f < vF)
                    {
                        vF = 32767.0f / 32768.0f;
                    }

                    // 型変換。
                    short vS = (short)(vF * 32768.0f);

                    //Console.WriteLine("{0:+00000;-00000}", vS);

                    // 書き込み。
                    w.Set(wIdx++, (byte)(vS & 0xff));
                    w.Set(wIdx++, (byte)((vS >> 8) & 0xff));
                }
                break;

            case 3:
                for (long pos = 0; pos < from.LongLength; ++pos)
                {
                    // 値vを取得。
                    float vF = from.At(pos);
                    if (vF < -1.0f)
                    {
                        vF = -1.0f;
                    }
                    if (8388607.0f / 8388608.0f < vF)
                    {
                        vF = 8388607.0f / 8388608.0f;
                    }

                    // 型変換。
                    int vI = (int)(vF * 2147483648.0f);

                    // 書き込み。
                    w.Set(wIdx++, (byte)((vI >> 8) & 0xff));
                    w.Set(wIdx++, (byte)((vI >> 16) & 0xff));
                    w.Set(wIdx++, (byte)((vI >> 24) & 0xff));
                }
                break;

            default:
                throw new ArgumentException(string.Format("Unexpected BytesPerSample {0}", bytesPerSample));
            }

            return(w);
        }
Esempio n. 30
0
        public static LargeArray <byte> ConvertTo32bitInt(
            int bitsPerSample, long numSamples,
            PcmData.ValueRepresentationType valueType, LargeArray <byte> data)
        {
            if (bitsPerSample == 32 && valueType == PcmData.ValueRepresentationType.SInt)
            {
                // すでに所望の形式。
                return(data);
            }

            var data32 = new LargeArray <byte>(numSamples * 4);

            switch (valueType)
            {
            case PcmData.ValueRepresentationType.SInt:
                switch (bitsPerSample)
                {
                case 16:
                    for (long i = 0; i < numSamples; ++i)
                    {
                        short v16 = (short)(
                            (uint)data.At(i * 2)
                            + ((uint)data.At(i * 2 + 1) << 8));
                        int v32 = v16;
                        v32 *= 65536;
                        data32.Set(i * 4 + 0, 0);
                        data32.Set(i * 4 + 1, 0);
                        data32.Set(i * 4 + 2, (byte)((v32 & 0x00ff0000) >> 16));
                        data32.Set(i * 4 + 3, (byte)((v32 & 0xff000000) >> 24));
                    }
                    return(data32);

                case 24:
                    for (long i = 0; i < numSamples; ++i)
                    {
                        int v32 = (int)(
                            ((uint)data.At(i * 3 + 0) << 8)
                            + ((uint)data.At(i * 3 + 1) << 16)
                            + ((uint)data.At(i * 3 + 2) << 24));
                        data32.Set(i * 4 + 0, 0);
                        data32.Set(i * 4 + 1, (byte)((v32 & 0x0000ff00) >> 8));
                        data32.Set(i * 4 + 2, (byte)((v32 & 0x00ff0000) >> 16));
                        data32.Set(i * 4 + 3, (byte)((v32 & 0xff000000) >> 24));
                    }
                    return(data32);

                case 32:
                    // 所望の形式。
                    System.Diagnostics.Debug.Assert(false);
                    return(null);

                case 64:
                    for (long i = 0; i < numSamples; ++i)
                    {
                        // 16.48 fixed point
                        int v32 = (int)(
                            ((uint)data.At(i * 8 + 2) << 0)
                            + ((uint)data.At(i * 8 + 3) << 8)
                            + ((uint)data.At(i * 8 + 4) << 16)
                            + ((uint)data.At(i * 8 + 5) << 24));
                        data32.Set(i * 4 + 0, (byte)((v32 & 0x000000ff) >> 0));
                        data32.Set(i * 4 + 1, (byte)((v32 & 0x0000ff00) >> 8));
                        data32.Set(i * 4 + 2, (byte)((v32 & 0x00ff0000) >> 16));
                        data32.Set(i * 4 + 3, (byte)((v32 & 0xff000000) >> 24));
                    }
                    return(data32);

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

            case PcmData.ValueRepresentationType.SFloat:
                for (long i = 0; i < numSamples; ++i)
                {
                    double v;
                    switch (bitsPerSample)
                    {
                    case 32: {
                        var b4 = new byte[4];
                        data.CopyTo(i * 4, ref b4, 0, 4);
                        v = BitConverter.ToSingle(b4, 0);
                    }
                    break;

                    case 64: {
                        var b8 = new byte[8];
                        data.CopyTo(i * 8, ref b8, 0, 8);
                        v = BitConverter.ToDouble(b8, 0);
                    }
                    break;

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

                    int v32 = 0;
                    if (1.0f <= v)
                    {
                        v32 = Int32.MaxValue;
                    }
                    else if (v < -1.0f)
                    {
                        v32 = Int32.MinValue;
                    }
                    else
                    {
                        long vMax = -((long)Int32.MinValue);

                        long v64 = (long)(v * vMax);
                        if (Int32.MaxValue < v64)
                        {
                            v64 = Int32.MaxValue;
                        }
                        v32 = (int)v64;
                    }

                    data32.Set(i * 4 + 0, (byte)((v32 & 0x000000ff) >> 0));
                    data32.Set(i * 4 + 1, (byte)((v32 & 0x0000ff00) >> 8));
                    data32.Set(i * 4 + 2, (byte)((v32 & 0x00ff0000) >> 16));
                    data32.Set(i * 4 + 3, (byte)((v32 & 0xff000000) >> 24));
                }
                return(data32);

            default:
                System.Diagnostics.Debug.Assert(false);
                return(null);
            }
        }
Esempio n. 31
0
 public void ReleaseCaptureMemory()
 {
     mCapturedPcmData = null;
     mNextWritePos    = 0;
 }