Netzwerkprodukte (32)
One reason programmers dislike meetings so much is that they're on a different type of schedule from other people. Meetings cost them more.
There are two types of schedule, which I'll call the manager's schedule and the maker's schedule. The manager's schedule is for bosses. It's embodied in the traditional appointment book, with each day cut into one hour intervals. You can block off several hours for a single task if you need to, but by default you change what you're doing every hour.
[…]
Most powerful people are on the manager's schedule. It's the schedule of command. But there's another way of using time that's common among people who make things, like programmers and writers. They generally prefer to use time in units of half a day at least. You can't write or program well in units of an hour. That's barely enough time to get started.
(Paul Graham: Maker's Schedule, Manager's Schedule[1]).
Die Arbeit eines Programmierers besteht keinesfalls darin, eine Zeile Sourcecode an die andere zu fügen, um am Ende des Tages eine bestimmte Funktionalität fertig zu haben, die der Compiler dann – womöglich noch über Nacht – in lauffähige Maschinensprache übersetzt. Der Prozeß dieser Arbeit ist wesentlich komplizierter und unberechenbarer, als ein Außenstehender wohl vermutet.
Eine Zeile Code darf – zunächst auf syntaktischer Ebene - keinen einzigen Fehler aufweisen. Das führt dazu, daß man in den meisten Fällen immer wieder den Compiler anwirft, um die Syntax von ihm überprüfen zu lassen. Auch erfahrene Programmierer müssen sehr aufmerksam hinschauen, wenn der Compiler seine Fehlermeldungen ausspuckt: dort wurde statt einem Komma ein Doppelpunkt gesetzt; an anderer Stelle eine Klammer zuviel oder zuwenig; woanders kennt der Compiler eine Referenz auf ein externes Symbol nicht, weil man vergessen hat, es zu deklarieren, usw.usf. Meist wird man nach wenigen Minuten aus der „eigentlichen“ Arbeit, dem ursprünglichen Gedankenfluß, herausgeworfen, und muß etwas korrigieren.
Selbst wenn der Compiler mit dem einverstanden ist, was im Sourcecode steht, ist nicht gesagt, daß dieser tut, was er soll. Man übersetzt wieder und wieder das komplette Programm, läßt es laufen, und testet es. Im besten Fall kann man automatisierte Tests abfeuern. Nicht selten muß man jedoch im Debugger den eben geschriebenen Code mehr als nur einmal Zeile für Zeile durchgehen, unter immer neuen Ausgangsbedingungen – die man im schlimmsten Fall im Userinterface des laufenden Programms erst herstellen muß.
Schreiben von Code und der Test, ob er korrekt ist, geht also Hand in Hand – auf verschiedenen Ebenen, aber fast immer in relativ kurzen Zyklen. Wenn man mit einem Problem beschäftigt ist, das auch nur triviale Komplexität aufweist, braucht man jedoch eine ganze Reihe solcher Zyklen, um es letztlich zu lösen. Wenn man ununterbrochen arbeiten kann, ist es möglich, die einzelnen Ebenen im Kurzzeitgedächtnis zu behalten. Während der Compiler die Syntax checkt, kann man kurz darüber nachdenken, wie die nächste Zeile Code aussehen müßte, und kann sie gleich hinschreiben, wenn der Compilerlauf erfolgreich war. Schon dann ist es ärgerlich, wenn man erst dumme Schnitzer ausbessern muß, wie etwa den falsch geschriebenen Namen einer Variablen[2].
Jede längere Unterbrechung bedeutet dann, daß man sich bei der Wiederaufnahme der Arbeit nur noch an die Sachen erinnert, die im Langzeitgedächtnis gelandet sind – und da ist man dann auf einer ganz anderen, mitunter sehr frustrierenden Ebene unterwegs, weil das, was man gerade noch gewußt hat, verloren ist, obwohl man sich genau daran erinnert, daß man es eben noch wußte. Um auf sie zurück geworfen zu werden, reicht oft schon eine Ablenkung von wenigen Minuten – von einem ein- oder mehrstündigen Meeting ganz zu schweigen.
- [1] Es lohnt sich sehr, in Grahams Sammlung von Essays ein wenig zu stöbern. „Hackers and Painters” ist mE. ein Klassiker, den jeder kennen sollte, der sich für die Kunst der Programmierung interessiert.
- [2] Das ist übrigens mE. ein zentraler Grund, warum Tools bei der Programmentwicklung eine gewichtige Rolle spielen, die schon im Vorfeld darauf hinweisen, daß man sich gerade verschreibt – und ein Grund dafür, daß die Rechtschreibprüfung in Textverarbeitungen ausnahmslos so vorzüglich funktioniert (die Programmierer haben hier aus purem Eigeninteresse gute Arbeit geleistet).
Userinterfaces (6)
Jede technische Innovation geht erst dann in die Breite, wenn sie nicht nur problemlos funktioniert, sondern auch einfach zu bedienen ist. Das ist bei Autos nicht anders als im Bereich von Computersoftware. Noch in den 60ern mußte man sich richtig mit seinem Fahrzeug auskennen, um nicht unvermittelt mit ihm liegen zu bleiben; auf das Internet Anfang/Mitte der 90er hatten nur Spezialisten Zugriff; etc.
Man sollte aber einen zweiten Punkt nicht übersehen. Wenn ich ein Familienauto verkaufen will, muß es einfach zu bedienen sein. Wenn ich jedoch einen Rennwagen baue, ist einfache Bedienbarkeit nur eine Anforderung. In erster Linie muß dieses Auto dem Fahrer alle Option geben, das Limit aus ihm herauszuholen. Das geht nicht ohne ein gewisses Maß an Komplexität im Userinterface – man muß sich nur einmal das Lenkrad eines Formel-1-Autos ansehen, um dafür ein Gefühl zu bekommen. Auch hier geht es natürlich nicht ohne erheblichen Aufwand beim Design der Bedienelemente – schließlich muß der Fahrer auf die Strecke schauen, und nicht auf die Knöpfe am Lenkrad. Es geht hier also nicht in erster Linie um Einfachheit, sondern Ergonomie bei der Bedienung, wobei man in Kauf nimmt, daß es eines gewissen Trainings bedarf, diese Bedienung zu erlernen. – Aber das ist jetzt genug mit Autometaphern.
Was ich sagen will: wenn man neue Sachen in der Software-Entwicklung ausprobiert, hat man nicht automatisch die richtigen Abstraktionen zur Hand, die dem User (und auch dem Programmierer) das Handwerk einfach machen. Wenn man dann noch die Kosten in der Entwicklung berücksichtigen muß (und nicht etwa mit einem Release Jahre warten will, weil man noch zahllose Iterationen bräuchte, um ein Feature „richtig” zu bekommen), hat man öfters nur zwei Möglichkeiten: man nimmt eine gewisse Komplexität hin, weil man dem User bestimmte Möglichkeiten nicht nehmen will; oder man streicht gewisse Optionen (indem man z.B. eine Auswahl durch einen Defaultwert ersetzt). Ich bin dann (nur dann, unter den oben genannten Restriktionen) eher geneigt, ein Menu mehr anzubieten, als es für ein sauberes Interface „richtig” wäre.
Ich bin überzeugt, die Mehrheit der User teilt meinen Standpunkt.
Note Expression in Cubase 6
Bei SoundOnSound findet sich ein Artikel, der sich mit „Note-Expression” beschäftigt – durchaus lesenswert:
To complement the newly improved Expression Maps, Cubase 6 introduces what is quite simply a breakthrough new feature: Note Expression. Since the emergence of MIDI, now nearly 30 years ago, the role of making programmed music sound more expressive has fallen to MIDI controller messages. […]
Netzwerkprodukte - Userinterfaces (6)
Ein Sequenzer, der MIDI wie auch Audio behandeln und gemeinsam abspielen will, steht vor dem Problem, daß es sich um sehr unterschiedliche Medien handelt, die immer wieder nach Sonderbehandlung vernehmlich rufen: MIDI basiert auf PPQ (und ist damit unabhängig vom Tempo); Audiodateien sind „timebased“ und laufen zunächst unabhängig vom eingestellten Tempo; etc., ich hatte das Thema schon ausführlicher behandelt.
Auch in der „Philosophie“ bei der Wiedergabe gibt es einen gewichtigen Unterschied: ein Audio-Track im Sequenzer entspricht idR. einem Kanalzug auf dem virtuellen Mischpult, während MIDI dort zunächst überhaupt nicht auftaucht. „Lautstärke“ ist ein Attribut, das man Audio nachträglich hinzufügt (indem man den „Stream“ gewissermaßen filtert, und jedes Sample, abhängig von der Stellung des Volume-Reglers auf dem Mischpult, skaliert). In der MIDI-Welt ist Lautstärke hingegen zunächst ein Attribut der einzelnen Noten (Velocity) – auch MIDI-Volume (Controller 7 und 11) kommt nicht „von außen hinzu“, sondern ist Teil des Datenstroms selbst.
Das ist historisch begründet, und nicht per se „gutes Design”. Man kann die Welten aus MIDI und Audio jedoch zumindest auf dieser Ebene nachträglich einigermaßen gut miteinander „verheiraten”: MIDI-Tracks bekommen z.B. einen Kanal im Mixer, der MIDI-Volume ausspuckt (wobei er dann regelmäßig in Kollision mit dem MIDI-Volume gerät, das der User im Track selbst abgelegt hat).
Diese unterschiedlichen Ansätze führen zu weiteren Konsequenzen. In der MIDI-Welt ist es z.B. kein Problem, mehrere Datenströme (z.B. in Form von „Parts“ in Cubase) auf demselben Track übereinander zu stapeln und gemeinsam abzuspielen. Bei Audio-Daten geht das nicht: hier geht genau eine Datei zur selben Zeit an den Ausgang. Wenn man mehrere Audio-Dateien auf demselben Track übereinanderstapelt, „gewinnt“ immer die, die „oben“ liegt; der Rest bleibt stumm. - Das hat wieder historische Ursachen; vergl. oben.
Die Tatsache, daß es eine „Hierarchie“ von Audio-Dateien auf demselben Track gibt, kann man fruchtbar machen, wenn es darum geht, aus mehreren Aufnahmen desselben Takes – aus mehreren, unmittelbar aufeinander folgenden Aufnahmen derselben Passage – die „beste“ Version zusammenzuschneiden. Der Sänger hat im ersten Take die Töne in Takt eins und zwei richtig, im nächsten sind die in Takt drei und vier besser: man schneidet innerhalb der „Lanes“ desselben Tracks, aktiviert jene Lanes, die am besten gefallen, und verläßt sich darauf, daß der Rest des Materials automatisch stumm ist. Wie gesagt: auf einem Audiotrack kann immer nur eine Audiodatei gleichzeitig spielen. Wenn man eine Datei (oder einen Ausschnitt davon) „nach vorne holt“, kommt der Rest automatisch zum Schweigen.
Dieses Konzept von „Lane-Editing“ (oder „Comping“) hat auf den ersten Blick eine Reihe von Vorteilen, die von den Usern auch erkannt und ausgiebig genutzt werden. Sie rasseln dann aber in Probleme, wenn sie das Feature für Aufgaben benutzen, für die es anfangs gar nicht konzipiert war. So gibt es regelmäßig Situationen, wo man nicht einfach zwischen den Versionen mehrerer Takes hin- und herschalten kann, ohne daß die Takes überlappen. Im Beispiel oben sind die ersten beiden Takte des Sängers vielleicht perfekt, haben aber am Ende einen langen Ton, den man nicht einfach abschneiden kann, wenn man in die beiden nächsten Takte auf dem anderen Take wechseln will. - Ich deute das nur an; wenn es um Take-basiertes Editing von Sprachaufnahmen (die keinem Taktmaß folgen) geht, landet man in noch ganz anderen Problemen.
Worauf ich hinaus will: es gibt in den meisten Programmen Features, die nur historisch begründet sind, und mit den Problemen, die ihre User lösen wollen, gar nichts zu tun haben. Das Konzept der „Lanes“ z.B. kommt vom Versuch, die ursprünglichen Limitierungen bei der Wiedergabe von Audiomaterial im Userinterface fruchtbar zu machen. Die User sehen das ganz anders: sie haben ein Problem, das man in der ursprünglichen Version des Features nicht recht lösen kann, und verlangen Nachbesserungen, selbst wenn die regelmäßig deutlich über die technischen Limitationen des ursprünglichen Designs hinaus weisen. Dann wird von den Entwicklern oft genug nachgebessert, bis ein Grad an Komplexität im Code (aber auch im Userinterface) entsteht, den keiner mehr recht versteht bzw. beherrscht.
(Wer übrigens der Meinung ist, dies sei ein Cubase- bzw. Steinberg-spezifisches Problem, sollte mal versuchen, Adobe Photoshop zu lernen.)
Cubase 6 - Note Expression (7)
Ich wollte längst schon über die praktischen Möglichkeiten von „Note Expression“ schreiben – das ist mittlerweile wohl eher überflüssig, weil genug Informationen im Netz die Runde machen.
Erwähnenswert wäre der Workshop von Holger Steinbrink [PDF], der die grundlegende Bedienung erklärt. Aufschlußreich finde ich auch einen Diskussions-Thread im „Logic Pro Help”-Forum. Die Möglichkeiten eines Musikinstruments, das durch „Note Expression“ letztlich erst benutzbar wird, illustriert die Demo von Eigenharp auf der letzten Musikmesse in Frankfurt.
Cubase 5 - VST-Expression (10)
Ein weiterer YouTube-Fund: Greg Ondo's Demo zeigt knapp und schlagend die zentralen Punkte, um die sich „VST Expression” dreht.
Cubase 6 - Note Expression (6)
Zu diesen Problemen bietet „Note Expression” (NE) eine Lösung.
-
Neben MIDI unterstützt NE ein internes Datenprotokoll (VST3-Events), bei dem der Wertebereich durch einen 10 Byte (also 80 Bit) breiten Datentyp („C++ double“) definiert ist. Das sind normalisierte Werte zwischen 0 und 1 in Gleitkommazahlen – theoretisch ist der Wertebereich nahezu unbegrenzt, in der Praxis kommt es durch die Umrechnung in vernünftig editierbare Werte zu Rundungen (wer will schon mehrstellige Nachkommastellen editieren).
-
Alle NE-Events (sowohl MIDI-, wie auch VST3-Events) sind nicht länger Bestandteil der Parts, sondern direkt an die einzelnen Noten gekoppelt. Wenn man eine Note verschiebt, wandern diese Events mit – sie behalten stets die relative Position zum Start der Note. Darüber hinaus werden, wenn man eine Note kopiert, auch die Controller-Informationen mitkopiert.
-
NE funktioniert, zumindest im Rahmen von VST3, polyphon. Man kann z.B. in einem mehrstimmigen Streichersatz für jede Note unterschiedliche Verläufe von Tonhöhe, Lautstärke, Pan, Modulation etc.pp. (je nachdem, welche Parameter das angesteuerte Instrument zur Verfügung stellt) realisieren. Bislang mußte man jede Stimme in eine je eigene Spur verschieben, wenn man sie z.B. individuell im Stereobild anordnen und ihnen verschiedene Verläufe in Lautstärke oder Modulation zuordnen wollte. Dieser Schritt entfällt; man kann dies jetzt machen, ohne den Überblick über die harmonischen Verläufe aufzugeben.
Ein Wort zum Verhältnis zwischen MIDI und VST. Erst beim Einsatz von VST3-Events hat man es mit den vollen Möglichkeiten des Features zu tun – und das bedeutet, daß man dann nur VST-Instrumente benutzen kann, die die neueste Version (3.5) des Protokolls unterstützen. Das ist momentan beschränkt auf unseren eigenen Sampler, Halion. Zu Cubase 6 gehört eine abgespeckte Variante, Halion Sonic SE, die zwar VST 3.5 und NE unterstützt, mit der man aber nur Sounds verwenden kann, die in ihrer „Interpretation“ von NE festgelegt sind. Erst in der Vollversion von Halion Sonic kann auch der User (in der sog. Modulationsmatrix) entscheiden, welche Parameter über NE angesteuert werden. - Das Angebot an Sounds, die sich über NE ansteuern lassen, ist also momentan ausgesprochen mager.
Bleibt MIDI. NE funktioniert auch in dieser „Welt”, wenn auch mit einigen Einschränkungen. Zunächst ist man auf monophones Material beschränkt, wobei es gerade für Soloinstrumente eine große Anzahl von Use-Cases gibt. Wer z.B. je mit einer MIDI-Gitarre gearbeitet hat, weiß, wie schwierig es ist, die erzeugten Controller(Pitchbend!)-Daten zu verwalten – solche Recordings kann man nicht einmal sinnvoll quantisieren. Aber auch mit dem Keyboard eingespielte Saxophone oder Trompeten, die ja nur durch intensiven Gebrauch von Controllern „lebendig“ werden, lassen sich mit konventionellen Methoden kaum nachträglich editieren. Mit NE ergeben sich hier radikal neue Möglichkeiten. Trotzdem muß man auch hier, in der eingeschränkten Welt der Monophonie, aufpassen: sobald sich Noten nur zufällig ein wenig überlappen, kann es zu Chaos in der Wiedergabe kommen, wenn die Controller am Ende einer Note mit jenen am Anfang einer neuen Note kollidieren (in Cubase gibt es immerhin Funktionen, mit denen sich solche Konflikte nachträglich auflösen lassen).
Es gibt noch einen Trick, wie sich auch mit MIDI „Note Expression” komplett nutzen läßt: in der Verwendung von polyphonem Aftertouch. Die wenigsten Keyboards können diesen Datentyp noch erzeugen; es gibt aber eine ganze Reihe von VST-Instrumenten, die ihn noch entgegen nehmen. Durch ein entsprechendes Mapping bei der Aufnahme (oder durch das „Malen” der Kurven im Editor) lassen sich Noten-bezogene Controller auch mit MIDI realisieren – allerdings beschränkt auf genau einen Parameter.
[Wird fortgesetzt; dies war jetzt sozusagen der theoretische Teil.]
Cubase 6 - Note Expression (5)
Controller-Daten im MIDI-Protokoll haben drei grundsätzliche Probleme:
-
Zunächst ist die Auflösung der Parameter kläglich. Pitchbend läßt sich noch am feinsten steuern – das ist ein 14Bit-Parameter, der einen Bereich von 16.384 unterschiedlichen Werten abdeckt. Die übrigen MIDI-Controller sind beschränkt auf 7Bit, dh. auf gerade mal 128 unterschiedliche „Zustände”.
-
MIDI-Controller bewegen sich frei im Datenstrom, und existieren „zwischen“ den Noten, „neben“ ihnen, auf der gleichen hierarchischen Ebene. Das läuft darauf hinaus, daß man, wenn man eine Note bewegt, nur eben diese Note bewegt, nicht aber die mit ihr „eigentlich“ assoziierten Controller. Wenn man zB. Pitchbend in einem vom Spiel einer verzerrten Gitarre inspirierten Solo auf dem Synthesizer verwendet, stehen die Pitchbend-Daten auf derselben Ebene wie die Noten. Wenn man dieses Solo im Sequenzer aufgenommen hat und die Performance zB. quantisieren will, kann man entweder alle Daten quantisieren (was für Pitchbend hier überhaupt keinen Sinn macht), oder die Quantisierung auf die Noten beschränken (wie das in jedem Sequencer auch gehandhabt wird; was aber die Pitchbend-Daten von den ihnen „eigentlich“ zugehörigen Noten zeitlich entfernt – mit radikalen klanglichen Konsequenzen).
-
MIDI-Controller sind „kanalbezogen“ – und das ist ein sehr abstraktes Konzept. Es besagt, daß man die unterschiedlichen Stimmen (z.B. die vier Instrumente in einem Streichersatz) eines „Instruments“ (einer „Spur“ auf dem virtuellen Tonband) nur dann unabhängig voneinander adressieren kann, wenn sie über unterschiedliche MIDI-Channels verteilt sind. Das kann man machen – das ist aber eine Sache allenfalls für Spezialisten, die sich mit den Details des MIDI-Protokolls auskennen. In der Praxis läuft es letztlich darauf hinaus, daß man pro Sound genau eine Ebene von Controllern benutzen kann: MIDI-Controller sind auf monophone Sounds beschränkt.