#include #include #include #include #include /* so it's easier to fwrite */ typedef struct { char cuehead[4]; int chunk_size; int numcues; int cueid; int cuepos; char datahead[4]; int chunk_start; int block_start; int sample_offset; } loop_t; /* -o enables users to specify at which point in the sample to start */ static int sample_offset; void process_wav2loop(char *filename) { FILE *fWAV; FILE *fLOOP; size_t szWAV; char *buffer; loop_t loopy; fWAV = fopen(filename, "rb"); if (!fWAV) { fprintf(stderr, "couldn't find %s\n", filename); return; } /* get wav file size */ fseek(fWAV, 0L, SEEK_END); szWAV = (size_t)ftell(fWAV); fseek(fWAV, 0L, SEEK_SET); /* load wav into memory */ buffer = (char *)malloc(szWAV); if (buffer == NULL) { fprintf(stderr, "error: Memory allocation failed. Exiting.\n"); exit(0); } fread(buffer, 1, szWAV, fWAV); fclose(fWAV); /* this is LAZY, however we're not going to bother writing a full WAV loader LMAO */ for (int i = 0; i < (szWAV - 4); i++ ) { if (buffer[i] == 'c') if (buffer[i+1] == 'u') if (buffer[i+2] == 'e') if (buffer[i+3] == ' ') { fprintf(stderr, "wav file %s has cue info already\n", filename); goto end; } } /* this is quite stupid, we're just appending it at the end, we don't even care if there already are other cue marks */ fLOOP = fopen(filename, "w+b"); fwrite(buffer, 1, szWAV, fLOOP); loopy.cuehead[0] = 'c'; loopy.cuehead[1] = 'u'; loopy.cuehead[2] = 'e'; loopy.cuehead[3] = ' '; loopy.chunk_size = 28; loopy.numcues = 1; loopy.cueid = 0; loopy.cuepos = 0; loopy.datahead[0] = 'd'; loopy.datahead[1] = 'a'; loopy.datahead[2] = 't'; loopy.datahead[3] = 'a'; loopy.chunk_start = 0; loopy.block_start = 0; loopy.sample_offset = sample_offset; /* append our data to the end of the file */ fwrite(&loopy, 1, sizeof(loop_t), fLOOP); fclose(fLOOP); /* inb4 goto considered harmful */ end: free(buffer); } int main(int argc, char *argv[]) { int c, ch; if (argc <= 1) { fprintf(stderr, "usage: wav2loop [-o offset] file.wav ...\n"); return 1; } /* by default, we loop at the very start */ sample_offset = 0; /* process arguments: TODO: add more? probably not */ while ((ch = getopt(argc, argv, "o")) != -1) { switch (ch) { case 'o': sample_offset = atoi(argv[optind]); optind++; printf("sample offset: %i\n", sample_offset); break; default: return 1; } } argc -= optind; argv += optind; for (c = 0; c < argc; c++) process_wav2loop(argv[c]); return 0; }