Created
March 4, 2017 00:56
-
-
Save hkailahi/b4b83782f2f9dd44d4cd125eb2a39571 to your computer and use it in GitHub Desktop.
Guitar Notes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.List; | |
public class Guitar { | |
private Note[][] guitar; | |
private int numFrets; | |
private int numStrings; | |
public Guitar(int numFrets, int numStrings) { | |
this.numFrets = numFrets; | |
this.numStrings = numStrings; | |
initGuitar(); | |
} | |
public void initGuitar() { | |
this.guitar = new Note[numFrets][numStrings]; | |
// Assume standard tuning for initial implementation | |
setTuning("standard"); | |
// Initialize notes -> guitar[fret][string] | |
for (int string = 0; string < numStrings; string++ ) { // column | |
for (int fret = 1; fret < numFrets; fret++) { // row | |
Note prev = guitar[fret-1][string]; | |
int currNote = (prev.getNote()+1)%12; | |
int currOctave = prev.getOctave(); | |
if (currNote==0) { | |
currOctave++; // "C" is the start of an octave in Hemholtz system | |
} | |
guitar[fret][string] = new Note(currNote, currOctave); | |
} | |
} | |
} | |
public void setAllDegrees(Scale s) { | |
// Initialize degrees -> guitar[fret][string] | |
for (int string = 0; string < numStrings; string++ ) { // column | |
for (int fret = 0; fret < numFrets; fret++) { // row | |
guitar[fret][string].setDegree(s.calcNoteDegree(guitar[fret][string])); | |
} | |
} | |
} | |
public void setTuning(String tuning) { | |
if (tuning=="standard") { | |
guitar[0][0] = new Note(4, 2); // E2 | |
guitar[0][1] = new Note(9, 2); // A2 | |
guitar[0][2] = new Note(2, 3); // D3 | |
guitar[0][3] = new Note(7, 3); // G3 | |
guitar[0][4] = new Note(11, 3); // B3 | |
guitar[0][5] = new Note(4, 4); // E4 | |
} else { | |
throw new RuntimeException("Non-standard tunings unavailable"); | |
// todo implement other tunings | |
} | |
} | |
/*==================== Printing Methods ====================*/ | |
public void printFrets(int spacing) { | |
StringBuilder sb = new StringBuilder(); | |
List<Integer> args = new ArrayList<>(); | |
sb.append("F> "); | |
for (int i = 0; i<=12; i++) { | |
sb.append("%" + spacing + "s"); | |
args.add(i); | |
} | |
String s = String.format(sb.toString(), args.toArray()); | |
int l = s.length(); | |
String n = "-"; | |
System.out.println(s); | |
s = new String(new char[l]).replace("\0", n); | |
System.out.println(s); | |
} | |
public void printGuitarAsNoteIntegers() { | |
int spacing = 5; | |
printFrets(spacing); | |
StringBuilder sb = new StringBuilder(); | |
List<Integer> args = new ArrayList<>(); | |
for (int string = 5; string >= 0; string-- ) { | |
sb.append(string+1); | |
sb.append(" |"); | |
for (int fret = 0; fret <= 12; fret++) { | |
sb.append("%" + spacing + "s"); | |
args.add(guitar[fret][string].getNote()); | |
} | |
sb.append("\n"); | |
} | |
System.out.print(String.format(sb.toString(), args.toArray())); | |
System.out.println("S^"); | |
} | |
public void printGuitarAsNoteNames() { | |
int spacing = 10; | |
printFrets(spacing); | |
StringBuilder sb = new StringBuilder(); | |
List<String> args = new ArrayList<>(); | |
for (int string = 5; string >= 0; string-- ) { | |
sb.append(string+1); | |
sb.append(" |"); | |
for (int fret = 0; fret <= 12; fret++) { | |
sb.append("%" + spacing + "s"); | |
args.add(guitar[fret][string].getPitchClass()); | |
} | |
sb.append("\n"); | |
} | |
System.out.print(String.format(sb.toString(), args.toArray())); | |
System.out.println("S^"); | |
} | |
public void printGuitarAsOctaves() { | |
int spacing = 5; | |
printFrets(spacing); | |
StringBuilder sb = new StringBuilder(); | |
List<Integer> args = new ArrayList<>(); | |
for (int string = 5; string >= 0; string-- ) { | |
sb.append(string+1); | |
sb.append(" |"); | |
for (int fret = 0; fret <= 12; fret++) { | |
sb.append("%" + spacing + "s"); | |
args.add(guitar[fret][string].getOctave()); | |
} | |
sb.append("\n"); | |
} | |
System.out.print(String.format(sb.toString(), args.toArray())); | |
System.out.println("S^"); | |
} | |
public void printGuitarAsScaleDegrees() { | |
int spacing = 5; | |
printFrets(spacing); | |
StringBuilder sb = new StringBuilder(); | |
List<String> args = new ArrayList<>(); | |
for (int string = 5; string >= 0; string-- ) { | |
sb.append(string+1); | |
sb.append(" |"); | |
for (int fret = 0; fret <= 12; fret++) { | |
sb.append("%" + spacing + "s"); | |
args.add(guitar[fret][string].getDegree()); | |
} | |
sb.append("\n"); | |
} | |
System.out.print(String.format(sb.toString(), args.toArray())); | |
System.out.println("S^"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Scanner; | |
public class Main { | |
public static void main(String[] args) { | |
int strings = 6, frets = 24; | |
System.out.println("Here's your Guitar!\n"); | |
Guitar g = new Guitar(frets, strings); | |
g.printFrets(5); | |
for (int i = 6; i >0; i--) { | |
System.out.println(i + " |"); | |
} | |
System.out.println("S^"); | |
System.out.println("\nWe've given you 6 strings, 12 frets, and put it in Standard Tuning (EADGBE).\n"); | |
System.out.println("Here's your guitar with all the note labeled:\n"); | |
g.printGuitarAsNoteNames(); | |
boolean cont = true; | |
int opt; | |
while(cont) { | |
System.out.println("\nOk what do you want to do?"); | |
System.out.println("\t1: View notes\n\t2: View notes in integer notation\n\t" + | |
"3: View note octaves\n\t4: Find notes in a key\n\t5: Exit\n"); | |
System.out.println("Enter selection: "); | |
Scanner input = new Scanner(System.in); | |
opt = input.nextInt(); | |
switch (opt) { | |
case 1: { | |
g.printGuitarAsNoteNames(); | |
break; | |
} | |
case 2: { | |
g.printGuitarAsNoteIntegers(); | |
break; | |
} | |
case 3: { | |
g.printGuitarAsOctaves(); | |
break; | |
} | |
case 4: { | |
Song s = new Song(); | |
s.queryForSongInfo(); | |
g.setAllDegrees(s.getScale()); | |
s.getScale().printScaleDegrees(); | |
System.out.println("\nHere are those notes, in \"" + s.getKey() + "\", on your guitar"); | |
g.printGuitarAsScaleDegrees(); | |
break; | |
} | |
case 5: { | |
System.out.println("See ya!"); | |
cont = false; | |
break; | |
} | |
default: { | |
System.out.println("Invalid input, please choose enter either 1, 2, 3, or 4."); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Note implements Comparable<Note> { | |
private static String[] pitchClassOpt = {"C", "C#/Db", "D", "D#/Eb", "E", "F", "F#/Gb", "G", "G#/Ab", "A", "A#/Bb", "B"}; | |
private int octave; | |
private int note; | |
private String pitchClass; | |
private String degree; | |
public Note(int note, int octave) { | |
this.octave = octave; | |
this.note = note; | |
this.pitchClass = pitchClassOpt[note]; | |
this.degree = null; // Calculated after key signature is selected | |
} | |
@Override | |
public int compareTo(Note other) { | |
// compareTo should return < 0 if this is supposed to be | |
// less than other, > 0 if this is supposed to be greater than | |
// other and 0 if they are supposed to be equal | |
int n1 = this.getNote() + (12 * this.getOctave()); | |
int n2 = other.getNote() + (12 * other.getOctave()); | |
return Integer.compare(n1, n2); | |
} | |
public int getNote() { | |
return this.note; | |
} | |
public int getOctave() { | |
return this.octave; | |
} | |
public String getPitchClass() { | |
return pitchClass; | |
} | |
public String getDegree() { | |
return degree; | |
} | |
public void setDegree(String degree) { | |
this.degree = degree; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Scale { | |
private final String[] majorSignatures = {"C", "G", "D", "A", "E", "B", "F#", "Db", "Ab", "Eb", "Bb", "F"}; // omitting enharmonic cb, c#, gb | |
private final String[] minorSignatures = {"Am", "Em", "Bm", "F#m", "C#m", "Abm", "Ebm", "Bbm", "Fm", "Cm", "Gm", "Dm"}; // omitting enharmonic g#, d#, a# | |
private final String[] chromaticSharpFive = {"1", "b2", "2", "b3", "3", "4", "b5", "5", "#5", "6", "b7", "7"}; | |
private final String[] chromaticFlatSix = {"1", "b2", "2", "b3", "3", "4", "b5", "5", "b6", "6", "b7", "7"}; | |
private final int[] majorDegrees = {0, 2, 4, 5, 7, 9, 11}; | |
private final int[] minorDegrees = {0, 2, 3, 5, 7, 8, 10}; | |
private int keySig; | |
private boolean isMajor = false; | |
public Scale() {} | |
public void printScaleDegrees() { | |
if (isMajor) { | |
System.out.print("The notes of a major key signature are the "); | |
for (int i = 0; i < 6; i++) { | |
System.out.print(chromaticSharpFive[majorDegrees[i]] + ", "); | |
} | |
System.out.println("and the " + chromaticSharpFive[majorDegrees[6]] + "."); | |
} else { | |
System.out.print("The notes of a minor key signature are the "); | |
for (int i = 0; i < 6; i++) { | |
System.out.print(chromaticFlatSix[minorDegrees[i]] + ", "); | |
} | |
System.out.println("and the " + chromaticFlatSix[minorDegrees[6]] + "."); | |
} | |
} | |
public String calcNoteDegree(Note n) { | |
int degree = (n.getNote()-keySig); | |
if (degree < 0) { | |
degree+=12; | |
} else { | |
degree = (degree % 12); | |
} | |
boolean isInScale = false; | |
if (isMajor) { | |
for(int i=0; i<7; i++) { | |
if (majorDegrees[i]==degree) { | |
isInScale=true; | |
break; | |
} | |
} | |
} else { | |
for(int i=0; i<7; i++) { | |
if (minorDegrees[i]==degree) { | |
isInScale=true; | |
break; | |
} | |
} | |
} | |
if(isInScale) { | |
return isMajor ? chromaticSharpFive[degree] : chromaticFlatSix[degree]; | |
} else { | |
return " "; | |
} | |
} | |
// Assume input is of the form note letter + (optional) accidental + (optional) minor signifier | |
public int getKeySigAsInt(String key) { | |
int ks = 0; | |
if (key.indexOf('m')==-1) { | |
isMajor=true; | |
for(int i=0; i<12; i++) { | |
if (key.equals(majorSignatures[i])) { | |
break; | |
} | |
ks=(ks+7)%12; // Calculates position relative to C Major moving clockwise around circle of fifths | |
} | |
} | |
else { | |
isMajor=false; | |
for(int i=0; i<12; i++) { | |
if (key.equals(minorSignatures[i])) { | |
break; | |
} | |
ks=(ks+7)%12; | |
} | |
ks=(ks+9)%12; // Calculates position relative to A Minor moving clockwise around circle of fifths | |
} | |
return ks; | |
} | |
public void printKeySignature() { | |
System.out.println(" (int notation: " + keySig + ")"); | |
} | |
public void setKeySig(int keySig) { | |
this.keySig = keySig; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Scanner; | |
public class Song { | |
private Scale scale; | |
private String key; | |
public Song() {} | |
public Scale getScale() { | |
return scale; | |
} | |
public String getKey() { | |
return key; | |
} | |
public void queryForSongInfo() { | |
Scanner input = new Scanner(System.in); | |
System.out.println("Choose a Key Signature:\n\tMajor options: C, G, D, A, E, B, F#, Db, Ab, Eb, Bb, F" + | |
"\n\tMinor options: Am, Em, Bm, F#m, C#m, Abm, Ebm, Bbm, Fm, Cm, Gm, Dm"); | |
System.out.println("\nEnter key (case-sensitive): "); | |
key = input.nextLine(); | |
while (!key.matches("(?![EB]#)(?![FC]b)([A-G])([#b])?([m])?")) { | |
System.out.println("You have entered an invalid key. Please enter one from either a major key " + | |
"(C, G, D, A, E, B, F#, Db, Ab, Eb, Bb, F)" + " or one from a minor key " + | |
"(Am, Em, Bm, F#m, C#m, Abm, Ebm, Bbm, Fm, Cm, Gm, Dm)."); | |
System.out.println("Enter Key Signature:"); | |
key = input.nextLine(); | |
} | |
this.scale = new Scale(); | |
scale.setKeySig( scale.getKeySigAsInt(key) ); | |
System.out.print("Key: " + key ); | |
scale.printKeySignature(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment