mirror of
				https://github.com/coop-deluxe/sm64coopdx.git
				synced 2025-10-30 08:01:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			190 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
	
		
			5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * Create an ADPCM codebook either by extracting it from an AIFF section, or
 | |
|  * by executing tabledesign.
 | |
|  */
 | |
| #define _XOPEN_SOURCE 500
 | |
| #include <unistd.h>
 | |
| #include <math.h>
 | |
| #include <string.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <stdarg.h>
 | |
| 
 | |
| typedef short s16;
 | |
| typedef int s32;
 | |
| typedef unsigned char u8;
 | |
| typedef unsigned int u32;
 | |
| 
 | |
| #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
 | |
| # define BSWAP16(x)
 | |
| # define BSWAP32(x)
 | |
| #else
 | |
| # define BSWAP16(x) x = __builtin_bswap16(x)
 | |
| # define BSWAP32(x) x = __builtin_bswap32(x)
 | |
| #endif
 | |
| 
 | |
| #define NORETURN __attribute__((noreturn))
 | |
| #define UNUSED __attribute__((unused))
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|     u32 start;
 | |
|     u32 end;
 | |
|     u32 count;
 | |
|     s16 state[16];
 | |
| } ALADPCMloop;
 | |
| 
 | |
| static const char usage[] = "input.aiff";
 | |
| static const char *progname, *infilename;
 | |
| 
 | |
| #define checked_fread(a, b, c, d) if (fread(a, b, c, d) != c) fail_parse("error parsing file")
 | |
| 
 | |
| NORETURN
 | |
| void fail_parse(const char *fmt, ...)
 | |
| {
 | |
|     char *formatted = NULL;
 | |
|     va_list ap;
 | |
|     va_start(ap, fmt);
 | |
|     int size = vsnprintf(NULL, 0, fmt, ap);
 | |
|     va_end(ap);
 | |
|     if (size >= 0) {
 | |
|         size++;
 | |
|         formatted = malloc(size);
 | |
|         if (formatted != NULL) {
 | |
|             va_start(ap, fmt);
 | |
|             size = vsnprintf(formatted, size, fmt, ap);
 | |
|             va_end(ap);
 | |
|             if (size < 0) {
 | |
|                 free(formatted);
 | |
|                 formatted = NULL;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (formatted != NULL) {
 | |
|         fprintf(stderr, "%s: %s [%s]\n", progname, formatted, infilename);
 | |
|         free(formatted);
 | |
|     }
 | |
|     exit(1);
 | |
| }
 | |
| 
 | |
| s32 readaifccodebook(FILE *fhandle, s32 ****table, s16 *order, s16 *npredictors)
 | |
| {
 | |
|     checked_fread(order, sizeof(s16), 1, fhandle);
 | |
|     BSWAP16(*order);
 | |
|     checked_fread(npredictors, sizeof(s16), 1, fhandle);
 | |
|     BSWAP16(*npredictors);
 | |
|     *table = malloc(*npredictors * sizeof(s32 **));
 | |
|     for (s32 i = 0; i < *npredictors; i++) {
 | |
|         (*table)[i] = malloc(8 * sizeof(s32 *));
 | |
|         for (s32 j = 0; j < 8; j++) {
 | |
|             (*table)[i][j] = malloc((*order + 8) * sizeof(s32));
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     for (s32 i = 0; i < *npredictors; i++) {
 | |
|         s32 **table_entry = (*table)[i];
 | |
|         for (s32 j = 0; j < *order; j++) {
 | |
|             for (s32 k = 0; k < 8; k++) {
 | |
|                 s16 ts;
 | |
|                 checked_fread(&ts, sizeof(s16), 1, fhandle);
 | |
|                 BSWAP16(ts);
 | |
|                 table_entry[k][j] = ts;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         for (s32 k = 1; k < 8; k++) {
 | |
|             table_entry[k][*order] = table_entry[k - 1][*order - 1];
 | |
|         }
 | |
| 
 | |
|         table_entry[0][*order] = 1 << 11;
 | |
| 
 | |
|         for (s32 k = 1; k < 8; k++) {
 | |
|             s32 j = 0;
 | |
|             for (; j < k; j++) {
 | |
|                 table_entry[j][k + *order] = 0;
 | |
|             }
 | |
| 
 | |
|             for (; j < 8; j++) {
 | |
|                 table_entry[j][k + *order] = table_entry[j - k][*order];
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
|     s16 order = -1;
 | |
|     s16 npredictors = -1;
 | |
|     s32 ***coefTable = NULL;
 | |
|     FILE *ifile;
 | |
|     progname = argv[0];
 | |
| 
 | |
|     if (argc < 2) {
 | |
|         fprintf(stderr, "%s %s\n", progname, usage);
 | |
|         exit(1);
 | |
|     }
 | |
| 
 | |
|     infilename = argv[1];
 | |
| 
 | |
|     if ((ifile = fopen(infilename, "rb")) == NULL) {
 | |
|         fail_parse("AIFF file could not be opened");
 | |
|         exit(1);
 | |
|     }
 | |
| 
 | |
|     char buf[5] = {0};
 | |
|     checked_fread(buf, 4, 1, ifile);
 | |
|     if (strcmp(buf, "FORM") != 0) fail_parse("not an AIFF file");
 | |
|     checked_fread(buf, 4, 1, ifile);
 | |
|     checked_fread(buf, 4, 1, ifile);
 | |
|     if (strcmp(buf, "AIFF") != 0 && strcmp(buf, "AIFC") != 0) {
 | |
|         fail_parse("not an AIFF file");
 | |
|     }
 | |
| 
 | |
|     for (;;) {
 | |
|         s32 size;
 | |
|         if (!fread(buf, 4, 1, ifile) || !fread(&size, 4, 1, ifile)) break;
 | |
|         BSWAP32(size);
 | |
|         s32 nextOffset = ftell(ifile) + ((size + 1) & ~1);
 | |
| 
 | |
|         if (strcmp(buf, "APPL") == 0) {
 | |
|             checked_fread(buf, 4, 1, ifile);
 | |
|             if (strcmp(buf, "stoc") == 0) {
 | |
|                 u8 len;
 | |
|                 checked_fread(&len, 1, 1, ifile);
 | |
|                 if (len == 11) {
 | |
|                     char chunkName[12];
 | |
|                     s16 version;
 | |
|                     checked_fread(chunkName, 11, 1, ifile);
 | |
|                     chunkName[11] = '\0';
 | |
|                     if (strcmp(chunkName, "VADPCMCODES") == 0) {
 | |
|                         checked_fread(&version, sizeof(s16), 1, ifile);
 | |
|                         BSWAP16(version);
 | |
|                         if (version == 1) {
 | |
|                             readaifccodebook(ifile, &coefTable, &order, &npredictors);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         fseek(ifile, nextOffset, SEEK_SET);
 | |
|     }
 | |
|     fclose(ifile);
 | |
| 
 | |
|     if (coefTable == NULL) {
 | |
|         execl("./tools/tabledesign", "tabledesign", "-s", "1", infilename, NULL);
 | |
|     } else {
 | |
|         printf("%d\n%d\n", order, npredictors);
 | |
|         for (s32 i = 0; i < npredictors; i++) {
 | |
|             for (s32 j = 0; j < order; j++) {
 | |
|                 for (s32 k = 0; k < 8; k++) {
 | |
|                     printf("% 5d ", coefTable[i][k][j]);
 | |
|                 }
 | |
|                 puts("");
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 | 
