forked from continue88/bjxa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbjxa.3.rst.in
311 lines (240 loc) · 11.2 KB
/
bjxa.3.rst.in
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
.. Copyright (C) 2018-2020 Dridi Boukelmoune
..
.. This program is free software: you can redistribute it and/or modify
.. it under the terms of the GNU General Public License as published by
.. the Free Software Foundation, either version 3 of the License, or
.. (at your option) any later version.
..
.. This program is distributed in the hope that it will be useful,
.. but WITHOUT ANY WARRANTY; without even the implied warranty of
.. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
.. GNU General Public License for more details.
..
.. You should have received a copy of the GNU General Public License
.. along with this program. If not, see <http://www.gnu.org/licenses/>.
=======
libbjxa
=======
------------------------------
BandJAM XA audio codec library
------------------------------
:Title upper: BJXA
:Manual section: 3
PROLOG
======
The goal of **libbjxa** is to provide a portable and clean interface to
interact with BandJAM XA audio files. It provides a decoder that can convert
any XA file to a PCM stream of 16 bits samples, and encoder for the opposite
conversion. It can work with simple WAV files containing mono or stereo 16
bits PCM samples.
It is a replacement for the **xadec.dll** library that was shipped with
BandJAM with a license allowing to use it for free of charge projects but its
source code is unavailable and the Windows library only exists for 32 bits x86
systems.
SYNOPSIS
========
| **#include <stdint.h>**
| **#include <stdio.h>**
| **#include <unistd.h>**
|
| **#include <bjxa.h>**
|
| **#define** *BJXA_HEADER_SIZE_XA*
| **#define** *BJXA_HEADER_SIZE_RIFF*
|
| **typedef struct bjxa_decoder bjxa_decoder_t;**
| **typedef struct bjxa_encoder bjxa_encoder_t;**
|
| **typedef struct {**
| **uint32_t** *data_len_pcm*\ **;**
| **uint32_t** *blocks*\ **;**
| **uint8_t** *block_size_pcm*\ **;**
| **uint8_t** *block_size_xa*\ **;**
| **uint16_t** *samples_rate*\ **;**
| **uint8_t** *sample_bits*\ **;**
| **uint8_t** *channels*\ **;**
| **} bjxa_format_t;**
|
| /\* decoder \*/
|
| **bjxa_decoder_t * bjxa_decoder(void);**
| **int bjxa_free_decoder(bjxa_decoder_t \*\***\ *decp*\ **);**
|
| **ssize_t bjxa_parse_header(bjxa_decoder_t \***\ *dec*\ **,** \
**const void \***\ *src*\ **, size_t** *len*\ **);**
| **ssize_t bjxa_fread_header(bjxa_decoder_t \***\ *dec*\ **,** \
**FILE \***\ *file*\ **);**
|
| **int bjxa_decode_format(bjxa_decoder_t \***\ *dec*\ **,** \
**bjxa_format_t \***\ *fmt*\ **);**
| **int bjxa_decode(bjxa_decoder_t \***\ *dec*\ **,** \
**void \***\ *dst*\ **, size_t** *dst_len*\ **,** \
**const void \***\ *src*\ **, size_t** *src_len*\ **);**
|
| **ssize_t bjxa_dump_riff_header(bjxa_decoder_t \***\ *dec*\ **,** \
**void \***\ *dst*\ **, size_t** *len*\ **);**
| **ssize_t bjxa_fwrite_riff_header(bjxa_decoder_t \***\ *dec*\ **,** \
**FILE \***\ *file*\ **);**
|
| **int bjxa_dump_pcm(void \***\ *dst*\ **, const int16_t \***\ *src*\ **,** \
**size_t** *len*\ **);**
| **int bjxa_fwrite_pcm(const int16_t \***\ *src*\ **, size_t** *len*\ **,** \
**FILE \***\ *file*\ **);**
|
| /\* encoder \*/
|
| **bjxa_encoder_t * bjxa_encoder(void);**
| **int bjxa_free_encoder(bjxa_encoder_t \*\***\ *encp*\ **);**
|
| **ssize_t bjxa_parse_riff_header(bjxa_format_t \***\ *fmt*\ **,** \
**const void \***\ *src*\ **, size_t** *len*\ **);**
| **ssize_t bjxa_fread_riff_header(bjxa_format_t \***\ *fmt*\ **,** \
**FILE \***\ *file*\ **);**
|
| **int bjxa_encode_init(bjxa_encoder_t \***\ *enc*\ **,** \
**bjxa_format_t \***\ *fmt*\ **, uint8_t** *bits*\ **);**
|
| **int bjxa_encode_format(bjxa_encoder_t \***\ *enc*\ **,** \
**bjxa_format_t \***\ *fmt*\ **);**
| **int bjxa_encode(bjxa_encoder_t \***\ *enc*\ **,** \
**void \***\ *dst*\ **, size_t** *dst_len*\ **,** \
**const void \***\ *src*\ **, size_t** *src_len*\ **);**
|
| **ssize_t bjxa_dump_header(bjxa_encoder_t \***\ *enc*\ **,** \
**void \***\ *dst*\ **, size_t** *len*\ **);**
| **ssize_t bjxa_fwrite_header(bjxa_encoder_t \***\ *enc*\ **,** \
**FILE \***\ *file*\ **);**
DESCRIPTION
===========
**bjxa_decoder()** and **bjxa_encoder()** respectively allocate a decoder or
an encoder for a single XA file at a time.
**bjxa_free_decoder()** and **bjxa_free_encoder()** respectively take pointers
to a decoder or an encoder, free the codecs and clear the pointers.
**bjxa_parse_header()** and **bjxa_fread_header()** parse the header of an XA
file respectively from memory or from a file. On success, the decoder is ready
to convert samples. A used decoder can parse a new XA header at any time, even
in the middle of a conversion. The state of the decoder is updated atomically
only on success.
**bjxa_parse_riff_header()** and **bjxa_fread_riff_header()** parse the header
of an WAV file respectively from memory or from a file. Only 16 bits mono or
stereo PCM formats are supported. On success, the format is populated and
ready to be consumed by **bjxa_encode_init()**. Only ``"RIFF"`` containers
starting with ``"WAVEfmt "`` and ``"data"`` segments are supported. Anything
past the ``"data"`` segment is ignored.
**bjxa_dump_header()** and **bjxa_fwrite_header()** write an XA file header
respectively to memory or to a file. The encoder must be in a read state. Such
a header followed by the data produced by **bjxa_encode()** produces a valid
XA file.
**bjxa_dump_riff_header()** and **bjxa_fwrite_riff_header()** write a RIFF
header of a WAV file respectively to memory or to a file. Such a header
followed by the data produced by **bjxa_decode()** produces a valid WAV file.
**bjxa_decode_format()** takes a decoder in a ready state and fills a
**bjxa_format_t** structure with information about the XA file. This
information can then be used to drive the decoding using **bjxa_decode()**.
On success the *sample_bits* field contains the number of bits per PCM sample.
**bjxa_decode()** decodes XA blocks read from *src* to PCM samples written to
*dst*. Stereo PCM samples are interleaved and both channels interpreted as a
single block. The number of blocks reported by **bjxa_format_t** are effective
blocks, meaning that two XA blocks needed to decode one stereo PCM "block" is
considered a single block because of the interleaving. The last PCM block may
be truncated if the number of remaining samples is less than the contents of a
full XA block. The field *data_len_pcm* can be used to keep track of how many
bytes were decoded over iterations.
**bjxa_encode_init()** puts an encoder in a ready state, initialized from a
**bjxa_format_t** structure and a number of *bits* per XA samples. The *fmt*
argument must have the *data_len_pcm*, *samples_rate*, *sample_bits* and
*channels* set. On success the *blocks*, *block_size_pcm* and *block_size_xa*
fields are set to the appropriate values. A used encoder can be reinitialized
at any time, even in the middle of a conversion. The *sample_bits* field
represents the number of bits per PCM sample and must be 16.
**bjxa_encode_format()** takes an encoder in a ready state and fills a
**bjxa_format_t** structure with information about the XA file. This
information can then be used to drive the encoding using **bjxa_encode()**.
On success the *sample_bits* field contains the number of bits per XA sample.
**bjxa_encode()** encodes XA blocks written to *dst* from PCM samples read from
*src*. It follows the same rules as **bjxa_decode()** but does the opposite
work.
**bjxa_dump_pcm()** and **bjxa_fwrite_pcm()** write PCM samples respectively
to memory or to a file, regardless of the host byte order. *len* is always
the buffer length for *src* and *dst*, not the number of samples.
RETURN VALUE
============
On success, a scalar greater or equal to zero or a valid pointer is returned.
A function returns either zero or a value greater than zero on success, so
only functions where the return value means more than just success are
described below.
On error, -1 or **NULL** is returned, and *errno* is set appropriately.
**bjxa_parse_header()** and **bjxa_fread_header()** return the number of bytes
read. On success this value is always *BJXA_HEADER_SIZE_XA* because XA files
have a fixed-size header.
**bjxa_dump_riff_header()** and **bjxa_fwrite_riff_header()** return the
number of bytes written. On success this value is always
*BJXA_HEADER_SIZE_RIFF* because **libbjxa** always produces fixed-size RIFF
headers.
**bjxa_decode()** returns the number of effective blocks decoded. The number
of bytes read from *src* and written to *dst* can be computed using the
*block_size_xa* and *block_size_pcm* fields.
ERRORS
======
**EFAULT**
*decp* is a null pointer or a pointer to a null decoder.
*encp* is a null pointer or a pointer to a null encoder.
*dec* or *enc* or *src* or *dst* or *file* or *fmt* is null.
**EINVAL**
*decp* is not a pointer to a valid decoder.
*encp* is not a pointer to a valid encoder.
*dec* is not a valid decoder, or a decoder not in a ready state.
*enc* is not a valid encoder, or an encoder not in a ready state.
*bits* is neither *4*, *6* nor *8*.
**EIO**
**bjxa_fread_header()** could not read a complete XA header.
**bjxa_fwrite_header()** could not write a complete XA header.
**ENOBUFS**
**bjxa_parse_header()** or **bjxa_dump_header()** got a *len* lower
than 32, so the memory buffer can't hold a complete XA header.
**bjxa_dump_riff_header()** got a *len* too low, so the memory
buffer can't hold a complete RIFF header.
**bjxa_decode()** got a *dst_len* lower than *block_size_pcm*, so the
memory buffer *dst* can't hold a complete PCM block.
**bjxa_decode()** got a *src_len* lower than *block_size_xa*, so the
memory buffer *src* can't hold a complete XA block.
**bjxa_encode()** got a *dst_len* lower than *block_size_xa*, so the
memory buffer *dst* can't hold a complete XA block.
**bjxa_encode()** got a *src_len* lower than *block_size_pcm*, so the
memory buffer *src* can't hold a complete PCM block.
**bjxa_dump_pcm()** got a *len* of zero or not aligning to the size of
a complete sample.
**bjxa_fwrite_pcm()** got a *len* of zero or not aligning to the size of
a complete sample.
**ENOMEM**
**bjxa_decoder()** could not allocate a decoder.
**bjxa_encoder()** could not allocate an encoder.
**EPROTO**
**bjxa_parse_header()** could not parse a valid XA header.
**bjxa_fread_header()** could not parse a valid XA header.
**bjxa_decode()** got an invalid XA block.
**bjxa_decode()** already decoded the complete XA stream.
**bjxa_encode_init()** got an invalid *fmt* argument.
ATTRIBUTES
==========
A codec is not MT-Safe. However **bjxa_decoder()** and **bjxa_encoder()**
functions are MT-Safe but any function taking a codec argument is not. A
codec should be manipulated by a single thread at a time.
EXAMPLE
=======
The following code demonstrates the conversion of one XA file to a WAV file
using a decoder, either incrementally or in a single pass:
.. include:: @builddir@/bjxa_decode.c.txt
:literal:
The following code demonstrates the conversion of one WAV file to an XA file
using an encoder, either incrementally or in a single pass:
.. include:: @builddir@/bjxa_encode.c.txt
:literal:
Both examples come from the **bjxa**\(1) actual source code.
BUGS
====
**libbjxa** does not understand the *nLoopPtr* field from the XA file header.
SEE ALSO
========
**bjxa**\(1),
**bjxa**\(5)