#include #include #include typedef struct wav_header wav_header; struct wav_header { uint8_t id[4]; uint8_t size[4]; char wave[4]; char fmt[4]; uint8_t fmt_data_len[4]; uint8_t type[2]; uint8_t channels[2]; uint8_t sample_rate[4]; uint8_t total_rate[4]; uint8_t audio_type[2]; uint8_t bbs[2]; char data_str[4]; uint8_t data_size[4]; }; int32_t little_endian(uint8_t bytes[4]) { int32_t le = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); return le; } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "extractor [usage]: input_file"); return EXIT_FAILURE; } wav_header header; char search; int count = 0; char out_name[128] = {0}; char *in = argv[1]; FILE *fin = fopen(in, "r"); fseek(fin, 0, SEEK_SET); while (fread(&search, sizeof(char), 1, fin) > 0) { if (search != 'R') continue; if (fread(&search, sizeof(char), 1, fin) <= 0) continue; if (search != 'I') continue; if (fread(&search, sizeof(char), 1, fin) <= 0) continue; if (search != 'F') continue; if (fread(&search, sizeof(char), 1, fin) <= 0) continue; if (search != 'F') continue; fpos_t pos; fseek(fin, -4 * sizeof(char), SEEK_CUR); fgetpos(fin, &pos); fread(&header, sizeof(wav_header), 1, fin); fseek(fin, pos, SEEK_SET); int32_t size = little_endian(header.data_size); char *data = (char *)malloc((size + 1) * sizeof(char)); fread(data, sizeof(char), size, fin); data[size + 1] = 0; snprintf(out_name, sizeof out_name, "%s_%d.wav", in, ++count); FILE *fout = fopen(out_name, "w"); fwrite(data, sizeof(char), size, fout); fclose(fout); free(data); } fclose(fin); return EXIT_SUCCESS; }