private void nextString(Chord chord, List <List <int> > notesOnFretboard, List <List <int> > bassesOnFretboard, ref int bassOnString, List <int[]> fingerings, int currentString, int[] currentFingering) { // first look for the bass note; only switch after it has been found List <List <int> > onFretboard = bassesOnFretboard; if (bassOnString < currentString) { onFretboard = notesOnFretboard; } bool found = false; for (int i = 0; i < onFretboard[currentString].Count() + 1; i++) { // jeden cyklus navic pro pripad, ze nebyla nalezena vhodna pozice na aktualni strune - tj. // ve vhodne vzdalenosti - v takovem pripade je povoleno zatlumeni struny (pozn.: pro prvni dve struny //je zatlumeni povoleno defaultne) if (i == onFretboard[currentString].Count()) { if (found == false) { currentFingering[currentString] = -1; if (bassOnString == currentString) { //pokud se hledal bas a nenasel se, jeho hledani se presouva na dalsi strunu bassOnString = currentString + 1; } } else { break; } } else { //pridame do prstokladu na aktualni pozici vybrany ton currentFingering[currentString] = onFretboard[currentString][i]; if (currentFingering[currentString] == -1) { //nasel se vhodny ton, ale je to -1 tzn. zatlumena nota - hledani basu se presouva o strunu vys //toto nastane pouze u prvnich dvou strun, kde je zatlumeni povoleno explicitne, u ostatnich jen //v pripade, ktery je osetren o par radek vyse if (bassOnString == currentString) { bassOnString = currentString + 1; } } } if (isFeasible(currentFingering, currentString)) // prorezavani stromu - v prohledavani vetve se pokracuje //jen tehdy, pokud akord stale jeste dava smysl { found = true; if (currentString < fretboard.StringsCount - 1) { //rekurzivni volani funkce pro dalsi strunu nextString(chord, notesOnFretboard, bassesOnFretboard, ref bassOnString, fingerings, currentString + 1, currentFingering); } else //posledni struna, nasli jsme smysluplny prstoklad { //test na obsazeni vsech tonu akordu if (containsAllNecessaryNotes(chord, currentFingering)) { //pridani tonu do seznamu prstokladu int[] fingering_copy = new int[fretboard.StringsCount]; //nemohu pridat referencne predavanou prommenou, musim vytvorit kopii for (int j = 0; j < fretboard.StringsCount; j++) { fingering_copy[j] = currentFingering[j]; } fingerings.Add(fingering_copy); } } } } }
/// <summary> /// For each of the 12 notes, return the symbol of a harmonic function this note fulfills in the chord. /// </summary> /// <returns>Dictionary with 12 entries containing the symbols of the harmonic functions of individual notes. If the note is not present in chord, the corresponding value is empty string.</returns> public Dictionary <Note, string> generateHarmonicFunctionSymbols(Chord chord) { var symbols = new Dictionary <Note, string>(); symbols[chord.Root] = "R"; // The order of assigning is IMPORTANT! // Same note can serve as different harmonic functions, e.g. major ninth and diminished third. // In case of such collision, the more important function will overwrite the other one (e.g. third will overwrite ninth). switch (chord.Ninth) { case 0: break; case 1: symbols[(Note)(((int)chord.Root + 1) % 12)] = "9b"; break; case 2: symbols[(Note)(((int)chord.Root + 2) % 12)] = "9"; break; default: break; } switch (chord.Eleventh) { case 0: break; case 1: symbols[(Note)(((int)chord.Root + 5) % 12)] = "11"; break; case 2: symbols[(Note)(((int)chord.Root + 6) % 12)] = "11#"; break; default: break; } switch (chord.Thirteenth) { case 0: break; case 1: symbols[(Note)(((int)chord.Root + 8) % 12)] = "13b"; break; case 2: symbols[(Note)(((int)chord.Root + 9) % 12)] = "13"; break; default: break; } switch (chord.Third) { case 0: break; case 1: symbols[(Note)(((int)chord.Root + 2) % 12)] = "2"; break; case 2: symbols[(Note)(((int)chord.Root + 3) % 12)] = "m3"; break; case 3: symbols[(Note)(((int)chord.Root + 4) % 12)] = "3"; break; case 4: symbols[(Note)(((int)chord.Root + 5) % 12)] = "4"; break; default: break; } switch (chord.Fifth) { case 0: break; case 1: symbols[(Note)(((int)chord.Root + 6) % 12)] = "5b"; break; case 2: symbols[(Note)(((int)chord.Root + 7) % 12)] = "5"; break; case 3: symbols[(Note)(((int)chord.Root + 8) % 12)] = "5#"; break; default: break; } switch (chord.Seventh) { case 0: break; case 1: symbols[(Note)(((int)chord.Root + 9) % 12)] = "6"; break; case 2: symbols[(Note)(((int)chord.Root + 10) % 12)] = "7"; break; case 3: symbols[(Note)(((int)chord.Root + 11) % 12)] = "M7"; break; default: break; } if (symbols[chord.Bass] == null) { // if the bass tone does not fulfill any other harmonic function, it is assigned its own symbol symbols[chord.Bass] = "(B)"; } return(symbols); }