FC (format pliku)
From Atariki
Wersja z dnia 02:41, 22 paź 2017 Mono (Dyskusja | wkład) (→Dane instrumentów - arpeggio) ← Previous diff |
Wersja z dnia 14:48, 23 paź 2017 KMK (Dyskusja | wkład) Next diff → |
||
Linia 3: | Linia 3: | ||
== Postać nieskompresowana == | == Postać nieskompresowana == | ||
- | <table border=1> | + | <table border=1 cellpadding="5"> |
- | <tr><td>offset</td><td>długość</td><td>opis</td></tr> | + | <tr><td><b>offset</b></td><td><b>długość</b></td><td><b>opis</b></td></tr> |
<tr><td>$0000</td><td>$0002</td><td>identyfikator: $26,$23</td></tr> | <tr><td>$0000</td><td>$0002</td><td>identyfikator: $26,$23</td></tr> | ||
<tr><td>$0002</td><td>$0001</td><td>tempo</td></tr> | <tr><td>$0002</td><td>$0001</td><td>tempo</td></tr> | ||
- | <tr><td>$0003</td><td>$0100</td><td>dane tracka 1</td></tr> | + | <tr><td>$0003</td><td>$0100</td><td>dane tracku 1</td></tr> |
- | <tr><td>$0103</td><td>$0100</td><td>dane tracka 2</td></tr> | + | <tr><td>$0103</td><td>$0100</td><td>dane tracku 2</td></tr> |
- | <tr><td>$0203</td><td>$0100</td><td>dane tracka 3</td></tr> | + | <tr><td>$0203</td><td>$0100</td><td>dane tracku 3</td></tr> |
<tr><td>$0303</td><td>$0080</td><td>dane 32 instrumentów (każdy z nich składa się z 4 bajtów)</td></tr> | <tr><td>$0303</td><td>$0080</td><td>dane 32 instrumentów (każdy z nich składa się z 4 bajtów)</td></tr> | ||
<tr><td>$0383</td><td>...</td><td>dane 64 patternów</td></tr> | <tr><td>$0383</td><td>...</td><td>dane 64 patternów</td></tr> | ||
Linia 19: | Linia 19: | ||
Znaczenie poszczególnych poleceń: | Znaczenie poszczególnych poleceń: | ||
* $00..$3F - numer patternu, | * $00..$3F - numer patternu, | ||
- | * $40 xx - ustawia AUDCTL wartością xx, | + | * $40 xx - ustawia AUDCTL na wartość xx, |
- | * $8x - ustawia transpozycję dla tracka (8 jest przyjmowane, jako transpozycja "zerowa"). | + | * $8x - ustawia transpozycję dla tracku (8 jest przyjmowane, jako transpozycja "zerowa"). |
* $FE - koniec songu, | * $FE - koniec songu, | ||
* $FF - zapętlenie songu. | * $FF - zapętlenie songu. | ||
Linia 49: | Linia 49: | ||
== Postać skompresowana == | == Postać skompresowana == | ||
- | Plik jest zgrywany bez żadnego nagłówka, jako zwykłe dane RAW i łącznie z procedurą odtwarzającą. | + | Plik jest zgrywany bez żadnego nagłówka, jako zwykłe dane RAW, i łącznie z procedurą odtwarzającą. |
- | <table border=1> | + | <table border=1 cellpadding="5"> |
- | <tr><td>offset</td><td>długość</td><td>opis</td></tr> | + | <tr><td><b>offset</b></td><td><b>długość</b></td><td><b>opis</b></td></tr> |
<tr><td>$0000</td><td>$0001</td><td>pozycja startowa w tracku</td></tr> | <tr><td>$0000</td><td>$0001</td><td>pozycja startowa w tracku</td></tr> | ||
<tr><td>$0001</td><td>$0321</td><td>program playera</td></tr> | <tr><td>$0001</td><td>$0321</td><td>program playera</td></tr> | ||
Linia 68: | Linia 68: | ||
</table> | </table> | ||
- | Na pozycji $0001 w pliku znajduje się rozkaz JSR INIT i na podstawie jego argumentu można odtworzyć adres, pod jaki skompilowano moduł playera i muzyki. | + | Na pozycji $0001 w pliku znajduje się rozkaz JSR INIT i na podstawie jego argumentu można odtworzyć adres, pod jaki skompilowano moduł playera i muzyki. Adres liczy się ze wzoru: |
- | Adres liczy się wzorem: | + | |
ADDR = msx[2] + $100 * msx[3] - $10 | ADDR = msx[2] + $100 * msx[3] - $10 | ||
Linia 77: | Linia 76: | ||
W tracku występują następujące rozkazy: | W tracku występują następujące rozkazy: | ||
* $00..$3F - numer patternu do odegrania, | * $00..$3F - numer patternu do odegrania, | ||
- | * $40 xx - ustawia AUDCTL wartością xx, | + | * $40 xx - ustawia AUDCTL na wartość xx, |
* $8x - transponuje dźwięk o x (8 jest uznawane za "poziom zerowy"), | * $8x - transponuje dźwięk o x (8 jest uznawane za "poziom zerowy"), | ||
* $FE - koniec odtwarzania, | * $FE - koniec odtwarzania, | ||
Linia 106: | Linia 105: | ||
== Tricki przy zapisie songów == | == Tricki przy zapisie songów == | ||
- | Ponieważ format nie precyzuje jak oznaczać subsongi, dlatego stosowane są dwie techniki: | + | Ponieważ format nie precyzuje, jak oznaczać subsongi, stosowane są dwie techniki: |
1. Na pozycji $0000 playera znajduje się komórka oznaczająca początek songu w trackach. Zmieniając jej wartość można spowodować odgrywanie songu od innego miejsca w trackach. Dzięki temu w jednym module można pomieścić kilka subsongów. Przykład z FLINSTON.FC: | 1. Na pozycji $0000 playera znajduje się komórka oznaczająca początek songu w trackach. Zmieniając jej wartość można spowodować odgrywanie songu od innego miejsca w trackach. Dzięki temu w jednym module można pomieścić kilka subsongów. Przykład z FLINSTON.FC: | ||
Linia 128: | Linia 127: | ||
0000300: 00 00 00 | 0000300: 00 00 00 | ||
- | Ponieważ song w każdym tracku może zajmować różną ilość miejsca, dlatego pola znajdujące się za subsongiem są po prostu ignorowane i mogą zawierać śmieci(!). | + | Ponieważ song w każdym tracku może zajmować różną ilość miejsca, pola znajdujące się za subsongiem są po prostu ignorowane i mogą zawierać śmieci(!). |
- | 2. Ponieważ player posiada tablicę adresów początków tracków (tablicę LSB adresów tracków w $0402 oraz MSB adresów w $0405), można upakować wiele subsongów zmieniając adresy początków tracków w tej tablicy. Offset songu w trackach ($0000) nie jest zmieniany. Np. | + | 2. Ponieważ player zawiera tablicę adresów początków tracków (tablicę LSB ich adresów w $0402 oraz MSB adresów w $0405), można upakować wiele subsongów zmieniając adresy początków tracków w tej tablicy. Offset songu w tracku ($0000) się nie zmienia. Np. |
0000000: 88 02 02 02 02 02 02 02 02 08 08 08 08 | 0000000: 88 02 02 02 02 02 02 02 02 08 08 08 08 | ||
Linia 160: | Linia 159: | ||
Ten trick pozwala na znacznie gęstsze upakowanie subsongów w module niż sposób 1. | Ten trick pozwala na znacznie gęstsze upakowanie subsongów w module niż sposób 1. | ||
- | |||
[[Kategoria: Formaty plików]] | [[Kategoria: Formaty plików]] |
Wersja z dnia 14:48, 23 paź 2017
Format modułu muzycznego obsługiwany przez program Future Composer w wersji 1.32 (mega).
Spis treści |
Postać nieskompresowana
offset | długość | opis |
$0000 | $0002 | identyfikator: $26,$23 |
$0002 | $0001 | tempo |
$0003 | $0100 | dane tracku 1 |
$0103 | $0100 | dane tracku 2 |
$0203 | $0100 | dane tracku 3 |
$0303 | $0080 | dane 32 instrumentów (każdy z nich składa się z 4 bajtów) |
$0383 | ... | dane 64 patternów |
... | ... | dane 32 obwiedni dźwięku |
Dane tracków
Znaczenie poszczególnych poleceń:
- $00..$3F - numer patternu,
- $40 xx - ustawia AUDCTL na wartość xx,
- $8x - ustawia transpozycję dla tracku (8 jest przyjmowane, jako transpozycja "zerowa").
- $FE - koniec songu,
- $FF - zapętlenie songu.
Dane patternów
Znaczenie poszczególnych poleceń:
- $00..$3F - zagranie nuty ($00 = C-1, $01 = C#1, ...),
- $40..$5f - odstęp między nutami (ilość definiują bity 0..4 - można w ten sposób zapisać odstęp o 32 pozycje patternu),
- $80..$9f - zmiana instrumentu (numer definiują bity 0..4),
- $FF - koniec patternu.
Dane instrumentów
Każdy instrument zdefiniowany jest za pomocą 4 bajtów:
- $00: numer obwiedni ($00..$1F),
- $01: zniekształcenia wpisywane do AUDCx,
- $02: głębokość dwupunktowego arpeggio (naprzemienne granie dźwięku podstawowego i podniesionego o podaną ilość półtonów),
- $03: efekt specjalny ($00 - brak, bit 7 - 0=vibrato, 1=slide down).
Dane obwiedni
Znaczenie poszczególnych poleceń:
- $00..$7F - dane są ORowane ze zniekształceniem instrumentu i wynik zapisywany jest do AUDCx,
- $80..$FE - dane są bezpośrednio zapisywane do AUDCx, a dodatkowo AUDFx ustawiany jest na 0,
- FF - koniec obwiedni.
Postać skompresowana
Plik jest zgrywany bez żadnego nagłówka, jako zwykłe dane RAW, i łącznie z procedurą odtwarzającą.
offset | długość | opis |
$0000 | $0001 | pozycja startowa w tracku |
$0001 | $0321 | program playera |
$0322 | $0040 | tablica LSB adresów patternów |
$0362 | $0020 | tablica LSB adresów obwiedni głośności instrumentów |
$0382 | $0040 | tablica MSB adresów patternów |
$03C2 | $0020 | tablica MSB adresów obwiedni głośności instrumentów |
$03E2 | $0020 | tablica czasów trwania nut obliczona na podstawie tempa utworu (pierwszy bajt jest równoważny tempu) |
$0402 | $0003 | tablica LSB adresów tracków |
$0405 | $0003 | tablica MSB adresów tracków |
$0408 | $0080 | dane 32 instrumentów |
$0488 | ... | dane 64 patternów |
... | ... | dane 32 obwiedni głośności dźwięku |
... | ... | dane 3 tracków |
Na pozycji $0001 w pliku znajduje się rozkaz JSR INIT i na podstawie jego argumentu można odtworzyć adres, pod jaki skompilowano moduł playera i muzyki. Adres liczy się ze wzoru:
ADDR = msx[2] + $100 * msx[3] - $10
Track
W tracku występują następujące rozkazy:
- $00..$3F - numer patternu do odegrania,
- $40 xx - ustawia AUDCTL na wartość xx,
- $8x - transponuje dźwięk o x (8 jest uznawane za "poziom zerowy"),
- $FE - koniec odtwarzania,
- $FF - zapętlenie odtwarzania.
Pattern
W patternie występują następujące rozkazy:
- $00..$3F - nuta,
- $40..$7F - czas trwania dźwięku (bity 0..4),
- $80..$9F - instrument (bity 0..4),
- $FF - koniec patternu.
Instrument
Instrument składa się z pól:
- $00: numer obwiedni głośności,
- $01: zniekształcenie (AUDCx),
- $02: vibrato,
- $03: efekt.
Obwiednia głośności
W obwiedni występują następujące rozkazy:
- $00..$FE - dane obwiedni,
- $FF - koniec obwiedni.
Tricki przy zapisie songów
Ponieważ format nie precyzuje, jak oznaczać subsongi, stosowane są dwie techniki:
1. Na pozycji $0000 playera znajduje się komórka oznaczająca początek songu w trackach. Zmieniając jej wartość można spowodować odgrywanie songu od innego miejsca w trackach. Dzięki temu w jednym module można pomieścić kilka subsongów. Przykład z FLINSTON.FC:
0000000: 83 00 00 17 17 00 fe 83 14 fe 83 12 fe 0000010:00 00 0083 0a 0b 0c 0c ff00 0000 00 00 00 00 0000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 0000100: 00 00 00
0000100: 88 00 18 18 18 19 fe 88 13 fe 88 10 11 0000110: fe00 0088 01 01 02 03 04 04 ff 00 00 00 00 00 0000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 0000200: 00 00 00
0000200: 88 15 16 15 16 19 fe 88 13 fe 88 0d 0e 0000210: 0d 0f fe 88 05 06 07 08 09 09 ff 00 00 00 00 00 0000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 0000300: 00 00 00
Ponieważ song w każdym tracku może zajmować różną ilość miejsca, pola znajdujące się za subsongiem są po prostu ignorowane i mogą zawierać śmieci(!).
2. Ponieważ player zawiera tablicę adresów początków tracków (tablicę LSB ich adresów w $0402 oraz MSB adresów w $0405), można upakować wiele subsongów zmieniając adresy początków tracków w tej tablicy. Offset songu w tracku ($0000) się nie zmienia. Np.
0000000: 88 02 02 02 02 02 02 02 02 08 08 08 08 0000010: 0b 08 08 08 08 0e 0e 11 12 ff 01 01 01 01 03 0a 0000020: 0c 0a 0f 0f 0f 14 ff 04 04 04 04 04 04 04 04 09 0000030: 09 09 09 0d 09 09 09 09 10 10 10 10 10 10 10 10 0000040: 10 10 10 10 13 ff 16 fe 15 ff 17 ff 18 fe ff 19 0000050: fe ff 1a fe ff 1b 1b 1b 1b 1e 1e 1e 1e ff 1c 1c 0000060: 1c 1c 1f 1f 1f 1f ff 1d 1d 20 20 ff 80 5f 08 ff ...
0000100: 81 01 01 01 01 03 0a 0c 0a 0f 0f 0f 14 0000110: ff 04 04 04 04 04 04 04 04 09 09 09 09 0d 09 09 0000120: 09 09 10 10 10 10 10 10 10 10 10 10 10 10 13 ff 0000130: 16 fe 15 ff 17 ff 18 fe ff 19 fe ff 1a fe ff 1b 0000140: 1b 1b 1b 1e 1e 1e 1e ff 1c 1c 1c 1c 1f 1f 1f 1f 0000150: ff 1d 1d 20 20 ff 80 5f 08 ff 82 41 27 20 28 20 0000160: 25 20 27 20 27 20 28 20 25 20 27 20 27 20 28 20 ...
0000200: 81 04 04 04 04 04 04 04 04 09 09 09 09 0000210: 0d 09 09 09 09 10 10 10 10 10 10 10 10 10 10 10 0000220: 10 13 ff 16 fe 15 ff 17 ff 18 fe ff 19 fe ff 1a 0000230: fe ff 1b 1b 1b 1b 1e 1e 1e 1e ff 1c 1c 1c 1c 1f 0000240: 1f 1f 1f ff 1d 1d 20 20 ff 80 5f 08 ff 82 41 27 0000250: 20 28 20 25 20 27 20 27 20 28 20 25 20 27 20 27 0000260: 20 28 20 25 20 27 20 27 20 28 20 25 20 27 20 ff ...
Ten trick pozwala na znacznie gęstsze upakowanie subsongów w module niż sposób 1.