Skip to content

Instantly share code, notes, and snippets.

@hkailahi
Created March 4, 2017 00:56
Show Gist options
  • Save hkailahi/b4b83782f2f9dd44d4cd125eb2a39571 to your computer and use it in GitHub Desktop.
Save hkailahi/b4b83782f2f9dd44d4cd125eb2a39571 to your computer and use it in GitHub Desktop.
Guitar Notes
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^");
}
}
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.");
}
}
}
}
}
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;
}
}
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;
}
}
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