1 /* AVR file format handler for SoX
2 * Copyright (C) 1999 Jan Paul Schmidt <jps@fundament.org>
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.
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.
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
24 #define AVR_MAGIC "2BIT"
26 /* Taken from the Audio File Formats FAQ */
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
49 char user
[64]; /* User defined. Typically ASCII message. */
55 * Do anything required before you start reading samples.
57 * Find out sampling rate,
58 * size and encoding of samples,
63 static int startread(sox_format_t
* ft
)
65 priv_t
* avr
= (priv_t
*)ft
->priv
;
68 lsx_reads(ft
, avr
->magic
, (size_t)4);
70 if (strncmp (avr
->magic
, AVR_MAGIC
, (size_t)4)) {
71 lsx_fail_errno(ft
,SOX_EHDR
,"AVR: unknown header");
75 lsx_readbuf(ft
, avr
->name
, sizeof(avr
->name
));
77 lsx_readw (ft
, &(avr
->mono
));
79 ft
->signal
.channels
= 2;
82 ft
->signal
.channels
= 1;
85 lsx_readw (ft
, &(avr
->rez
));
87 ft
->encoding
.bits_per_sample
= 8;
89 else if (avr
->rez
== 16) {
90 ft
->encoding
.bits_per_sample
= 16;
93 lsx_fail_errno(ft
,SOX_EFMT
,"AVR: unsupported sample resolution");
97 lsx_readw (ft
, &(avr
->sign
));
99 ft
->encoding
.encoding
= SOX_ENCODING_SIGN2
;
102 ft
->encoding
.encoding
= SOX_ENCODING_UNSIGNED
;
105 lsx_readw (ft
, &(avr
->loop
));
107 lsx_readw (ft
, &(avr
->midi
));
109 lsx_readdw (ft
, &(avr
->rate
));
111 * No support for AVRs created by ST-Replay,
112 * Replay Proffesional and PRO-Series 12.
114 * Just masking the upper byte out.
116 ft
->signal
.rate
= (avr
->rate
& 0x00ffffff);
118 lsx_readdw (ft
, &(avr
->size
));
120 lsx_readdw (ft
, &(avr
->lbeg
));
122 lsx_readdw (ft
, &(avr
->lend
));
124 lsx_readw (ft
, &(avr
->res1
));
126 lsx_readw (ft
, &(avr
->res2
));
128 lsx_readw (ft
, &(avr
->res3
));
130 lsx_readbuf(ft
, avr
->ext
, sizeof(avr
->ext
));
132 lsx_readbuf(ft
, avr
->user
, sizeof(avr
->user
));
134 rc
= lsx_rawstartread (ft
);
141 static int startwrite(sox_format_t
* ft
)
143 priv_t
* avr
= (priv_t
*)ft
->priv
;
147 lsx_fail_errno(ft
,SOX_EOF
,"AVR: file is not seekable");
151 rc
= lsx_rawstartwrite (ft
);
156 lsx_writes(ft
, AVR_MAGIC
);
169 if (ft
->signal
.channels
== 1) {
172 else if (ft
->signal
.channels
== 2) {
173 lsx_writew (ft
, 0xffff);
176 lsx_fail_errno(ft
,SOX_EFMT
,"AVR: number of channels not supported");
181 if (ft
->encoding
.bits_per_sample
== 8) {
184 else if (ft
->encoding
.bits_per_sample
== 16) {
188 lsx_fail_errno(ft
,SOX_EFMT
,"AVR: unsupported sample resolution");
193 if (ft
->encoding
.encoding
== SOX_ENCODING_SIGN2
) {
194 lsx_writew (ft
, 0xffff);
196 else if (ft
->encoding
.encoding
== SOX_ENCODING_UNSIGNED
) {
200 lsx_fail_errno(ft
,SOX_EFMT
,"AVR: unsupported encoding");
205 lsx_writew (ft
, 0xffff);
208 lsx_writew (ft
, 0xffff);
211 lsx_writedw(ft
, (unsigned)(ft
->signal
.rate
+ .5));
214 /* Don't know the size yet. */
221 /* Don't know the size yet, so we can't set lend, either. */
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
));
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
));
246 static size_t write_samples(sox_format_t
* ft
, const sox_sample_t
*buf
, size_t nsamp
)
248 priv_t
* avr
= (priv_t
*)ft
->priv
;
252 return (lsx_rawwrite (ft
, buf
, nsamp
));
255 static int stopwrite(sox_format_t
* ft
)
257 priv_t
* avr
= (priv_t
*)ft
->priv
;
259 unsigned size
= avr
->size
/ ft
->signal
.channels
;
262 lsx_seeki(ft
, (off_t
)26, SEEK_SET
);
263 lsx_writedw (ft
, size
);
266 lsx_seeki(ft
, (off_t
)34, SEEK_SET
);
267 lsx_writedw (ft
, size
);
272 LSX_FORMAT_HANDLER(avr
)
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,
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
)