binary_mp3_strip/AI_gen_Approach.c

75 lines
2.2 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
// Simplified frame length calculation (MPEG1 Layer3 only)
uint32_t calc_frame_len(uint32_t header) {
const int bitrates[] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320};
const int samplerates[] = {44100, 48000, 32000};
int br_idx = (header >> 12) & 0xF;
int sr_idx = (header >> 10) & 0x3;
int padding = (header >> 9) & 0x1;
int bitrate = bitrates[br_idx] * 1000;
int samplerate = samplerates[sr_idx];
return 144 * bitrate / samplerate + padding;
}
int main(int argc, char** argv) {
if(argc != 2) return fprintf(stderr, "Usage: %s <input_file>\n", argv[0]), 1;
FILE* fin = fopen(argv[1], "rb");
if(!fin) return perror("fopen"), 1;
FILE* fout = NULL;
long file_count = 0;
uint32_t pos = 0;
uint32_t header;
uint8_t buf[4];
while(fread(buf, 1, 4, fin) == 4) {
header = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
// Check for valid MP3 header: 0xFF 0xE? (sync + version)
if(buf[0] == 0xFF && (buf[1] & 0xE0) == 0xE0) {
uint32_t frame_len = calc_frame_len(header >> 8);
if(frame_len > 0 && frame_len < (10*1024*1024)) { // Sanity check
if(!fout) {
char fname[128];
snprintf(fname, sizeof(fname), "output_%ld.mp3", file_count++);
fout = fopen(fname, "wb");
if(!fout) { perror("fopen output"); break; }
printf("Extracting %s\n", fname);
}
// Save header
fwrite(buf, 1, 4, fout);
// Save frame data
for(uint32_t i = 4; i < frame_len; i++) {
int c = fgetc(fin);
if(c == EOF) break;
fputc(c, fout);
}
pos = ftell(fin);
continue;
}
}
if(fout) {
fclose(fout);
fout = NULL;
}
// Rewind 3 bytes to allow overlapping frames
fseek(fin, ++pos, SEEK_SET);
}
if(fout) fclose(fout);
fclose(fin);
return 0;
}