Ist eine Note in einem Midi-Sequencer eine Klasseninstanz?



  • Hi,

    meine Frage ist jetzt nicht Programmiersprachenspezifisch sondern eher generell gemeint für Objektorientierte Sprachen.

    Ich schreibe ja gerade an einer Audio-Software und bin nun am Noteneditor angekommen.

    Meine Frage heute war wie machen das Programme wie Cubase, Reason oder FL-Studio mit den Noten. Jede Note selbst hat ja Eigenschaften wie Anschlagsstärke (Velocity), Panning, Start-Zeit und Dauer und (bei manchen Programmen auch noch eine Farbe/Layer).

    Ein einzelner Track kann ziemlich viele Noten enthalten (man kann ja auch mehrere gleichzeitig anschlagen, z.B. als Chord) und diese Noten sind einzeln anklickbar, verschiebar und verkleiner- und vergrößerbar.

    Mein Arbeitskollege meinte heute ich sollte bei so einer Datenmenge auf gar keinen Fall jede Note als einzelnes Klassenobjekt definieren, aufgrund des Overheads, sondern von Scrolling, Zooming, etc. mit der Mausposition auf Vectoren ableiten damit die Performance nicht leidet. Da musste ich ihm zustimmen.

    Nun habe ich mir aber mal aus Interesse das Linux Multimedia Studio (LMMS) angeschaut um da aus dem Quellcode zu lernen, da ja dort mit der Piano-Roll im Prinzip dasselbe gemacht wird was ich gerade versuche.

    Die haben da aber tatsächlich für JEDEN Anschlag eine Instanz einer Klasse "Note", dass hat mich dann doch schon erstaunt.

    Mit einer eigenen Klasseninstanz für jeden Notenanschlag ist das natürlich sau-bequem. Aber ich hab immer noch große Skepsis ob das bei so einer Datenmenge überhaupt performant sein kann 😕

    Bin ich jetzt auf dem Holzweg zu denken das soviele Klasseninstanzen "böse" wären?
    Hat jemand mit sowas Erfahrungen und kann mir dazu etwas sagen?

    Viele Grüße
    m74



  • GoaZwerg schrieb:

    Bin ich jetzt auf dem Holzweg zu denken das soviele Klasseninstanzen "böse" wären?

    Ja. Überleg doch einfach mal ganz logisch. Du hast x "gedachte" Objekte. Jedes Objekt hat y Eigenschaften. Macht es jetzt einen Unterschied, ob da noch class oder struct oder sonst etwas drumherum steht? Wohl nicht. (Außer mit Padding vielleicht, aber ich denke das kann man hier vernachlässigen.)

    Insofern ist deine Angst unbegründet. Nimm Objekte und Kapsel sie. Das kostet nichts, und sollte es auch nicht.

    Wo man dann aber wieder aufpassen muss, ist bei Dingen die man implizit ausdrücken kann.

    Ein einfaches Beispiel: Ein Bild. Man kann jeden Bildpunkt als Objekt sehen, um im ersten moment denken, es wäre ein gute Idee, eine Pixelklasse zu erstellen. Das an sich wäre ja sogar noch irgendwie ok, aber ein Bild besteht halt nicht aus einem array aus Pixelobjekten, in dem jeder Pixel seine Position kennt.* Nein, die Position ist hier implizit und wesentlich effizienter durch die Position im Speicher ausgedrückt. Ein Pixelklasse ist somit ok, aber die Position im Bild ist dabei keine direkte Eigenschaft eines Pixel.

    Du musst hier also unterscheiden: Kannst du das so machen? Hat ein Lied eine feste Rasterisierung, sodass du die Position einer Note so ausdrücken kannst? (Bzw. die Position aller Noten als Index in ein Array.)
    Wenn ja, nutz das aus. Wenn nein, pack das anders. Aber es ist und bleibt keine Eigenschaft des Objekts, und nur weil du Klassen nutzt wird nicht der Speicherverbrauch magisch steigen.

    * Es könnte eine map sein, aber das würde nur dann Sinn machen, wenn das Bild viele "Löcher" hätte. Das ist aber vom Konzept her das Gleiche.



  • Erstens musst du unterscheiden zwischen der GUI-Komponente der Note und den Daten der Note.

    Zweitens kannst du ja einfach mal hochrechnen. Wenn 70 MB Speicherverbrauch akzeptabel ist und 50 MB davon an die Noteninstanzen gehen, können bei 64 Bytes/Note 800.000 Noten existieren. Klingt OK, wie ich finde.

    Ich würde es einfach mal so probieren und wenn es irgendwo klemmt, machst du halt punktuelle Workarounds um effizient Platz zu sparen.



  • Ja, die Daten wollte ich eh in einem Stream speichern. Macht Sinn, Dein Ansatz.


  • Mod

    Interessanter ist eigentlich, wie man den Notensound manipulieren kann z.B. in Abhängigkeit der anderen Noten und Parameter, Spielschnelligkeit, Vornoten, Vorfiltereinistellungen, Hüllkurven, Oszillatormodulationsverhälnis, LowFrequenzOszillatoren, diverse Effekte...

    Früher hatte man über Midi-Parametereinstellungen viele Modulationsmöglichkeiten bei Sythesizern gehabt, Echzeitmodulationen zu machen Oszillatorsynchronisierung, Oktavenüberblendungen, Interaktive Filtermodulationen, nette Verschuckeffekte usw.

    Jetzt ist aber die Frage, wenn man z.B. ein Physical Modelling - Synth hat, was jetzt das Editorprg macht, und was das Synth-Plugin und wie können die beiden Interagieren.

    Am besten erstmal einen einfachen Ansatz finden (z.B. einen Drumkiteditor) mit einfach nur Lautstärke Anschlagstärke und eventuell Trommelwirbelmöglichkeiten und so Zeug, so das man Triolen und so Zeugs eineditieren kann o.ä.)
    Siehe auch hier, recht spartanisch, aber ganz nett:
    http://www.threechords.com/hammerhead/



  • ...und aus genau diesen Gründen wirst Du froh sein, wenn Du sogar unterschiedliche und abgeleitete Objekte der Basisklasse Note hast.
    Der Sequenzer läuft dann auf der Basisklasse und die versorgten Elemente bekommen die Daten, wie sie sie brauchen.



  • GoaZwerg schrieb:

    Mit einer eigenen Klasseninstanz für jeden Notenanschlag ist das natürlich sau-bequem. Aber ich hab immer noch große Skepsis ob das bei so einer Datenmenge überhaupt performant sein kann 😕

    wenn du jede Sekunde 10-mal einen 100-stimmigen Akkord spielst, und mit 16 byte overhead pro Note, dann reichen rund 1.4 GByte für einen ganzen Tag Spielzeit aus. Bei 64 byte overhead (weiß nicht, wozu eine einzelne Note 512 Bit Information benötigen sollte) immer noch für 6 Stunden.

    ein Pianist ohne anatomische Besonderheiten kann max. 10-stimmig spielen, und bei 10 x 10-stimmigen Akkorden pro Sekunde dürften die meisten schon weit vor Tagesende einen Krampf bekommen, sodaß der Speicherbedarf realistisch eher im MByte-Bereich liegen dürfte, wenn nicht gerade das Skrjabin-Gesamtwerk am Stück gespielt wird.

    aktuelle PCs dürften das eigentlich im RAM halten können, warum sollte das nicht performant sein.



  • Falls in diesem Fall sinnvoll könnte auch das Flyweight Pattern etwas für dich sein.



  • GoaZwerg schrieb:

    Mit einer eigenen Klasseninstanz für jeden Notenanschlag ist das natürlich sau-bequem. Aber ich hab immer noch große Skepsis ob das bei so einer Datenmenge überhaupt performant sein kann 😕

    "premature optimization is the root of all evil" 😉
    Machs erstmal so, dass der Code übersichtlich/schön bleibt. Wenns danach später langsam ist, guck mit einem Profiler, wo der tatsächliche Falschenhals liegt. Erst dann ist Zeit fürs Optimieren. (Und dann musst du natürlich noch zwischen Geschwindigkeits-Problemen und Speicher-Problemen unterscheiden. Im zweiten Fall wär dann vielleicht der Link vom Kenner etwas für dich. Aber so weit bist du ja noch gar nicht. :))
    Warum deine Noten kein Fall sind, wo man schon im Voraus sehen kann, dass man was tun muss, hat cooky ja schon gut erklärt.


Anmelden zum Antworten