aiff_extract_codebook.c (5011B)
1 /** 2 * Create an ADPCM codebook either by extracting it from an AIFF section, or 3 * by executing tabledesign. 4 */ 5 #include <unistd.h> 6 #include <math.h> 7 #include <string.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <stdarg.h> 11 12 typedef short s16; 13 typedef int s32; 14 typedef unsigned char u8; 15 typedef unsigned int u32; 16 17 #define BSWAP16(x) x = __builtin_bswap16(x) 18 #define BSWAP32(x) x = __builtin_bswap32(x) 19 20 #define NORETURN __attribute__((noreturn)) 21 #define UNUSED __attribute__((unused)) 22 23 typedef struct 24 { 25 u32 start; 26 u32 end; 27 u32 count; 28 s16 state[16]; 29 } ALADPCMloop; 30 31 static const char usage[] = "input.aiff"; 32 static const char *progname, *infilename; 33 34 #define checked_fread(a, b, c, d) if (fread(a, b, c, d) != c) fail_parse("error parsing file") 35 36 NORETURN 37 void fail_parse(const char *fmt, ...) 38 { 39 char *formatted = NULL; 40 va_list ap; 41 va_start(ap, fmt); 42 int size = vsnprintf(NULL, 0, fmt, ap); 43 va_end(ap); 44 if (size >= 0) { 45 size++; 46 formatted = malloc(size); 47 if (formatted != NULL) { 48 va_start(ap, fmt); 49 size = vsnprintf(formatted, size, fmt, ap); 50 va_end(ap); 51 if (size < 0) { 52 free(formatted); 53 formatted = NULL; 54 } 55 } 56 } 57 58 if (formatted != NULL) { 59 fprintf(stderr, "%s: %s [%s]\n", progname, formatted, infilename); 60 free(formatted); 61 } 62 exit(1); 63 } 64 65 s32 readaifccodebook(FILE *fhandle, s32 ****table, s16 *order, s16 *npredictors) 66 { 67 checked_fread(order, sizeof(s16), 1, fhandle); 68 BSWAP16(*order); 69 checked_fread(npredictors, sizeof(s16), 1, fhandle); 70 BSWAP16(*npredictors); 71 *table = malloc(*npredictors * sizeof(s32 **)); 72 for (s32 i = 0; i < *npredictors; i++) { 73 (*table)[i] = malloc(8 * sizeof(s32 *)); 74 for (s32 j = 0; j < 8; j++) { 75 (*table)[i][j] = malloc((*order + 8) * sizeof(s32)); 76 } 77 } 78 79 for (s32 i = 0; i < *npredictors; i++) { 80 s32 **table_entry = (*table)[i]; 81 for (s32 j = 0; j < *order; j++) { 82 for (s32 k = 0; k < 8; k++) { 83 s16 ts; 84 checked_fread(&ts, sizeof(s16), 1, fhandle); 85 BSWAP16(ts); 86 table_entry[k][j] = ts; 87 } 88 } 89 90 for (s32 k = 1; k < 8; k++) { 91 table_entry[k][*order] = table_entry[k - 1][*order - 1]; 92 } 93 94 table_entry[0][*order] = 1 << 11; 95 96 for (s32 k = 1; k < 8; k++) { 97 s32 j = 0; 98 for (; j < k; j++) { 99 table_entry[j][k + *order] = 0; 100 } 101 102 for (; j < 8; j++) { 103 table_entry[j][k + *order] = table_entry[j - k][*order]; 104 } 105 } 106 } 107 return 0; 108 } 109 110 int main(int argc, char **argv) 111 { 112 s16 order = -1; 113 s16 npredictors = -1; 114 s32 ***coefTable = NULL; 115 FILE *ifile; 116 progname = argv[0]; 117 118 if (argc < 2) { 119 fprintf(stderr, "%s %s\n", progname, usage); 120 exit(1); 121 } 122 123 infilename = argv[1]; 124 125 if ((ifile = fopen(infilename, "rb")) == NULL) { 126 fail_parse("AIFF file could not be opened"); 127 exit(1); 128 } 129 130 char buf[5] = {0}; 131 checked_fread(buf, 4, 1, ifile); 132 if (strcmp(buf, "FORM") != 0) fail_parse("not an AIFF file"); 133 checked_fread(buf, 4, 1, ifile); 134 checked_fread(buf, 4, 1, ifile); 135 if (strcmp(buf, "AIFF") != 0 && strcmp(buf, "AIFC") != 0) { 136 fail_parse("not an AIFF file"); 137 } 138 139 for (;;) { 140 s32 size; 141 if (!fread(buf, 4, 1, ifile) || !fread(&size, 4, 1, ifile)) break; 142 BSWAP32(size); 143 s32 nextOffset = ftell(ifile) + ((size + 1) & ~1); 144 145 if (strcmp(buf, "APPL") == 0) { 146 checked_fread(buf, 4, 1, ifile); 147 if (strcmp(buf, "stoc") == 0) { 148 u8 len; 149 checked_fread(&len, 1, 1, ifile); 150 if (len == 11) { 151 char chunkName[12]; 152 s16 version; 153 checked_fread(chunkName, 11, 1, ifile); 154 chunkName[11] = '\0'; 155 if (strcmp(chunkName, "VADPCMCODES") == 0) { 156 checked_fread(&version, sizeof(s16), 1, ifile); 157 BSWAP16(version); 158 if (version == 1) { 159 readaifccodebook(ifile, &coefTable, &order, &npredictors); 160 } 161 } 162 } 163 } 164 } 165 166 fseek(ifile, nextOffset, SEEK_SET); 167 } 168 fclose(ifile); 169 170 if (coefTable == NULL) { 171 execl("./tools/tabledesign", "tabledesign", "-s", "1", infilename, NULL); 172 } else { 173 printf("%d\n%d\n", order, npredictors); 174 for (s32 i = 0; i < npredictors; i++) { 175 for (s32 j = 0; j < order; j++) { 176 for (s32 k = 0; k < 8; k++) { 177 printf("% 5d ", coefTable[i][k][j]); 178 } 179 puts(""); 180 } 181 } 182 } 183 return 0; 184 }