1import pyglet 2 3 4class Keyboard: 5 def __init__(self): 6 """A VERY basic semi-realtime synthesizer.""" 7 self.window = pyglet.window.Window(720, 480) 8 instructions = "Press keys on your keyboard to play notes." 9 self.instructions = pyglet.text.Label(text=instructions, font_size=20, x=10, y=10) 10 self.current_note = pyglet.text.Label(text="", font_size=33, x=50, y=200) 11 12 self.c4_notes = {"C": 261.63, "C#": 277.183, 13 "D": 293.66, "D#": 311.127, 14 "E": 329.63, 15 "F": 349.23, "F#": 369.994, 16 "G": 392.00, "G#": 415.305, 17 "A": 440.00, "A#": 466.164, 18 "B": 493.88, "R": 0} 19 20 self.key_map = {pyglet.window.key.S: "C#", 21 pyglet.window.key.D: "D#", 22 pyglet.window.key.G: "F#", 23 pyglet.window.key.H: "G#", 24 pyglet.window.key.J: "A#", 25 pyglet.window.key.L: "C#", 26 pyglet.window.key.SEMICOLON: "D#", 27 pyglet.window.key.Z: "C", 28 pyglet.window.key.X: "D", 29 pyglet.window.key.C: "E", 30 pyglet.window.key.V: "F", 31 pyglet.window.key.B: "G", 32 pyglet.window.key.N: "A", 33 pyglet.window.key.M: "B", 34 pyglet.window.key.COMMA: "C", 35 pyglet.window.key.PERIOD: "D", 36 pyglet.window.key.BACKSLASH: "E"} 37 38 self.note_cache = {} 39 40 @self.window.event 41 def on_key_press(key, mod): 42 try: 43 self.play_note(self.c4_notes[self.key_map[key]]) 44 self.current_note.text = "Current note: {0}".format(self.key_map[key]) 45 except KeyError: 46 pass 47 48 @self.window.event 49 def on_draw(): 50 self.window.clear() 51 self.instructions.draw() 52 self.current_note.draw() 53 54 def play_note(self, frequency, length=0.6): 55 if frequency in self.note_cache: 56 note_wave = self.note_cache[frequency] 57 note_wave.play() 58 else: 59 adsr = pyglet.media.synthesis.ADSREnvelope(0.05, 0.2, 0.1) 60 note_wave = pyglet.media.StaticSource( 61 pyglet.media.synthesis.Sawtooth(duration=length, frequency=frequency, envelope=adsr)) 62 self.note_cache[frequency] = note_wave 63 note_wave.play() 64 65 66if __name__ == "__main__": 67 keyboard = Keyboard() 68 pyglet.app.run() 69