package com.PP.LunarTabsAndroid.InstrumentModels; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import com.PP.LunarTabsAndroid.UI.DataModel; import com.PP.LunarTabsAndroid.UI.ResourceModel; import com.example.lunartabsandroid.R; import android.content.Context; import android.util.Log; public class ChordDB { //db structures private List<List<String>> chordNotes; private List<String> chordNames; private Map<String,String> chordHashToName; /** * Singleton pattern */ private ChordDB() {} private static ChordDB instance; public static ChordDB getInstance() { if(instance==null) { instance = new ChordDB(); instance.generateChordDB(); } return instance; } /** * Debug function for contents of database. */ public void debugDump() { for(int x=0; x < chordNotes.size(); x++) { Log.d("DUMP", chordNames.get(x) + " : " + chordNotes.get(x)); } } /** * Chord formulas * @return */ protected List<int[]> getFormulas() { //create formulas //evil -- incorrect solution //LET THIS BE A LESSON TO COMPUTATIONAL MUSIC STUDENTS!!!! //A MAJOR 2 is DIFFERENT FROM A MINOR 2. //HOW TO REALLY SCREW UP A SOFTWARE RELEASE! RIGHT HERE! /* int[] MAJOR_CHORD = {1,3,5}; int[] MINOR_CHORD = {1,2,5}; int[] ADD4_CHORD = {1,3,4,5}; int[] D7_CHORD = {1,3,5,6}; int[] DIM_CHORD = {1,2,4}; */ //correct solution int[] MAJOR = {0,4,7}; int[] SUS = {0,5,7}; int[] MINOR = {0,3,7}; int[] AUG = {0,4,8}; int[] DIM = {0,3,6}; int[] MAJOR_6TH = {0,4,7,9}; int[] MAJOR_7TH = {0,4,7,11}; int[] DOM_7TH = {0,4,7,10}; int[] DOM_7TH_SUS4 = {0,5,7,10}; int[] MINOR_6TH = {0,3,7,9}; int[] MINOR_MAJ7 = {0,4,7,11}; int[] MINOR_7TH = {0,3,7,10}; int[] MAJ_7TH_N5 = {0,4,8,11}; int[] AUG_7TH = {0,4,8,10}; int[] MIN_7TH_b5 = {0,3,6,10}; int[] DIM_7TH = {0,3,6,9}; int[] ADD4 = {0,4,5,7}; //add to structure List<int[]> rtn = new ArrayList<int[]>(); rtn.add(MAJOR); rtn.add(SUS); rtn.add(MINOR); rtn.add(AUG); rtn.add(DIM); rtn.add(MAJOR_6TH); rtn.add(MAJOR_7TH); rtn.add(DOM_7TH); rtn.add(DOM_7TH_SUS4); rtn.add(MINOR_6TH); rtn.add(MINOR_MAJ7); rtn.add(MINOR_7TH); rtn.add(MAJ_7TH_N5); rtn.add(AUG_7TH); rtn.add(MIN_7TH_b5); rtn.add(DIM_7TH); rtn.add(ADD4); return rtn; } /** * Descriptors for chord formulas * @return */ protected String[] getDescriptors() { return ResourceModel.getInstance().CHORD_DESCRIPTORS; } /** * Hash function for chords * @param chordNotes * @return Hash */ public static String chordHash(List<String> chordNotes) { // chordNotes = ListUtil.unique(chordNotes); // Collections.sort(chordNotes); StringBuffer rtn = new StringBuffer(); for(int x=0; x < chordNotes.size(); x++) { rtn.append(chordNotes.get(x)); } return rtn.toString(); } /** * Init chord database. */ public void generateChordDB() { chordNotes = new ArrayList<List<String>>(); chordNames = new ArrayList<String>(); chordHashToName = new HashMap<String,String>(); List<int[]> formulas = getFormulas(); for(int x=0; x < GuitarModel.MUSIC_NOTES_SHARP.length; x++) { for(int y=0; y < formulas.size(); y++) { //generate data String chordName = GuitarModel.MUSIC_NOTES_SHARP[x].replaceAll("#", "-"+ResourceModel.getInstance().SHARP) + " " + getDescriptors()[y]; List<String> notesInChord = generateChord(GuitarModel.MUSIC_NOTES_SHARP[x],formulas.get(y),getDescriptors()[y]); String chordHash = chordHash(notesInChord); //store in database chordNames.add(chordName); chordNotes.add(notesInChord); chordHashToName.put(chordHash, chordName); } } } public List<String> generateChord(String rootNote, int[] formula, String descriptor) { //find root note index int rootIndex = GuitarModel.getInstance().getNoteIndex(rootNote); //create list of notes in chord List<String> rtn = new ArrayList<String>(); for(int x=0; x < formula.length; x++) { int index = (formula[x]+rootIndex) % GuitarModel.MUSIC_NOTES_SHARP.length; rtn.add(GuitarModel.MUSIC_NOTES_SHARP[index]); } //maintain data in lex sorted order rtn = ListUtil.unique(rtn); Collections.sort(rtn); //return return rtn; } /** * @return the chordNotes */ public List<List<String>> getChordNotes() { return chordNotes; } /** * @return the chordNames */ public List<String> getChordNames() { return chordNames; } /** * @return the chordHashToName */ public Map<String, String> getChordHashToName() { return chordHashToName; } }