public static void GetChord(List<Note> chordNotes, out Note BaseNote, out ChordType type) { List<Note> notes = PrepareNotes(chordNotes); int typeIndex = GetChordType(notes); if (typeIndex < chordTypes.Length) { BaseNote = notes[0]; type = chordTypes[typeIndex]; } else if (chordNotes.Count <= 7) { bool unknown = true; var possibleChord = new List<Note>(notes); foreach (var perm in Utils.GeneratePermutation(possibleChord)) { for (int k = 1; k < perm.Count; ++k) // Убираем промежутки между нотами ( > 12 полутонов ) { if (perm[k].Tone > perm[k - 1].Tone) { perm[k] = new Note(perm[k - 1].Octave, perm[k].Tone); } else { perm[k] = new Note((byte) (perm[k - 1].Octave + 1), perm[k].Tone); } } typeIndex = GetChordType(possibleChord); if (typeIndex < chordTypes.Length) { unknown = false; break; // Мы нашли что нужно, выходим } } if (!unknown) { BaseNote = possibleChord[0]; type = chordTypes[typeIndex]; } else { throw new Exception("неизвестный аккорд"); } } else { throw new Exception("неизвестный аккорд"); } }
public int GetFretForNote(Note note) { int fret = -1; // -1 означает, что нельзя сыграть ноту на этой струне if (open <= note) { int octDiff = note.Octave - open.Octave; int noteDiff = note.Tone - open.Tone; fret = octDiff*12 + noteDiff; } return fret; }
public List<Note> BuildChord(Note baseNote) { var result = new List<Note>(); result.Add(baseNote); Note current = baseNote; foreach (int interval in intervals) { current = current + interval; result.Add(current); } return result; }
public List<Tuple<byte, byte>> GetFretsForNote(Note note) { var result = new List<Tuple<byte, byte>>(); // 1-е значение номер стпуны (от 1 до 6), 2-е - номер лада ( 0 - открытая струна) byte currentString = 0; foreach (GuitarString str in strs) { int fret = str.GetFretForNote(note); if (fret != -1) // Если на этой струне можно сыграть заданную ноту { result.Add(new Tuple<byte, byte>(currentString, (byte) fret)); } ++currentString; } return result; }
public bool IsNotePlayed(Note note) { return _playingTones.Contains(note.Id); }
private void ToggleSelectedChord() { if (CChords.SelectedIndex >= 0 && CChordMods.SelectedIndex >= 0) { StopPlayAll(); var chord = CChords.SelectedValue as string; int mod = CChordMods.SelectedIndex; chord = chord.Replace("#", "d"); var baseNote = new Note(3, chord.ConvertToEnum<Tones>()); List<Note> lst = Chords.chordTypes[mod].BuildChord(baseNote); foreach (Note chordNote in lst) { ToggleNote(chordNote); } } }
// major - объект лада, который необходимо подсветить как основной private void HighlightNote(Note note, Shape major = null) { // ReSharper disable ConditionIsAlwaysTrueOrFalse Color newColor = (note.Octave >= StartOctave && note.Octave <= EndOctave) ? GetColor() : Colors.Black; // ReSharper restore ConditionIsAlwaysTrueOrFalse var baseColor = new SolidColorBrush(newColor); Color tmp = newColor; tmp.A = InactiveFretAlpha; var highlighted = new SolidColorBrush(tmp); List<Tuple<byte, byte>> lst = _guitar.GetFretsForNote(note); foreach (var objName in lst) { object o = LogicalTreeHelper.FindLogicalNode(FretsGrid, GenerateFretName(objName.Item1, objName.Item2)); if (o != null) { ((Shape) o).Fill = highlighted; } } if (major != null) { major.Fill = baseColor; } string str = GenerateKeyName(note); TChordName.Text = note.ToString().Replace('#', '♯'); var bNote = (TextBlock) LogicalTreeHelper.FindLogicalNode(KeysGrid, str); // имя клавиши имеет след. вид: "Тон[d]Октава" if (bNote != null) { bNote.Background = baseColor; bNote.Focus(); } }
private string GenerateKeyName(Note note) { return note.ToString().Replace('#', 'd'); }
private void DehightlightNote(Note note) { List<Tuple<byte, byte>> lst = _guitar.GetFretsForNote(note); foreach (var objName in lst) { object o = LogicalTreeHelper.FindLogicalNode(FretsGrid, GenerateFretName(objName.Item1, objName.Item2)); if (o != null) { var shape = o as Shape; Brush brushCopy = shape.Fill.Clone(); shape.Fill = brushCopy; var fretFadeAnimation = new ColorAnimation(((SolidColorBrush) shape.Fill).Color, _inactiveFret.Color, new Duration(TimeSpan.FromSeconds(2))); var easing = new QuinticEase {EasingMode = EasingMode.EaseOut}; fretFadeAnimation.EasingFunction = easing; var fretStoryboard = new Storyboard(); fretStoryboard.Children.Add(fretFadeAnimation); string elementName = shape.Name; if (FindName(elementName) == null) { RegisterName(elementName, shape); } Storyboard.SetTargetName(fretFadeAnimation, elementName); Storyboard.SetTargetProperty(fretFadeAnimation, new PropertyPath("Fill.Color")); fretStoryboard.Begin(this); } } TChordName.Text = ""; string str = GenerateKeyName(note); var bNote = (TextBlock) LogicalTreeHelper.FindLogicalNode(KeysGrid, str); if (bNote != null) { FreeColor(((SolidColorBrush) bNote.Background).Color); SolidColorBrush targetColor = str.Length == 2 ? _genericColor : _diezColor; Brush brushCopy = bNote.Background.Clone(); bNote.Background = brushCopy; var noteFadeAnimation = new ColorAnimation(((SolidColorBrush) bNote.Background).Color, targetColor.Color, new Duration(TimeSpan.FromSeconds(3))); var easing = new QuinticEase {EasingMode = EasingMode.EaseOut}; noteFadeAnimation.EasingFunction = easing; var noteStoryboadrd = new Storyboard(); noteStoryboadrd.Children.Add(noteFadeAnimation); if (FindName(bNote.Name) == null) { RegisterName(bNote.Name, bNote); } Storyboard.SetTargetName(noteFadeAnimation, bNote.Name); Storyboard.SetTargetProperty(noteFadeAnimation, new PropertyPath("Background.Color")); noteStoryboadrd.Begin(this); } }
internal void ToggleNote(Note note, Shape major = null) { if (_toggled.Contains(note)) { DehightlightNote(note); _toggled.Remove(note); } else { HighlightNote(note, major); _toggled.Add(note); } _toggled = _toggled.OrderBy(x => x.Id).ToList(); UpdateChord(); }
public MainWindow() { InitializeComponent(); _player = new Player(this); WindowStartupLocation = WindowStartupLocation.CenterScreen; CInstrument.ItemsSource = InstrumentNames; CTunes.ItemsSource = _tunes; CChordMods.ItemsSource = Chords.chordMods; CChords.ItemsSource = Chords.chordsBases; for (double speed = 0.25; speed <= 2.0; speed += 0.25) { CPlaySpeed.Items.Add(speed); } int devicesCount = MidiIn.NumberOfDevices; for (int i = 0; i < devicesCount; i++) { MidiInCapabilities device = MidiIn.DeviceInfo(i); CSelectedInput.Items.Add(device); } #region Генерация клавиш пианино int keyPosition = KeysOffset; for (byte octave = StartOctave; octave <= EndOctave; ++octave) { for (int i = 0; i < 12; ++i) // 12 полутонов в октаве { var currentKey = new TextBlock(); var note = new Note(octave, (Tones) i); currentKey.Text = note.ToString(); currentKey.Name = GenerateKeyName(note); if (!note.isDiez()) //Если не диез { currentKey.Width = KeyWidth; currentKey.Height = KeyHeight; currentKey.Background = _genericColor; currentKey.Margin = new Thickness(keyPosition, 0, 0, 0); currentKey.Padding = new Thickness(0, 130, 0, 0); currentKey.SetValue(Panel.ZIndexProperty, 0); keyPosition += KeyWidth + KeysOffset; currentKey.Foreground = Brushes.Black; currentKey.FontSize = 14; } else { currentKey.Width = DiezWiddth; currentKey.Height = DiezHeight; currentKey.Background = _diezColor; currentKey.Margin = new Thickness(keyPosition - DiezWiddth/2 + KeysOffset/2, 0, 0, 0); currentKey.Padding = new Thickness(0, 75, 0, 0); currentKey.SetValue(Panel.ZIndexProperty, 1); currentKey.Foreground = Brushes.White; currentKey.FontSize = 10; } currentKey.TextAlignment = TextAlignment.Center; currentKey.FontWeight = FontWeights.Bold; currentKey.Focusable = true; currentKey.HorizontalAlignment = HorizontalAlignment.Left; currentKey.VerticalAlignment = VerticalAlignment.Top; currentKey.PreviewMouseLeftButtonDown += PianoKeyDown; currentKey.PreviewMouseLeftButtonUp += PianoKeyUp; currentKey.MouseLeave += PianoKeyLeave; currentKey.PreviewMouseRightButtonUp += KeyToggled; KeysGrid.Children.Add(currentKey); } } #endregion #region Генерация ладов для гитары for (byte guitarString = 0; guitarString < 6; ++guitarString) { for (byte fret = 0; fret < FretsCount; ++fret) { Shape currentFret; if (fret != 0) { currentFret = new Ellipse {Margin = new Thickness(FretOffset)}; } else { currentFret = new Rectangle {Margin = new Thickness(0)}; } currentFret.Name = GenerateFretName(guitarString, fret); currentFret.Stroke = _fretStroke; currentFret.Fill = _inactiveFret; FretsGrid.Children.Add(currentFret); currentFret.SetValue(Grid.ColumnProperty, (int) fret); currentFret.SetValue(Grid.RowProperty, (int) guitarString); currentFret.PreviewMouseLeftButtonDown += FretMouseDown; currentFret.PreviewMouseLeftButtonUp += FretMouseUp; currentFret.MouseLeave += FretMouseLeave; currentFret.PreviewMouseRightButtonUp += FretToggled; } } #endregion }
private static List<Note> PrepareNotes(List<Note> notes) { var tmp = new List<Note>(); bool finded = false; for (int i = 0; i < notes.Count; ++i) { finded = false; Note note = notes[i]; for (int j = 0; j < tmp.Count; ++j) { if (note.Tone == tmp[j].Tone) { finded = true; break; } } if (!finded) { tmp.Add(note); } } if (tmp.Count == 1 && notes.Count > 1) { return notes; } byte lowest = tmp[0].Octave; Tones lowesTone = tmp[0].Tone; for (int i = 0; i < tmp.Count; ++i) { if (tmp[i].Octave > lowest) { if (Utils.CountOfTones(tmp[i].Tone, notes) > 1) { if (tmp[i].Tone > lowesTone) { tmp[i] = new Note(lowest, tmp[i].Tone); } else { tmp[i] = new Note((byte) (lowest + 1), tmp[i].Tone); } } } } tmp = tmp.OrderBy(x => x.Id).ToList(); return tmp; }
public GuitarString(Note note) { open = note; }
public void SetTune(Note note) { open = note; }
private int RunCmd(string cmd) { int newInterval = 0; if (cmd.Length > 0) // Если не пустая строка { if (!int.TryParse(cmd, out newInterval)) // Если не число (если не интервал) { if (cmd.StartsWith("@")) // Если аккорд { string[] lst = cmd.Substring(1).Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); if (lst.Length > 0) { try { Note baseNote; // 0-й элемент содержит базовую ноту аккорда (Например D#4 - D# 4-й октавы) try { baseNote = Note.FromString(lst[0]); } catch { baseNote = new Note(3, lst[0].Replace("#", "d").ConvertToEnum<Tones>()); //Возможно не указана октава } string chordName = ""; if (lst.Length >= 2) // Если через пробел еще что-то было, значит аккорд не мажорный (у мажорного нет никаких суфиксов) { chordName = lst[1]; // 1-й элемент должен содержать тип аккорда (например sus2) } int type = 0; foreach (ChordType chord in Chords.chordTypes) { if (chord.name == chordName) { break; } ++type; } if (type < Chords.chordTypes.Length) { parent.Dispatcher.Invoke((Action) parent.StopPlayAll, null); List<Note> chord = Chords.chordTypes[type].BuildChord(baseNote); foreach (Note chordNote in chord) { parent.Dispatcher.Invoke((ToggleNoteDelegate) parent.ToggleNote, new object[] {chordNote, null}); } parent.Dispatcher.Invoke((Action) parent.PlayToggled, null); } } catch (Exception e) { Trace.WriteLine(e.Message); } } } else // Если набор нот { string[] lst = cmd.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries); if (lst.Length > 0) { parent.Dispatcher.Invoke((Action) parent.StopPlayAll, null); foreach (string note in lst.Distinct()) { try { Note tmp = Note.FromString(note); parent.Dispatcher.Invoke((ToggleNoteDelegate) parent.ToggleNote, new object[] {tmp, null}); } catch (Exception) { } } parent.Dispatcher.Invoke((Action) parent.PlayToggled, null); } } } } return newInterval; }