Mit dem Raspberry Pi Musik machen und "Alle meine Entchen" spielen
Diesmal wollen wir das Sirene-Projekt aus dem letzten Teil ein bisschen abwandeln und versuchen, dem Raspberry Pi eine Melodie zu entlocken.Eine Warnung gleich vorweg: Die Melodie wird grauenhaft klingen und so mancher Ton wird daneben liegen. Das liegt vor Allem daran, dass das Timing nicht perfekt ist, weil der Raspberry auch noch mit anderen Dingen beschäftigt ist. Besonders bei Aktivität wird es sehr schräg werden.
Als Melodie habe ich mich etwas ganz einfaches ausgesucht, nämlich "Alle meine Entchen". Ich bin nämlich nicht gerade musikalisch, aber hier hat es gerade noch bei mir gereicht, die Noten zu lesen. Außerdem sollte es etwas sein, dass man leicht wiedererkennen kann.
Und so hört sich das Ganze an:
# -*- encoding: utf-8 -*-
# 2018 by Oliver Kuhlemann
# Bei Verwendung freue ich mich über Namensnennung,
# Quellenangabe und Verlinkung
# Quelle: http://cool-web.de/raspberry/
import RPi.GPIO as GPIO # Funktionen für die GPIO-Ansteuerung laden
import time # für sleep() (Pause) nötig
import sys # um die übergebenen Parameter von der Shell abzufragen
GPIO.setmode(GPIO.BCM) # die GPIO-Pins im BCM-Modus ansprechen
led=14 # LED/Speaker hängen an BCM-Pin 14
GPIO.setup(led, GPIO.OUT) # in den Pin wird "geschrieben"
# Nachfolgend werden die Frequenzen in Hertz für einige Klaviernoten definiert
noten = {"c4":261.626, "c#4":277.183, "d4":293.665, "d#4":311.127, "e4":329.628, "f4":349.228, "f#4":369.994, "g4":391.995, "g#4":415.305, "a4":440, "a#4":466.164, "b4":493.883,
"c5":523.251, "c#5":554.365, "d5":587.330, "d#5":622.254, "e5":659.255, "f5":698.456, "f#5":739.989, "g5":783.991, "g#5":830.609, "a5":880, "a#5":932.328, "b5":987.767 }
tGanze=0.75 # wieviele Sekunden dauert eine ganze Note?
pNote=0.04 # Pause / Stille zwischen Noten
def sound(freq, t): # Diese Funktion erzeugt eine bestimmte Zeit t lang
dur=1.0/freq/2.0 # die Frequenz freq
anz=int(t/dur/2)
for i in range (0,anz):
GPIO.output(led, GPIO.HIGH)
time.sleep (dur)
GPIO.output(led, GPIO.LOW)
time.sleep (dur)
def spieleNote (note, xtel):
try:
freq = noten[note]
except KeyError:
print "Die Note " + note + " ist nicht definiert."
return
t = tGanze / xtel
sound (freq, t)
time.sleep (pNote)
print "Spiele Alle Meine Entchen (4/4 Takt)..."
spieleNote("c4", 4) # Al-
spieleNote("d4", 4) # le
spieleNote("e4", 4) # mei-
spieleNote("f4", 4) # ne
spieleNote("g4", 2) # Ent-
spieleNote("g4", 2) # chen
spieleNote("a4", 4) # schwim-
spieleNote("a4", 4) # men
spieleNote("a4", 4) # auf
spieleNote("a4", 4) # dem
spieleNote("g4", 1) # See,
spieleNote("a4", 4) # schwim-
spieleNote("a4", 4) # men
spieleNote("a4", 4) # auf
spieleNote("a4", 4) # dem
spieleNote("g4", 1) # See,
spieleNote("f4", 4) # Köpf-
spieleNote("f4", 4) # chen
spieleNote("f4", 4) # in
spieleNote("f4", 4) # dem
spieleNote("e4", 2) # Was-
spieleNote("e4", 2) # ser
spieleNote("d4", 4) # Schwänz-
spieleNote("d4", 4) # chen
spieleNote("d4", 4) # in
spieleNote("d4", 4) # die
spieleNote("c4", 1) # Höh.
GPIO.cleanup() # Programm sauber verlassen und Resourcen wieder freigeben
tGanze definiert, wie lange eine ganze Note in Sekunden dauert. Eine halbe Note dauert dann entsprechend halb so lang. Je kleine tGanze ist, je schneller wird das Musikstück gespielt. Es ist wichtig, die Zahl als Fließkommazahl anzugeben, also 1.0 statt 1. Sonst interpretiert Python die Zahl als Integer und hat nachfolgend Schwierigkeit, damit zu rechnen.pNote ist die Pause in Sekunden zwischen dem Anschlage zwischen zwei Noten, also im Prinzip wie lange z. B. ein Pianist braucht, um von einer Taste zur nächsten zu kommen.
Die Funktion sound(freq, t): kennen wir ja schon aus unserem Sirenen-Projekt.
Darauf baut die Funktion spieleNote (note, xtel) auf. Diese versucht (Befehlswort try) die übergebene Note note im Dictionary noten zu finden. Ist dies nicht der Fall, tritt ein Fehler namens KeyError auf, der durch except KeyError: abgefangen wird. Es wird dann eine Fehlermeldung ausgegeben und die Nicht-Note ignoriert (return verlässt die Funktion augenblicklich).
Außer der Note wird noch die Notenlänge als xtel übergeben, wobei 1 für 1/1, also eine ganze, 2 für 1/2, also eine halbe, 4 für 1/4, also eine viertel und 8 für eine achtel Note steht. Nach dem Spielen einer Note wird eine kurze Pause pNote eingelegt, sonst klingt es ein wenig komisch.
Nachfolgend sieht man am Beispiel von "Alle meine Entchen", wie man die einzelnen Noten eines Liedes abspielt. Bereits definiert sind die zwei Oktaven 4 und 5 samt der Zwischennoten (den schwarzen Tasten auf dem Klavier), wobei c#4 zwischen c4 und d4 liegt. Ihr dürft das Dictionary gern erweitern, falls nötig. Die nötigen Frequenzen findet ihr z. B. hier oder indem ihr nach ihr nach noten frequenzen googelt. Falls ihr eine tolle, eigene Melodie geschrieben habt, dann schickt sie mir doch einfach per e-mail (am Ende der Seite). Viel Spaß beim Experimentieren und Komponieren!