Re: Trackermodul-Engine (sehr einfach)
Verfasst: Do 31. Mär 2016, 00:10
@DOSferatu: Jetzt wo es was mit Musik bzw. Sound zu tun hat bin ich auch richtig bei der Sache und
auch schon ein Stück mehr motiviert, ein Spiel oder wenigstens so eine Art interaktive Demo zu machen.
Übliche Tracker haben halt einen dicken Nachteil, die Redundanz der Patterndaten, wenn es sich
nicht unbedingt um komplexe klassische Musik handelt, die man da getrackert hat, was aber meistens
sowieso nicht so gut rüberkommt. Es gibt ein paar MODs, da wird jeder Befehl und alle Tricks ausgereizt,
um mit einem einzigen Pattern auf eine Länge von einer halben Minute zu kommen. Aber dann kann
man wirklich fast ein komplexeres Format wählen mit Programmcode-ähnlichen Befehlen.
Ein Speicherfresser bei meiner Patternkompression ist noch das "Gerüst": Die Flags, die ansagen,
in welcher Zeile und auf welchem Track ein Befehl steht. Während der Programmierung habe ich
festgestellt dass simples Zeilenweises flagging mit 1 Bit jeweils effektiver ist als wenn man da
optional oder permanent Lauflängen mit reinbringt. Bei einem (1) Track mit 64 Zeilen sind das
8 Byte, zumindest wenn es keine ganzen Leerzeilen gibt, die als solche geflagt würden.
Jedenfalls kann sich das ganze so zusammenläppern, dass ich alleine für das Gerüst 32 Byte oder
bei 16 Kanälen sogar 128 Byte habe, im ungünstigsten Fall.
Aber mir kommt gerade eine neue Idee, und zwar dass ich diese Gerüste, oder nennen wir sie mal
Masken, tabellarisch ablege und dann einfach per Byte (oder so viel Bit wie es braucht für die Anzahl
aller vorkommenden verschiedenen Masken) jedem Track zuordne. Dabei könnte man diese dann
auch noch je nach Typ entsprechend komprimieren - je nach Pattern kommt es auch mal vor, dass
jede Zeile auf einem Track belegt ist. Solch ein Muster braucht ja nichts ausser der Information
dass alles voll ist.
Es könnte sich so noch eine wesentlich höhere Kompressionsrate ergeben, denn ich habe das
Format so angelegt, dass jeder Track eine Tabelle hat (es sei denn sie braucht mehr Speicher
als wenn die direkten Werte im Track gespeichert stehen plus der Indizes im Track). Es gibt drei
Arten von Tabellen: Samplenummer und Volume, und es gibt eine dritte, die nicht für jeden Track
erzeugt wird, sondern generell für jedes Sample: Die Pitch-Tabelle. Worauf ich hinaus will:
Für den Ausnahmefall, dass wir es z.B. mit einer Hihat zu tun haben, die auf einem Track
gespielt wird auf einer festen Lautstärke, dann hat dieser Track nur eine Samplenummer, nur
eine Lautstärke und nur eine Note. Folglich werden gar keine Bits gelesen, weil für diesen Track
schon alles fest definiert ist - nur das Gerüst gibt an, WANN die Hihat gespielt werden soll.
Naja und wenn ich diese Gerüste nochmal zusammenstreiche, dann wird es öfter Tracks oder
im Extremfall ganze Patterns geben, die mehr oder weniger 0 Byte belegen, von den (kleinen)
Tabellen und dem Hinweis für jeden Track, welches Gerüst er haben muss, abgesehen.
EDIT: Nochmal drüber nachgedacht... So wie beschrieben werde ich es nicht umsetzen. Der Overhead
würde den Gewinn nahezu kompensieren und die Leseroutinen würden unverhältnismäßig komplex.
Nur irgendwie meine ich, müsste da noch was gehen. Wobei der Zweck schon erfüllt ist, ich bekäme
rund 500 Patterns in 64K, und das erlaubt rund 1 Stunde nichtredundante Musik. Ob man 4 oder
16 Kanäle hat macht dabei gar nicht so viel aus, da man automatisch bei mehr Kanälen alles
nicht so dicht bepackt.
Ich halte es übrigens nicht für unmöglich, redundante MOD Patterns wirklich effizient und intelligent
zu komprimieren. Aber das würde schon etwas mehr Programmieraufwand erfordern, und
da kommen mir auch solche Dinge wie Brute Force in den Sinn...
Aber mitunter winkt eine größere Effizienz als wenn man einfach ZIP drüberjagt.
Ähnlich wie bei meinem ZVID, welches zwar an sich Grafiken nicht ganz so klein bekommt
wie GIF, dann aber wiederum, ergeben sich deutlich kleinere Daten, wenn man ein ZVID mit ZIP
komprimiert, als wenn man Grafik komprimiert, die nicht durch ZVID gelaufen ist.
auch schon ein Stück mehr motiviert, ein Spiel oder wenigstens so eine Art interaktive Demo zu machen.
Übliche Tracker haben halt einen dicken Nachteil, die Redundanz der Patterndaten, wenn es sich
nicht unbedingt um komplexe klassische Musik handelt, die man da getrackert hat, was aber meistens
sowieso nicht so gut rüberkommt. Es gibt ein paar MODs, da wird jeder Befehl und alle Tricks ausgereizt,
um mit einem einzigen Pattern auf eine Länge von einer halben Minute zu kommen. Aber dann kann
man wirklich fast ein komplexeres Format wählen mit Programmcode-ähnlichen Befehlen.
Ein Speicherfresser bei meiner Patternkompression ist noch das "Gerüst": Die Flags, die ansagen,
in welcher Zeile und auf welchem Track ein Befehl steht. Während der Programmierung habe ich
festgestellt dass simples Zeilenweises flagging mit 1 Bit jeweils effektiver ist als wenn man da
optional oder permanent Lauflängen mit reinbringt. Bei einem (1) Track mit 64 Zeilen sind das
8 Byte, zumindest wenn es keine ganzen Leerzeilen gibt, die als solche geflagt würden.
Jedenfalls kann sich das ganze so zusammenläppern, dass ich alleine für das Gerüst 32 Byte oder
bei 16 Kanälen sogar 128 Byte habe, im ungünstigsten Fall.
Aber mir kommt gerade eine neue Idee, und zwar dass ich diese Gerüste, oder nennen wir sie mal
Masken, tabellarisch ablege und dann einfach per Byte (oder so viel Bit wie es braucht für die Anzahl
aller vorkommenden verschiedenen Masken) jedem Track zuordne. Dabei könnte man diese dann
auch noch je nach Typ entsprechend komprimieren - je nach Pattern kommt es auch mal vor, dass
jede Zeile auf einem Track belegt ist. Solch ein Muster braucht ja nichts ausser der Information
dass alles voll ist.
Es könnte sich so noch eine wesentlich höhere Kompressionsrate ergeben, denn ich habe das
Format so angelegt, dass jeder Track eine Tabelle hat (es sei denn sie braucht mehr Speicher
als wenn die direkten Werte im Track gespeichert stehen plus der Indizes im Track). Es gibt drei
Arten von Tabellen: Samplenummer und Volume, und es gibt eine dritte, die nicht für jeden Track
erzeugt wird, sondern generell für jedes Sample: Die Pitch-Tabelle. Worauf ich hinaus will:
Für den Ausnahmefall, dass wir es z.B. mit einer Hihat zu tun haben, die auf einem Track
gespielt wird auf einer festen Lautstärke, dann hat dieser Track nur eine Samplenummer, nur
eine Lautstärke und nur eine Note. Folglich werden gar keine Bits gelesen, weil für diesen Track
schon alles fest definiert ist - nur das Gerüst gibt an, WANN die Hihat gespielt werden soll.
Naja und wenn ich diese Gerüste nochmal zusammenstreiche, dann wird es öfter Tracks oder
im Extremfall ganze Patterns geben, die mehr oder weniger 0 Byte belegen, von den (kleinen)
Tabellen und dem Hinweis für jeden Track, welches Gerüst er haben muss, abgesehen.
EDIT: Nochmal drüber nachgedacht... So wie beschrieben werde ich es nicht umsetzen. Der Overhead
würde den Gewinn nahezu kompensieren und die Leseroutinen würden unverhältnismäßig komplex.
Nur irgendwie meine ich, müsste da noch was gehen. Wobei der Zweck schon erfüllt ist, ich bekäme
rund 500 Patterns in 64K, und das erlaubt rund 1 Stunde nichtredundante Musik. Ob man 4 oder
16 Kanäle hat macht dabei gar nicht so viel aus, da man automatisch bei mehr Kanälen alles
nicht so dicht bepackt.
Ich halte es übrigens nicht für unmöglich, redundante MOD Patterns wirklich effizient und intelligent
zu komprimieren. Aber das würde schon etwas mehr Programmieraufwand erfordern, und
da kommen mir auch solche Dinge wie Brute Force in den Sinn...
Aber mitunter winkt eine größere Effizienz als wenn man einfach ZIP drüberjagt.
Ähnlich wie bei meinem ZVID, welches zwar an sich Grafiken nicht ganz so klein bekommt
wie GIF, dann aber wiederum, ergeben sich deutlich kleinere Daten, wenn man ein ZVID mit ZIP
komprimiert, als wenn man Grafik komprimiert, die nicht durch ZVID gelaufen ist.