View Full Version : kotorwav2mp3

01-08-2010, 01:33 PM
kotorwav2mp3 v1.1 (12.74 kB) (http://tonttu.cu.cc/download.php?view.2)
v1.1 is a complete rewrite of the first version.
This package still includes old versions of analyze.exe and bincut.exe as I didn't have the time to rewrite them.
Includes source code for kotorwav2mp3.

Scans file for MP3 sync byte and copies everything after the first sync byte to new file
Usage: kotorwav2mp3 input [input2] [input3] [...]
To convert all WAV files in a folder you can use kotorwav2mp3 *.wav

File still doesn't work after using kotorwav2mp3?
Perhaps it is WAV file with fake MP3 header
With the help of these 2 tools you can cut at chosen offset

Analyzes the first 2048 bytes of file and reports all MP3 sync byte and WAVE header offsets
Usage: analyze input [input2] [input3] [...]

Cuts binary file at chosen offset. Use with analyze to cut at WAVE header or MP3 sync byte
Usage: bincut input offset output

C:\kotorwav2mp3>analyze al_en_starforge.wav
Analyzing the first 2048 bytes of al_en_starforge.wav
Possible MP3 sync byte found at 0x0
Possible MP3 sync byte found at 0x9C
Possible MP3 sync byte found at 0x139
Possible WAVE header found at 0x1D6

C:\kotorwav2mp3>bincut al_en_starforge.wav 0x1d6 new_file.wav

if you already downloaded the first version then this doesn't offer any new features for you (unless you want the source code)

Source code

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int mp3_sync_byte(unsigned char *, int);

int main (int argc, char *argv[]) {
FILE *inFile, *outFile;
char *inName, *outName, *ext;
size_t size, result;
int c, i, j, sync_byte = -1;
unsigned char *buffer;

printf("kotorwav2mp3 v1.1 written by Tonttu\n\n");
if (argc < 2) {
printf("Usage: kotorwav2mp3 input [input2] [input3] [...]\n");
return 0;
//Loop through the input files
for (i=1; i<argc; i++) {
//Read input file
inName = argv[i];
inFile = fopen(inName, "rb");
if (inFile == NULL) {
printf("%s: File doesn't exist\n", inName);
fseek(inFile, 0, SEEK_END);
size = ftell(inFile);
buffer = malloc(sizeof(unsigned char) * size); //Allocate memory
result = fread(buffer, 1, size, inFile);
if (result != size) {
printf("%s: Reading error\n", inName);

//Get the first MP3 sync byte in input file
sync_byte = mp3_sync_byte(buffer, size);
if (sync_byte < 0) {
printf("%s:\n\tNo MP3 sync byte found\n\tSkipping file\n", inName);

//Output filename
outName = malloc(sizeof(inName) + 4*sizeof(char*));
strcpy(outName, inName);
ext = strstr(outName, ".wav");
if (ext != NULL) {
strcpy(ext, ".mp3"); //replace .wav with .mp3
} else {
strcat(outName, ".mp3"); //append .mp3
printf("%s:\n\tMP3 sync byte found at 0x%X\n\tWriting output %s\n", inName, sync_byte, outName);

//Write output
outFile = fopen(outName, "wb");
if (outFile != NULL) {
for(j=sync_byte; j<size; j++) {
c = buffer[j];
fputc(c, outFile);
} else {
printf("Can\'t create %s\n", outName);

return 0;

A Frame sync 11 (length in bits)
B MPEG audio version (MPEG-1, 2, etc.) 2
C MPEG layer (Layer I, II, III, etc.) 2
D Protection (if on, then checksum follows header) 1
1111 1111 1111 1010 = FA = MPEG-1 layer 3
1111 1111 1111 0010 = F2 = MPEG-2 layer 3
1111 1111 1110 0010 = E2 = MPEG-2.5 layer 3

int mp3_sync_byte (unsigned char *buffer, int size) {
int i, a=0, b=0, sync_byte=-1;

for(i=0; i<size; i++) {
a = b;
b = buffer[i];
if (a == 0xff &&
((b & 0xfe) == 0xfa ||
(b & 0xfe) == 0xf2 ||
(b & 0xfe) == 0xe2 ))
sync_byte = i-1;

return sync_byte;