static class Chords { public static ChordType[] chordTypes = new ChordType[]{ new ChordType(" ", "", 4,3), new ChordType(" ", "m", 3,4), new ChordType(" ", "5+", 4,4), new ChordType(" ", "m-5", 3,3), new ChordType(" ", "maj7", 4,3,4), new ChordType(" ", "m+7", 3,4,4), new ChordType("", "7", 4,3,3), new ChordType(" ", "m7", 3,4,3), new ChordType(" ", "maj5+", 4,4,3), new ChordType(" ", "m7-5", 3,3,4), new ChordType(" ", "dim", 3,3,3), new ChordType(" (IV)", "sus2", 2,5), new ChordType(" (II)", "sus4", 5,2), new ChordType("","6", 4,3,2), new ChordType("", "m6", 3,4,2), new ChordType(" ", "9", 4,3,3,4), new ChordType(" ", "m9", 3,4,3,4), new ChordType(" ", "-9", 4,3,3,3), new ChordType(" ", "m-9", 3,4,3,3), new ChordType("",""), new ChordType(" ", " - 2", 1), new ChordType(" ", " - 2", 2), new ChordType(" ", " - 3", 3), new ChordType(" ", " - 3", 4), new ChordType(" ", " - 4", 5), new ChordType(" ", " - 4", 6), new ChordType(" ", " - 5", 7), new ChordType(" ", " - 6", 8), new ChordType(" ", " - 6", 9), new ChordType(" ", " - 7", 10), new ChordType(" ", " - 7", 11), new ChordType("", " - ", 12), new ChordType(" ", " - 9", 13), new ChordType(" ", " - 9", 14) }; public static string[] chordsBases = new string[] { "A","A#","B","C","C#","D","D#","E", "F","F#","G","G#" }; public static string[] chordMods = new string[] { "","m","5+","m-5","maj7","m+7","7", "m7","maj5+","m7-5","dim","sus2","sus4", "6","m6","9","m9","-9","m-9" }; private static int GetChordType( List<Note> tmp ) { int[] intervals = new int[tmp.Count - 1]; for( int i = 0; i < tmp.Count - 1; ++i ) { intervals[i] = tmp[i] - tmp[i + 1]; } int type = 0; foreach( var chordType in Chords.chordTypes ) { if( Utils.CompareArrays( intervals, chordType.intervals ) ) break; ++type; } return type; } 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 { bool unknown = true; var possibleChord = new List<Note>( notes ); // foreach( List<Note> perm in Utils.GeneratePermutation( possibleChord ) ) { // ( > 12 ) for( int k = 1; k < perm.Count; ++k ) { 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 < Chords.chordTypes.Length ) { unknown = false; break; // , } } if( unknown ) { throw new Exception( " " ); } else { BaseNote = possibleChord[0]; type = chordTypes[typeIndex]; } } } private static List<Note> PrepareNotes( List<Note> notes ) { List<Note> tmp = new List<Note>(); bool finded = false; for( int i = 0; i < notes.Count; ++i ) { finded = false; var 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; var 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; } }