Ejemplo n.º 1
0
        public static async Task <ScaleFinderResultSet> FindScalesAsync(IScaleFinderOptions scaleFinderOptions, CancellationToken cancelToken)
        {
            if (null == scaleFinderOptions)
            {
                throw new ArgumentNullException(nameof(scaleFinderOptions));
            }

            InternalNote root  = NoteUtils.ToInternalNote(scaleFinderOptions.RootNote);
            IScale       scale = scaleFinderOptions.Scale;

            InternalNote[] notesInScale = NamedInterval.GetNotes(root, scale.Intervals);

            ScaleFinderResultSet results = new ScaleFinderResultSet(scaleFinderOptions);

            if (cancelToken.IsCancellationRequested)
            {
                return(results);
            }

            foreach (NoteNode startingNode in FindNodes(notesInScale[0], scaleFinderOptions))
            {
                await FindAllScalesAsync(results, startingNode, notesInScale, 1, startingNode.String, scaleFinderOptions, cancelToken);
            }

            return(results);
        }
Ejemplo n.º 2
0
        internal ScaleFinderResult(ScaleFinderResultSet parent, IEnumerable <MarkPosition> marks)
        {
            if (null == marks)
            {
                throw new ArgumentNullException(nameof(marks));
            }

            Parent = parent ?? throw new ArgumentNullException(nameof(parent));
            _marks = new List <MarkPosition>(marks);
        }
Ejemplo n.º 3
0
        private static async Task FindAllScalesAsync(ScaleFinderResultSet results, NoteNode noteNode, InternalNote[] targetNotes, int nextNote, int str, IScaleFinderOptions scaleFinderOptions, CancellationToken cancelToken)
        {
            if (cancelToken.IsCancellationRequested)
            {
                return;
            }

            IInstrument instrument = scaleFinderOptions.Instrument;

            if (nextNote == targetNotes.Length) // Build a scale result
            {
                List <MarkPosition> marks = new List <MarkPosition>();

                NoteNode nn = noteNode;

                // Walk back up the tree to set the marks on the result and flag each target note
                while (null != nn)
                {
                    if (nn.Fret >= 0)
                    {
                        marks.Add(new MarkPosition(nn.String + 1, nn.Fret));
                    }

                    nn = nn.Parent;
                }

                results.AddResult(marks);
            }
            else if (str < instrument.NumStrings) // Keep building the tree
            {
                // Look at all the notes on the string
                int startingFret = scaleFinderOptions.AllowOpenStrings ? 0 : 1;

                if (null != noteNode && noteNode.String == str)
                {
                    startingFret = noteNode.Fret + 1;
                }

                for (int fret = startingFret; fret <= scaleFinderOptions.MaxFret; fret++)
                {
                    InternalNote note = NoteUtils.Shift(scaleFinderOptions.Tuning.RootNotes[str].InternalNote, fret);

                    // See if the note is the next target note
                    if (note == targetNotes[nextNote])
                    {
                        NoteNode child = new NoteNode(str, fret, note, noteNode);                                                  // Add found note
                        await FindAllScalesAsync(results, child, targetNotes, nextNote + 1, str, scaleFinderOptions, cancelToken); // Look for the next note on the same string
                    }
                }

                await FindAllScalesAsync(results, noteNode, targetNotes, nextNote, str + 1, scaleFinderOptions, cancelToken); // Look for the next note on the next string
            }
        }