📄 bwcnv.c
字号:
/*--------------------------------------------------------
MS PCM to BrueWave format Converter
Copyright(C)2001 BluePlanet
2001/1/27 ver.0.1
--------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*----------------------------------
DEFINEs
-----------------------------------*/
#define VERSION "0.1"
#define BUFF_SIZE 0x1000
#define FNAME_SIZE 256
#define DST_EXT ".fr"
#define BASE_FREQ 12000
#define WAV_HEADER_SIZE sizeof(WAV_HEADER)
#define BW_HEADER_SIZE sizeof(BW_HEADER)
/*----------------------------------
PCM MODEs
-----------------------------------*/
#define PCM_ID_WAV 1
#define PCM_ID_X68 2
/*----------------------------------
TYPEDEFs
-----------------------------------*/
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef struct{
char riff[4];
ulong file_size;
char wavefmt[8];
ulong head_size;
ushort data_type;
ushort channels1;
ulong rate;
ulong rate_avg;
ushort channels2;
ushort smpl_bits;
ulong data;
ulong pcm_size;
} WAV_HEADER;
typedef struct{
char magic[2];
char type[2];
ushort file_size;
ushort id;
ulong pcm_size;
char pcm_type;
char rate;
char reserve[2];
} BW_HEADER;
typedef struct{
int err_no;
char src_fname[FNAME_SIZE];
char dst_fname[FNAME_SIZE];
ulong pcm_size;
BW_HEADER h;
} PARAM;
/*----------------------------------
VARIABLEs
-----------------------------------*/
static BW_HEADER default_bw_header = {
{ 'F', 'R' }, /* magic */
{ 'B', 'W' }, /* type */
0, /* file size */
0, /* id */
0, /* pcm size */
PCM_ID_WAV, /* pcm type */
1, /* rate, freq = 16000Hz / rate */
0 /* reserve */
};
static int s_level = 0;
static int a_level = 0;
/*----------------------------------
TABLEs
-----------------------------------*/
static unsigned scaleval[]={
16, 17, 19, 21, 23, 25, 28,
31, 34, 37, 41, 45, 50, 55,
60, 66, 73, 80, 88, 97, 107,
118, 130, 143, 157, 173, 190, 209,
230, 253, 279, 307, 337, 371, 408,
449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552
};
static unsigned levelchg[]={-1,-1,-1,-1,2,4,6,8};
/*----------------------------------
CODEs
-----------------------------------*/
int adpcm2pcm(int d)
{
int a, q;
a = (((d & 7)<<1) + 1) * scaleval[s_level];
a >>= 3;
if(d&8) a = -a;
a_level += a;
if( a_level>511 ) a_level= 511;
if( a_level<-512 ) a_level= -512;
q = a_level<<6;
s_level += levelchg[d&7];
if( s_level<0 ) s_level = 0;
if( s_level>48 ) s_level = 48;
return q;
}
int pcm2adpcm(int d)
{
int a, q;
d -= 0x8000;
a = (d>>6) - a_level;
q = 0;
if( a<0 ){
a = -a;
q = 8;
}
a /= (scaleval[s_level]>>3);
if( a>=16 ){
q |= 7;
}
else if( a!=0 ){
q |= ((a-1)>>1);
}
adpcm2pcm( q );
return q;
}
void wav2bw( FILE *dst_fp, FILE *src_fp, PARAM *param )
{
int i, n, m, d;
int end_flg;
ulong size, read_size;
char *p, *q;
static char src_buff[BUFF_SIZE];
static char dst_buff[BUFF_SIZE];
end_flg = 0;
size = param->pcm_size;
if( param->h.pcm_type==PCM_ID_WAV ){
while( end_flg==0 ){
read_size = (size>BUFF_SIZE) ? BUFF_SIZE : size;
size -= read_size;
n = fread( src_buff, 1, read_size, src_fp );
if( n<BUFF_SIZE ){
end_flg = 1;
m = 0x0010 - (n&0x000f);
if( m!=0x0010 ){
memset( src_buff+n, 0x80, m );
n += m;
}
if( n==0 ){
break;
}
}
fwrite( src_buff, 1, n, dst_fp );
param->h.pcm_size += n;
}
}
else{
while( end_flg==0 ){
read_size = (size>BUFF_SIZE) ? BUFF_SIZE : size;
size -= read_size;
n = fread( src_buff, 1, read_size, src_fp );
if( n<BUFF_SIZE ){
end_flg = 1;
m = 0x0020 - (n&0x001f);
if( m!=0x0020 ){
memset( src_buff+n, 0x80, m );
n += m;
}
}
p = src_buff;
q = dst_buff;
m = n/2;
for( i=0; i<m; i++ ){
d = pcm2adpcm( (*p++)<<8 );
d |= (pcm2adpcm( (*p++)<<8 ))<<4;
*q++ = d;
}
fwrite( dst_buff, 1, m, dst_fp );
param->h.pcm_size += m;
}
}
return;
}
int init_param(int argc, char **argv, PARAM *p)
{
int i;
char *q;
int err_flg;
strncpy(p->src_fname, "", FNAME_SIZE);
strncpy(p->dst_fname, "", FNAME_SIZE);
p->err_no = 0;
p->h = default_bw_header;
s_level = 0;
a_level = 0;
err_flg = 0;
argv++;
for( i=1; i<argc; i++, argv++ ){
if( **argv=='-' || **argv=='/' ){
switch( *(*argv+1) ){
case 'F':
case 'f': p->h.pcm_type = atoi(*argv+2);
break;
case 'd':
case 'D': p->h.id = atoi(*argv+2);
break;
default:
err_flg = 1;
break;
}
}
else{
if( strlen(p->src_fname)==0 ){
strncpy(p->src_fname, *argv, FNAME_SIZE-8);
}
else if( strlen(p->dst_fname)==0 ){
strncpy(p->dst_fname, *argv, FNAME_SIZE-8);
}
else{
err_flg = 1;
}
}
}
if( strlen(p->src_fname)==0 ){
err_flg = 2;
}
else if( strlen(p->dst_fname)==0 ){
strcpy(p->dst_fname, p->src_fname);
q = strrchr(p->dst_fname, '.');
if( q>strrchr(p->dst_fname, '\\') ){
*q = '\0';
}
strcat(p->dst_fname, DST_EXT);
}
return err_flg;
}
FILE *fopen_src(PARAM *p)
{
FILE *fp;
WAV_HEADER wav_info;
fp = fopen(p->src_fname, "rb");
if( fp!=NULL ){
fread( &wav_info, WAV_HEADER_SIZE, 1, fp );
if( strncmp( wav_info.riff, "RIFF", 4)!=0
|| wav_info.channels1!=1
|| wav_info.smpl_bits>16
){
fclose( fp );
fp=NULL;
p->err_no = 2;
}
p->h.rate = (int)((BASE_FREQ + wav_info.rate/2) / wav_info.rate);
p->pcm_size = wav_info.pcm_size;
}
else{
p->err_no = 1;
}
return fp;
}
FILE *fopen_dst(PARAM *p)
{
FILE *fp;
fp = fopen(p->dst_fname, "wb");
if( fp!=NULL ){
fwrite( &(p->h), BW_HEADER_SIZE, 1, fp );
}
else{
p->err_no = 1;
}
return fp;
}
void write_header( FILE *fp, PARAM *p )
{
p->h.file_size = (p->h.pcm_size + 16L)>>4;
rewind( fp );
fwrite( &(p->h), BW_HEADER_SIZE, 1, fp );
}
void put_version(void)
{
fprintf( stderr, "MS-PCM to BrueWave Converter BWCNV ver.%s (C)2001 BluePlanet\n", VERSION );
}
void usage(void)
{
fprintf( stderr, "Usage: bwcnv [<optines>] <source filename> [<destination filename>]\n", VERSION );
fprintf( stderr, "-f<format>: <format> is 1=8bit PCM(default), 2=4bit ADPCM\n" );
fprintf( stderr, "-d<id> : <id> is Resource ID. (default=0)\n" );
}
int main(int argc, char **argv)
{
int ret;
PARAM param;
FILE *src_fp, *dst_fp;
put_version();
ret = init_param( argc, argv, ¶m );
if( ret ){
usage();
return ret;
}
src_fp = fopen_src( ¶m );
if( src_fp==NULL ){
if( param.err_no==1 ){
fprintf( stderr, "\"%s\" open error.\n", param.src_fname );
}
else{
fprintf( stderr, "\"%s\" format error. Monaural 8bit only.\n", param.src_fname );
}
return ret;
}
dst_fp = fopen_dst( ¶m );
if( dst_fp==NULL ){
fprintf( stderr, "\"%s\" open error.\n", param.dst_fname );
fclose( src_fp );
return ret;
}
wav2bw( dst_fp, src_fp, ¶m );
write_header( dst_fp, ¶m );
fclose( src_fp );
fclose( dst_fp );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -