#include #include #include void fail(char *error) { fprintf(stderr, "%s\n", error); exit(1); } int main(int argc, char **argv) { FILE *f; unsigned char buffer[1024]; long int sample_size[31]; int num_samples; int num_channels; int num_patterns; int total_sample = 0; long int expected_size; int i, n; if (argc < 2) { fprintf(stderr, "usage: conv4-8 \n"); exit(1); } f = fopen(argv[1], "rb"); if (!f) fail("can't open file"); fprintf(stderr, "converting module...\n"); fseek(f, 1080, SEEK_SET); if (fread(buffer, 1, 4, f) < 4) fail("seek failed"); buffer[4] = '\0'; if(!strcmp(buffer, "M.K.") || !strcmp(buffer, "M!K!")) { num_samples = 31; } else { num_samples = 15; } num_channels = 4; fprintf(stderr, "number of samples : %i\n", num_samples); fprintf(stderr, "number of channels : %i\n", num_channels); fseek(f, 0, SEEK_SET); if (fread(buffer, 1, 20, f) < 20) fail("seek failed : song name"); fwrite(buffer, 1, 20, stdout); for (i = 0; i < num_samples; i++) { if (fread(buffer, 1, 30, f) < 30) fail("read error : sample info"); sample_size[i] = (buffer[22] << 8) | buffer[23]; total_sample += sample_size[i]; fwrite(buffer, 1, 30, stdout); } fprintf(stderr, "total sample size : %i (%i)\n", total_sample, total_sample*2); i = 130 + ((num_channels > 15) ? 4 : 0); if (fread(buffer, 1, i, f) < i) fail("read error : song info"); fwrite(buffer, 1, i, stdout); num_patterns = buffer[2]; for (i = 3; i < 130; i++) { if (buffer[i] > num_patterns) { num_patterns = buffer[i]; } } num_patterns++; fprintf(stderr, "number of patterns : %i\n", num_patterns); expected_size = 20 + (30*num_samples) + 130 + (num_samples>15?4:0) + (num_patterns*64*4*num_channels) + total_sample; fprintf(stderr, "expected size (4-bit) : %li\n", expected_size); expected_size = 20 + (30*num_samples) + 130 + (num_samples>15?4:0) + (num_patterns*64*4*num_channels) + total_sample*2; fprintf(stderr, "expected size (8-bit) : %li\n", expected_size); for (i = 0; i < num_patterns; i++) { int j = 64 * 4 * num_channels; while (j > 0) { int k = j > 1024 ? 1024 : j; if (fread(buffer, 1, k, f) < k) fail("read error : pattern data"); fwrite(buffer, 1, k, stdout); j -= k; } } /* first half of the sample data */ n = ftell(f); while(!feof(f)) { int j = fread(buffer, 1, 1024, f); for(i = 0; i < j; i++) buffer[i] = buffer[i] & 0xf0; fwrite(buffer, 1, j, stdout); } /* second half */ fseek(f, n, SEEK_SET); while(!feof(f)) { int j = fread(buffer, 1, 1024, f); for(i = 0; i < j; i++) buffer[i] = (buffer[i] & 0x0f) << 4; fwrite(buffer, 1, j, stdout); } fprintf(stderr, "actual size (input) : %li\n", ftell(f)); fprintf(stderr, "actual size (output) : %li\n", ftell(stdout)); fprintf(stderr, "done\n"); fclose(f); return 0; }