Protoze jsem delal velky uklid v M4_FORTH repozitari a snazil jsem se udelat LITE verzi a zbavit se vseho nepotrebneho co se za cas okolo prekladace nabalilo, tak jsem odstranil beeperovou hudbu z repozitare a vytvoril novy repozitar jen na to. Repozitar s hudbou me ted ukazuje 90 Mb a 1700+ souboru.... (55 Mb a 570 souboru, git si neco pridava...)
Snazil jsem se znovu prekompilovat kazdou skladbu, abych overil funkcnost a taky aby se spustil automaticky basicovsky zavadec.
Vedel jsem ze nedokazi zachovat puvodni vyzneni skladby, protoze jak jsem postupne zkousel dalsi a dalsi skladby tak se ten engine okolo toho ruzne vyvijel podle potreby a pridaval jsem nove a nove vychytavky, mnohdy nekompatibilni...
Ale ze to bude az takovy PROBLEM jsem necekal.
Postupne jak jsem zjistil ze puvodni prevodnik XM --> DAT totalne ignoruje ze pri prechodu mezi patterny proste puvodni zvuk bezi dal a misto toho na zacatku kazdeho patternu znovu vyresetuje veskery zvuk.
Takze jsem musel tedy pracne a pomalu znovu na zacatku kazdeho patternu psat ten ton znovu a znovu...
To melo dalsi neblahy vliv, protoze kazdy napsany TON predpoklada ze se teda znovu UDERI klavesa jakoby na klaviru, takze je tam silny ton, ktery postupne odezniva... takze ted to vypadalo jakoby tam byl falesny novy zacatek.
Takze jsem ruzne laboroval s prevodnikem XM --> DAT az jsem zavedl nejakou promennou LAST_... ktera pri parametru -c (jako continue) dokazala ten zvuk zachovat do dalsiho patternu.
Pak jsem pouzival -c vlastne vsude, protoze presne tak se kazde XM chova. Az se stalo ze jsem to nekde bugnul a prenasi to castecne kdyz se -c neuvede...
Dalsi problem u toho byl ze nove skladby prevedene z MIDI souboru meli automaticky v seznamu hranych patternu postupne rostouci cisla jako 0,1,2... atd.
Takze kdyz se ta skladba analyzovala tak se taky nacitali bez ohledu na poradi pri prehravani ty patterny 0,1,2... Proste jak jsou ulozeny v XM. Takze to NAVAZOVALO SPRAVNE.
To ale u originalnich MOD, XM skladeb atd nemusi vubec platit.
Tam je to kolikrat uplne prehazene a zacina skadba hrat patternem 3, prokracuje 5 a pak je 1, 2, 2, 4, ...
Jasne vidite, ze pak je parametr -c tak maximalne k vzteku, ze to hraje co nema.
Reseni bylo proste analyzovat tu skladbu ne podle toho jak jsou ulozene patterny, ale jak se prehravaji.
Fajn, udelal jsem to a mysel si jak jsem na to vyzral...
Az u nejake skladby to v jeden okamzik zacalo hrat falesne ze jsem to slysel i ja...
Zacal jsem resit co se deje... prvni den, druhy den, treti den...
Postupne odhaloval nejake chyby co jsem provedel... ale reseni nikde.
Tak jsem se vratil k puvodni verzi kde to hralo dobre a pridaval postupne uz jednou udelane zmeny... az narazim na problem...
Zase nic, jedine co jsem dokazal bylo nakonec najit jen stopu, neco co se chova necekane odlisne a pomalu ji vice a vice izolovat...
Skoncil jsem u neceho co vubec nedavalo smyl, proc to sakra nefunguje...
Chyba byla uz v originalni verzi xm2octode2k16.cpp...
Protoze ten prevod byl zjednoduseny...
A jak jsem postupne zkoumal jak to je udelany a studoval XM format
https://jss.sourceforge.net/moddoc/xm-form.txtTak jsem narazil na tohle
Kód:
********************
* General layout *
********************
The layout of a typical XM is like this:
XM header (up to and excluding header size field, now 60 bytes)
Rest of the header (length including header size field)
Pattern 0 header (length in header)
Pattern 0 data (length in header)
Pattern 1 header (length in header)
Pattern 1 data (length in header)
... (* number of patterns)
Instrument 0 header (length in size field is this and next one together)
if (numSample > 0)
Extra header
Sample 0 header (size in instrument extra header)
Sample 1 header (size in instrument extra header)
... (* number of samples in instrument)
Sample 0 data (length in sample header)
Sample 1 data (length in sample header)
... (* number of samples in instrument)
Instrument 1 header (length in size field is this and next one together)
... (* number of instruments)
******************************
* The XM file structure: *
******************************
HEADER
======
Offset|Length| Type | Description
------+------+--------+--------------------------------------------
0 | 17 | (char) | ID text: 'Extended Module: '
| | | (The last character is space, i.e. $20)
17 | 20 | (char) | Module name, padded with zeros.
37 | 1 | (char) | Always $1a
38 | 20 | (char) | Tracker name
58 | 2 | (word) | Version number, hi-byte major and low-byte minor
| | | The current format is version $0104. Format
| | | versions below $0104 have a LOT of differences.
| | | Remember to check this field! Your loader will
| | | probably crash if you don't!
| | |
60 | 4 | (dword)| Header size
| | | Calculated FROM THIS OFFSET, NOT from
| | | the beginning of the file!
+4 | 2 | (word) | Song length (in pattern order table)
+6 | 2 | (word) | Song restart position
+8 | 2 | (word) | Number of channels (2, 4, 6, 8, 10, ..., 32)
+10 | 2 | (word) | Number of patterns (max 256)
| | | NOTICE: This might not include all patterns used!
| | | If empty patterns are used at the end of the song
| | | they are NOT saved to the file!!
+12 | 2 | (word) | Number of instruments (max 128)
+14 | 2 | (word) | Flags field:
| | | bit0: 0 = Amiga frequency table
| | | 1 = Linear frequency table
+16 | 2 | (word) | Default tempo
+18 | 2 | (word) | Default BPM
+20 | 256 | (byte) | Pattern order table
PATTERNS
========
Offset|Length| Type | Description
------+------+--------+--------------------------------------------
? | 4 | (dword)| Pattern header length
+4 | 1 | (byte) | Packing type (always 0)
+5 | 2 | (word) | Number of rows in pattern (1..256)
+7 | 2 | (word) | Packed patterndata size
| | | << Note! This is zero if the pattern is
| | | completely empty and no pattern data
| | | follows! >>
| | |
? | ? | | Packed pattern data.
A problem byl v tom ze XM proste neulozi kdyz na konci je pattern se samyma nulama...
Dokonce zapomene i jeho delku (pocet radku) a nastavi to na 64.
Takze kdyz mate skaldbu kde se rozhodnete ze tesne pred koncem bude hrat nejaky zvuk dele nez se ukonci a mezi patterny
06 ... tohle zacina hrat posledni ton dlouze...
01 ... tohle postupne umlcuje jednotlive tony az ztichne
vlozite novy pattern, ktery je automaticky 7 jako nove nejvyssi cislo...
06
07 ...kde same nuly nevadi protoze to jen prodluzuje dobu trvani
01
Tak se pak nestacite divit...
V seznamu prehravanych patternu bude neco jako 0 1 2 3 4 5 7 6.
V delce skladby bude 8 patternu.
V poctu unikatnich patternu bude ale 7.
Ono je to jeste horsi kdyz ten pattern neni posledni, ale je ulozen... protoze je ulozen bez DAT jak je v popisku uvedeno.
Takze jsem pak CETL DATA Z HEADERU (protoze offset nula nebo jiny spatny offset) A NESTACIL SE DIVIT PROC MAM MISTO PRAZDNEHO RADKU DIVNE TONY.
Nekolik dni...
Takze ted se to vetvi krome komprimovany radek patternu nebo nekomprimovany jeste na neexistujici (imaginarni), protoze neni prazdny radek jako prazdny radek, podle toho co pokracuje....
Krome toho jsem pridal jeste vylepsenou podporu prace z modifikaci casu.
Jedna z mala veci co dokaze trosku vylepsit zvuk...
Kdyz mam rychlost (nebo spis pomalost, protoze cim vetsi cislo tim pomalejsi, protoze delsi trvani) na 2.
A hraji neco jako
Kód:
A-5 C#5
... ...
... ...
A-5 C#4
Tak se vklada mezi dvojici stejneho tonu ukonceni, protoze to hraje monotone na rozdil od toho uderu na klaviru.
Kód:
A-5 C#5
... ...
=== ...
A-5 C#4
Aby bylo poznat rytmus.
Na 99% plati ze tony jsou na sudych radcich a to ukonceni je na lichych...
Takze to hraje
2 "casy" A-5
2 "casy" pokracuje A-5
2 "casy" pokracuje A-5
2 "casy" ticho
Ale cim je ta mezera kratsi tim lepe a mene PRERUSOVANE ty skladby zneji.
ale zdvojnasobit rychlost znamena zdvojnasobit ctena data...
Ale s tou modifikaci casu kdy jsem zadal ze chci rozdelit radky po 2 (-mod=2)
A prvni radek (nulty) chci prodlouzit o 1 (-e=0)
A nasledujici radek (1) chci zkratit (trim) o 1 (-t=1)
Tak to hralo
3 "casy" A-5
1 "cas" pokracuje A-5
3 "casy" pokracuje A-5
1 "cas" ticho
Tohle nejde pouzit kde se uprava casu pouziva pro jemne doladeni rychlosti prehravani jako ma NUMB.XM, kde potrebuji skladbu zpomalit o cca 1/8.
Takze jsem volal "-m=4 -e=0", pri puvodni rychlosti 2 to teda hralo
3 "casy" A-5
2 "cas" pokracuje A-5
2 "casy" pokracuje A-5
2 "cas" ticho
Trik s +1 a -1 pak nejde pouzit. Protoze -e je uz pouzito a dalsi -e by zase zrychlilo skladbu.
Zbyvalo me bude pouzit dalsi parametry jako -t2 -e2... a nebo povolit opakovani parametru a ja zvolil to druhe...
Upravil jsem cpp tak ze kazdy -e a nebo -t modifikuje pole modify_time ktere je na poctku vynulovne
-e=0 -e=0 -t=1 -e=2 -t=3 -m=4 provede postupne
+1 0 0 0 0 0 ...
+2 0 0 0 0 0 ...
+2 -1 0 0 0 0 ...
+2 -1 +1 0 0 0 ...
+2 -1 +1 -1 0 0 ...
ted se dozvim ze mod je 4, programu to ale nevadi, ze je to nakonec, protoze ma napevno delku pole 256 (maximalni mozna delka patternu).
A az PO nacteni (presneji analyze) vsech parametru, se prvni 4 hodnoty (bylo zadano -m=4) opakovane duplikuji.
+2 -1 +1 -1 +2 -1 +1 -1 +2 -1 +1 -1 +2 -1 +1 -1 ...
S tim, ze pokud bych zadal v -e=4 (coz je vic nebo stejne jako mod) tak bych mel pouze tento paty (pocita se od 0) radek o +1 vic. Duplikuji se jen prvni 4 hodnoty. No duplikuji, prave ze spis se da rici ze pricitaji.
+2 -1 +1 -1 +3 -1 +1 -1 +2 -1 +1 -1 +2 -1 +1 -1 ...
Na konci programu, az se uklada DAT soubor se tohle pricte ke globalni rychlosti ke kazdemu radku( kecam je to slozitejsi, presnejsi je rici k aktualni rychlosti, protoze se da ruzne modifikovat efektama v XM souboru). Kdyz to klesne pod 1 na nulu nebo zaporny cas, tak se to z vypisu vynechava. Takze uz nemusim mit ani tu ignoraci v parametrech.
No, to je asi tak vse co jsem chtel napsat...
PS:
https://codeberg.org/DW0RKiN/M4_FORTH_MusicPPS: Konecne take chapu proc si ten XM soubor dokaze pamatovat nejake veci... jako ze zrusite nejaky pattern ze skladby, ale on jde OBNOVIT... no protoze je stale ulozen... jen neni pouzit. Dokud neudelate nejakou TRIM operaci, co to dokaze i precislovat...