ADX (format pliku)
Deweloperzy | Oprogramowanie pośredniczące CRI |
---|---|
Pierwsze wydanie | 1996 |
Platforma | Międzyplatformowe |
Typ | Kodek / Format pliku |
Licencja | Prawnie zastrzeżony |
Strona internetowa | Oprogramowanie pośredniczące CRI |
CRI ADX to stratny zastrzeżony format przechowywania i kompresji dźwięku opracowany przez CRI Middleware specjalnie do użytku w grach wideo ; wywodzi się z ADPCM . Jego najbardziej godną uwagi cechą jest funkcja zapętlania, która okazała się przydatna w przypadku dźwięków tła w różnych grach, które przyjęły ten format, w tym w wielu grach na konsolę Sega Dreamcast , a także w niektórych grach na PlayStation 2 , GameCube i Wii . Jedną z pierwszych gier korzystających z ADX był Burning Rangers na Sega Saturn . Warto zauważyć, że seria Sonic the Hedgehog od generacji Dreamcast do co najmniej Shadow the Hedgehog używała tego formatu do nagrań dźwiękowych i głosowych. Jet Set Radio Future na oryginalną konsolę Xbox również używał tego formatu.
Oprócz głównego kodowania ADPCM, zestaw narzędzi ADX zawiera także siostrzany format, AHX, który wykorzystuje wariant dźwięku MPEG-2 przeznaczony specjalnie do nagrań głosowych oraz archiwum pakietów, AFS, do łączenia wielu ścieżek CRI ADX i AHX w jeden pojedynczy plik kontenera.
Wersja 2 formatu (ADX2) wykorzystuje rozszerzenia HCA i HCA-MX, które są zwykle dołączane do pliku kontenera z rozszerzeniami ACB i AWB. Rozszerzenia AWB nie należy mylić z formatem Audio z tym samym rozszerzeniem i zawiera głównie dane binarne dla plików HCA.
Przegląd ogólny
CRI ADX to skompresowany format audio, ale w przeciwieństwie do MP3 i podobnych formatów, nie stosuje psychoakustycznego modelu do dźwięku, aby zmniejszyć jego złożoność. Zamiast tego model ADPCM przechowuje próbki, rejestrując błąd w stosunku do funkcji przewidywania, co oznacza, że więcej oryginalnego sygnału przetrwa proces kodowania; jako taka kompresja ADPCM zamiast tego zamienia dokładność reprezentacji na rozmiar, używając stosunkowo małych rozmiarów próbek, zwykle 4 bity. Tolerancja ludzkiego układu słuchowego na powodowany przez niego hałas powoduje, że utrata dokładności jest ledwo zauważalna.
Podobnie jak inne formaty kodowania, CRI ADX obsługuje wiele częstotliwości próbkowania, takich jak 22050 Hz , 44100 Hz, 48000 Hz itp. Jednak głębokość próbkowania danych wyjściowych jest zablokowana na poziomie 16 bitów, głównie ze względu na wspomniany już brak precyzji. Obsługuje wiele kanałów, ale wydaje się, że istnieje niejawne ograniczenie dźwięku stereo (2-kanałowego), chociaż sam format pliku może reprezentować do 255 kanałów. Jedyną szczególnie wyróżniającą cechą, która odróżnia CRI ADX od alternatyw, takich jak IMA ADPCM (inna niż posiadanie innej funkcji przewidywania), jest zintegrowana funkcja zapętlania, która umożliwia odtwarzaczowi audio opcjonalne przeskakiwanie do tyłu po osiągnięciu pojedynczego określonego punktu na ścieżce w celu utworzenia spójna pętla; hipotetycznie ta funkcja mogłaby być również używana do przeskakiwania do przodu, ale byłoby to zbędne, ponieważ zamiast tego dźwięk można by po prostu przyciąć za pomocą programu do edycji.
Do odtwarzania jest kilka wtyczek do WinAmp i narzędzie do konwersji na fale (patrz sekcja referencje). Program / biblioteka open source FFmpeg ma również zaimplementowaną obsługę CRI ADX, jednak jego dekoder jest zakodowany na stałe, więc może poprawnie dekodować tylko ADX 44100 Hz.
Opis techniczny
Specyfikacja CRI ADX nie jest ogólnodostępna, jednak najważniejsze elementy struktury zostały poddane inżynierii wstecznej i udokumentowane w różnych miejscach w sieci. Informacje tutaj mogą być niekompletne, ale powinny wystarczyć do zbudowania działającego kodeka lub transkodera .
Na marginesie, pliki archiwum AFS, w które czasami pakowane są CRI ADX, są prostym wariantem tarballa, który używa indeksów numerycznych do identyfikacji zawartości, a nie nazw. Kod źródłowy ekstraktora można znaleźć w archiwum ADX pod adresem.
Nagłówek pliku
Format dysku ADX jest zdefiniowany w big-endian . Zidentyfikowane sekcje głównego nagłówka przedstawiono poniżej:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | mi | F | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0 | 0x80 | 0x00 | Przesunięcie praw autorskich | Typ kodowania | Rozmiar bloku | Próbka głębi bitowej | Liczba kanałów | Próbna stawka | Suma próbek | |||||||
0x10 | Częstotliwość górnoprzepustowa | Wersja | Flagi | Próbki wyrównania pętli (v3) | Pętla włączona (v3) | Pętla włączona (v3) | Przykładowy indeks początku pętli (v3) | |||||||||
0x20 | Indeks bajtu początku pętli (v3) | Pętla włączona (v4) Indeks próbki końca pętli (v3) |
Przykładowy indeks początku pętli (v4) Indeks bajtów końca pętli (v3) |
Indeks bajtu początku pętli (v4) | ||||||||||||
0x30 | Indeks próbki końca pętli (v4) | Indeks bajtów końca pętli (v4) | Zero lub więcej bajtów pustej przestrzeni | |||||||||||||
??? | [CopyrightOffset - 2] Ciąg ASCII (niezakończony): "(c)CRI" | |||||||||||||||
... | [CopyrightOffset + 4] Dane audio zaczynają się tutaj |
Pola oznaczone jako „Nieznane” zawierają nieznane dane lub najwyraźniej są zarezerwowane (tj. wypełnione bajtami zerowymi). Pola oznaczone „v3” lub „v4”, ale nie obydwoma, są uważane za „Nieznane” w wersji, w której nie są oznaczone. Ten nagłówek może mieć zaledwie 20 bajtów (0x14), zgodnie z przesunięciem praw autorskich, które domyślnie usuwa obsługę pętli, ponieważ te pola nie są obecne.
Pole „Rodzaj kodowania” powinno zawierać jedną z następujących wartości:
- 0x02 dla CRI ADX z ustawionymi współczynnikami predykcji
- 0x03 dla standardowego CRI ADX
- 0x04 dla CRI ADX ze skalą wykładniczą
- 0x10 lub 0x11 dla AHX
Pole „Wersja” powinno zawierać jedną z następujących opcji:
- 0x03 dla CRI ADX „wersja 3”
- 0x04 dla CRI ADX „wersja 4”
- 0x05 dla wariantu CRI ADX 4 bez obsługi pętli
Podczas dekodowania dźwięku AHX pole wersji wydaje się nie mieć żadnego znaczenia i można je bezpiecznie zignorować.
Pliki z typem kodowania „2” używają 4 możliwych zestawów współczynników predykcji wymienionych poniżej:
Współczynnik 0 | Współczynnik 1 | |
---|---|---|
Ustaw 0 | 0x0000 | 0x0000 |
Zestaw 1 | 0x0F00 | 0x0000 |
Zestaw 2 | 0x1CC0 | 0xF300 |
Zestaw 3 | 0x1880 | 0xF240 |
Przykładowy format
Dane audio zakodowane w CRI ADX są dzielone na serię „bloków”, z których każdy zawiera dane tylko dla jednego kanału. Bloki są następnie układane w „ramki”, które składają się z jednego bloku z każdego kanału w porządku rosnącym. Na przykład w strumieniu stereo (2-kanałowym) składałoby się to z Ramki 1: blok lewego kanału, blok prawego kanału; Ramka 2: lewa, prawa; itp. Bloki mają zwykle rozmiar 18 bajtów i zawierają próbki 4-bitowe, chociaż technicznie możliwe są inne rozmiary, przykład takiego bloku wygląda następująco:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Predyktor/Skala | 32 4-bitowe próbki |
Pierwsze 3 bity liczby całkowitej „Predictor/Scale” zawierają indeks predyktora. Skala jest zawarta w pozostałych 13 bitach.
Indeks predyktora jest 3-bitową liczbą całkowitą, która określa, który zestaw współczynników predykcji powinien być użyty do zdekodowania tego bloku. Jest to używane tylko w plikach z typem kodowania „2”.
Skala jest 13-bitową liczbą całkowitą bez znaku ( big-endian jak nagłówek), która jest zasadniczo wzmocnieniem wszystkich próbek w tym bloku. Każda próbka w bloku musi być dekodowana w kolejności strumienia bitów, to znaczy najpierw najbardziej znaczący bit. Na przykład, gdy rozmiar próbki wynosi 4 bity:
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|
Pierwsza próbka | Druga próbka |
Same próbki nie są odwrócone, więc nie ma potrzeby bawić się nimi po ich wydobyciu. Każda próbka jest podpisana, więc w tym przykładzie wartość może mieścić się w zakresie od -8 do +7 (co zostanie pomnożone przez skalę podczas dekodowania). Na marginesie, chociaż dowolna głębia bitowa między 1 a 255 jest możliwa dzięki nagłówkowi. Jest mało prawdopodobne, aby kiedykolwiek wystąpiły próbki jednobitowe, ponieważ mogą one reprezentować tylko wartości {0, 1}, {-1, 0} lub {-1, 1}, z których wszystkie nie są szczególnie przydatne do kodowania utworów — jeśli miały wystąpić, to nie jest jasne, która z trzech możliwości jest właściwą interpretacją.
Dekodowanie CRI ADX
W tej sekcji omówiono dekodowanie CRI ADX „wersja 3” lub „wersja 4”, gdy „Typ kodowania” to „Standardowy CRI ADX” ( 0x03 ). Koder można również zbudować, po prostu odwracając kod, aby działał w odwrotnej kolejności. Wszystkie przykłady kodu w tej sekcji są napisane przy użyciu języka C99 .
Zanim „standardowy” CRI ADX będzie mógł zostać zakodowany lub zdekodowany, należy obliczyć zestaw współczynników predykcji. Zasadniczo najlepiej jest to zrobić na etapie inicjalizacji:
0
#define M_PI acos(-1.0) double a , b , c ; a = sqrt ( 2.0 ) - cos ( 2.0 * M_PI * ( ( podwójne ) adx_header -> highpass_frequency / adx_header -> sample_rate )); b = sqrt ( 2,0 ) - 1,0 ; do = ( a - sqrt (( a + b ) * ( a - b ))) / b ; //(a+b)*(ab) = a*ab*b, jednak prostsza formuła traci dokładność w liczbach zmiennoprzecinkowych // podwójny współczynnik[2]; współczynnik [ ] = c * 2,0 ; współczynnik [ 1 ] = - ( do * do );
Ten kod oblicza współczynniki predykcji do przewidywania bieżącej próbki na podstawie 2 poprzednich próbek. Współczynniki te tworzą również filtr górnoprzepustowy pierwszego rzędu o skończonej odpowiedzi impulsowej . [ wymagane wyjaśnienie ]
Znając współczynniki dekodowania, może rozpocząć dekodowanie strumienia:
0
0
0
0
0 0
0
0
static int32_t * przeszłe_próbki ; // Wcześniej zdekodowane próbki z każdego kanału, zerowane na początku (size = 2*channel_count) static uint_fast32_t sample_index = ; // sample_index jest indeksem zestawu próbek, który musi zostać zdekodowany następny static ADX_header * adx_header ; // bufor to miejsce, w którym zostaną umieszczone zdekodowane próbki // sampling_needed określa, ile „zestawów” próbek (po jednej próbce z każdego kanału) należy zdekodować, aby wypełnić bufor // looping_enabled to flaga logiczna kontrolująca użycie wbudowanego in loop // Zwraca liczbę „zestawów” próbek w buforze, których nie można było wypełnić (EOS) unsigned decode_adx_standard ( int16_t * buffer , unsigned sampling_needed , bool looping_enabled ) { unsigned const sampling_per_block = ( adx_header -> block_size - 2 ) * 8 / adx_header -> próbka_bitgłębokość ; int16_t skala [ adx_header -> channel_count ]; if ( włączona_pętla && ! nagłówek_adx -> włączona pętla ) włączona_pętla = fałsz ; // Zapętlanie do momentu zdekodowania żądanej liczby próbek lub osiągnięcia końca pliku while ( potrzebne_próbki > && indeks_próbki < adx_header -> total_samples ) { // Oblicz liczbę próbek, które pozostały do zdekodowania w bieżącym bloku unsigned próbka_przesunięcie = próbka_indeks % próbki_na_blok ; unsigned sample_can_get = sample_per_block - sample_offset ; // Zablokuj próbki, które możemy pobrać podczas tego przebiegu, jeśli nie zmieszczą się w buforze if ( próbki_puszka_pobieranie > potrzebne_próbki ) pobieranie_puszek_puszek = potrzebne_próbki ; // Ogranicz liczbę próbek do pobrania, jeśli strumień nie jest wystarczająco długi lub wyzwalacz pętli jest w pobliżu if ( looping_enabled && sample_index + sampling_can_get > adx_header -> loop_end_index ) sampling_can_get = adx_header -> loop_end_index - sample_index ; w przeciwnym razie if ( indeks_próbki + pobranie_puszki_adx > nagłówek_adx -> całkowita_próbki ) pobranie_puszki_próbki = nagłówek_adx -> całkowita_próbki - indeks_próbek ; // Oblicz adres bitowy początku ramki, w której znajduje się indeks_próbki i zapisz tę lokalizację unsigned long begin_at = ( adx_header -> copyright_offset + 4 + \ sample_index / sample_per_block * adx_header -> block_size * adx_header -> channel_count ) * 8 ; // Odczytaj wartości skali od początku każdego bloku w tej ramce for ( unsigned i = ; i < adx_header -> channel_count ; ++ i ) { bitstream_seek ( start_at + adx_header -> block_size * i * 8 ); skala [ i ] = ntohs ( bitstream_read ( 16 ) ); } // Wstępne obliczenie wartości stopu dla sample_offset unsigned sample_endoffset = sample_offset + sampling_can_get ; // Zapisz adres strumienia bitów pierwszej próbki bezpośrednio po skali w pierwszym bloku ramki rozpoczęty_at += 16 ; while ( przesunięcie_próbki < przesunięcie_końca próbki ) { for ( unsigned i = ; i < nagłówek_adx -> liczba_kanałów ; ++ i ) { // Przewidywanie następnej próbki podwójna predykcja_próbki = współczynnik [ ] * próbki_przeszłe [ i * 2 + ] + współczynnik [ 1 ] * próbki_przeszłości [ i * 2 + 1 ]; // Znajdź próbkę przesunięcia, przeczytaj i podpisz, rozszerz ją do 32-bitowej liczby całkowitej // Implementacja rozszerzenia znaku jest pozostawiona jako ćwiczenie dla czytelnika // Rozszerzenie znaku będzie również wymagało uwzględnienia korekty endian, jeśli jest więcej niż 8 bitów bitstream_seek ( rozpoczęty_at + adx_header -> próbka_bitgłębokość * próbka_przesunięcie + \ adx_header -> rozmiar_bloku * 8 * i ); int_fast32_t sample_error = bitstream_read ( nagłówek_adx -> próbka_głębokość bitów ); błąd_próbki = rozszerzenie_znaku ( błąd_próbki , nagłówek_adx -> głębia bitów_próbki ); // Skaluj wartość korekcji błędów sample_error *= scale [ i ]; // Oblicz próbkę przez połączenie predykcji z korekcją błędów int_fast32_t sample = sample_error + ( int_fast32_t ) sample_prediction ; // Zaktualizuj poprzednie próbki nowszą próbką past_samples [ i * 2 + 1 ] = past_samples [ i * 2 + ]; próbki_przeszłości [ i * 2 + ] = próbka ; // Dopasuj zdekodowaną próbkę do prawidłowego zakresu dla 16-bitowej liczby całkowitej if ( próbka > 32767 ) próbka = 32767 ; inaczej if ( próbka < -32768 ) próbka = -32768 ; // Zapisz próbkę w buforze, a następnie przesuń o jedno miejsce * buffer ++ = sample ; } ++ przesunięcie_próbki ; // Zdekodowaliśmy po jednej próbce z każdego bloku, przesuwając przesunięcie bloku o 1 ++ sample_index ; // Oznacza to również, że jesteśmy o jedną próbkę dalej w strumieniu -- sampling_needed ; // Jest więc o jeden zestaw sampli mniej do zdekodowania } // Sprawdź, czy trafiliśmy w znacznik końca pętli, jeśli tak, musimy przeskoczyć do początku pętli if ( looping_enabled && sample_index == adx_header -> loop_end_index ) sample_index = adx_header -> loop_start_index ; } zwróć potrzebne_próbki ; }
Większość powyższego kodu powinna być wystarczająco prosta dla każdego, kto zna C. Wskaźnik „ ADX_header
” odnosi się do danych wyodrębnionych z nagłówka, jak opisano wcześniej, zakłada się, że zostały już przekonwertowane na Endian hosta. Ta implementacja nie ma być optymalna, a kwestie zewnętrzne zostały zignorowane, takie jak specyficzna metoda rozszerzenia znaku i metoda pozyskiwania strumienia bitów ze źródła pliku lub sieci. buforze wyjściowym będą potrzebne zestawy próbek (jeśli stereo, będą na przykład pary) sampli . Dekodowane próbki będą w PCM z przeplotem w standardzie host-endian, tj. lewy 16-bitowy, prawy 16-bitowy, lewy, prawy itd. Wreszcie, jeśli zapętlanie nie jest włączone lub nie jest obsługiwane, funkcja zwróci liczbę spacji próbek, które nie były używane w buforze. Osoba dzwoniąca może sprawdzić, czy ta wartość nie wynosi zero, aby wykryć koniec strumienia i w razie potrzeby upuścić lub zapisać ciszę w nieużywanych miejscach.
Szyfrowanie
CRI ADX obsługuje prosty schemat szyfrowania, który XOR-uje wartości z liniowego, zgodnego generatora liczb pseudolosowych z wartościami skali bloku. Ta metoda jest niedroga obliczeniowo do odszyfrowania (zgodnie z dekodowaniem w czasie rzeczywistym CRI ADX), ale sprawia, że zaszyfrowane pliki są bezużyteczne. Szyfrowanie jest aktywne, gdy wartość „Flags” w nagłówku wynosi 0x08 . Ponieważ XOR jest symetryczny, ta sama metoda jest używana do deszyfrowania i szyfrowania. Klucz szyfrowania to zestaw trzech 16-bitowych wartości: mnożnik, przyrost i wartości początkowe dla liniowego generatora kongruencji (moduł wynosi 0x8000, aby zachować wartości w 15-bitowym zakresie prawidłowych skal blokowych). Zazwyczaj wszystkie pliki ADX z jednej gry będą używać tego samego klucza.
Metoda szyfrowania jest podatna na ataki ze znanym tekstem jawnym . Jeśli znana jest niezaszyfrowana wersja tego samego dźwięku, można łatwo pobrać strumień liczb losowych i określić na jego podstawie kluczowe parametry, dzięki czemu każdy CRI ADX zaszyfrowany tym samym kluczem będzie możliwy do odszyfrowania. Metoda szyfrowania próbuje to utrudnić, nie szyfrując cichych bloków (ze wszystkimi przykładowymi nybbles równymi 0), ponieważ wiadomo, że ich skala wynosi 0.
Nawet jeśli zaszyfrowany CRI ADX jest jedyną dostępną próbką, możliwe jest określenie klucza zakładając, że wartości skali odszyfrowanego CRI ADX muszą mieścić się w „niskim zakresie”. Jednak ta metoda niekoniecznie pozwala znaleźć klucz użyty do zaszyfrowania pliku. Chociaż zawsze może określić klucze, które dają pozornie poprawne dane wyjściowe, błędy mogą istnieć niewykryte. Wynika to z coraz bardziej losowego rozkładu dolnych bitów wartości skali, co staje się niemożliwe do oddzielenia od losowości dodanej przez szyfrowanie.
dekodowanie AHX
Jak wspomniano wcześniej, AHX jest tylko implementacją dźwięku MPEG2 , a metoda dekodowania jest w zasadzie taka sama jak standardowa, możliwe jest po prostu demultipleksowanie strumienia z kontenera CRI ADX i przepuszczenie go przez standardowy dekoder MPEG Audio, taki jak mpg123 . „Częstotliwość próbkowania” i „całkowita liczba próbek” nagłówka CRI ADX są zwykle poprawne, jeśli dekoder ich potrzebuje (więc powinno to być ustawione przez implementacje enkodera/muxera), ale większość innych pól, takich jak „rozmiar bloku” i „próbka głębi bitowej” zwykle będzie wynosić zero — jak wspomniano powyżej, funkcja zapętlania jest również niedostępna.
- ^ https://imgur.com/rPTv8K2 [ bez adresu URL ]
- ^ „Tytuł nieznany” . Zarchiwizowane od oryginału w dniu 2009-03-18.