#include <clip.h>

#if 1 /*0:整数版/1:実数版*/
#define MP3DRIVER		MP3RDRIVER
#define mp3_init		mp3r_init
#define mp3_decode_frame	mp3r_decode_frame
#endif

unsigned char in_buf[16 * 1024 * 1024];
int in_size;
unsigned char out_buf[48 * 1024 * 1024];
int out_size;

MP3DRIVER mp3;

typedef struct _WAVHDR {
	char riff_chunk_id[4];
	int riff_chunk_size;
	char wave_tag[4];
	char fmt_chunk_id[4];
	int fmt_chunk_size;
	short fmt_tag;
	short channels;
	int samples_per_sec;
	int avg_bytes_per_sec;
	short block_align;
	short bits_per_sample;
	char data_chunk_id[4];
	int data_chunk_size;
} WAVHDR;
WAVHDR wav;

int
main(int argc, char* argv[])
{
	FILE* fp;
	char path[_MAX_PATH];
	char drive[_MAX_DRIVE];
	char dir[_MAX_DIR];
	char fname[_MAX_FNAME];
	char ext[_MAX_EXT];
	int i_frame;

	/* 読み込み。 */
	if(argc != 1 + 1) DIE();
	_splitpath(argv[1], drive, dir, fname, ext);
	if(strlen(ext) == 0) strcpy(ext, "mp3");
	_makepath(path, drive, dir, fname, ext);
	fp = fopen(path, "rb");
	if(!fp) DIE();
	in_size = fread(in_buf, 1, sizeof in_buf, fp);
	fclose(fp);

	/* デコード。 */
	i_frame = 0;
	if(mp3_init(&mp3, in_buf, in_size) != 0) DIE();
	do {
		memcpy(out_buf + out_size, mp3.fbuff, mp3.c_fbuff * sizeof(short));
		out_size += mp3.c_fbuff * sizeof(short);
		if(i_frame % 1000 == 0) printf("%5d\n", i_frame);
		i_frame++;
	} while(mp3_decode_frame(&mp3) == 0);

	/* ヘッダ作成。 */
	memset(&wav, 0, sizeof wav);
	memcpy(wav.riff_chunk_id, "RIFF", 4);
	wav.riff_chunk_size	= 36 + out_size;
	memcpy(wav.wave_tag, "WAVE", 4);
	memcpy(wav.fmt_chunk_id, "fmt ", 4);
	wav.fmt_chunk_size	= 16;
	wav.fmt_tag		= 1/*WAVE_FORMAT_PCM*/;
	wav.channels		= 1;
	wav.samples_per_sec	= mp3.sampling_frequency;
	wav.avg_bytes_per_sec	= mp3.sampling_frequency * sizeof(short);
	wav.block_align		= 1/*ch*/ * sizeof(short);
	wav.bits_per_sample	= 8/*bit*/ * sizeof(short);
	memcpy(wav.data_chunk_id, "data", 4);
	wav.data_chunk_size	= out_size;

	/* 書き込み。 */
	_makepath(path, drive, dir, fname, "wav");
	fp = fopen(path, "wb");
	if(!fp) DIE();
	fwrite(&wav, sizeof wav, 1, fp);
	fwrite(out_buf, 1, out_size, fp);
	fclose(fp);

	return 0;
}
