1 /*
2 * voc.c
3 *
4 * Converts pvf <--> voc.
5 *
6 * $Id: voc.c,v 1.4 1998/09/09 21:07:05 gert Exp $
7 *
8 */
9
10 #include "../include/voice.h"
11
12 static char voc_hdr[32] =
13 {
14 'C','r','e','a','t','i','v','e',' ',
15 'V','o','i','c','e',' ','F','i','l','e',
16 0x1a,0x1a,0x00,0x0a,0x01,0x29,0x11,
17 0x01,(unsigned char) 0x82,0x70,0x00,(unsigned char) 0x98,0x00
18 };
19
20 /*
21 * static char *voc_type[] =
22 * {
23 * "8 bit",
24 * "4 bit",
25 * "2.6 bit",
26 * "2 bit",
27 * "Multi DAC, 1 channel",
28 * "Multi DAC, 2 channels",
29 * "Multi DAC, 3 channels",
30 * "Multi DAC, 4 channels",
31 * "unknown"
32 * };
33 */
34
pvftovoc(FILE * fd_in,FILE * fd_out,pvf_header * header_in)35 int pvftovoc (FILE *fd_in, FILE *fd_out, pvf_header *header_in)
36 {
37 int blocksize = 0x7080;
38 int count;
39 long rate = header_in->speed;
40 static unsigned char voc_blk[4] = {0x02, 0x80, 0x70, 0x00};
41 int data;
42
43 voc_hdr[30] = 256 - ((long) 1000000 / rate);
44 fwrite(voc_hdr, 1, sizeof(voc_hdr), fd_out);
45
46 count = blocksize;
47
48 while (!feof(fd_in))
49 {
50 data = header_in->read_pvf_data(fd_in) >> 16;
51
52 if (data > 0x7f)
53 data = 0x7f;
54
55 if (data < -0x80)
56 data = -0x80;
57
58 putc(data + 0x80, fd_out);
59 count--;
60
61 if (!count)
62 {
63 count = blocksize;
64 fwrite(voc_blk, 1, 4, fd_out);
65 };
66
67 };
68
69 while (count--)
70 putc(0x7f, fd_out);
71
72 putc(0x00, fd_out);
73 return(OK);
74 }
75
voctopvf(FILE * fd_in,FILE * fd_out,pvf_header * header_out)76 int voctopvf (FILE *fd_in, FILE *fd_out, pvf_header *header_out)
77 {
78 char hdr[32];
79 int data_offset;
80 int type;
81 long count;
82 long blocksize;
83
84 header_out->speed = -1;
85 fread(hdr, 1, 0x1a, fd_in);
86
87 if (strncmp(hdr, voc_hdr, 0x14))
88 {
89 fprintf(stderr, "%s: not a VOC file", program_name);
90 return(ERROR);
91 };
92
93 data_offset = hdr[0x14] | (hdr[0x15] << 8);
94
95 if (hdr[0x17] != 1)
96 {
97 fprintf(stderr, "%s: unsupported VOC major version %d",
98 program_name, hdr[0x17]);
99 return(ERROR);
100 };
101
102 for (count = 0x20; count < data_offset; count++)
103 getc(fd_in);
104
105 /*
106 * read the data blocks
107 */
108
109 blocksize = 0;
110 count = 0;
111
112 while (TRUE)
113 {
114 type = getc(fd_in);
115
116 if (type == 0)
117 {
118 /*
119 * terminator
120 */
121
122 return(OK);
123 }
124 else
125 {
126 blocksize = getc(fd_in);
127 blocksize |= (getc(fd_in) << 8);
128 blocksize |= (getc(fd_in) << 16);
129 count = blocksize;
130
131 if (type > 2)
132 fprintf(stderr,
133 "%s: unknown block type %d, skipping...\n", program_name,
134 type);
135
136 if (type == 1)
137 {
138 long sample_rate = 1000000L / (long) (256 - getc(fd_in));
139 int data_type = getc(fd_in);
140
141 if (header_out->speed == -1)
142 {
143 header_out->speed = sample_rate;
144 write_pvf_header(fd_out, header_out);
145 }
146 else
147
148 if (header_out->speed != sample_rate)
149 {
150 fprintf(stderr,
151 "%s: unsupported sample rate change",
152 program_name);
153 return(ERROR);
154 };
155
156 if (data_type != 0)
157 {
158 fprintf(stderr, "%s: unsupported data type %d",
159 program_name, data_type);
160 return(ERROR);
161 };
162
163 count -= 2;
164 };
165
166 while (count--)
167 {
168 int d = getc(fd_in);
169
170 if (feof(fd_in))
171 return(OK);
172
173 if (type <= 2)
174 header_out->write_pvf_data(fd_out, (d - 0x80) << 16);
175
176 };
177
178 };
179
180 };
181
182 return(OK);
183 }
184