def closestChord(allFrets, bestChords, allChords): # this method is basically a rough adaptation of # how I remembered the shorest path algorithm. # Each level of recursion that a chord goes down # adds another note to it. If best chords have # 5 chords in it then the best 5 chords have been made, # so exit and if allchords is empty then # all combinations have been tried to exit if ((len(bestChords) == 5) or (len(allChords) == 0)): return # get the chord with the lowest score from heap chord = heapq.heappop(allChords) # if the chord holds all of the notes in it then it is finished if (len(allFrets) <= chord.numNotes): # this for loop sees if the finished # chord is a duplicate, if so move on for x in range(0, len(bestChords)): if chord.__eq__(bestChords[x]): # continue recursion closestChord(allFrets, bestChords, allChords) return # tail recursion bestChords.append(chord) # add the finished chord to the list closestChord(allFrets, bestChords, allChords) # continue recursion return # tail recursion numNotes = chord.numNotes # finds which note the chord is on # the loop gets the frets of the next note to be for y in range(0, len(allFrets[numNotes])): # makes sure that the string that the fret is on is not in use if (chord.frets[allFrets[numNotes][y].string] is None): # this makes sure the note being added # is not lower than the bass note if (chord.bass <= allFrets[numNotes][y].note.numValue): # add fret to chord chord.frets[allFrets[numNotes] [y].string] = allFrets[numNotes][y] # create a new chord to add the new fret onto tempChord = Chord(chord.frets) tempChord.bass = chord.bass # set the bass note of new chord # creates a new chord using the base chord's notes so that # the base chord can be altered without altering the new chord # Push it onto the heap heapq.heappush(allChords, tempChord) # remove the fret from the base chord so that other # frets on the note can be added to the chord chord.frets[allFrets[numNotes][y].string] = None closestChord(allFrets, bestChords, allChords) # continue recursion return # tail recursion
def chordCreate(notes, tuning, numFrets, targetFret, low, high, fretsOnStrings, isBass): app.logger.debug('in chordCreate') # list that will hold all of the possible frets that # can be played with the given notes allFrets = [] for note in notes: # returns the frets that each note can be played on frets = getFrets(note, tuning, numFrets, targetFret, low, high) frets = sortStuff(frets) # sort the frets by distance to the target for fret in frets: # makes sure not to add duplicate frets # if the user say has two of the same note if fret not in fretsOnStrings[fret.string]: # this will store all of the frets that # can be played on each string for the ui fretsOnStrings[fret.string].append(fret) allFrets.append(frets) strings = [None] * 6 # create a 6 unit long list full of None baseChord = Chord(strings) # This is a chord with no notes in it bestChords = [] # stores the five best chords allChords = [] # stores all of the chords that get created in method # creates chords that each hold only one fret of the first note if (len(allFrets) > 0): for fret in allFrets[0]: # get each possible fret of the first note # add the fret of the first note to the baseChord baseChord.frets[fret.string] = fret # create a new chord with the strings tempChord = Chord(baseChord.frets) if (bool(isBass)): # if the user wants to use a bass note this will set it, # it is intialized to 0 otherwise tempChord.bass = fret.note.numValue heapq.heappush(allChords, tempChord) # heap push it to allChords # remove the fret so that the chord is empty again baseChord.frets[fret.string] = None # this is the method that finds the best chords closestChord(allFrets, bestChords, allChords) if len(bestChords) >= 1: # this means at least one chord was found return bestChords # The chord is not possible to make errorStrings = [] for x in range(0, 6): errorStrings.append(Fret(-1, -1, 100, Note(0))) bestChords.append(Chord(errorStrings)) # returns an array holding only one chord with no notes in it return bestChords