phoned/lib/libpvf/voc.c
2005-06-14 02:40:07 +00:00

184 lines
4.2 KiB
C

/*
* voc.c
*
* Converts pvf <--> voc.
*
* $Id: voc.c,v 1.4 1998/09/09 21:07:05 gert Exp $
*
*/
#include <string.h>
#include <stdio.h>
#include "pvf.h"
static char voc_hdr[32] =
{
'C','r','e','a','t','i','v','e',' ',
'V','o','i','c','e',' ','F','i','l','e',
0x1a,0x1a,0x00,0x0a,0x01,0x29,0x11,
0x01,(unsigned char) 0x82,0x70,0x00,(unsigned char) 0x98,0x00
};
/*
* static char *voc_type[] =
* {
* "8 bit",
* "4 bit",
* "2.6 bit",
* "2 bit",
* "Multi DAC, 1 channel",
* "Multi DAC, 2 channels",
* "Multi DAC, 3 channels",
* "Multi DAC, 4 channels",
* "unknown"
* };
*/
int pvftovoc (FILE *fd_in, FILE *fd_out, pvf_header *header_in)
{
int blocksize = 0x7080;
int count;
long rate = header_in->speed;
static unsigned char voc_blk[4] = {0x02, 0x80, 0x70, 0x00};
int data;
voc_hdr[30] = 256 - ((long) 1000000 / rate);
fwrite(voc_hdr, 1, sizeof(voc_hdr), fd_out);
count = blocksize;
while (!feof(fd_in))
{
data = header_in->read_pvf_data(fd_in) >> 16;
if (data > 0x7f)
data = 0x7f;
if (data < -0x80)
data = -0x80;
putc(data + 0x80, fd_out);
count--;
if (!count)
{
count = blocksize;
fwrite(voc_blk, 1, 4, fd_out);
};
};
while (count--)
putc(0x7f, fd_out);
putc(0x00, fd_out);
return(OK);
}
int voctopvf (FILE *fd_in, FILE *fd_out, pvf_header *header_out)
{
char hdr[32];
int data_offset;
int type;
long count;
long blocksize;
header_out->speed = -1;
fread(hdr, 1, 0x1a, fd_in);
if (strncmp(hdr, voc_hdr, 0x14))
{
fprintf(stderr, "%s: not a VOC file", program_name);
return(ERROR);
};
data_offset = hdr[0x14] | (hdr[0x15] << 8);
if (hdr[0x17] != 1)
{
fprintf(stderr, "%s: unsupported VOC major version %d",
program_name, hdr[0x17]);
return(ERROR);
};
for (count = 0x20; count < data_offset; count++)
getc(fd_in);
/*
* read the data blocks
*/
blocksize = 0;
count = 0;
while (TRUE)
{
type = getc(fd_in);
if (type == 0)
{
/*
* terminator
*/
return(OK);
}
else
{
blocksize = getc(fd_in);
blocksize |= (getc(fd_in) << 8);
blocksize |= (getc(fd_in) << 16);
count = blocksize;
if (type > 2)
fprintf(stderr,
"%s: unknown block type %d, skipping...\n", program_name,
type);
if (type == 1)
{
long sample_rate = 1000000L / (long) (256 - getc(fd_in));
int data_type = getc(fd_in);
if (header_out->speed == -1)
{
header_out->speed = sample_rate;
write_pvf_header(fd_out, header_out);
}
else
if (header_out->speed != sample_rate)
{
fprintf(stderr,
"%s: unsupported sample rate change",
program_name);
return(ERROR);
};
if (data_type != 0)
{
fprintf(stderr, "%s: unsupported data type %d",
program_name, data_type);
return(ERROR);
};
count -= 2;
};
while (count--)
{
int d = getc(fd_in);
if (feof(fd_in))
return(OK);
if (type <= 2)
header_out->write_pvf_data(fd_out, (d - 0x80) << 16);
};
};
};
return(OK);
}