156 lines
4.4 KiB
Python
156 lines
4.4 KiB
Python
#!/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()
|