Und jetzt das Erstaunliche: Pinfonie! [Blockierte Grafik: http://www.beautiful-homepage.de/images/pinfonie.jpg]
Auf beautiful-homepage.de ist die magische Pinfonie [326 KB MIDI-Datei] zu hören (für Download - Rechtsklick + "Ziel speichern unter...")
Das war meine erste Erfahrung mit Visual Basic - ich habe mir zum Ziel gesetzt, die erste halbe Million Nachkommastellen von der Zahl Pi (Verhältnis der Umkreislänge zum Durchmesser) in MIDI-Noten umzurechnen und mir anzuhören, wie die Zahl Pi klingt! Ich bin folgendermaßen vorgegangen:
3,14159265358979323846264338327950288...
1. Die ersten 10 Mio. Nachkommastellen als PDF-Datei heruntergeladen, die sogenannte "Pibel" bei den Freunden der Zahl Pi auf www.pibel.de.
2. PDF-Datei über die Zwischenablage in Textdatei umgewandelt.
3. Dann musste ich, um Absatzmarken und Leerräume zu entfernen, mein erstes VB-Programm schreiben - wenn man nämlich das Word für Windows mit einer solchen sisyphischen Aufgabe über "Suchen" und "Ersetzen" beauftragt, stürzt der Computer ab! Das Programm bestand aus einem einzigen Modul und sah so aus:
Alles anzeigen
Die Prozedur dauerte auf meinem Rechner zwar ganze 10 min lang, aber dann hatte ich die 10-Mio-Zeichen in einer ununterbrochenen Sequenz. Wozu das gut ist? Naja, zum Beispiel habe ich mich sehr gewundert, dass mein Geburtsdatum (6-Ziffern-Folge) dort "nur" 4 Mal vorkommt. Die Zahlensequenz 123456 - 13 Mal und die 111111 - bloß ein Mal... Ach, das gewährt schon Einblicke in die Natur der Dinge und hilft beim Lottospielen
4. Dann habe ich den Algorithmus der Zahlenumwandlung in die MIDI-Ereignisse bestimmt: Jede Pinfonie-Note hat mehrere Eigenschaften, die ich nun mit Dezimalzahlen kodieren sollte:
4.1. Trackzugehörigkeit (welches Instrument?) In meinem Orchester spielen 10 MIDI-Instrumente, also bedarf man fürs Codieren dieser Eigenschaft nur einer Dezimalstelle (0 bis 9)
4.2. Notenanfang (welcher Takt?) Ich hab mich für dieses Stück auf 1000 Takte festgelegt, so brauchte ich für Codieren drei Dezimalstellen (000 bis 999)
4.3. Notenanfang (welches Beat?) Innerhalb eines Taktes gab es für ein Ereignis 100 Möglichkeiten einzusetzen. Dafür hatte ich ein für konventionelle Musiker etwas ungewöhnliches Metrum gewählt, und zwar 100/128 beim Tempo von 55 bpm. 100 Optionen ergeben zwei Code-Stellen
4.4. Notenlänge. Meine Konvention für max. Notenlänge war ca. 30 sec, was 10 Takten entspricht (eine Stelle) plus die Note-Off Position innerhalb des Taktes (zwei Stellen) ergeben insgesamt drei Stellen
4.5. Tonhöhe. Hier wählte ich 100 Noten in chromatischer Anordnung von D1 bis A9, die man mit zwei Stellen kodieren kann.
4.6. Lautstärke. Hier musste ich 10 Möglichkeiten (eine Dezimalstelle) mit 128 MIDI-Lautstärken vereinbaren. Dies geschah mit einer Grundformel v = (f + 1) * 12,7
Zusammengefasst: 1+3+2+3+2+1=12, also brauchte man für das Codieren einer Note eine Zeichenfolge von 12 Ziffern. Um einen vollen Klang zu erwirken, beschloss ich, in meinem Werk, das knapp eine Stunde klingen sollte, 480 x 1024 = 491520 Nachkommastellen zu verarbeiten und erstellte eine 480 KB große TOREAD.TXT Datei, die diese beinhielt, fürs weitere Vorgehen. Die Dateigröße würde in meinem Programm prinzipiell durch die in VB 6.0 maximal mögliche Stringlänge ohnehin für einen Durchlauf auf 480 k limitiert werden, doch diese Datenmenge war mehr als ausreichend.
5. Nun schrieb ich ein Programm, das mir ermöglichte, die 491520-Stellen-lange Sequenz in 12er-Strings zu zerschneiden, und diese, je nach Anfangsziffer in zehn Dateien TRACK0.TXT bis TRACK9.TXT zu verteilen, und sie dort durch Absatzzeichen zu trennen. Dieses Programm sah so aus:
Alles anzeigen
6. Die eigentliche Umwandlung von 12er-Gruppen in MIDI-Ereignisse in Textform geschah mit dem folgenden Programm:
Alles anzeigen
7. Die letzten Schritte waren, die Ereignisse in den Tracks nach Ereigniszeit aufsteigend zu sortieren (z.B. mit Word für Windows), in einer Vorlage-Textdatei zusammenzufügen und das Textformat in MIDI-Format umzuwandeln. Das Letztere geschah mit der Hilfe des wunderbaren Programms von Jeff Glatt namens "MIDI File DisAssembler" (www.borg.com/~jglatt). Die Vorlage-Textdatei wurde aus einer in meinem MIDI-Sequenzer erstellten Vorlage-MIDI-Datei ebenfalls durch "MIDI File DisAssembler" erstellt.
Auf beautiful-homepage.de ist die magische Pinfonie [326 KB MIDI-Datei] zu hören (für Download - Rechtsklick + "Ziel speichern unter...")
Das war meine erste Erfahrung mit Visual Basic - ich habe mir zum Ziel gesetzt, die erste halbe Million Nachkommastellen von der Zahl Pi (Verhältnis der Umkreislänge zum Durchmesser) in MIDI-Noten umzurechnen und mir anzuhören, wie die Zahl Pi klingt! Ich bin folgendermaßen vorgegangen:
3,14159265358979323846264338327950288...
1. Die ersten 10 Mio. Nachkommastellen als PDF-Datei heruntergeladen, die sogenannte "Pibel" bei den Freunden der Zahl Pi auf www.pibel.de.
2. PDF-Datei über die Zwischenablage in Textdatei umgewandelt.
3. Dann musste ich, um Absatzmarken und Leerräume zu entfernen, mein erstes VB-Programm schreiben - wenn man nämlich das Word für Windows mit einer solchen sisyphischen Aufgabe über "Suchen" und "Ersetzen" beauftragt, stürzt der Computer ab! Das Programm bestand aus einem einzigen Modul und sah so aus:
Quellcode
- Sub Main()
- 'Entfernt Absatzmarken und Leerräume in TOREAD.TXT
- 'und schreibt die neue
- 'Zeichenfolge in
- 'TOWRITE.TXT hinein.
- Dim LineN As String, toread As String, towrite As String
- Dim LineNo As String
- toread = "C:\toread.txt"
- Open toread For Input As 101
- towrite = "C:\towrite.txt"
- Open towrite For Output As 102
- Do Until EOF(101)
- Line Input 101, LineN
- LineNo = Replace(LineN, " ", "")
- Print #102, LineNo
- Loop
- Close
- End Sub
Die Prozedur dauerte auf meinem Rechner zwar ganze 10 min lang, aber dann hatte ich die 10-Mio-Zeichen in einer ununterbrochenen Sequenz. Wozu das gut ist? Naja, zum Beispiel habe ich mich sehr gewundert, dass mein Geburtsdatum (6-Ziffern-Folge) dort "nur" 4 Mal vorkommt. Die Zahlensequenz 123456 - 13 Mal und die 111111 - bloß ein Mal... Ach, das gewährt schon Einblicke in die Natur der Dinge und hilft beim Lottospielen

4. Dann habe ich den Algorithmus der Zahlenumwandlung in die MIDI-Ereignisse bestimmt: Jede Pinfonie-Note hat mehrere Eigenschaften, die ich nun mit Dezimalzahlen kodieren sollte:
4.1. Trackzugehörigkeit (welches Instrument?) In meinem Orchester spielen 10 MIDI-Instrumente, also bedarf man fürs Codieren dieser Eigenschaft nur einer Dezimalstelle (0 bis 9)
4.2. Notenanfang (welcher Takt?) Ich hab mich für dieses Stück auf 1000 Takte festgelegt, so brauchte ich für Codieren drei Dezimalstellen (000 bis 999)
4.3. Notenanfang (welches Beat?) Innerhalb eines Taktes gab es für ein Ereignis 100 Möglichkeiten einzusetzen. Dafür hatte ich ein für konventionelle Musiker etwas ungewöhnliches Metrum gewählt, und zwar 100/128 beim Tempo von 55 bpm. 100 Optionen ergeben zwei Code-Stellen
4.4. Notenlänge. Meine Konvention für max. Notenlänge war ca. 30 sec, was 10 Takten entspricht (eine Stelle) plus die Note-Off Position innerhalb des Taktes (zwei Stellen) ergeben insgesamt drei Stellen
4.5. Tonhöhe. Hier wählte ich 100 Noten in chromatischer Anordnung von D1 bis A9, die man mit zwei Stellen kodieren kann.
4.6. Lautstärke. Hier musste ich 10 Möglichkeiten (eine Dezimalstelle) mit 128 MIDI-Lautstärken vereinbaren. Dies geschah mit einer Grundformel v = (f + 1) * 12,7
Zusammengefasst: 1+3+2+3+2+1=12, also brauchte man für das Codieren einer Note eine Zeichenfolge von 12 Ziffern. Um einen vollen Klang zu erwirken, beschloss ich, in meinem Werk, das knapp eine Stunde klingen sollte, 480 x 1024 = 491520 Nachkommastellen zu verarbeiten und erstellte eine 480 KB große TOREAD.TXT Datei, die diese beinhielt, fürs weitere Vorgehen. Die Dateigröße würde in meinem Programm prinzipiell durch die in VB 6.0 maximal mögliche Stringlänge ohnehin für einen Durchlauf auf 480 k limitiert werden, doch diese Datenmenge war mehr als ausreichend.
5. Nun schrieb ich ein Programm, das mir ermöglichte, die 491520-Stellen-lange Sequenz in 12er-Strings zu zerschneiden, und diese, je nach Anfangsziffer in zehn Dateien TRACK0.TXT bis TRACK9.TXT zu verteilen, und sie dort durch Absatzzeichen zu trennen. Dieses Programm sah so aus:
Quellcode
- Sub Main()
- 'Teilt eine Ziffernsequenz in TOREAD.TXT in 12er-Gruppen auf und schreibt
- 'diese je nach Anfangsziffer in Dateien TRACK1.TXT bis TRACK0.TXT
- 'Max. Dateigröße TOREAD.TXT 480 KB (491520 Zeichen) - 1'43'' Bearbeitungszeit
- Dim Twelver As String, BigString As String, WhatTrack As String
- Dim Digit1 As String
- Dim Digits89 As String, Digits10and11 As String, Digit12 As String
- Dim v As Double, OffStart As Integer, OffStartBar As Integer
- Dim m As Integer, a As Integer, b As Integer, c As Integer, h As Integer
- Dim d As Integer, e As Integer, f As Integer, g As Integer
- Open "c:\Pi\track1.txt" For Output As 91
- Open "c:\Pi\track2.txt" For Output As 92
- Open "c:\Pi\track3.txt" For Output As 93
- Open "c:\Pi\track4.txt" For Output As 94
- Open "c:\Pi\track5.txt" For Output As 95
- Open "c:\Pi\track6.txt" For Output As 96
- Open "c:\Pi\track7.txt" For Output As 97
- Open "c:\Pi\track8.txt" For Output As 98
- Open "c:\Pi\track9.txt" For Output As 99
- Open "c:\Pi\track0.txt" For Output As 100
- Open "c:\Pi\TOREAD.TXT" For Input As 101
- Input #101, BigString
- Schleife:
- Twelver = Left(BigString, 12)
- BigString = Mid$(BigString, 13)
- WhatTrack = Left(Twelver, 1)
- If WhatTrack = "1" Then Print #91, Twelver
- If WhatTrack = "2" Then Print #92, Twelver
- If WhatTrack = "3" Then Print #93, Twelver
- If WhatTrack = "4" Then Print #94, Twelver
- If WhatTrack = "5" Then Print #95, Twelver
- If WhatTrack = "6" Then Print #96, Twelver
- If WhatTrack = "7" Then Print #97, Twelver
- If WhatTrack = "8" Then Print #98, Twelver
- If WhatTrack = "9" Then Print #99, Twelver
- If WhatTrack = "0" Then Print #100, Twelver
- v = Len(BigString)
- If v > 11 Then GoTo Schleife
- Close
- End Sub
6. Die eigentliche Umwandlung von 12er-Gruppen in MIDI-Ereignisse in Textform geschah mit dem folgenden Programm:
Quellcode
- Sub Main()
- 'Verarbeitet 12-Digit-Rohevents in MIDI-Track-Daten.TXT
- Dim Twelver As String, Pon As String, Poff As String
- Dim Digits234 As String, Digits56 As String, Digit7 As String
- Dim Digits89 As String, Digits10and11 As String, Digit12 As String
- Dim v As Integer, OffStart As Integer, OffStartBar As Integer
- Dim m As Integer, a As Integer, b As Integer, c As Integer, h As Integer
- Dim d As Integer, e As Integer, f As Integer, g As Integer
- Open "c:\Pi-Tracks\track2.txt" For Input As 100
- Open "c:\Pi-Tracks\track2e.txt" For Output As 101
- Do Until EOF(100)
- Line Input #100, Twelver
- Digits234 = Mid$(Twelver, 2, 3)
- Digits56 = Mid$(Twelver, 5, 2)
- Digit7 = Mid$(Twelver, 7, 1)
- Digits89 = Mid$(Twelver, 8, 2)
- Digits10and11 = Mid$(Twelver, 10, 2)
- Digit12 = Mid$(Twelver, 12, 1)
- a = Val(Digits234) + 1
- b = Val(Digits56) + 1
- c = Val(Digit7) + 1
- d = Val(Digits89) + 1
- e = Val(Digits10and11)
- f = Val(Digit12)
- v = (f + 1) * 127 / 10
- m = ((f + 1) * 127) Mod 10
- If m >= 5 Then v = v + 1 Else v = v
- OffStart = a + c
- OffStartBar = b + d
- If OffStartBar > 100 Then g = OffStartBar - 100 Else g = OffStartBar
- If OffStartBar <= 100 Then h = OffStart Else h = OffStart + 1
- If e = 0 Then Pon = "D1"
- If e = 1 Then Pon = "D#1"
- If e = 2 Then Pon = "E1"
- If e = 3 Then Pon = "F1"
- If e = 4 Then Pon = "F#1"
- If e = 5 Then Pon = "G1"
- If e = 6 Then Pon = "G#1"
- If e = 7 Then Pon = "A1"
- If e = 8 Then Pon = "A#1"
- If e = 9 Then Pon = "B1"
- If e = 10 Then Pon = "C2"
- If e = 11 Then Pon = "C#2"
- If e = 12 Then Pon = "D2"
- If e = 13 Then Pon = "D#2"
- If e = 14 Then Pon = "E2"
- If e = 15 Then Pon = "F2"
- If e = 16 Then Pon = "F#2"
- If e = 17 Then Pon = "G2"
- If e = 18 Then Pon = "G#2"
- If e = 19 Then Pon = "A2"
- If e = 20 Then Pon = "A#2"
- If e = 21 Then Pon = "B2"
- If e = 22 Then Pon = "C3"
- If e = 23 Then Pon = "C#3"
- If e = 24 Then Pon = "D3"
- If e = 25 Then Pon = "D#3"
- If e = 26 Then Pon = "E3"
- If e = 27 Then Pon = "F3"
- If e = 28 Then Pon = "F#3"
- If e = 29 Then Pon = "G3"
- If e = 30 Then Pon = "G#3"
- If e = 31 Then Pon = "A3"
- If e = 32 Then Pon = "A#3"
- If e = 33 Then Pon = "B3"
- If e = 34 Then Pon = "C4"
- If e = 35 Then Pon = "C#4"
- If e = 36 Then Pon = "D4"
- If e = 37 Then Pon = "D#4"
- If e = 38 Then Pon = "E4"
- If e = 39 Then Pon = "F4"
- If e = 40 Then Pon = "F#4"
- If e = 41 Then Pon = "G4"
- If e = 42 Then Pon = "G#4"
- If e = 43 Then Pon = "A4"
- If e = 44 Then Pon = "A#4"
- If e = 45 Then Pon = "B4"
- If e = 46 Then Pon = "C5"
- If e = 47 Then Pon = "C#5"
- If e = 48 Then Pon = "D5"
- If e = 49 Then Pon = "D#5"
- If e = 50 Then Pon = "E5"
- If e = 51 Then Pon = "F5"
- If e = 52 Then Pon = "F#5"
- If e = 53 Then Pon = "G5"
- If e = 54 Then Pon = "G#5"
- If e = 55 Then Pon = "A5"
- If e = 56 Then Pon = "A#5"
- If e = 57 Then Pon = "B5"
- If e = 58 Then Pon = "C6"
- If e = 59 Then Pon = "C#6"
- If e = 60 Then Pon = "D6"
- If e = 61 Then Pon = "D#6"
- If e = 62 Then Pon = "E6"
- If e = 63 Then Pon = "F6"
- If e = 64 Then Pon = "F#6"
- If e = 65 Then Pon = "G6"
- If e = 66 Then Pon = "G#6"
- If e = 67 Then Pon = "A6"
- If e = 68 Then Pon = "A#6"
- If e = 69 Then Pon = "B6"
- If e = 70 Then Pon = "C7"
- If e = 71 Then Pon = "C#7"
- If e = 72 Then Pon = "D7"
- If e = 73 Then Pon = "D#7"
- If e = 74 Then Pon = "E7"
- If e = 75 Then Pon = "F7"
- If e = 76 Then Pon = "F#7"
- If e = 77 Then Pon = "G7"
- If e = 78 Then Pon = "G#7"
- If e = 79 Then Pon = "A7"
- If e = 80 Then Pon = "A#7"
- If e = 81 Then Pon = "B7"
- If e = 82 Then Pon = "C8"
- If e = 83 Then Pon = "C#8"
- If e = 84 Then Pon = "D8"
- If e = 85 Then Pon = "D#8"
- If e = 86 Then Pon = "E8"
- If e = 87 Then Pon = "F8"
- If e = 88 Then Pon = "F#8"
- If e = 89 Then Pon = "G8"
- If e = 90 Then Pon = "G#8"
- If e = 91 Then Pon = "A8"
- If e = 92 Then Pon = "A#8"
- If e = 93 Then Pon = "B8"
- If e = 90 Then Pon = "C9"
- If e = 91 Then Pon = "C#9"
- If e = 92 Then Pon = "D9"
- If e = 93 Then Pon = "D#9"
- If e = 94 Then Pon = "E9"
- If e = 95 Then Pon = "F9"
- If e = 96 Then Pon = "F#9"
- If e = 97 Then Pon = "G9"
- If e = 98 Then Pon = "G#9"
- If e = 99 Then Pon = "A9"
- Poff = LCase(Pon)
- Print #101, "Absatz", a, ":", b, ": 0 |On Note | chan= 2 | pitch=", Pon, " | vol=", v
- Print #101, "Absatz", h, ":", g, ": 0 |Off Note | chan= 2 | pitch=", Poff, " | vol=64 "
- Loop
- Close
- 'für Track#.txt auch chan= # schreiben
- End Sub
7. Die letzten Schritte waren, die Ereignisse in den Tracks nach Ereigniszeit aufsteigend zu sortieren (z.B. mit Word für Windows), in einer Vorlage-Textdatei zusammenzufügen und das Textformat in MIDI-Format umzuwandeln. Das Letztere geschah mit der Hilfe des wunderbaren Programms von Jeff Glatt namens "MIDI File DisAssembler" (www.borg.com/~jglatt). Die Vorlage-Textdatei wurde aus einer in meinem MIDI-Sequenzer erstellten Vorlage-MIDI-Datei ebenfalls durch "MIDI File DisAssembler" erstellt.
Wir sind nicht da, um die Höchstleistung zu erbringen und dann abzubrennen, wir sind da, um die Welt zu bewundern!