Building the chord finder section

Now that we have had a glimpse of working with JSON files, this should be easy. Let's take a look at the first few lines of the chords.json file from the json directory:

{
"Major" : [0, 4, 7],
"Minor" : [0, 3, 7],
"Sus4" : [0, 5, 7],
"5" : [0, 4, 6],
"Diminished" : [0, 3, 6],
...
}

This is very similar to the scales structure. Let's say we want to figure out what the C# major chord would look like. So we start with the C# key, which is 0. Then we look at the list of major chords, which read: [0, 4, 7]. So starting at C# the next key to highlight is 4 semitones above and the next is 7 semitones above C#. So the final chord structure for the C# major chord would be:

C#,    (C# + 4 semitones) ,      (C# + 7 semitones) 

The GUI is also very similar to the scales section:

We begin by adding a constant for the path to the chords.json file in  7.05 constants.py:

CHORDS_JSON_FILE = '../json/chords.json'

Next, we read the contents of this file in a new class attribute, self.chords:

 with open(CHORDS_JSON_FILE, 'r') as f:
self.chords = json.load(f, object_pairs_hook=OrderedDict)

We then modify the chords frame GUI to add two combobox (see the complete GUI in 7.05 view.py build_chords_frame):

self.chords_selector = ttk.Combobox(self.chords_frame,  values=[k for k 
in self.chords.keys()])
self.chords_selector.current(0)
self.chords_selector.bind("<<ComboboxSelected>>", self.on_chord_changed)
self.chords_selector.grid(row=1, column=1, sticky='e', padx=10,
pady=10)
self.chords_key_selector = ttk.Combobox(self.chords_frame, values=[k
for k in KEYS])
self.chords_key_selector.current(0)
self.chords_key_selector.bind("<<ComboboxSelected>>", self.on_chords_key_changed)

Next, we added the two event callbacks defined previously:

def on_chord_changed(self, event):
self.remove_all_key_highlights()
self.find_chord(event)

def on_chords_key_changed(self, event):
self.remove_all_key_highlights()
self.find_chord(event)

 The find_chord method queries the self.chords dict for the keys to be highlighted, adds the key offsets from the root note, and calls it to be highlighted and played:

def find_chord(self, event=None):
self.selected_chord = self.chords_selector.get()
self.chords_selected_key = self.chords_key_selector.get()
index_of_selected_key = KEYS.index(self.chords_selected_key)
self.keys_to_highlight = [ ALL_KEYS[i+index_of_selected_key] for
i in self.chords[self.selected_chord]]
self.highlight_list_of_keys(self.keys_to_highlight)
play_chord_in_new_thread(self.keys_to_highlight)

The final code in this iteration modifies the on_mode_changed method to highlight the chord as soon as the chord mode is selected:

 def on_mode_changed(self, event):
self.remove_all_key_highlights()
selected_mode = self.mode_selector.get()
if selected_mode == 'Scales':
self.show_scales_frame()
self.find_scale()
elif selected_mode == 'Chords':
self.show_chords_frame()
self.find_chord()
elif selected_mode == 'Chord Progressions':
self.show_progressions_frame()

That concludes the iteration. If you now run 7.05 view.py, you will find a functional chords section that lets us find chords of different varieties in different scales.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.205.99