Difference between revisions of "ADF"
(link at wiki) |
m |
||
(5 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
The [[ADF]] file format is used for the [[List of radio stations (VC)|radio stations]] in [[Vice City]]. It is equal to a raw MP3 file with no ID3 tag (though a tag will likely be ignored) with a very simple encryption: every byte should be XOR-ed against the value 0x22. | The [[ADF]] file format is used for the [[List of radio stations (VC)|radio stations]] in [[Vice City]]. It is equal to a raw MP3 file with no ID3 tag (though a tag will likely be ignored) with a very simple encryption: every byte should be XOR-ed against the value 0x22. | ||
− | == | + | == Example == |
− | + | This is an example of performing a XOR operation on a byte within a file. The first byte in an ADF file is 0xDD. In binary, that would be 0b11011101. Perform a XOR on that against the value 0x22, which is 0b100010 in binary. If the digit in 0xDD corresponds to 0x22's digit "1", then switch the digit to its opposite. If the digit in 0xDD corresponds to 0x22's digit "0", then leave the digit alone. The result would be 0b11111111, which is 0xFF. | |
+ | 0xDD 0b11011101 | ||
+ | 0x22 0b00100010 | ||
+ | 0b11111111 = 0xFF | ||
+ | Another example, performing a XOR on 0x10 against 0x22: | ||
+ | 0x10 0b00010000 | ||
+ | 0x22 0b00100010 | ||
+ | 0b00110010 = 0x32 | ||
+ | |||
+ | When this is done to every byte within the ADF file, the file will result in a file that is listenable in standard audio players. | ||
+ | |||
+ | Below is an example of a simple C++ program: | ||
+ | <source lang="cpp"> | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | |||
+ | int main(int argc, char *argv[]) | ||
+ | { | ||
+ | // check command-line arguments | ||
+ | if (argc != 3) | ||
+ | { | ||
+ | printf("Usage: adftool <inputFile> <outputFile>\n"); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | // open input file | ||
+ | FILE *inputFile = fopen(argv[1], "rb"); | ||
+ | if (!inputFile) | ||
+ | { | ||
+ | printf("Failed to open %s!\n", argv[1]); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | // open output file | ||
+ | FILE *outputFile = fopen(argv[2], "wb"); | ||
+ | if (!outputFile) | ||
+ | { | ||
+ | printf("Failed to open %s!\n", argv[2]); | ||
+ | fclose(inputFile); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | // allocate buffer (16 MB) | ||
+ | const size_t bufferSize = 1024 * 1024 * 16; | ||
+ | char *buffer = (char *)malloc(bufferSize); | ||
+ | if (!buffer) | ||
+ | { | ||
+ | printf("Failed to allocate buffer!\n"); | ||
+ | fclose(inputFile); | ||
+ | fclose(outputFile); | ||
+ | return 1; | ||
+ | } | ||
+ | |||
+ | // read input file into buffer block by block | ||
+ | size_t size; | ||
+ | while ((size = fread(buffer, 1, bufferSize, inputFile)) > 0) | ||
+ | { | ||
+ | // xor buffer against 0x22 | ||
+ | char *iterator = buffer; | ||
+ | for (size_t i = 0; i < size; i++) | ||
+ | { | ||
+ | *iterator++ ^= 0x22; | ||
+ | } | ||
+ | |||
+ | // write buffer to output file | ||
+ | fwrite(buffer, 1, size, outputFile); | ||
+ | } | ||
+ | |||
+ | // deallocate buffer and close files | ||
+ | free(buffer); | ||
+ | fclose(inputFile); | ||
+ | fclose(outputFile); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == External links == | ||
+ | * [[Wikipedia:MP3|MP3 format description at Wikipedia]] | ||
+ | * [[Wikipedia:Bitwise_operation#XOR|Bitwise exclusive OR at Wikipedia]] | ||
+ | * {{GTAF|96504|Early topic on decoding ADF}} | ||
+ | |||
+ | {{N|VC}} | ||
[[Category:Audio Formats]] | [[Category:Audio Formats]] |
Latest revision as of 15:45, 2 April 2015
The ADF file format is used for the radio stations in Vice City. It is equal to a raw MP3 file with no ID3 tag (though a tag will likely be ignored) with a very simple encryption: every byte should be XOR-ed against the value 0x22.
Example
This is an example of performing a XOR operation on a byte within a file. The first byte in an ADF file is 0xDD. In binary, that would be 0b11011101. Perform a XOR on that against the value 0x22, which is 0b100010 in binary. If the digit in 0xDD corresponds to 0x22's digit "1", then switch the digit to its opposite. If the digit in 0xDD corresponds to 0x22's digit "0", then leave the digit alone. The result would be 0b11111111, which is 0xFF.
0xDD 0b11011101 0x22 0b00100010 0b11111111 = 0xFF
Another example, performing a XOR on 0x10 against 0x22:
0x10 0b00010000 0x22 0b00100010 0b00110010 = 0x32
When this is done to every byte within the ADF file, the file will result in a file that is listenable in standard audio players.
Below is an example of a simple C++ program:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
// check command-line arguments
if (argc != 3)
{
printf("Usage: adftool <inputFile> <outputFile>\n");
return 1;
}
// open input file
FILE *inputFile = fopen(argv[1], "rb");
if (!inputFile)
{
printf("Failed to open %s!\n", argv[1]);
return 1;
}
// open output file
FILE *outputFile = fopen(argv[2], "wb");
if (!outputFile)
{
printf("Failed to open %s!\n", argv[2]);
fclose(inputFile);
return 1;
}
// allocate buffer (16 MB)
const size_t bufferSize = 1024 * 1024 * 16;
char *buffer = (char *)malloc(bufferSize);
if (!buffer)
{
printf("Failed to allocate buffer!\n");
fclose(inputFile);
fclose(outputFile);
return 1;
}
// read input file into buffer block by block
size_t size;
while ((size = fread(buffer, 1, bufferSize, inputFile)) > 0)
{
// xor buffer against 0x22
char *iterator = buffer;
for (size_t i = 0; i < size; i++)
{
*iterator++ ^= 0x22;
}
// write buffer to output file
fwrite(buffer, 1, size, outputFile);
}
// deallocate buffer and close files
free(buffer);
fclose(inputFile);
fclose(outputFile);
return 0;
}
External links
- MP3 format description at Wikipedia
- Bitwise exclusive OR at Wikipedia
- GTAForums: Early topic on decoding ADF