Пример #1
0
        private void DisplayScaleCore(Scale targetScale)
        {
            try
            {
                var noteInScale = targetScale.GetElementsNote().ToList();

                foreach (var children in Pianokey.Children)
                {
                    Image  img  = children as Image;
                    string tag  = img.Tag as string;
                    Note   note = NoteUtils.ParseNote(tag.Split('-')[1]);
                    if (noteInScale.Contains(note))
                    {
                        ChangePianoKeyChooseStatus(img, status: "Choose");
                    }
                    else
                    {
                        ChangePianoKeyChooseStatus(img, status: "CancelChoose");
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("音阶键位显示出现未知错误!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Пример #2
0
        public FullNote Shift(int steps, InternalNoteStringStyle style)
        {
            if (steps == 0)
            {
                return(new FullNote(NoteUtils.ToNote(InternalNote, style), Octave));
            }

            int direction = Math.Sign(steps);

            InternalNote note   = InternalNote;
            int          octave = Octave;

            for (int i = 0; i < steps; i++)
            {
                int noteIndex = (int)note + direction;
                if (noteIndex < 0)
                {
                    noteIndex += 12;
                }

                note = (InternalNote)(noteIndex % 12);

                if (direction > 0 && note == InternalNote.C)
                {
                    octave++;
                }
                else if (direction < 0 && note == InternalNote.B)
                {
                    octave--;
                }
            }

            return(new FullNote(NoteUtils.ToNote(note, style), octave));
        }
Пример #3
0
        private string GetText(InternalNote?[] notes, int str, MarkTextOption markTextOption)
        {
            if (str < 0 || str >= notes.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(str));
            }

            string text = "";

            if (notes[str].HasValue)
            {
                switch (markTextOption)
                {
                case MarkTextOption.ShowNote_PreferFlats:
                    text = NoteUtils.ToString(notes[str].Value, InternalNoteStringStyle.PreferFlat);
                    break;

                case MarkTextOption.ShowNote_PreferSharps:
                    text = NoteUtils.ToString(notes[str].Value, InternalNoteStringStyle.PreferSharp);
                    break;

                case MarkTextOption.ShowNote_ShowBoth:
                    text = NoteUtils.ToString(notes[str].Value, InternalNoteStringStyle.ShowBoth);
                    break;
                }
            }

            return(text);
        }
Пример #4
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);
        }
Пример #5
0
        public void Set(string key, Note value)
        {
            if (StringUtils.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            Set(key, NoteUtils.ToString(value));
        }
Пример #6
0
        public bool IsRoot(MarkPosition mark)
        {
            if (null == mark)
            {
                throw new ArgumentOutOfRangeException(nameof(mark));
            }

            return(NoteAt(mark) == NoteUtils.ToInternalNote(Parent.ScaleFinderOptions.RootNote));
        }
Пример #7
0
        public bool TryGet(string key, out Note result, bool recursive = true)
        {
            if (TryGet(key, out string rawResult, recursive))
            {
                return(NoteUtils.TryParseNote(rawResult, out result));
            }

            result = default(Note);
            return(false);
        }
Пример #8
0
        public static ObservableCollection <string> GetNotes()
        {
            ObservableCollection <string> collection = new ObservableCollection <string>();

            for (int i = 0; i < Enum.GetValues(typeof(Note)).Length; i++)
            {
                collection.Add(NoteUtils.ToString((Note)i));
            }

            return(collection);
        }
Пример #9
0
        public static ObservableCollection <string> GetInternalNotes()
        {
            ObservableCollection <string> collection = new ObservableCollection <string>();

            for (int i = 0; i < Enum.GetValues(typeof(InternalNote)).Length; i++)
            {
                collection.Add(NoteUtils.ToString((InternalNote)i, InternalNoteStringStyle.ShowBoth));
            }

            return(collection);
        }
Пример #10
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
            }
        }
Пример #11
0
        private void DisplayScaleClickEvent(object sender, RoutedEventArgs e)
        {
            ClearChoosePianoKey();
            string keyStr = ScaleKey.Text;
            string type   = ScaleType.Text;

            ChordNameTextBox.Text = string.Empty;

            Scale targetScale = new Scale(NoteUtils.ParseNote(keyStr), Common.TryEnum <Tonic>(type));

            DisplayScaleCore(targetScale);
        }
Пример #12
0
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Left.Visibility  = Visibility.Hidden;
            Right.Visibility = Visibility.Hidden;
            if (PianoKeyChooseNote.Count() == 0)
            {
                MessageBox.Show("未指定钢琴上的键位!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                ArrowMode = "DetectChord";
                string style       = PianoChordStyle.Text;
                string bassStyle   = PianoChordBassStyle.Text;
                string bassNoteStr = PianoKeyChooseNote.First(s =>
                                                              int.Parse(s.Split('-')[2]) == PianoKeyChooseNote.Min(k => int.Parse(k.Split('-')[2]))).Split('-')[1];
                List <Note> NoteList = new List <Note>();

                foreach (var keyNote in PianoKeyChooseNote)
                {
                    int    index   = int.Parse(keyNote.Split('-')[0]);
                    string noteStr = keyNote.Split('-')[1];
                    var    note    = NoteUtils.ParseNote(noteStr);
                    if (!NoteList.Contains(note))
                    {
                        NoteList.Add(note);
                    }
                }

                RetroChord res;
                try
                {
                    if (bassStyle == "不指定低音")
                    {
                        res = ChordAnalysis.ChordRecognizer(NoteList);
                    }
                    else
                    {
                        res = ChordAnalysis.ChordRecognizer(NoteList, bass: NoteUtils.ParseNote(bassNoteStr));
                    }


                    candidate             = res.Select(r => r.chord).ToList();
                    ChordNameTextBox.Text = res.BestChord.Title;
                    Left.Visibility       = Visibility.Visible;
                    Right.Visibility      = Visibility.Visible;
                }
                catch
                {
                    MessageBox.Show("和弦分析出现未知错误!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
Пример #13
0
        public void SetTarget(Note rootNote, IChordQuality chordQuality)
        {
            if (null == chordQuality)
            {
                throw new ArgumentNullException(nameof(chordQuality));
            }

            Settings[Prefix + "rootnote"]     = NoteUtils.ToString(rootNote);
            Settings[Prefix + "chordquality"] = chordQuality.LongName;
            ChordQualityLevel = chordQuality.Level;

            _cachedChordQuality = chordQuality;
        }
Пример #14
0
        public void SetTarget(Note rootNote, IScale scale)
        {
            if (null == scale)
            {
                throw new ArgumentNullException(nameof(scale));
            }

            Settings[Prefix + "rootnote"] = NoteUtils.ToString(rootNote);
            Settings[Prefix + "scale"]    = scale.LongName;
            ScaleLevel = scale.Level;

            _cachedScale = scale;
        }
Пример #15
0
        public InternalNote InternalNoteAt(int str, int fret)
        {
            if (str < 0 || str >= RootNotes.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(str));
            }

            if (fret < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(fret));
            }

            return(NoteUtils.Shift(RootNotes[str].InternalNote, fret));
        }
Пример #16
0
        public static InternalNote[] GetNotes(InternalNote root, int[] intervals)
        {
            if (null == intervals || intervals.Length == 0)
            {
                throw new ArgumentNullException(nameof(intervals));
            }

            InternalNote[] notes = new InternalNote[intervals.Length];

            for (int i = 0; i < notes.Length; i++)
            {
                notes[i] = NoteUtils.Shift(root, intervals[i]);
            }

            return(notes);
        }
Пример #17
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;
                }
            }
        }
Пример #18
0
        /// <summary>
        /// Call from JQuery to find the chords.
        /// </summary>
        /// <param name="instrument">The instrument.</param>
        /// <param name="tuning">The tuning.</param>
        /// <param name="notes">The root note for the chord.</param>
        /// <param name="chordQualities">The chord qualities.</param>
        /// <param name="numFrets">The number of frets to display.</param>
        /// <param name="maxFrets">The maximum number of frets to use.</param>
        /// <param name="maxReach">The maximum fret reach for the fingers.</param>
        /// <param name="autoAddBarres">Auto add barres?</param>
        /// <param name="allowOpenStrings">Allow open strings?</param>
        /// <param name="allowMutedStrings">Allow muted strings?</param>
        /// <param name="mirrorResults">Mirror the results for left-handed chords?</param>
        /// <param name="allowRootlessChords">Allow rootless chords?</param>
        /// <returns>List of SVG images to display in the UI.</returns>
        public JsonResult FindChords(string instrument, string tuning, string notes, string chordQualities, string numFrets, string maxFrets, string maxReach, string autoAddBarres, string allowOpenStrings, string allowMutedStrings, string mirrorResults, string allowRootlessChords)
        {
            // Initialize the ConfigFile object.
            InitConfig();

            // Define the objects.
            Instrument         Instrument     = null;
            ChordQuality       ChordQuality   = null;
            ChordFinderOptions myOptions      = null;
            ChordFinder        chordFinder    = null;
            ChordResultSet     chordResultSet = null;
            ChordOptions       chordOptions   = null;
            Tuning             Tuning         = null;
            Note myNote = NoteUtils.ParseNote(notes);

            Instrument   = GetAnInstrument(instrument);
            ChordQuality = GetChordQuality(chordQualities);

            if (Instrument != null)
            {
                // Instantiate the selected tuning object from the instrument.
                Tuning = GetTheTuning(Instrument, tuning);

                // Instantiate the chord finder options.
                myOptions = BuildChordFinderOptions(instrument, tuning, numFrets, maxFrets, maxReach, autoAddBarres, allowOpenStrings, allowMutedStrings, mirrorResults, allowRootlessChords);

                // Instantiate the chord finder object.
                chordFinder = new ChordFinder(Instrument, Tuning);

                // Instantiate the chord result set.
                chordResultSet = chordFinder.FindChords(myNote, ChordQuality, myOptions);

                // Instantiate the chord options.
                chordOptions = BuildChordOptions();

                // Build the list of SVG images to return to the screen.
                return(Json(BuildSVGList(chordResultSet, chordOptions), JsonRequestBehavior.AllowGet));
            }
            else
            {
                // The instrument doesn't exist.
                return(Json(String.Empty, JsonRequestBehavior.AllowGet));
            }
        }
Пример #19
0
        [TestCase(new double[] { 1000, 3000 }, 0.3, 1, null)] // start + duration should not exceed 1
        public void TestSliceNoteTime(double[] time, double startPercentage, double durationPercentage, double[] actualTime)
        {
            var note = new Note
            {
                StartTime = time[0],
                Duration  = time[1],
            };

            try
            {
                var sliceNote = NoteUtils.SliceNote(note, startPercentage, durationPercentage);
                Assert.AreEqual(sliceNote.StartTime, actualTime[0]);
                Assert.AreEqual(sliceNote.Duration, actualTime[1]);
            }
            catch
            {
                Assert.IsNull(actualTime);
            }
        }
Пример #20
0
        private void DisplayChordAccordingToNameClickEvent(object sender, RoutedEventArgs e)
        {
            Chord target  = GetChordByNameSet();
            var   bass    = target.BassNote;
            int   bassNum = ((int)bass + 1);

            ChordNoteNumTmp.Add(bassNum);
            string        bassTag  = "1-" + NoteUtils.ToString(bass) + "-" + bassNum.ToString();
            var           noteList = target.ToInternalNoteList().Where(n => n != null).Cast <InternalNote>().ToList();
            List <string> noteTags = new List <string>()
            {
                bassTag
            };

            noteList.ForEach(n =>
            {
                string level;
                string note = NoteUtils.ToString(n);
                string num;
                if ((int)n > (int)bass)
                {
                    level = "1";
                    num   = (bassNum + (int)n - (int)bass).ToString();
                }
                else if ((int)n == (int)bass)
                {
                    level = "2";
                    num   = (12 + bassNum).ToString();
                }
                else
                {
                    level = "2";
                    num   = (12 + bassNum - (int)bass + (int)n).ToString();
                }
                noteTags.Add($"{level}-{note}-{num}");
                ChordNoteNumTmp.Add(int.Parse(num));
            });
            DisplayKeyCore(noteTags);
            ArrowMode = "DisplayChord";
            ChordNoteNumTmp.Sort();
            CheckArrowVisibleState();
        }
Пример #21
0
        private void DisplayChordArpeggioEvent(object sender, RoutedEventArgs e)
        {
            Left.Visibility  = Visibility.Hidden;
            Right.Visibility = Visibility.Hidden;
            Chord target   = GetChordByNameSet();
            var   noteList = target.ToInternalNoteList().Where(n => n != null).Cast <InternalNote>().ToList();

            noteList.Add(target.BassNote);
            noteList.Distinct();
            foreach (var children in Pianokey.Children)
            {
                Image  img     = children as Image;
                string imgTag  = img.Tag as string;
                string noteStr = imgTag.Split('-')[1];
                if (noteList.Any(n => noteStr == NoteUtils.ToString(n)))
                {
                    ChangePianoKeyChooseStatus(img, status: "Choose");
                }
            }
        }
Пример #22
0
        public string GetText(MarkPosition mark, MarkTextOption markTextOption)
        {
            string text = "";

            switch (markTextOption)
            {
            case MarkTextOption.ShowNote_PreferFlats:
                text = NoteUtils.ToString(NoteAt(mark), InternalNoteStringStyle.PreferFlat);
                break;

            case MarkTextOption.ShowNote_PreferSharps:
                text = NoteUtils.ToString(NoteAt(mark), InternalNoteStringStyle.PreferSharp);
                break;

            case MarkTextOption.ShowNote_ShowBoth:
                text = NoteUtils.ToString(NoteAt(mark), InternalNoteStringStyle.ShowBoth);
                break;
            }
            return(text);
        }
Пример #23
0
 private void DisplayKeyCore(string tag)
 {
     try
     {
         foreach (var children in Pianokey.Children)
         {
             Image  img    = children as Image;
             string imgTag = img.Tag as string;
             Note   note   = NoteUtils.ParseNote(imgTag.Split('-')[1]);
             if (imgTag == tag)
             {
                 ChangePianoKeyChooseStatus(img, status: "Choose");
                 break;
             }
         }
     }
     catch (Exception)
     {
         MessageBox.Show("和弦显示出现未知错误!", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
     }
 }
Пример #24
0
        public static async Task <ChordFinderResultSet> FindChordsAsync(IChordFinderOptions chordFinderOptions, CancellationToken cancelToken)
        {
            if (null == chordFinderOptions)
            {
                throw new ArgumentNullException(nameof(chordFinderOptions));
            }

            InternalNote  root         = NoteUtils.ToInternalNote(chordFinderOptions.RootNote);
            IChordQuality chordQuality = chordFinderOptions.ChordQuality;

            InternalNote[] notesInChord = NamedInterval.GetNotes(root, chordQuality.Intervals);

            ChordFinderResultSet results = new ChordFinderResultSet(chordFinderOptions);

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

            await FindAllChordsAsync(results, null, notesInChord, 0, chordFinderOptions, cancelToken);

            return(results);
        }
Пример #25
0
        public static FullNote Parse(string s)
        {
            if (StringUtils.IsNullOrWhiteSpace(s))
            {
                throw new ArgumentNullException(nameof(s));
            }

            s = s.Trim();

            int splitIndex = s.IndexOfAny(digits);

            if (splitIndex <= 0)
            {
                throw new ArgumentException(Strings.InvalidNoteArgumentExceptionMessage);
            }

            string notePortion   = s.Substring(0, splitIndex);
            string octavePortion = s.Substring(splitIndex);

            Note note   = NoteUtils.ParseNote(notePortion);
            int  octave = int.Parse(octavePortion);

            return(new FullNote(note, octave));
        }
Пример #26
0
        public Diagram ToDiagram(ChordFinderStyle chordFinderStyle)
        {
            int[] marks = MarkUtils.AbsoluteToRelativeMarks(Marks, out int baseLine, Parent.ChordFinderOptions.NumFrets);

            InternalNote?[] notes    = MarkUtils.GetInternalNotes(Marks, Parent.ChordFinderOptions.Tuning);
            InternalNote    rootNote = NoteUtils.ToInternalNote(Parent.ChordFinderOptions.RootNote);

            if (chordFinderStyle.MirrorResults)
            {
                Array.Reverse(marks);
                Array.Reverse(notes);
            }

            int numStrings = marks.Length;

            int numFrets = Parent.ChordFinderOptions.NumFrets;

            Diagram d = new Diagram(chordFinderStyle.Style, numStrings, numFrets);

            if (chordFinderStyle.AddTitle)
            {
                d.Title = NoteUtils.ToString(Parent.ChordFinderOptions.RootNote) + Parent.ChordFinderOptions.ChordQuality.Abbreviation;
                d.Style.TitleLabelStyle = DiagramLabelStyle.ChordName;
            }

            // Add marks
            for (int i = 0; i < marks.Length; i++)
            {
                int @string = i + 1;

                int          fret = Math.Max(marks[i], 0);
                MarkPosition mp   = new MarkPosition(@string, fret);

                DiagramMark dm = d.NewMark(mp);

                // Set mark type
                if (marks[i] == -1) // Muted string
                {
                    dm.Type = DiagramMarkType.Muted;
                }
                else if (marks[i] == 0) // Open string
                {
                    dm.Type = DiagramMarkType.Open;
                }

                // Change to root if necessary
                if (chordFinderStyle.AddRootNotes && notes[i].HasValue && notes[i].Value == rootNote)
                {
                    dm.Type = (dm.Type == DiagramMarkType.Open) ? DiagramMarkType.OpenRoot : DiagramMarkType.Root;
                }

                // Add text
                if (chordFinderStyle.MarkTextOption != MarkTextOption.None)
                {
                    dm.Text = GetText(notes, i, chordFinderStyle.MarkTextOption);
                }

                // Add bottom marks
                if (chordFinderStyle.AddBottomMarks)
                {
                    MarkPosition bottomPosition = new MarkPosition(@string, numFrets + 1);
                    DiagramMark  bottomMark     = d.NewMark(bottomPosition);
                    bottomMark.Type = DiagramMarkType.Bottom;
                    bottomMark.Text = GetText(notes, i, chordFinderStyle.BottomMarkTextOption);
                }
            }

            // Add nut or fret label
            if (baseLine == 0)
            {
                d.Style.GridNutVisible = true;
            }
            else
            {
                d.Style.GridNutVisible = false;
                FretLabelPosition flp = new FretLabelPosition(chordFinderStyle.FretLabelSide, 1);
                d.NewFretLabel(flp, baseLine.ToString());
            }

            // Add barre
            BarrePosition bp = MarkUtils.AutoBarrePosition(marks, chordFinderStyle.BarreTypeOption, chordFinderStyle.MirrorResults);

            if (null != bp)
            {
                d.NewBarre(bp);
            }

            return(d);
        }
Пример #27
0
 public override string ToString()
 {
     return(string.Format("{0}{1}", NoteUtils.ToString(Note), Octave));
 }
Пример #28
0
        public Diagram ToDiagram(ScaleFinderStyle scaleFinderStyle)
        {
            int numStrings = Parent.ScaleFinderOptions.Instrument.NumStrings;
            int numFrets   = Parent.ScaleFinderOptions.NumFrets;

            IEnumerable <MarkPosition> marks = MarkUtils.AbsoluteToRelativeMarks(Marks, out int baseLine, numFrets, numStrings);

            Diagram d = new Diagram(scaleFinderStyle.Style, numStrings, numFrets);

            if (scaleFinderStyle.AddTitle)
            {
                d.Title = NoteUtils.ToString(Parent.ScaleFinderOptions.RootNote) + " " + Parent.ScaleFinderOptions.Scale.Name;
                d.Style.TitleLabelStyle = DiagramLabelStyle.Regular;
            }

            int markPositionIndex = 0;

            // Add existing marks
            foreach (MarkPosition mark in marks)
            {
                int @string = mark.String;

                if (scaleFinderStyle.MirrorResults)
                {
                    @string = numStrings - (@string - 1);
                }

                int          fret = mark.Fret;
                MarkPosition mp   = new MarkPosition(@string, fret);

                DiagramMark dm = d.NewMark(mp);

                // Set mark type
                if (scaleFinderStyle.AddRootNotes && IsRoot(markPositionIndex))  // Use markPositionIndex, to get the correct roots in mirror mode
                {
                    dm.Type = DiagramMarkType.Root;
                }

                if (fret == 0) // Open string
                {
                    dm.Type = (dm.Type == DiagramMarkType.Root) ? DiagramMarkType.OpenRoot : DiagramMarkType.Open;
                }

                // Add text
                dm.Text = GetText(markPositionIndex, scaleFinderStyle.MarkTextOption);  // Use markPositionIndex, not mp, to get the correct text in mirror mode

                markPositionIndex++;
            }

            // Add nut or fret label
            if (baseLine == 0)
            {
                d.Style.GridNutVisible = true;
            }
            else
            {
                d.Style.GridNutVisible = false;
                FretLabelPosition flp = new FretLabelPosition(scaleFinderStyle.FretLabelSide, 1);
                d.NewFretLabel(flp, baseLine.ToString());
            }

            return(d);
        }
Пример #29
0
        private static async Task FindAllChordsAsync(ChordFinderResultSet results, NoteNode noteNode, InternalNote[] targetNotes, int str, IChordFinderOptions chordFinderOptions, CancellationToken cancelToken)
        {
            if (cancelToken.IsCancellationRequested)
            {
                return;
            }

            IInstrument instrument = chordFinderOptions.Instrument;

            if (str == instrument.NumStrings) // Build a chord result
            {
                int[] marks = new int[instrument.NumStrings];

                NoteNode nn = noteNode;
                str--;

                bool[] hasNotes = new bool[targetNotes.Length];

                // Walk back up the tree to set the marks on the result and flag each target note
                while (null != nn)
                {
                    marks[str] = nn.Fret;

                    for (int i = 0; i < targetNotes.Length; i++)
                    {
                        if (nn.Note == targetNotes[i])
                        {
                            hasNotes[i] = true;
                        }
                    }

                    nn = nn.Parent;
                    str--;
                }

                InternalNote rootNote = NoteUtils.ToInternalNote(chordFinderOptions.RootNote);

                // Add result if it had all the target notes
                bool valid = true;
                for (int i = 0; i < hasNotes.Length; i++)
                {
                    // Validate:
                    // 1. All notes when !AllowRootlessChords
                    // 2. Non-root notes only when AllowRootlessChords
                    if (!chordFinderOptions.AllowRootlessChords ||
                        (chordFinderOptions.AllowRootlessChords && targetNotes[i] != rootNote))
                    {
                        valid = valid && hasNotes[i];
                    }
                }

                if (valid)
                {
                    results.AddResult(marks);
                }
            }
            else // Keep building the tree
            {
                // Look at the muted string
                if (chordFinderOptions.AllowMutedStrings)
                {
                    NoteNode muted = new NoteNode
                    {
                        Parent = noteNode
                    };
                    await FindAllChordsAsync(results, muted, targetNotes, str + 1, chordFinderOptions, cancelToken);
                }

                // Look at all the notes on the string
                int startingFret = chordFinderOptions.AllowOpenStrings ? 0 : 1;
                for (int fret = startingFret; fret <= chordFinderOptions.MaxFret; fret++)
                {
                    InternalNote note = NoteUtils.Shift(chordFinderOptions.Tuning.RootNotes[str].InternalNote, fret);

                    // See if the note is a target note
                    for (int i = 0; i < targetNotes.Length; i++)
                    {
                        // If it's a target note add it and search on the next string
                        if (note == targetNotes[i])
                        {
                            NoteNode child = new NoteNode(fret, note, noteNode);
                            await FindAllChordsAsync(results, child, targetNotes, str + 1, chordFinderOptions, cancelToken);

                            break;
                        }
                    }
                }
            }
        }
Пример #30
0
 private bool IsRoot(int markPositionIndex)
 {
     return(NoteAt(markPositionIndex) == NoteUtils.ToInternalNote(Parent.ScaleFinderOptions.RootNote));
 }