// gcc audiosort.c -o audiosort -O3 // this for me so i don't lose later: // gcc audiosort.c -o audiosort -O0 -Wall -Wextra -Werror -Wno-unused-result // requires ffmpeg // ./audiosort #include #include #include #include #define BUFFER_SIZE 4800 #define conststrlen(s) ((sizeof(s))-1) typedef short sample_t; static void* safe_malloc(const size_t bytes) { void* ptr = malloc(bytes); if (ptr == NULL) exit(1); return ptr; } #define put_some_shit(text) do { \ memcpy(ptr, text, conststrlen(text)); \ ptr += conststrlen(text); \ } while (0) #define put_SINGLE_shit(c) do { \ *ptr++ = c; \ } while (0) static FILE* get_input_pipe(const char* filename) { size_t len = conststrlen("ffmpeg -i") + conststrlen(" -f s16le -ar 48000 -ac 2 -") + 1; for (const char* s = filename; *s; s++, len += 1 + (*s == ' ')) {} char* command = safe_malloc(len); char* ptr = command; put_some_shit("ffmpeg -i "); for (const char* c = filename; *c; c++) { if (*c == ' ') put_SINGLE_shit('\\'); put_SINGLE_shit(*c); } put_some_shit(" -f s16le -ar 48000 -ac 2 -"); put_SINGLE_shit('\0'); FILE* pipe = popen(command, "r"); free(command); if (pipe == NULL) exit(1); return pipe; } static FILE* get_output_pipe(const char* filename) { size_t len = conststrlen("ffmpeg -f s16le -ar 48k -ac 2 -i pipe: -y ") + 1; for (const char* s = filename; *s; s++, len += 1 + (*s == ' ')) {} char* command = safe_malloc(len); char* ptr = command; put_some_shit("ffmpeg -f s16le -ar 48k -ac 2 -i pipe: -y "); for (const char* c = filename; *c; c++) { if (*c == ' ') put_SINGLE_shit('\\'); put_SINGLE_shit(*c); } put_SINGLE_shit('\0'); FILE* pipe = popen(command, "w"); free(command); if (pipe == NULL) exit(1); return pipe; } static int get_buffers_count(FILE* file) { int size = 0; int16_t buffer[BUFFER_SIZE]; while (1) { if (fread(buffer, sizeof(sample_t), BUFFER_SIZE, file) == 0) break; size++; } return size; } static int sample_sorter(const void* a, const void* b) { int64_t diff = 0; for (int i = 0; i < BUFFER_SIZE; i++) { diff += abs((*(sample_t**)a)[i]) - abs((*(sample_t**)b)[i]); } return (diff > 0) - (diff < 0); } int main(const int argc, const char* argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } FILE* input = get_input_pipe(argv[1]); const int bufc = get_buffers_count(input); pclose(input); input = get_input_pipe(argv[1]); sample_t** pcm = safe_malloc(sizeof(sample_t*) * bufc); for (int i = 0; i < bufc; i++) { pcm[i] = safe_malloc(sizeof(sample_t) * BUFFER_SIZE); fread(pcm[i], sizeof(sample_t), BUFFER_SIZE, input); } pclose(input); qsort(pcm, bufc, sizeof(sample_t*), sample_sorter); FILE* output = get_output_pipe(argv[2]); for (int i = 0; i < bufc; i++) { fwrite(pcm[i], sizeof(sample_t), BUFFER_SIZE, output); free(pcm[i]); } pclose(output); free(pcm); return 0; }