오디오 스트림(GTA)
산 안드레아스는 GTA III나 GTA 바이스 시티와는 완전히 다른 방식으로 음악을 처리합니다. 라디오 방송국을 위한 단순한 긴 루프 방식 대신, 산 안드레아스의 방송국은 동적이며 게임 상태에 따라 변경됩니다. 그 결과로 산 안드레아스에서는 스트림 형식이 도입되었습니다. 이 문서는 스트림 형식에 대해 알려진 내용을 자세히 설명합니다.
인코딩
디스크상의 스트림은 인코딩되어 있어 직접 읽거나 쓸 수 없습니다. 다행히 인코딩 알고리즘은 매우 간단합니다. 본질적으로 스트림 데이터를 특정 키 값으로 XOR 연산하는 것입니다. 키는 16바이트 길이입니다. 스트림의 연속적인 바이트들이 키의 연속적인 바이트들과 XOR 연산되며, 키의 끝에 도달하면 다시 처음으로 돌아갑니다. 인코딩에 접근하는 방법은 여러 가지가 있으며, 이 문서에서는 바이트 단위 인코딩을 다룹니다. 프로그램은 키를 적절히 조정하여 2, 4, 8 또는 16바이트 단위로 스트림을 인코딩할 수도 있습니다(스트림은 리틀 엔디언 방식입니다).
16바이트 인코딩 키(16진수 표기):
EA 3A C4 A1 9A A8 14 F3 48 B0 D7 23 9D E8 FF F1
인코딩 알고리즘은 다음과 같습니다:
- 스트림의 첫 번째 바이트와 키의 첫 번째 바이트(EA)를 XOR
- 스트림의 두 번째 바이트와 키의 두 번째 바이트(3A)를 XOR
... (계속) ...
- 스트림의 16번째 바이트와 키의 16번째 바이트(F1)를 XOR
- 스트림의 17번째 바이트와 키의 첫 번째 바이트(EA)를 XOR
인코딩을 수행하는 간단한 C++ 알고리즘입니다(San Andreas Audio Toolkit 소스 코드에서 발췌):
void stream_encode(int8_t *buff, const size_t size, int &index) {
for (size_t i = 0; i < size; ++i) {
buff[i] ^= encode_key[index];
index = (index + 1) % 16;
}
return;
}
이것은 양방향 인코딩 방식이므로 데이터 청크를 인코딩 알고리즘에 두 번 실행하면 원래 데이터가 됩니다. 따라서 같은 알고리즘을 인코딩과 디코딩 모두에 사용할 수 있습니다.
트랙
디코딩된 스트림은 단순히 트랙들의 연속적인 목록입니다. 트랙은 메타데이터가 담긴 헤더와 그 뒤를 잇는 Ogg Vorbis 형식의 실제 오디오로 구성됩니다.
트랙 헤더
트랙 헤더는 8068바이트 길이입니다. 이는 크게 3개의 주요 섹션으로 나뉩니다: 8000바이트의 비트 정보, 사운드 파일의 길이 및 기타 정보를 담은 64바이트, 그리고 의미를 알 수 없는 4개의 상수 바이트입니다.
트랙 헤더:
8000 바이트 - 비트 항목(Beat Entry) x 1000 - 아래 세부 정보 참조
64 바이트 - 길이 항목(Length Entry) x 8 - 아래 세부 정보 참조
4 바이트 - CHAR[4] - 항상 "01 00 CD CD" (16진수)
비트 섹션은 댄스 미니게임과 로우라이더 챌린지 미니게임에 사용됩니다. 이 게임들에서 플레이어는 지정된 시간에 지정된 조작을 입력하여 노래의 리듬에 맞춰야 합니다. 이 비트 정보는 트랙 헤더에 명시되어 있습니다.
비트 항목(Beat Entry): 4 바이트 - DWORD - 타이밍 값 4 바이트 - DWORD - 조작 값
타이밍 값은 비트가 트리거되는 노래의 지점(밀리초 단위)을 나타내는 정수입니다. 트랙에 비트 정보가 필요하지 않은 경우 기본값은 -1(0xFFFFFF)입니다. 조작 값은 눌러야 할 버튼이나 키 등을 나타내는 정수입니다. 이 값들은 아래에 정의되어 있습니다. 트랙에 비트 정보가 필요하지 않은 경우 기본값은 0입니다.
| 값 (16진수) | 입력 조작 | ||
|---|---|---|---|
| Xbox | PS2 | PC 기본값 | |
| 0x01 | A | X | 아래 화살표 |
| 0x02 | X | 네모 | 왼쪽 화살표 |
| 0x03 | Y | 세모 | 위 화살표 |
| 0x04 | B | 동그라미 | 오른쪽 화살표 |
| 0x21 | 비트 종료 토큰 | ||
| 값 (16진수) | 입력 조작 | |
|---|---|---|
| Xbox 또는 PS2 | PC 기본값 | |
| 0x09 | 우측 아날로그 스틱: 오른쪽 | 숫자패드 6 |
| 0x0a | 우측 아날로그 스틱: 왼쪽 | 숫자패드 4 |
| 0x0b | 우측 아날로그 스틱: 위 & 오른쪽 | 숫자패드 8 & 숫자패드 6 |
| 0x0c | 우측 아날로그 스틱: 아래 & 왼쪽 | 숫자패드 2 & 숫자패드 4 |
| 0x0d | 우측 아날로그 스틱: 위 | 숫자패드 8 |
| 0x0e | 우측 아날로그 스틱: 아래 | 숫자패드 2 |
| 0x0f | 우측 아날로그 스틱: 위 & 왼쪽 | 숫자패드 8 & 숫자패드 4 |
| 0x10 | 우측 아날로그 스틱: 아래 & 오른쪽 | 숫자패드 2 & 숫자패드 6 |
| 0x21 | 비트 종료 토큰 | |
두 번째 헤더 섹션은 다소 특이합니다. 이는 8개의 DWORD '길이 항목(Length Entry)' 쌍으로 구성되어 있는데, 하나를 제외한 모든 쌍은 사용되지 않는 패딩 값을 담고 있습니다. 또한, 8개 중 어떤 쌍이 패딩이 아닌지는 상황에 따라 다릅니다.
길이 항목(Length Entry): 4 바이트 - DWORD - Ogg Vorbis 파일의 길이 또는 0xCDCDCDCD 패딩 4 바이트 - DWORD - 변수, 사용되지 않거나 0xCDCDCDCD 패딩
특정 항목이 패딩인 경우, 두 DWORD 모두 0xCDCDCDCD입니다. 패딩이 아닌 하나의 길이 항목 쌍에서 첫 번째 DWORD는 뒤따르는 Ogg Vorbis 파일의 길이이며, 두 번째 DWORD는 샘플 레이트용으로 의도되었으나 현재는 사용되지 않는 변수 값입니다. 수정되지 않은 오디오 스트림에서 이 값은 일반적으로 AMBIENCE(앰비언스) 트랙의 경우 24000, CUTSCENE(컷신) 트랙의 경우 0, 그 외 트랙은 48000입니다. 이 지침에는 몇 가지 예외가 있습니다.
수정되지 않은 게임에서 8개의 길이 항목 중 첫 번째 항목에 유용한 길이 정보가 포함되어 있는 것이 일반적입니다. 하지만 비트 정보가 포함된 6개의 트랙에서는 길이 정보가 두 번째 길이 항목 쌍에 저장됩니다.
위에서 언급했듯이 트랙 헤더의 마지막 4바이트는 항상 "01 00 CD CD"(16진수)입니다.
Ogg Vorbis 사운드
트랙 헤더 뒤에는 실제 사운드(Ogg Vorbis 형식)가 스트림에 직접 저장됩니다. 사운드의 길이는 가변적이지만 헤더에 저장된 값을 통해 알 수 있습니다. 수정되지 않은 게임 스트림의 Ogg Vorbis 사운드에는 코멘트 태그가 포함되어 있지 않지만, 사운드 내에 그러한 태그가 존재한다고 해서 문제가 발생하지는 않습니다.
스크립팅
외부 링크
- GTA:SA SFX 디렉토리
- 온라인 SFX 브라우저 – 사용자가 생성. 산 안드레아스의 사운드와 대사를 찾아보고 들을 수 있습니다.