def run(self, screen): screen_size = (1024,600) screen_color = (0, 0 ,0) #build frequency to note dictionary notes_dictionary = self.build_range() #sort the keys and turn into a numpy array for logical indexing frequencies = numpy.array(sorted(notes_dictionary.keys())) top_note = 24 #set it two octaves higher bottom_note = 0 #other variables screen = pygame.display.set_mode(screen_size) screen.fill(screen_color) input_note = 1 #the y value on the plot old_position = (0,0) #the last position of note played show_notes = True #show the note signal_level = 0 #volume level trys = 1 line = True sound_gate = 15 #zero is loudest possible input level target_note = 0 #closest note in the dictionary sound_recorder = SwhRecorder() #microphone while trys <> 0: trys += 1 for n in range(0, screen_size[0], 40): sound_recorder.setup() raw_data_signal = sound_recorder.getAudio() signal_level = round(abs(self.loudness(raw_data_signal)),2) #find the volume level from raw data try: input_note = round(freq_from_autocorr(raw_data_signal,sound_recorder.RATE),2) #find the freq from the audio sample except: input_note == 0 sound_recorder.close() if input_note > frequencies[len(notes_dictionary)-1] or input_note < frequencies[0]: #if the frequency is too high, do nothing continue if signal_level > sound_gate: #noise gate to prevent ambient noises continue target_note = self.closest_value_index(frequencies, round(input_note, 2)) #find the closest note in the note dictionary position = ((n), (screen_size[1]-(int(screen_size[1]/(frequencies[top_note]-frequencies[bottom_note]) * (input_note - frequencies[bottom_note])))) ) #user interface for event in pygame.event.get(): #quit program if event.type == QUIT: sound_recorder.close() return elif event.type == KEYDOWN: #increase top_note range if event.key == K_s: if top_note <= len(notes_dictionary)-7: top_note += 6 #decrease top note range no lower than an octave higher than bottom note if event.key == K_x: if top_note >= 6 and top_note >= bottom_note + 6: top_note -= 6 #increase bottom note range no higher than an octave lower than top note if event.key == K_a: if bottom_note < top_note: bottom_note += 6 #decrease bottom note range if event.key == K_z: if bottom_note >= 6: bottom_note -= 6 #quit program if event.key == K_q: sound_recorder.close() return if n == 0 or n == screen_size[0]: old_position = position #draw info box on top meter = "###################################" info_font = pygame.font.Font(None, 18) top_info = info_font.render( "Bottom : " + str(notes_dictionary[frequencies[bottom_note]]) + " : dec(z), inc(a) " + "Top : " + str(notes_dictionary[frequencies[top_note]]) + " : dec(x), inc(s) " #+ " Show Notes(n):" + str(show_notes) + " Lines(l):" + str(line) + " Loudness: " + meter[1:int(20-signal_level)] , 1, (255,255,255)) pygame.draw.rect(screen, (0,0,0), (0,0,screen_size[0],20)) pygame.draw.line(screen, (200,200,200),(0,20),(1024,20), 1) screen.blit(top_info, (5,5)) #draw lines if input_note < frequencies[len(notes_dictionary)-1]: if old_position < position: random_color = (randint(20,255),randint(20,255),randint(20,255)) pygame.draw.line(screen, random_color, old_position, position, 2) old_position = position #draw notes name font = pygame.font.Font(None, 30) text = font.render(str(notes_dictionary[frequencies[target_note]]), 1, (0,255,0)) screen.blit(text, (position)) #update the display pygame.display.flip() pygame.display.update() #clear screen at the end of every loop run screen.blit(screen, (0, 0)) screen.fill(screen_color)