1 /* AVR file format handler for SoX
2 * Copyright (C) 1999 Jan Paul Schmidt <jps@fundament.org>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or (at
7 * your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "sox_i.h"
20
21 #include <stdio.h>
22 #include <string.h>
23
24 #define AVR_MAGIC "2BIT"
25
26 /* Taken from the Audio File Formats FAQ */
27
28 typedef struct {
29 char magic [5]; /* 2BIT */
30 char name [8]; /* null-padded sample name */
31 unsigned short mono; /* 0 = mono, 0xffff = stereo */
32 unsigned short rez; /* 8 = 8 bit, 16 = 16 bit */
33 unsigned short sign; /* 0 = unsigned, 0xffff = signed */
34 unsigned short loop; /* 0 = no loop, 0xffff = looping sample */
35 unsigned short midi; /* 0xffff = no MIDI note assigned,
36 0xffXX = single key note assignment
37 0xLLHH = key split, low/hi note */
38 uint32_t rate; /* sample frequency in hertz */
39 uint32_t size; /* sample length in bytes or words (see rez) */
40 uint32_t lbeg; /* offset to start of loop in bytes or words.
41 set to zero if unused. */
42 uint32_t lend; /* offset to end of loop in bytes or words.
43 set to sample length if unused. */
44 unsigned short res1; /* Reserved, MIDI keyboard split */
45 unsigned short res2; /* Reserved, sample compression */
46 unsigned short res3; /* Reserved */
47 char ext[20]; /* Additional filename space, used
48 if (name[7] != 0) */
49 char user[64]; /* User defined. Typically ASCII message. */
50 } priv_t;
51
52
53
54 /*
55 * Do anything required before you start reading samples.
56 * Read file header.
57 * Find out sampling rate,
58 * size and encoding of samples,
59 * mono/stereo/quad.
60 */
61
62
startread(sox_format_t * ft)63 static int startread(sox_format_t * ft)
64 {
65 priv_t * avr = (priv_t *)ft->priv;
66 int rc;
67
68 lsx_reads(ft, avr->magic, (size_t)4);
69
70 if (strncmp (avr->magic, AVR_MAGIC, (size_t)4)) {
71 lsx_fail_errno(ft,SOX_EHDR,"AVR: unknown header");
72 return(SOX_EOF);
73 }
74
75 lsx_readbuf(ft, avr->name, sizeof(avr->name));
76
77 lsx_readw (ft, &(avr->mono));
78 if (avr->mono) {
79 ft->signal.channels = 2;
80 }
81 else {
82 ft->signal.channels = 1;
83 }
84
85 lsx_readw (ft, &(avr->rez));
86 if (avr->rez == 8) {
87 ft->encoding.bits_per_sample = 8;
88 }
89 else if (avr->rez == 16) {
90 ft->encoding.bits_per_sample = 16;
91 }
92 else {
93 lsx_fail_errno(ft,SOX_EFMT,"AVR: unsupported sample resolution");
94 return(SOX_EOF);
95 }
96
97 lsx_readw (ft, &(avr->sign));
98 if (avr->sign) {
99 ft->encoding.encoding = SOX_ENCODING_SIGN2;
100 }
101 else {
102 ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
103 }
104
105 lsx_readw (ft, &(avr->loop));
106
107 lsx_readw (ft, &(avr->midi));
108
109 lsx_readdw (ft, &(avr->rate));
110 /*
111 * No support for AVRs created by ST-Replay,
112 * Replay Proffesional and PRO-Series 12.
113 *
114 * Just masking the upper byte out.
115 */
116 ft->signal.rate = (avr->rate & 0x00ffffff);
117
118 lsx_readdw (ft, &(avr->size));
119
120 lsx_readdw (ft, &(avr->lbeg));
121
122 lsx_readdw (ft, &(avr->lend));
123
124 lsx_readw (ft, &(avr->res1));
125
126 lsx_readw (ft, &(avr->res2));
127
128 lsx_readw (ft, &(avr->res3));
129
130 lsx_readbuf(ft, avr->ext, sizeof(avr->ext));
131
132 lsx_readbuf(ft, avr->user, sizeof(avr->user));
133
134 rc = lsx_rawstartread (ft);
135 if (rc)
136 return rc;
137
138 return(SOX_SUCCESS);
139 }
140
startwrite(sox_format_t * ft)141 static int startwrite(sox_format_t * ft)
142 {
143 priv_t * avr = (priv_t *)ft->priv;
144 int rc;
145
146 if (!ft->seekable) {
147 lsx_fail_errno(ft,SOX_EOF,"AVR: file is not seekable");
148 return(SOX_EOF);
149 }
150
151 rc = lsx_rawstartwrite (ft);
152 if (rc)
153 return rc;
154
155 /* magic */
156 lsx_writes(ft, AVR_MAGIC);
157
158 /* name */
159 lsx_writeb(ft, 0);
160 lsx_writeb(ft, 0);
161 lsx_writeb(ft, 0);
162 lsx_writeb(ft, 0);
163 lsx_writeb(ft, 0);
164 lsx_writeb(ft, 0);
165 lsx_writeb(ft, 0);
166 lsx_writeb(ft, 0);
167
168 /* mono */
169 if (ft->signal.channels == 1) {
170 lsx_writew (ft, 0);
171 }
172 else if (ft->signal.channels == 2) {
173 lsx_writew (ft, 0xffff);
174 }
175 else {
176 lsx_fail_errno(ft,SOX_EFMT,"AVR: number of channels not supported");
177 return(0);
178 }
179
180 /* rez */
181 if (ft->encoding.bits_per_sample == 8) {
182 lsx_writew (ft, 8);
183 }
184 else if (ft->encoding.bits_per_sample == 16) {
185 lsx_writew (ft, 16);
186 }
187 else {
188 lsx_fail_errno(ft,SOX_EFMT,"AVR: unsupported sample resolution");
189 return(SOX_EOF);
190 }
191
192 /* sign */
193 if (ft->encoding.encoding == SOX_ENCODING_SIGN2) {
194 lsx_writew (ft, 0xffff);
195 }
196 else if (ft->encoding.encoding == SOX_ENCODING_UNSIGNED) {
197 lsx_writew (ft, 0);
198 }
199 else {
200 lsx_fail_errno(ft,SOX_EFMT,"AVR: unsupported encoding");
201 return(SOX_EOF);
202 }
203
204 /* loop */
205 lsx_writew (ft, 0xffff);
206
207 /* midi */
208 lsx_writew (ft, 0xffff);
209
210 /* rate */
211 lsx_writedw(ft, (unsigned)(ft->signal.rate + .5));
212
213 /* size */
214 /* Don't know the size yet. */
215 lsx_writedw (ft, 0);
216
217 /* lbeg */
218 lsx_writedw (ft, 0);
219
220 /* lend */
221 /* Don't know the size yet, so we can't set lend, either. */
222 lsx_writedw (ft, 0);
223
224 /* res1 */
225 lsx_writew (ft, 0);
226
227 /* res2 */
228 lsx_writew (ft, 0);
229
230 /* res3 */
231 lsx_writew (ft, 0);
232
233 /* ext */
234 lsx_writebuf(ft, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(avr->ext));
235
236 /* user */
237 lsx_writebuf(ft,
238 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
239 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
240 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
241 "\0\0\0\0", sizeof (avr->user));
242
243 return(SOX_SUCCESS);
244 }
245
write_samples(sox_format_t * ft,const sox_sample_t * buf,size_t nsamp)246 static size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp)
247 {
248 priv_t * avr = (priv_t *)ft->priv;
249
250 avr->size += nsamp;
251
252 return (lsx_rawwrite (ft, buf, nsamp));
253 }
254
stopwrite(sox_format_t * ft)255 static int stopwrite(sox_format_t * ft)
256 {
257 priv_t * avr = (priv_t *)ft->priv;
258
259 unsigned size = avr->size / ft->signal.channels;
260
261 /* Fix size */
262 lsx_seeki(ft, (off_t)26, SEEK_SET);
263 lsx_writedw (ft, size);
264
265 /* Fix lend */
266 lsx_seeki(ft, (off_t)34, SEEK_SET);
267 lsx_writedw (ft, size);
268
269 return(SOX_SUCCESS);
270 }
271
LSX_FORMAT_HANDLER(avr)272 LSX_FORMAT_HANDLER(avr)
273 {
274 static char const * const names[] = { "avr", NULL };
275 static unsigned const write_encodings[] = {
276 SOX_ENCODING_SIGN2, 16, 8, 0,
277 SOX_ENCODING_UNSIGNED, 16, 8, 0,
278 0};
279 static sox_format_handler_t handler = {SOX_LIB_VERSION_CODE,
280 "Audio Visual Research format; used on the Mac",
281 names, SOX_FILE_BIG_END | SOX_FILE_MONO | SOX_FILE_STEREO,
282 startread, lsx_rawread, NULL,
283 startwrite, write_samples, stopwrite,
284 NULL, write_encodings, NULL, sizeof(priv_t)
285 };
286 return &handler;
287 }
288