예제 #1
0
        private void AddGraphLine(OxyPlot.PlotModel plotModel, MatchPair matchPair)
        {
            var lineSeries = new LineSeries();

            lineSeries.Title = matchPair.Track1.Name + " <-> " + matchPair.Track2.Name;
            lineSeries.TrackerFormatString = "{0}\n{1}: {2}\n{3}: {4}"; // bugfix https://github.com/oxyplot/oxyplot/issues/265
            matchPair.Matches.OrderBy(match => match.Track1Time).ToList()
            .ForEach(match => lineSeries.Points.Add(new DataPoint(
                                                        DateTimeAxis.ToDouble(match.Track1.Offset + match.Track1Time),
                                                        DateTimeAxis.ToDouble((match.Track1.Offset + match.Track1Time) - (match.Track2.Offset + match.Track2Time)))));
            plotModel.Series.Add(lineSeries);
        }
예제 #2
0
        private bool IsInOtherCluster(MatchPair <T> matchPair)
        {
            // check, if a connection point (startnode or endnode) is already in another cluster
            bool found = false;

            foreach (var checkCluster in this.clusters)
            {
                if (checkCluster.Any(x => x.From.Equals(matchPair.From) || x.To.Equals(matchPair.To)))
                {
                    // when found add to this cluster
                    checkCluster.Add(matchPair);
                    found = true;
                    break;
                }
            }
            return(found);
        }
예제 #3
0
        private void correlationButton_Click(object sender, RoutedEventArgs e)
        {
            List <MatchGroup> trackGroups = DetermineMatchGroups();

            foreach (MatchGroup trackGroup in trackGroups)
            {
                foreach (MatchPair trackPair in trackGroup.MatchPairs)
                {
                    MatchPair localMP = trackPair;
                    Task.Factory.StartNew(() => {
                        TimeSpan t1Offset;
                        TimeSpan t2Offset;
                        if (localMP.Track1.Offset < localMP.Track2.Offset)
                        {
                            t1Offset = localMP.Track2.Offset - localMP.Track1.Offset;
                            t2Offset = TimeSpan.Zero;
                        }
                        else
                        {
                            t1Offset = TimeSpan.Zero;
                            t2Offset = localMP.Track1.Offset - localMP.Track2.Offset;
                        }
                        TimeSpan length;
                        if (localMP.Track1.Length > localMP.Track2.Length)
                        {
                            length = localMP.Track2.Length;
                        }
                        else
                        {
                            length = localMP.Track1.Length;
                        }
                        TimeSpan interval = CorrelationIntervalSize;
                        TimeSpan window   = CorrelationWindowSize;

                        List <Match> computedMatches = new List <Match>();
                        for (TimeSpan position = TimeSpan.Zero; position < length; position += interval)
                        {
                            Interval t1Interval = new Interval((t1Offset + position).Ticks, (t1Offset + position + window).Ticks);
                            Interval t2Interval = new Interval((t2Offset + position).Ticks, (t2Offset + position + window).Ticks);

                            if (t1Interval.TimeTo >= localMP.Track1.Length || t2Interval.TimeTo >= localMP.Track2.Length)
                            {
                                // not enough samples remaining to compute the correlation (end of track reached)
                                break;
                            }

                            CrossCorrelation.Result ccr;
                            IAudioStream s1 = localMP.Track1.CreateAudioStream();
                            IAudioStream s2 = localMP.Track2.CreateAudioStream();
                            TimeSpan offset = CrossCorrelation.Calculate(s1, t1Interval, s2, t2Interval, progressMonitor, out ccr);
                            s1.Close();
                            s2.Close();
                            // always apply a positive offset that moves the match position inside the corelation interval,
                            // else it can happen that a negative offset is applied to a match at the beginning of the stream
                            // which means that the matching point would be at a negative position in the audio stream
                            computedMatches.Add(new Match {
                                Track1     = localMP.Track1, Track1Time = t1Offset + position + (offset < TimeSpan.Zero ? -offset : TimeSpan.Zero),
                                Track2     = localMP.Track2, Track2Time = t2Offset + position + (offset >= TimeSpan.Zero ? offset : TimeSpan.Zero),
                                Similarity = ccr.AbsoluteMaxValue,
                                Source     = "CC"
                            });
                        }

                        Dispatcher.BeginInvoke((Action) delegate {
                            foreach (Match match in computedMatches)
                            {
                                multiTrackViewer.Matches.Add(match);
                            }
                        });
                    });
                }
            }
        }
예제 #4
0
        public override void Execute()
        {
            // build the graph
            Graph <T> graph = new Graph <T>();

            //graph.AddUndirectedEdge("Frankfurt", "Wiesbaden", 40);
            //graph.AddUndirectedEdge("Frankfurt", "Mainz", 30);
            //graph.AddUndirectedEdge("Mainz", "Wiesbaden", 15);
            //graph.AddUndirectedEdge("Rüdesheim", "Geisenheim", 4);

            foreach (var matchpair in this.matches)
            {
                graph.AddUndirectedEdge(matchpair.From, matchpair.To, matchpair.Cost);
            }

            // uses the FloyWarshall algorithm to compute the transitive closure this
            // means to determine all possible ways in a graph (so you can check, if nodes have a way to each other in the graph)
            FloydWarshall <T> transClosureAlgorithm = new FloydWarshall <T>();

            transClosureAlgorithm.Execute(graph);

            // now for all nodes in the graph e.g (Wiesbaden, Mainz, Frankfurt, Rüdesheim, Geisenheim)
            for (int i = 0; i < transClosureAlgorithm.CostMatrix.GetLength(0); i++)
            {
                var cluster = new List <MatchPair <T> >();

                T startNode = transClosureAlgorithm.Graph.Nodes[i].Value;

                // loop through all nodes in the graph e.g (Wiesbaden, Mainz, Frankfurt, Rüdesheim, Geisenheim)
                for (int j = 0; j < transClosureAlgorithm.CostMatrix.GetLength(0); j++)
                {
                    T   endNode = transClosureAlgorithm.Graph.Nodes[j].Value;
                    var cost    = transClosureAlgorithm.CostMatrix[i, j];

                    // only when a way in the graph exits (waycosts != Infinity)
                    // and it is not himself (startNode != endNode)
                    if (cost != transClosureAlgorithm.Graph.Infinity &&
                        !startNode.Equals(endNode))
                    {
                        // a way exists
                        var matchPair = new MatchPair <T>(startNode, endNode, cost);

                        // checked if it is in the original list
                        if (this.matches.Contains(matchPair))
                        {
                            // check, if a connection point (startnode or endnode) is already in another cluster
                            var found = this.IsInOtherCluster(matchPair);

                            if (!found)
                            {
                                // add to the new cluster
                                cluster.Add(matchPair);
                            }
                        }
                    }
                }

                // when a cluster was build, add to the clusterlist
                if (cluster.Count > 0)
                {
                    this.clusters.Add(cluster);
                }

                // clusters will be e.g.
                // Cluster 1: (Frankfurt, Wiesbaden, Mainz)
                // Cluster 2: (Rüdesheim, Geisenheim)
            }
        }
        public override void Execute()
        {
            // build the graph
            Graph <T> graph = new Graph <T>();

            //graph.AddUndirectedEdge("Frankfurt", "Wiesbaden", 40);
            //graph.AddUndirectedEdge("Frankfurt", "Mainz", 30);
            //graph.AddUndirectedEdge("Mainz", "Wiesbaden", 15);
            //graph.AddUndirectedEdge("Rüdesheim", "Geisenheim", 4);

            foreach (MatchPair <T> matchpair in this.matches)
            {
                graph.AddUndirectedEdge(matchpair.From, matchpair.To, matchpair.Cost);
            }

            BreadthFirstSearch <T> bfsSearch = new BreadthFirstSearch <T>();

            // take every node from the graph as startnode for the search e.g. "Frankfurt", "Wiesbaden", "Mainz", "Rüdesheim", "Geisenheim"
            GraphNode <T> startNode = null;
            GraphNode <T> endNode   = null;
            int           cost      = graph.Infinity;
            int           i         = 0;

            while (i < graph.Nodes.Count)
            {
                var cluster = new List <MatchPair <T> >();

                // take current node as startnode and search the whole graph for reachable nodes
                startNode = (GraphNode <T>)graph.Nodes[i];
                bfsSearch.Execute(startNode, null, null);

                // add the found nodes to the subgraph
                int j = 0;
                while (j < bfsSearch.AllNodes.Count)
                {
                    endNode = (GraphNode <T>)bfsSearch.AllNodes[j];
                    cost    = startNode.CostToNeighbor(endNode);

                    if (!startNode.Equals(endNode))
                    {
                        var matchPair = new MatchPair <T>(startNode.Value, endNode.Value, cost);

                        // check, if it is in the original list
                        if (this.matches.Contains(matchPair))
                        {
                            // check, if a connection point (startnode or endnode) is already in another cluster
                            var found = this.IsInOtherCluster(matchPair);

                            if (!found)
                            {
                                // add to the new cluster
                                cluster.Add(matchPair);
                            }
                        }
                    }

                    j++;
                }

                // when a cluster was build, add to the clusterlist
                if (cluster.Count > 0)
                {
                    this.clusters.Add(cluster);
                }

                // clusters will be e.g.
                // Cluster 1: (Frankfurt, Wiesbaden, Mainz)
                // Cluster 2: (Rüdesheim, Geisenheim)

                i++;
            }
        }