Sonntag, 26. April 2020

AlgoLine B (work in progress)

Die letzten Tage wurde wieder etwas am Programm geschraubt. Ich habe neu eine sustain Instruktion eingebaut, die das Halten von Tönen für bestimmte Längen veranlasst, und dazu auch gleich ein modulo Keyword. Ein Halten von Tönen für Längen kongruent mit 0 modulo 8 erzeugt, wenn es stark genug gewichtet ist, für einen regelmäßigen langsameren Puls, der sich durch das Stück zieht.

(Es ist oft so, dass sich das Gewichtsverhältnis von Instruktionen im Verlauf ändert - im Test hatte ich auch ein Stück, das am Anfang einem klaren Puls folgt, der aber nach einer Weile zusammenbricht und ab dann überhaupt nicht mehr erkennbar aufscheint.)

Modulo ist ein wichtiges Keyword; ich will das bei einigen anderen Instruktionen einbauen. Schon gesehen ist dies bei same_intervals, wo es eine besonders große Rolle spielt - es ist also jetzt möglich, dass diese Instruktion z.B. ein Intervall aufwärts zu einem C und zwei Oktaven abwärts zu einem C als das gleiche ansieht. Auch möglich ist es, Intervalle als gespiegelt zu betrachten, sodass 5 Schritte aufwärts und 5 Schritte abwärts gemeinsam gezählt wird. (same_intervals zählt von Anfang an mit, welche Intervalle schon im Stück sind, und vermeidet oder bevorzugt je nach Häufigkeit)

Leider führt das im Moment zu einer deutlich höheren Rechenzeit - zwar speichere ich die verwendeten Intervalle während dem Generieren mit, aber das tue ich nur für die tatsächlichen, nicht für Modulo. Und da die "Notenzeile" selbst nicht wissen kann, welche Modulo später über sie angewendet werden, kann ich das auch nicht so ohne weiteres mitspeichern. Daher müssen für jeden Schritt alle Intervalle von Anfang an wieder durchlaufen werden, was ein enormer Aufwand ist. Mal sehen, ob ich das geschickter hinkriege - eigentlich müssten ja eher die Instruktionen mitspeichern. Im Moment führt das dazu, dass das Generieren geschätzt zehnmal langsamer abläuft. (Vermutlich noch durch andere Faktoren beeinflusst - allmählich summiert sich schlechte Implementierung auf.)

~

Ein grundsätzliches Problem ist, dass alle Instruktionen aufsummiert werden, aber das Auswählen der Töne auf Basis von den Besten funktioniert. D.h. wenn eine Funktion bewirkt, dass Töne a, b, c, d, e, ... um +1000 bevorzugt werden, aber eine andere bewirkt, dass Ton b um +1 bevorzugt wird - dann ist b alleine der beste Ton und alle fast gleichen anderen werden ignoriert.

Damit das nicht so ist, gibt es jetzt das Selector-Keyword threshold. Damit ist z.B. eine Auswahl aus der Menge aller Töne mit einer Bewertung von den mit 98% bis 100% des jeweiligen Maximalwertes möglich.

Exzessiv angewandt habe ich dieses Keyword in Fumbling Important Extremely Talon. Dort gibt es an Instruktionen überhaupt nur das allereinfachste avoid same_pitches, und die eigentliche Arbeit machen die Selektoren - die entweder die tiefsten oder die höchsten Werte auswählen, allerdings aus vielen verschiedenen Prozentbereichen. Darunter auch so niedrige wie 15% - 25%. Das heißt, dass schlecht bewertete Töne nach einer Weile auch ausgewählt werden, was dazu führt, dass unter einer Aufwärtsbewegung allmählich weitere entstehen. Die durcheinanderlaufenden Geraden mit unterschiedlicher Steigung sind auch optisch schön, ich habe aber leider kein Bild davon erstellt.

~

Im Moment ist der Code an vielen Stellen chaotisch und es gibt Inkonsistenzen gegenüber der Eingabe und der Ausgabe, was natürlich absolut nicht ideal ist, da ich ja die Rezepte aus dem Programm wieder als Text speichern können möchte, und zwar exakt der Eingabe entsprechend.

Je mehr Keywords ich hinzufüge, desto größer wird das Chaos, da es dieses und jenes Keyword bei der einen Instruktion gibt und bei der anderen nicht, und sie überall mehrfach implementiert sind. (Bis zu einem gewissen Grad notwendig, da sie verschiedene Dinge tun.) Für die wichtigsten Keywords möchte ich das aber ändern, sie sollen gemeinsam erfasst werden, und nur bei den Instruktionen einen Effekt haben, bei denen es eine Implementierung dafür gibt.

Etwas, was ich außerdem gerne einführen möchte, ist ein Keyword start, das bewirkt, dass eine Instruktion erst ab einer gewissen Stelle hinzugeschaltet wird. Eigentlich wollte ich das ursprünglich gar nicht, da ich es interessanter fand, wenn Veränderungen allein aus den immer-geltenden Instruktionen, die gegeneinander greifen, entstehen... aber mal sehen. Interessanter ist vielleicht das Keyword end. Denn oft ist es ja so, dass eine Instruktion unbedingt notwendig ist, damit am Anfang ein bisschen "Chaos" erzeugt wird, und z.B. vermieden wird, dass nur Tonleitern übrigbleiben. Sobald das aber einmal geschehen ist, läuft es eigentlich auch ohne dieser interessant weiter.

~

Zum Abschluss: Cute demon faces! <3


Ich habe den Graphikbereich um einiges verbreitert - weil ich zwischendurch mal Achtzehnteltöne implementiert habe, für die schlicht nicht mehr genug Pixel da waren - und so sieht es jetzt aus. Am GUI arbeite ich selten. Es gibt eine Reihe von praktischen Tastenkürzeln, d.h. die Buttons auf der rechten Seite sind nur ein paar der Befehle, die es gibt.

Ein Uploads stehen an, für die muss ich jetzt aber erst noch Bilder machen. Theoretisch wäre es wohl interessant, eine Aufnahme vom Programm in Bewegung zu sehen, wie ich das beim alten AlgoLine gemacht habe - aber in der Praxis läuft mein Rechner bereits heiß und der surrende Lüfter packt es fast nicht mehr. Es macht mir aber auch Spaß, passende Bilder zu finden/erstellen, und es verkürzt die Video-Erstellungszeit um ... eigentlich quasi alles, also Faktor 1000 oder sowas.^^