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