def decompose(self, n=4, accuracy=30): if not hasattr(self, 'notes'): self.notes = [] if not hasattr(self, 'frequency_ranges'): self.frequency_ranges = [] self.note_integrals = {} self.note_counts = {} total_integral = 0 all_notes = Note.range('E2', 'B5') self.total_integral = sum(self.fft_out) for note in all_notes: self.note_integrals[str(note)] = 0 ranges = [*note.overtone_ranges(n, accuracy)] for chosen_note in self.notes: ranges = [*ranges, *chosen_note.overtone_ranges(n, accuracy)] ranges = FrequencyRange.simplify(ranges) for note_range in ranges: if note_range.start > self.fft_max: break start = self.get_index_of_frequency(note_range.start) start = np.max([0, start]) end = self.get_index_of_frequency(note_range.end) end = np.min([self.fft_count, end]) self.note_counts[str(note)] = end - start self.note_integrals[str(note)] += sum( list(self.fft_out[start:end])) for key in self.note_integrals: self.note_integrals[key] = ( self.note_integrals[key] / self.total_integral) - (self.note_counts[key] / self.fft_count)
def set_note_axes(self): plt.grid(True, which='major', axis='x') plt.grid(True, linestyle='--', which='minor', axis='x') major_tick_notes = Note.range(Note('E2'), Note('E7'), step=12) minor_tick_notes = list( filter(lambda n: n.note != 'E', Note.range(Note('E2'), Note('E7'), step=1))) ax = plt.gca() ax.set_xticks(list(map(lambda n: n.frequency, minor_tick_notes)), minor=True) ax.set_xticklabels(list(map(str, minor_tick_notes)), fontsize=5, rotation=90, minor=True) ax.set_xticks(list(map(lambda n: n.frequency, major_tick_notes)), minor=False) ax.set_xticklabels(list(map(str, major_tick_notes)), fontsize=10, rotation=90, minor=False)