示例#1
0
        public virtual List<Tuple<TimeSpan, TimeSpan>> Execute(IAudioStream s1, IAudioStream s2) {
            s1 = PrepareStream(s1);
            s2 = PrepareStream(s2);

            int diagonalWidth = (int)(searchWidth.TotalSeconds * (1d * FrameReader.SAMPLERATE / FrameReader.WINDOW_HOP_SIZE));

            // init ring buffers
            rb1 = new float[diagonalWidth][];
            rb1FrameCount = 0;
            rb2 = new float[diagonalWidth][];
            rb2FrameCount = 0;

            stream1FrameQueue = new BlockingCollection<float[]>(20);
            FrameReader stream1FrameReader = new FrameReader(s1);
            Task.Factory.StartNew(() => {
                while (stream1FrameReader.HasNext()) {
                    float[] frame = new float[FrameReader.FRAME_SIZE];
                    stream1FrameReader.ReadFrame(frame);
                    //Thread.Sleep(20);
                    stream1FrameQueue.Add(frame);
                }
                stream1FrameQueue.CompleteAdding();
            });

            stream2FrameQueue = new BlockingCollection<float[]>(20);
            FrameReader stream2FrameReader = new FrameReader(s2);
            Task.Factory.StartNew(() => {
                while (stream2FrameReader.HasNext()) {
                    float[] frame = new float[FrameReader.FRAME_SIZE];
                    stream2FrameReader.ReadFrame(frame);
                    //Thread.Sleep(20);
                    stream2FrameQueue.Add(frame);
                }
                stream2FrameQueue.CompleteAdding();
            });

            IProgressReporter progressReporter = progressMonitor.BeginTask("DTW aligning...", true);
            int n = stream1FrameReader.WindowCount;
            int m = stream2FrameReader.WindowCount;

            double deltaN;
            double deltaM;
            if (m > n) {
                deltaN = (double)(n - 1) / (m - 1);
                deltaM = 1d;
            }
            else if (m < n) {
                deltaN = 1d;
                deltaM = (double)(m - 1) / (n - 1);
            }
            else {
                deltaN = 1d;
                deltaM = 1d;
            }

            // NOTE the SparseMatrix is NOT USABLE for DTW -> OutOfMemoryException (1.3GB RAM) at a densely filled matrix of ~4000x3000
            IMatrix<double> totalCostMatrix = new PatchMatrix<double>(double.PositiveInfinity);
            IMatrix<double> cellCostMatrix = new PatchMatrix<double>(double.PositiveInfinity);

            // init matrix
            // NOTE do not explicitely init the PatchMatrix, otherwise the sparse matrix characteristic would 
            //      be gone and the matrix would take up all the space like a standard matrix does
            totalCostMatrix[0, 0] = 0;
            cellCostMatrix[0, 0] = 0;

            double progressN = 0;
            double progressM = 0;
            int i, x = 0;
            int j, y = 0;

            FireOltwInit(diagonalWidth, cellCostMatrix, totalCostMatrix);

            while (x < n || y < m) {
                x = (int)progressN + 1;
                y = (int)progressM + 1;
                ReadFrames(x, y);

                i = Math.Max(x - diagonalWidth, 1);
                j = y;
                for (; i <= x; i++) {
                    double cost = CalculateCost(rb1[(i - 1) % diagonalWidth], rb2[(j - 1) % diagonalWidth]);
                    totalCostMatrix[i, j] = cost + Min(
                        totalCostMatrix[i - 1, j], 
                        totalCostMatrix[i, j - 1], 
                        totalCostMatrix[i - 1, j - 1]);
                    cellCostMatrix[i, j] = cost;
                }

                i = x;
                j = Math.Max(y - diagonalWidth, 1);
                for (; j <= y; j++) {
                    double cost = CalculateCost(rb1[(i - 1) % diagonalWidth], rb2[(j - 1) % diagonalWidth]);
                    totalCostMatrix[i, j] = cost + Min(
                        totalCostMatrix[i - 1, j], 
                        totalCostMatrix[i, j - 1], 
                        totalCostMatrix[i - 1, j - 1]);
                    cellCostMatrix[i, j] = cost;
                }

                FireOltwProgress(x, y, x, y, false);

                progressReporter.ReportProgress((double)x / n * 100);

                progressN += deltaN;
                progressM += deltaM;
            }
            FireOltwProgress(x, y, x, y, true);
            progressReporter.Finish();

            List<Pair> path = OptimalWarpingPath(totalCostMatrix);
            path.Reverse();

            return WarpingPathTimes(path, true);
        }
示例#2
0
        public override List <Tuple <TimeSpan, TimeSpan> > Execute(IAudioStream s1, IAudioStream s2)
        {
            s1 = PrepareStream(s1);
            s2 = PrepareStream(s2);

            int searchWidth = (int)(this.searchWidth.TotalSeconds * (1d * FrameReader.SAMPLERATE / FrameReader.WINDOW_HOP_SIZE));

            totalCostMatrix = new PatchMatrix <double>(double.PositiveInfinity);
            cellCostMatrix  = new PatchMatrix <double>(double.PositiveInfinity);
            rb1             = new RingBuffer <float[]>(searchWidth);
            rb1FrameCount   = 0;
            rb2             = new RingBuffer <float[]>(searchWidth);
            rb2FrameCount   = 0;

            stream1FrameQueue = new BlockingCollection <float[]>(20);
            FrameReader stream1FrameReader = new FrameReader(s1);

            Task.Factory.StartNew(() => {
                while (stream1FrameReader.HasNext())
                {
                    float[] frame = new float[FrameReader.FRAME_SIZE];
                    stream1FrameReader.ReadFrame(frame);
                    Thread.Sleep(20);
                    stream1FrameQueue.Add(frame);
                }
                stream1FrameQueue.CompleteAdding();
            });

            stream2FrameQueue = new BlockingCollection <float[]>(20);
            FrameReader stream2FrameReader = new FrameReader(s2);

            Task.Factory.StartNew(() => {
                while (stream2FrameReader.HasNext())
                {
                    float[] frame = new float[FrameReader.FRAME_SIZE];
                    stream2FrameReader.ReadFrame(frame);
                    Thread.Sleep(20);
                    stream2FrameQueue.Add(frame);
                }
                stream2FrameQueue.CompleteAdding();
            });

            // init matrix
            // NOTE do not explicitely init the PatchMatrix, otherwise the sparse matrix characteristic would
            //      be gone and the matrix would take up all the space like a standard matrix does
            totalCostMatrix[0, 0] = 0;
            cellCostMatrix[0, 0]  = 0;

            IProgressReporter progressReporter = progressMonitor.BeginTask("OLTW", true);
            int totalFrames = stream1FrameReader.WindowCount + stream2FrameReader.WindowCount;

            // --------- OLTW -----------

            t        = 1;
            j        = 1;
            previous = GetIncResult.None;
            runCount = 0;
            c        = searchWidth;
            EvaluatePathCost(t, j);

            FireOltwInit(c, cellCostMatrix, totalCostMatrix);

            while (rb1FrameCount + rb2FrameCount < totalFrames)
            {
                GetIncResult getInc = GetInc(t, j);
                if (t < stream1FrameReader.WindowCount && getInc != GetIncResult.Column)
                {
                    t++;
                    for (int k = j - c + 1; k <= j; k++)
                    {
                        if (k > 0)
                        {
                            EvaluatePathCost(t, k);
                        }
                    }
                }
                if (j < stream2FrameReader.WindowCount && getInc != GetIncResult.Row)
                {
                    j++;
                    for (int k = t - c + 1; k <= t; k++)
                    {
                        if (k > 0)
                        {
                            EvaluatePathCost(k, j);
                        }
                    }
                }
                if (getInc == previous)
                {
                    runCount++;
                }
                else
                {
                    runCount = 1;
                }
                if (getInc != GetIncResult.Both)
                {
                    previous = getInc;
                }

                FireOltwProgress(t, j, t, j, false);

                //Debug.WriteLine(t + " " + j + " " + getInc);

                progressReporter.ReportProgress((rb1FrameCount + rb2FrameCount) / (double)totalFrames * 100);
            }

            FireOltwProgress(t, j, t, j, true);

            Debug.WriteLine("OLTW finished @ t={0}/{1}, j={2}/{3}",
                            t, stream1FrameReader.WindowCount,
                            j, stream2FrameReader.WindowCount);

            progressReporter.Finish();


            // --------- generate results -----------

            List <Pair> path = OptimalWarpingPath(totalCostMatrix);

            path.Reverse();

            List <Tuple <TimeSpan, TimeSpan> > pathTimes = new List <Tuple <TimeSpan, TimeSpan> >();

            foreach (Pair pair in path)
            {
                Tuple <TimeSpan, TimeSpan> timePair = new Tuple <TimeSpan, TimeSpan>(
                    PositionToTimeSpan(pair.i1 * FrameReader.WINDOW_HOP_SIZE),
                    PositionToTimeSpan(pair.i2 * FrameReader.WINDOW_HOP_SIZE));
                if (timePair.Item1 >= TimeSpan.Zero && timePair.Item2 >= TimeSpan.Zero)
                {
                    pathTimes.Add(timePair);
                }
            }

            return(pathTimes);
        }