#!/usr/bin/env python import pygame import pygame.midi from os import environ from pygame.locals import QUIT, JOYBUTTONUP, JOYBUTTONDOWN, \ JOYAXISMOTION, JOYHATMOTION # Braucht man fuer die Abfrage-Rate clock = pygame.time.Clock() # Bekannte Joysticks (ich verwende aber nur den ersten) JOYSTICKS = [] # Redefinition Buttons (bei sind es zufaellig 0,1,2,3) BUTTONS = {0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,11:8} # Verwandle die gedrueckten Buttons ueber Bits in eine Zahl (Button 0 und 1 gedrueckt waeren dann 2^0 + 2^1 = 3) PRESSED = 0 # Midi-Offset (Leersaiten E2,A2,D3,G3,B3,E4) MOF = {0:28,1:33,2:38,3:43,4:47,5:52} CAPO = 12 # In welchem Bund sind die Saiten gedrueckt (-1 = nicht gespielt, 0 = Leersaite, 1 = 1. Bund usw.) CHORDS = { "A":[-1,0,2,2,2,0], "Am":[-1,0,2,2,1,0], "B":[-1,2,4,4,4,2], "Bm":[-1,2,4,4,3,2], "C":[-1,3,2,0,1,0], "Cm":[-1,3,5,5,4,3], "D":[-1,-1,0,2,3,2], "Dm":[-1,-1,0,2,3,1], "E":[0,2,2,1,0,0], "Em":[0,2,2,0,0,0], "F":[1,3,3,2,1,1], "Fm":[1,3,3,1,1,1], "G":[3,2,0,0,3,3], "Gm":[3,5,5,3,3,3] } MAP = { 16:"G", 64:"Em", 128:"C", 32:"D", 4:"Am", 80:"F", 192:"E", 160:"B", 36:"A" } # Hilfsfunktionen fuer die Bit-Manipulation (PRESSED) def setbit(int_type, offset): mask = 1 << offset return(int_type | mask) def clearbit(int_type, offset): mask = ~(1 << offset) return(int_type & mask) def proc_event(event,midi_out): global PRESSED global CAPO "Parse and act upon event" if event.type == QUIT: print("Received event 'Quit', exiting.") exit(0) elif event.type == JOYAXISMOTION: print("axis %d value %0.3f" % (event.axis, event.value)) print PRESSED try: # Bei analogen Joysticks erst ab einem Fuenftel reagieren if event.value > 0.2 or event.value < -0.2: if PRESSED > 0: CHORD = MAP[PRESSED] print CHORD # Nach unten ist > 0 Chordarray wird von links nach rechts gespielt if event.value > 0: i = 0 j = 1 PLAY = CHORDS[CHORD] # nach oben halt von rechts nach links else: i = 5 j = -1 PLAY = CHORDS[CHORD][::-1] # Spiele jede Note fuer die angeschlagene Saite des Akkords for NOTE in PLAY: if NOTE > (-1): print MOF[i]+NOTE midi_out.note_on(MOF[i]+NOTE+CAPO,127) else: pass i += j except: pass elif event.type == JOYBUTTONDOWN: try: #print("button %d down." % event.button) PRESSED = setbit(PRESSED,BUTTONS[event.button]) #print("PRESSED = %s" % PRESSED) except: pass elif event.type == JOYBUTTONUP: try: #print("button %d up." % event.button) PRESSED = clearbit(PRESSED,BUTTONS[event.button]) #print("PRESSED = %s" % PRESSED) except: pass def main(): # Initialisieren pygame.init() pygame.midi.init() # Default-Ausgabe (normalerweise "Midi Through") port = pygame.midi.get_default_output_id() ###print ("using output_id :%s:" % port) # Latenz 0 (man kann es ja mal versuchen) midi_out = pygame.midi.Output(port, 0) # Was man nicht braucht, wird einfach abgeschaltet environ["SDL_VIDEODRIVER"] = "dummy" environ["SDL_AUDIODRIVER"] = "dummy" # Alle Joysticks, die du findest #for i in range(0, pygame.joystick.get_count()): # JOYSTICKS.append(pygame.joystick.Joystick(i)) # Ein Joystick/Controller reicht JOYSTICKS.append(pygame.joystick.Joystick(0)) JOYSTICKS[-1].init() print("Detected joystick '%s'" % JOYSTICKS[-1].get_name()) # 5 Millisekunden warten, bevor das Dingens hier weiterlaeuft clock.tick(50) while 1: try: for event in pygame.event.get(): proc_event(event,midi_out) except KeyboardInterrupt: del midi_out pygame.midi.quit() print("\n" "Interrupted") exit(0) if __name__ == "__main__": main()