13.4.2016

Samplerate Mythen: Harry Nyquist und die Mathemathik

In their heyday, researchers at Bell Labs earned 7 Nobel Prizes in total, and in 1960, the IEEE gave their “Medal of Honor” to Harry Nyquist, who had researched there for almost 40 years.

Back in the 1920s, the Yale graduate had worked on an early version of the fax machine. By 1947, he had made his most lasting contribution: a mathematical proof that showed any sound wave could be perfectly re-created so long as it was limited in bandwidth and sampled at a rate more than twice its own frequency.

Justin Colletti, Trust Me I'm a Scientist

Das Essay räumt gründlich auf mit einigen Mißverständnissen, denen zufolge hochauflösendes Audio (Samplerates mit 96kHz, 192kHz, oder womöglich noch mehr; Stichwort: DSD) „besser” sei, als das Standard-CD-Format mit 44.1kHz / 16Bit.

Der im Text vertretene Standpunkt ist keine Einzelmeinung, sondern vertritt den derzeitigen Stand der Wissenschaft; vergleiche zB. hier:

Articles last month revealed that musician Neil Young and Apple's Steve Jobs discussed offering digital music downloads of 'uncompromised studio quality'. Much of the press and user commentary was particularly enthusiastic about the prospect of uncompressed 24 bit 192kHz downloads. 24/192 featured prominently in my own conversations with Mr. Young's group several months ago.

Unfortunately, there is no point to distributing music in 24-bit/192kHz format. Its playback fidelity is slightly inferior to 16/44.1 or 16/48, and it takes up 6 times the space.

Monty, xiph.org (Hervorhebung von mir)

3.12.2014

Cubase 8 - Chord Pads

Die Chord Pads von Cubase 8 sind eine Fortführung des Chord Track-Feature von Cubase 7. Sie setzen Konzepte fort, die dort begonnen wurden. Wer mit dem Chord Track vertraut ist, wird wohl schon auf den ersten Blick einige Gemeinsamkeiten bemerken:

  • Der Editor der Akkorde ist identisch zu dem im Chord Track;
  • der „Chord Assistant“ ist – mehr oder weniger – derselbe geblieben[1];
  • das Konzept von „Voicings“ spielt auch für die Chord Pads eine zentrale Rolle; etc.
  • Cubase 8 liefert hier etwas nach, was schon bei der ursprünglichen Planung des Chord Track vorgesehen war: die Möglichkeit, Akkorde in Echtzeit vom MIDI-Keyboard anzuspielen bzw. – ganz zentral – via Remote zu verändern.

    Das UI (User Interface) läßt eigentlich recht wenige Fragen offen: man klickt auf ein Pad, und bekommt einen Akkord zu hören, dessen Symbol man im UI sehen kann.

  • Um die Akkorde zu hören, muß man einen (MIDI- oder Instrument-)Track anlegen, und diesen auf „Record“ oder „Monitor“ stellen (was Cubase normalerweise sowieso tut, sobald man einen Track anwählt, „selektiert“).
  • Man kann das Akkordsymbol ändern – beim „Mouse-Over“ findet sich ein Icon, auf das man klicken kann, um den dazugehörigen Dialog zu öffnen.
  • Soweit ist das ein Feature, das ungefähr alle auf dem Markt befindlichen „Chord-Tools“ an Bord haben.

    Es gibt jedoch (wie ich finde: entscheidende) Unterschiede.

    Adaptive Voicings

    Wenn man zwei Pads nacheinander anschlägt, werden nicht stumpf zwei statisch abgelegte „Sammlungen von Tönen“ (aka „Voicing“) nacheinander abgespielt. Die Übergänge zwischen den Voicings ist abhängig vom Kontext, in dem die Akkorde wechseln – es kommen Regeln der Stimmführung zur Anwendung. Wenn man (zB.) von C nach G über *F* geht, ist das Voicing von G möglicherweise(!) ein anderes, als wenn man von C nach G über *Ab7* geht.

    Als User muß man nicht großartig darüber nachdenken. Das Ergebnis – so, wie es derAlgorithmus liefert – klingt (zumindest für meine Ohren) fast immer „richtig“.

    Besonders dann, wenn man mit den Chord Pads „Gitarre spielt“ (dh., einen „Guitar Player“ im Setup der Chord Pads anlegt), werden die Stärken im Umgang mit Akkorden in Cubase deutlich: man bekommt Voicings, die von einem Gitarristen so tatsächlich gespielt werden (können).

    Mehr noch: auch die Gitarren-Voicings werden, für aufeinander folgende Akkorde, ineinander „übergeblendet“ (folgend den von Cubase implementierten Regeln für Stimmführung) – was in der Praxis allenfalls echten Könnern auf dem Instrument vorbehalten sein dürfte.

    Tension Control

    Eine Premiere im Bereich der Computeralgorithmen für die „Interpretation von Akkorden“ ist wohl der Regler für „Tensions“ (ein „Overlay-Control“ auf jedem Pad).

    Wenn man ihn nach rechts bewegt, bekommt man zunehmende Spannungsnoten für den Akkord auf dem Pad. Aus einem C-Dur-Dreiklang wird ein C9, ein C6. Danach wechselt man in die Welt der Vier- bzw. Fünfklänge: Cmaj7, Cmaj7/9, Cmaj7/9/13, etc.

    Wenn man mit einem Akkord auf der Dominante beginnt, geht es, bei der Verschiebung des Reglers nach links, auch (wie oben) in Richtung der Dreiklänge. Wenn man ihn nach rechts bewegt, bekommt man nach und nach all die wilden Alterationen des Modern Jazz oder der Spätromantik über den Dominant-Sept-Akkord: C7/9, C7/b9, C7/#9, C7/9/#11 (etc. pp).

    Auch hier greifen die Regeln des Übergangs zwischen Voicings: wenn man die Spannungsebenen wechselt, bleiben die Noten „eng beieinander“ – sprich: zB. die Septe wird nicht einfach auf den Dreiklang „oben drauf gesetzt“, sondern, soweit das logisch ist, in ihn „eingeblendet“ (so daß sie nicht unbedingt im Sopran, sondern zB. im Tenor erscheint).

    In Verbindung mit der Möglichkeit, dieses Feature (und andere) via Remote zu steuern, kann man auf sehr abgefahrene musikalische Wege geraten – und zwar selbst dann, wenn man sich darauf beschränkt, mit einem Klaviersound nur die kompletten Akkorde abzufeuern.

    Aber damit ist es ja nicht getan (ich komme auf das Thema zurück).

    1. [1] ...obwohl der sehr anders aussieht, und sogar einen kompletten „Rewrite” des Algorithmus hinter sich hat.

    Cubase 8 - Chord Pads (Steinberg Video)

    Selbst im Forum von Native Instruments wird das Video als Referenz verlinkt.

    Zitat dort:

    back to the topic... i like the way they threw in a bit of theory with the chords in cubase 8

    Meine Empfehlung hat es auch noch – die zehn Minuten für des Ansehen des Videos sind mE. gut investierte Zeit, wenn man sich für das Feature interessiert.

    4.9.2014

    Working (with) Legacy Code

    First of all: never (ever) assume you're confronted with bad code.

    People that wrote it are probably as smart as you are – maybe even smarter, since they (sometimes) wrote code that make a product that sells pretty well over a couple of decades.

    So here we go (and I have just two points):

  • Don't change code only because you assume that it has faults.

    You have to prove that, first (using debugger / profiler). We are not in a beauty contest, here.

  • Don't change interfaces.

    Changing the behavior of a Class / Method is no problem, if that Class / Method is used in a precisely defined, local context. Changing interfaces of Classes / Methods that are wildly used in a complex application are a no-go even in the context of a quasi-automated Refactoring.

    Don't do that. Use the Compiler to unveil your errors: rename a Class / Method that needs a new behavior, and let the Compiler's errors lead your way thru.


  • Sidenote:

    If some code doesn't do what you assumes it should do, that doesn't mean someone else shares your assumptions (and your reasons for changing it's behavior).

    She might rely on some assumptions that might seem stupid to you, but she might rely on them for good reasons (even if those reasons are founded on a reality that goes decades back).

    4.7.2014

    Cubase 7 - Chord Track: Mozart

    (Thema)

    Ich gebe zu, ich habe das Video nur ausschnittsweise gesehen. So schon bin ich nicht schlecht am Staunen, was man mit dem Chordtrack-Feature anstellen kann.

    3.7.2014

    Inheritance Is The Base Class of Evil

    Der Vortrag von Sean Parent ist bemerkenswert– das Konzept, das er dort vorträgt, ist geradezu verführerisch.

    Offen bleibt, wie man es im konkreten Code einer komplexen Applikation verwendet. Sein Beispiel von Photoshop mag zum Schluß verleiten, daß es leicht ist, es umzusetzen. Die Voraussetzung, dort, ist: alle Daten sind kopierbar (oder, durch smart-pointer, auch ohne explizite Kopie, gewissermaßen persistent).

    Im Kontext einer einigermaßen komplexen Applikation ist das jedoch eine Voraussetzung, die hart erkämpft werden müßte.

    5.3.2014

    C++11 Lambda Binding (Virtual Methods at Runtime)

    Ich finde das gerade extrem spannend: einem in der funktionalen Programmierung erfahrenden Entwickler erzähle ich hier nichts Neues; würde ich den Grund nennen, warum mich dieses Konstrukt gerade so begeistert, würde ich meinen Arbeitsvertrag bei Steinberg übelst verletzen, weil ich dann Betriebsgeheimnisse ausplauderte (man beachte den Konjunktiv).

    Wenn ich das richtig sehe, ist man wieder in den 90ern gelandet, wo die Parametrisierung via Funktionspointern eine Selbstverständlichkeit war. C++ Lambda = Pointer To Function? Genau das ist das – plus einigem Syntax-Sugar, wenn es darum geht, die Argumente durchzureichen (das „Caputure”-Feature in C++-Lambda ist mE. Sugar, nicht mehr – wie hilfreich das im konkreten Kontext auch ist).



    Consider:
    struct ITest { virtual ~ITest () {} virtual void out () const = 0; }; struct TestImpl : public ITest { TestImpl (const char* str) : str (str) {} void out () const override { printf (str); } const char* str; };
    Usage:
    ITest* test = new TestImpl ("Test"); test->out (); // => Test


    Consider:
    struct ITest { virtual ~ITest () {} virtual void out () const = 0; }; template <typename Call> struct TTest : public ITest { TTest (const Call& call) : call (call) {} void out () const override { call (); } private: const Call& call; }; template <typename Call> ITest* makeTest (const Call& call) { return new TTest<Call> (call); }
    Usage:
    ITest* test = makeTest ([]() { printf ("Lambda"); }); test->out (); // => Lambda


    Consider (the fun starts here):
    struct Test { void out () const { call (); } //--------- void setCall (Call _call) { call = _call; } private: std::function<void(void)> call; };
    Usage:
    Test* test = new Test; // no interface- or template magic needed test->setCall ([]() { printf ("Lambda runtime binding\n"); }); test->out (); // => Lambda runtime binding
    13.2.2014

    Wenige Buchstaben in einer eher obskuren Konfiguration

    Ende letzten Jahres hat mein IP-Provider meine Site „umgezogen“ - sprich: auf einen anderen Platz in seinem Server-Park verschoben. Das hat dazu geführt, daß ich die Verwaltungssoftware meiner Seiten nicht mehr erreichen konnte (was, für mich, kein Drama ist). Irgendwann habe ich beim Support nachgefragt, und bekam einen neuen Zugriff - Problem gelöst (dachte ich).

    Vor etwa zwei Wochen bin ich dann darüber gestolpert, daß die Anzahl der Zugriffe auf meine Website via Google immer weiter zurück geht. Bis zu diesem Zeitpunkt hatte ich ca. 50 Google-Anfragen täglich (ich habe ja eine ganz kleine Website, ein Hobby) – plötzlich keine mehr. Googles Webmaster-Tool half, das Rätsel zumindest teilweise zu lösen: jeder Request auf meine Seiten vom Google-Bot löste einen 404-Error („Page not found“) aus. Ich habe erst nicht kapiert, warum – der Zugriff auf die angeblich nicht vorhandenen Seiten funktionierte, im Browser, nach wie vor fehlerfrei.

    Nachdem ich bei dem Versuch, das Problem zu verstehen, im Setup des Webservers (Apache; in der .htaccess-Datei) ein wenig herumgespielt hatte, kamen dann alle Zugriffe auf Links auf meine Seite mit einem 404-Error zurück – nicht nur von Google, sondern auch vom Browser. An dieser Stelle war ich durchaus erleichtert: es war klar, daß nicht etwa Google etwas gegen meine Präsenz im 'net hat, sondern daß da irgendwo ein technischer Fehler vorliegt.

    Ich habe länger herumgesucht (meine php-Scripts mit "echo"-Ausgaben geradezu verseucht, um so etwas wie Debugging zumindest zu simulieren; nach Hinweisen gegoogelt), um endlich zum Schluß zu kommen, daß es nicht an meinen Skripten liegt, sondern an der Konfiguration des Servers.

    To cut a long story short: der „Umzug“ war auch mit einem Update der Server-Software verbunden. Apache, in der neueren Version, „versteht“ es nicht mehr, daß der Access auf meine Seiten über eine Datei ohne Extension verläuft. Der Hauptanker war bislang eine Datei namens „htdocs“. Das funktioniert nicht mehr; ich mußte das ersetzen durch „index.php“ („htdocs.xx“ wäre wahrscheinlich auch gut genug; ich habe das erst gar nicht versucht; keine Lust auf Experimente).

    Um den Zugriff auf meine Site auch mit „alten“ URLs zu ermöglichen, habe ich im .htaccess von Apache ein „redirect“ eingeführt (ich gehöre nicht dem ehrwürdigen Berufsstand der Web-Admins an, und habe somit nicht die leiseste Ahnung, was ich hier mache – es scheint aber zu funktionieren):

    RewriteEngine on Redirect /htdocs/ /index.php/

    Jetzt sollte das alles wieder so funktionieren wie zuvor. Der Google-Bot braucht allerdings sicherlich noch einige Zeit, bis er Google dazu verleitet, die Suchbegriffe, die in den letzten Jahren zuverlässig auf meine Site verwiesen, wieder oben in den Suchergebnissen aufzulisten.

    Warum erzähle ich das so ausführlich? Die Schlußfolgerung finde ich ebenso spannend wie beängstigend: wenige Buchstaben in einer eher obskuren Datei entscheiden darüber, was man in dieser Welt gilt.


    Start - Neuere Einträge - Ältere Einträge
    (Seite 1 von 20 / 158 Einträge)