Пример #1
0
        public static async Task <ScaleFinderResultSet> FindScalesAsync(IScaleFinderOptions scaleFinderOptions, CancellationToken cancelToken)
        {
            if (null == scaleFinderOptions)
            {
                throw new ArgumentNullException("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);
        }
Пример #2
0
        public static ScaleFinderResultSet FindScales(IScaleFinderOptions scaleFinderOptions)
        {
            CancellationTokenSource cts = new CancellationTokenSource();

            Task <ScaleFinderResultSet> task = FindScalesAsync(scaleFinderOptions, cts.Token);

            task.Wait();

            return(task.Result);
        }
Пример #3
0
        private static IEnumerable <NoteNode> FindNodes(InternalNote targetNote, IScaleFinderOptions scaleFinderOptions)
        {
            for (int str = 0; str < scaleFinderOptions.Instrument.NumStrings; str++)
            {
                InternalNote rootNote = scaleFinderOptions.Tuning.RootNotes[str].InternalNote;

                int fret = NoteUtils.GetShift(rootNote, targetNote);

                while (fret <= scaleFinderOptions.MaxFret)
                {
                    yield return(new NoteNode(str, fret, targetNote, null));

                    fret += 12;
                }
            }
        }
Пример #4
0
        public static bool ValidateScale(IEnumerable <MarkPosition> scaleMarks, IScaleFinderOptions scaleFinderOptions)
        {
            if (null == scaleMarks)
            {
                throw new ArgumentNullException("scaleMarks");
            }

            if (null == scaleFinderOptions)
            {
                throw new ArgumentNullException("scaleFinderOptions");
            }

            MarkAnalysis ma = ScaleAnalysis(scaleMarks, scaleFinderOptions.Instrument.NumStrings);

            bool reachPass = ma.Reach <= scaleFinderOptions.MaxReach;
            bool openPass  = scaleFinderOptions.AllowOpenStrings ? true : !ma.HasOpenStrings;
            bool mutePass  = scaleFinderOptions.AllowMutedStrings ? true : !ma.HasMutedStrings;

            return(reachPass && openPass && mutePass);
        }
Пример #5
0
 internal ScaleFinderResultSet(IScaleFinderOptions scaleFinderOptions)
 {
     ScaleFinderOptions = scaleFinderOptions;
     _results           = new List <ScaleFinderResult>();
 }
Пример #6
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
            }
        }