Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/tools/audiofile/audiofile.cpp
7857 views
1
// libaudiofile b62c902
2
// https://github.com/mpruett/audiofile
3
// To simplify compilation, all files have been concatenated into one.
4
// Support for all formats except WAVE, AIFF(C) and RAW has been stripped out.
5
6
/*
7
GNU LESSER GENERAL PUBLIC LICENSE
8
Version 2.1, February 1999
9
10
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
11
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
12
Everyone is permitted to copy and distribute verbatim copies
13
of this license document, but changing it is not allowed.
14
15
[This is the first released version of the Lesser GPL. It also counts
16
as the successor of the GNU Library Public License, version 2, hence
17
the version number 2.1.]
18
19
Preamble
20
21
The licenses for most software are designed to take away your
22
freedom to share and change it. By contrast, the GNU General Public
23
Licenses are intended to guarantee your freedom to share and change
24
free software--to make sure the software is free for all its users.
25
26
This license, the Lesser General Public License, applies to some
27
specially designated software packages--typically libraries--of the
28
Free Software Foundation and other authors who decide to use it. You
29
can use it too, but we suggest you first think carefully about whether
30
this license or the ordinary General Public License is the better
31
strategy to use in any particular case, based on the explanations below.
32
33
When we speak of free software, we are referring to freedom of use,
34
not price. Our General Public Licenses are designed to make sure that
35
you have the freedom to distribute copies of free software (and charge
36
for this service if you wish); that you receive source code or can get
37
it if you want it; that you can change the software and use pieces of
38
it in new free programs; and that you are informed that you can do
39
these things.
40
41
To protect your rights, we need to make restrictions that forbid
42
distributors to deny you these rights or to ask you to surrender these
43
rights. These restrictions translate to certain responsibilities for
44
you if you distribute copies of the library or if you modify it.
45
46
For example, if you distribute copies of the library, whether gratis
47
or for a fee, you must give the recipients all the rights that we gave
48
you. You must make sure that they, too, receive or can get the source
49
code. If you link other code with the library, you must provide
50
complete object files to the recipients, so that they can relink them
51
with the library after making changes to the library and recompiling
52
it. And you must show them these terms so they know their rights.
53
54
We protect your rights with a two-step method: (1) we copyright the
55
library, and (2) we offer you this license, which gives you legal
56
permission to copy, distribute and/or modify the library.
57
58
To protect each distributor, we want to make it very clear that
59
there is no warranty for the free library. Also, if the library is
60
modified by someone else and passed on, the recipients should know
61
that what they have is not the original version, so that the original
62
author's reputation will not be affected by problems that might be
63
introduced by others.
64
65
Finally, software patents pose a constant threat to the existence of
66
any free program. We wish to make sure that a company cannot
67
effectively restrict the users of a free program by obtaining a
68
restrictive license from a patent holder. Therefore, we insist that
69
any patent license obtained for a version of the library must be
70
consistent with the full freedom of use specified in this license.
71
72
Most GNU software, including some libraries, is covered by the
73
ordinary GNU General Public License. This license, the GNU Lesser
74
General Public License, applies to certain designated libraries, and
75
is quite different from the ordinary General Public License. We use
76
this license for certain libraries in order to permit linking those
77
libraries into non-free programs.
78
79
When a program is linked with a library, whether statically or using
80
a shared library, the combination of the two is legally speaking a
81
combined work, a derivative of the original library. The ordinary
82
General Public License therefore permits such linking only if the
83
entire combination fits its criteria of freedom. The Lesser General
84
Public License permits more lax criteria for linking other code with
85
the library.
86
87
We call this license the "Lesser" General Public License because it
88
does Less to protect the user's freedom than the ordinary General
89
Public License. It also provides other free software developers Less
90
of an advantage over competing non-free programs. These disadvantages
91
are the reason we use the ordinary General Public License for many
92
libraries. However, the Lesser license provides advantages in certain
93
special circumstances.
94
95
For example, on rare occasions, there may be a special need to
96
encourage the widest possible use of a certain library, so that it becomes
97
a de-facto standard. To achieve this, non-free programs must be
98
allowed to use the library. A more frequent case is that a free
99
library does the same job as widely used non-free libraries. In this
100
case, there is little to gain by limiting the free library to free
101
software only, so we use the Lesser General Public License.
102
103
In other cases, permission to use a particular library in non-free
104
programs enables a greater number of people to use a large body of
105
free software. For example, permission to use the GNU C Library in
106
non-free programs enables many more people to use the whole GNU
107
operating system, as well as its variant, the GNU/Linux operating
108
system.
109
110
Although the Lesser General Public License is Less protective of the
111
users' freedom, it does ensure that the user of a program that is
112
linked with the Library has the freedom and the wherewithal to run
113
that program using a modified version of the Library.
114
115
The precise terms and conditions for copying, distribution and
116
modification follow. Pay close attention to the difference between a
117
"work based on the library" and a "work that uses the library". The
118
former contains code derived from the library, whereas the latter must
119
be combined with the library in order to run.
120
121
GNU LESSER GENERAL PUBLIC LICENSE
122
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
123
124
0. This License Agreement applies to any software library or other
125
program which contains a notice placed by the copyright holder or
126
other authorized party saying it may be distributed under the terms of
127
this Lesser General Public License (also called "this License").
128
Each licensee is addressed as "you".
129
130
A "library" means a collection of software functions and/or data
131
prepared so as to be conveniently linked with application programs
132
(which use some of those functions and data) to form executables.
133
134
The "Library", below, refers to any such software library or work
135
which has been distributed under these terms. A "work based on the
136
Library" means either the Library or any derivative work under
137
copyright law: that is to say, a work containing the Library or a
138
portion of it, either verbatim or with modifications and/or translated
139
straightforwardly into another language. (Hereinafter, translation is
140
included without limitation in the term "modification".)
141
142
"Source code" for a work means the preferred form of the work for
143
making modifications to it. For a library, complete source code means
144
all the source code for all modules it contains, plus any associated
145
interface definition files, plus the scripts used to control compilation
146
and installation of the library.
147
148
Activities other than copying, distribution and modification are not
149
covered by this License; they are outside its scope. The act of
150
running a program using the Library is not restricted, and output from
151
such a program is covered only if its contents constitute a work based
152
on the Library (independent of the use of the Library in a tool for
153
writing it). Whether that is true depends on what the Library does
154
and what the program that uses the Library does.
155
156
1. You may copy and distribute verbatim copies of the Library's
157
complete source code as you receive it, in any medium, provided that
158
you conspicuously and appropriately publish on each copy an
159
appropriate copyright notice and disclaimer of warranty; keep intact
160
all the notices that refer to this License and to the absence of any
161
warranty; and distribute a copy of this License along with the
162
Library.
163
164
You may charge a fee for the physical act of transferring a copy,
165
and you may at your option offer warranty protection in exchange for a
166
fee.
167
168
2. You may modify your copy or copies of the Library or any portion
169
of it, thus forming a work based on the Library, and copy and
170
distribute such modifications or work under the terms of Section 1
171
above, provided that you also meet all of these conditions:
172
173
a) The modified work must itself be a software library.
174
175
b) You must cause the files modified to carry prominent notices
176
stating that you changed the files and the date of any change.
177
178
c) You must cause the whole of the work to be licensed at no
179
charge to all third parties under the terms of this License.
180
181
d) If a facility in the modified Library refers to a function or a
182
table of data to be supplied by an application program that uses
183
the facility, other than as an argument passed when the facility
184
is invoked, then you must make a good faith effort to ensure that,
185
in the event an application does not supply such function or
186
table, the facility still operates, and performs whatever part of
187
its purpose remains meaningful.
188
189
(For example, a function in a library to compute square roots has
190
a purpose that is entirely well-defined independent of the
191
application. Therefore, Subsection 2d requires that any
192
application-supplied function or table used by this function must
193
be optional: if the application does not supply it, the square
194
root function must still compute square roots.)
195
196
These requirements apply to the modified work as a whole. If
197
identifiable sections of that work are not derived from the Library,
198
and can be reasonably considered independent and separate works in
199
themselves, then this License, and its terms, do not apply to those
200
sections when you distribute them as separate works. But when you
201
distribute the same sections as part of a whole which is a work based
202
on the Library, the distribution of the whole must be on the terms of
203
this License, whose permissions for other licensees extend to the
204
entire whole, and thus to each and every part regardless of who wrote
205
it.
206
207
Thus, it is not the intent of this section to claim rights or contest
208
your rights to work written entirely by you; rather, the intent is to
209
exercise the right to control the distribution of derivative or
210
collective works based on the Library.
211
212
In addition, mere aggregation of another work not based on the Library
213
with the Library (or with a work based on the Library) on a volume of
214
a storage or distribution medium does not bring the other work under
215
the scope of this License.
216
217
3. You may opt to apply the terms of the ordinary GNU General Public
218
License instead of this License to a given copy of the Library. To do
219
this, you must alter all the notices that refer to this License, so
220
that they refer to the ordinary GNU General Public License, version 2,
221
instead of to this License. (If a newer version than version 2 of the
222
ordinary GNU General Public License has appeared, then you can specify
223
that version instead if you wish.) Do not make any other change in
224
these notices.
225
226
Once this change is made in a given copy, it is irreversible for
227
that copy, so the ordinary GNU General Public License applies to all
228
subsequent copies and derivative works made from that copy.
229
230
This option is useful when you wish to copy part of the code of
231
the Library into a program that is not a library.
232
233
4. You may copy and distribute the Library (or a portion or
234
derivative of it, under Section 2) in object code or executable form
235
under the terms of Sections 1 and 2 above provided that you accompany
236
it with the complete corresponding machine-readable source code, which
237
must be distributed under the terms of Sections 1 and 2 above on a
238
medium customarily used for software interchange.
239
240
If distribution of object code is made by offering access to copy
241
from a designated place, then offering equivalent access to copy the
242
source code from the same place satisfies the requirement to
243
distribute the source code, even though third parties are not
244
compelled to copy the source along with the object code.
245
246
5. A program that contains no derivative of any portion of the
247
Library, but is designed to work with the Library by being compiled or
248
linked with it, is called a "work that uses the Library". Such a
249
work, in isolation, is not a derivative work of the Library, and
250
therefore falls outside the scope of this License.
251
252
However, linking a "work that uses the Library" with the Library
253
creates an executable that is a derivative of the Library (because it
254
contains portions of the Library), rather than a "work that uses the
255
library". The executable is therefore covered by this License.
256
Section 6 states terms for distribution of such executables.
257
258
When a "work that uses the Library" uses material from a header file
259
that is part of the Library, the object code for the work may be a
260
derivative work of the Library even though the source code is not.
261
Whether this is true is especially significant if the work can be
262
linked without the Library, or if the work is itself a library. The
263
threshold for this to be true is not precisely defined by law.
264
265
If such an object file uses only numerical parameters, data
266
structure layouts and accessors, and small macros and small inline
267
functions (ten lines or less in length), then the use of the object
268
file is unrestricted, regardless of whether it is legally a derivative
269
work. (Executables containing this object code plus portions of the
270
Library will still fall under Section 6.)
271
272
Otherwise, if the work is a derivative of the Library, you may
273
distribute the object code for the work under the terms of Section 6.
274
Any executables containing that work also fall under Section 6,
275
whether or not they are linked directly with the Library itself.
276
277
6. As an exception to the Sections above, you may also combine or
278
link a "work that uses the Library" with the Library to produce a
279
work containing portions of the Library, and distribute that work
280
under terms of your choice, provided that the terms permit
281
modification of the work for the customer's own use and reverse
282
engineering for debugging such modifications.
283
284
You must give prominent notice with each copy of the work that the
285
Library is used in it and that the Library and its use are covered by
286
this License. You must supply a copy of this License. If the work
287
during execution displays copyright notices, you must include the
288
copyright notice for the Library among them, as well as a reference
289
directing the user to the copy of this License. Also, you must do one
290
of these things:
291
292
a) Accompany the work with the complete corresponding
293
machine-readable source code for the Library including whatever
294
changes were used in the work (which must be distributed under
295
Sections 1 and 2 above); and, if the work is an executable linked
296
with the Library, with the complete machine-readable "work that
297
uses the Library", as object code and/or source code, so that the
298
user can modify the Library and then relink to produce a modified
299
executable containing the modified Library. (It is understood
300
that the user who changes the contents of definitions files in the
301
Library will not necessarily be able to recompile the application
302
to use the modified definitions.)
303
304
b) Use a suitable shared library mechanism for linking with the
305
Library. A suitable mechanism is one that (1) uses at run time a
306
copy of the library already present on the user's computer system,
307
rather than copying library functions into the executable, and (2)
308
will operate properly with a modified version of the library, if
309
the user installs one, as long as the modified version is
310
interface-compatible with the version that the work was made with.
311
312
c) Accompany the work with a written offer, valid for at
313
least three years, to give the same user the materials
314
specified in Subsection 6a, above, for a charge no more
315
than the cost of performing this distribution.
316
317
d) If distribution of the work is made by offering access to copy
318
from a designated place, offer equivalent access to copy the above
319
specified materials from the same place.
320
321
e) Verify that the user has already received a copy of these
322
materials or that you have already sent this user a copy.
323
324
For an executable, the required form of the "work that uses the
325
Library" must include any data and utility programs needed for
326
reproducing the executable from it. However, as a special exception,
327
the materials to be distributed need not include anything that is
328
normally distributed (in either source or binary form) with the major
329
components (compiler, kernel, and so on) of the operating system on
330
which the executable runs, unless that component itself accompanies
331
the executable.
332
333
It may happen that this requirement contradicts the license
334
restrictions of other proprietary libraries that do not normally
335
accompany the operating system. Such a contradiction means you cannot
336
use both them and the Library together in an executable that you
337
distribute.
338
339
7. You may place library facilities that are a work based on the
340
Library side-by-side in a single library together with other library
341
facilities not covered by this License, and distribute such a combined
342
library, provided that the separate distribution of the work based on
343
the Library and of the other library facilities is otherwise
344
permitted, and provided that you do these two things:
345
346
a) Accompany the combined library with a copy of the same work
347
based on the Library, uncombined with any other library
348
facilities. This must be distributed under the terms of the
349
Sections above.
350
351
b) Give prominent notice with the combined library of the fact
352
that part of it is a work based on the Library, and explaining
353
where to find the accompanying uncombined form of the same work.
354
355
8. You may not copy, modify, sublicense, link with, or distribute
356
the Library except as expressly provided under this License. Any
357
attempt otherwise to copy, modify, sublicense, link with, or
358
distribute the Library is void, and will automatically terminate your
359
rights under this License. However, parties who have received copies,
360
or rights, from you under this License will not have their licenses
361
terminated so long as such parties remain in full compliance.
362
363
9. You are not required to accept this License, since you have not
364
signed it. However, nothing else grants you permission to modify or
365
distribute the Library or its derivative works. These actions are
366
prohibited by law if you do not accept this License. Therefore, by
367
modifying or distributing the Library (or any work based on the
368
Library), you indicate your acceptance of this License to do so, and
369
all its terms and conditions for copying, distributing or modifying
370
the Library or works based on it.
371
372
10. Each time you redistribute the Library (or any work based on the
373
Library), the recipient automatically receives a license from the
374
original licensor to copy, distribute, link with or modify the Library
375
subject to these terms and conditions. You may not impose any further
376
restrictions on the recipients' exercise of the rights granted herein.
377
You are not responsible for enforcing compliance by third parties with
378
this License.
379
380
11. If, as a consequence of a court judgment or allegation of patent
381
infringement or for any other reason (not limited to patent issues),
382
conditions are imposed on you (whether by court order, agreement or
383
otherwise) that contradict the conditions of this License, they do not
384
excuse you from the conditions of this License. If you cannot
385
distribute so as to satisfy simultaneously your obligations under this
386
License and any other pertinent obligations, then as a consequence you
387
may not distribute the Library at all. For example, if a patent
388
license would not permit royalty-free redistribution of the Library by
389
all those who receive copies directly or indirectly through you, then
390
the only way you could satisfy both it and this License would be to
391
refrain entirely from distribution of the Library.
392
393
If any portion of this section is held invalid or unenforceable under any
394
particular circumstance, the balance of the section is intended to apply,
395
and the section as a whole is intended to apply in other circumstances.
396
397
It is not the purpose of this section to induce you to infringe any
398
patents or other property right claims or to contest validity of any
399
such claims; this section has the sole purpose of protecting the
400
integrity of the free software distribution system which is
401
implemented by public license practices. Many people have made
402
generous contributions to the wide range of software distributed
403
through that system in reliance on consistent application of that
404
system; it is up to the author/donor to decide if he or she is willing
405
to distribute software through any other system and a licensee cannot
406
impose that choice.
407
408
This section is intended to make thoroughly clear what is believed to
409
be a consequence of the rest of this License.
410
411
12. If the distribution and/or use of the Library is restricted in
412
certain countries either by patents or by copyrighted interfaces, the
413
original copyright holder who places the Library under this License may add
414
an explicit geographical distribution limitation excluding those countries,
415
so that distribution is permitted only in or among countries not thus
416
excluded. In such case, this License incorporates the limitation as if
417
written in the body of this License.
418
419
13. The Free Software Foundation may publish revised and/or new
420
versions of the Lesser General Public License from time to time.
421
Such new versions will be similar in spirit to the present version,
422
but may differ in detail to address new problems or concerns.
423
424
Each version is given a distinguishing version number. If the Library
425
specifies a version number of this License which applies to it and
426
"any later version", you have the option of following the terms and
427
conditions either of that version or of any later version published by
428
the Free Software Foundation. If the Library does not specify a
429
license version number, you may choose any version ever published by
430
the Free Software Foundation.
431
432
14. If you wish to incorporate parts of the Library into other free
433
programs whose distribution conditions are incompatible with these,
434
write to the author to ask for permission. For software which is
435
copyrighted by the Free Software Foundation, write to the Free
436
Software Foundation; we sometimes make exceptions for this. Our
437
decision will be guided by the two goals of preserving the free status
438
of all derivatives of our free software and of promoting the sharing
439
and reuse of software generally.
440
441
NO WARRANTY
442
443
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
444
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
445
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
446
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
447
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
448
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
449
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
450
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
451
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
452
453
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
454
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
455
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
456
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
457
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
458
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
459
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
460
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
461
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
462
DAMAGES.
463
464
END OF TERMS AND CONDITIONS
465
466
How to Apply These Terms to Your New Libraries
467
468
If you develop a new library, and you want it to be of the greatest
469
possible use to the public, we recommend making it free software that
470
everyone can redistribute and change. You can do so by permitting
471
redistribution under these terms (or, alternatively, under the terms of the
472
ordinary General Public License).
473
474
To apply these terms, attach the following notices to the library. It is
475
safest to attach them to the start of each source file to most effectively
476
convey the exclusion of warranty; and each file should have at least the
477
"copyright" line and a pointer to where the full notice is found.
478
479
<one line to give the library's name and a brief idea of what it does.>
480
Copyright (C) <year> <name of author>
481
482
This library is free software; you can redistribute it and/or
483
modify it under the terms of the GNU Lesser General Public
484
License as published by the Free Software Foundation; either
485
version 2.1 of the License, or (at your option) any later version.
486
487
This library is distributed in the hope that it will be useful,
488
but WITHOUT ANY WARRANTY; without even the implied warranty of
489
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
490
Lesser General Public License for more details.
491
492
You should have received a copy of the GNU Lesser General Public
493
License along with this library; if not, write to the Free Software
494
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
495
496
Also add information on how to contact you by electronic and paper mail.
497
498
You should also get your employer (if you work as a programmer) or your
499
school, if any, to sign a "copyright disclaimer" for the library, if
500
necessary. Here is a sample; alter the names:
501
502
Yoyodyne, Inc., hereby disclaims all copyright interest in the
503
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
504
505
<signature of Ty Coon>, 1 April 1990
506
Ty Coon, President of Vice
507
508
That's all there is to it!
509
510
*/
511
512
#define HAVE_UNISTD_H 1
513
#if defined __BIG_ENDIAN__
514
# define WORDS_BIGENDIAN 1
515
#endif
516
#include <stdlib.h>
517
518
// file: Features.h
519
/*
520
Audio File Library
521
Copyright (C) 2013 Michael Pruett <[email protected]>
522
523
This library is free software; you can redistribute it and/or
524
modify it under the terms of the GNU Lesser General Public
525
License as published by the Free Software Foundation; either
526
version 2.1 of the License, or (at your option) any later version.
527
528
This library is distributed in the hope that it will be useful,
529
but WITHOUT ANY WARRANTY; without even the implied warranty of
530
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
531
Lesser General Public License for more details.
532
533
You should have received a copy of the GNU Lesser General Public
534
License along with this library; if not, write to the
535
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
536
Boston, MA 02110-1301 USA
537
*/
538
539
#ifndef Features_h
540
#define Features_h
541
542
#define ENABLE(FEATURE) (defined ENABLE_##FEATURE && ENABLE_##FEATURE)
543
544
#endif
545
546
// file: Compiler.h
547
/*
548
Audio File Library
549
Copyright (C) 2013 Michael Pruett <[email protected]>
550
551
This library is free software; you can redistribute it and/or
552
modify it under the terms of the GNU Lesser General Public
553
License as published by the Free Software Foundation; either
554
version 2.1 of the License, or (at your option) any later version.
555
556
This library is distributed in the hope that it will be useful,
557
but WITHOUT ANY WARRANTY; without even the implied warranty of
558
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
559
Lesser General Public License for more details.
560
561
You should have received a copy of the GNU Lesser General Public
562
License along with this library; if not, write to the
563
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
564
Boston, MA 02110-1301 USA
565
*/
566
567
#ifndef COMPILER_H
568
#define COMPILER_H
569
570
#if defined(__GNUC__) && !defined(__clang__)
571
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
572
#define GCC_VERSION_AT_LEAST(major, minor, patch) \
573
(GCC_VERSION >= (major * 10000 + minor * 100 + patch))
574
#if GCC_VERSION_AT_LEAST(4, 7, 0) && defined(__cplusplus) && __cplusplus >= 201103L
575
#define OVERRIDE override
576
#endif
577
#endif
578
579
#if defined(__clang__)
580
#if __has_extension(cxx_override_control)
581
#define OVERRRIDE override
582
#endif
583
#endif
584
585
#ifndef OVERRIDE
586
#define OVERRIDE
587
#endif
588
589
#endif
590
591
// file: error.h
592
/*
593
Audio File Library
594
Copyright (C) 1998, Michael Pruett <[email protected]>
595
596
This library is free software; you can redistribute it and/or
597
modify it under the terms of the GNU Lesser General Public
598
License as published by the Free Software Foundation; either
599
version 2.1 of the License, or (at your option) any later version.
600
601
This library is distributed in the hope that it will be useful,
602
but WITHOUT ANY WARRANTY; without even the implied warranty of
603
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
604
Lesser General Public License for more details.
605
606
You should have received a copy of the GNU Lesser General Public
607
License along with this library; if not, write to the
608
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
609
Boston, MA 02110-1301 USA
610
*/
611
612
#ifndef ERROR_H
613
#define ERROR_H
614
615
#ifdef __cplusplus
616
extern "C" {
617
#endif
618
619
#if !defined(__GNUC__) && !defined(__clang__) && !defined(__attribute__)
620
#define __attribute__(x)
621
#endif
622
623
void _af_error (int errorCode, const char *fmt, ...)
624
__attribute__((format(printf, 2, 3)));
625
626
#ifdef __cplusplus
627
}
628
#endif
629
630
#endif
631
632
// file: extended.h
633
/*
634
Audio File Library
635
Copyright (C) 1998, Michael Pruett <[email protected]>
636
637
This library is free software; you can redistribute it and/or
638
modify it under the terms of the GNU Lesser General Public
639
License as published by the Free Software Foundation; either
640
version 2.1 of the License, or (at your option) any later version.
641
642
This library is distributed in the hope that it will be useful,
643
but WITHOUT ANY WARRANTY; without even the implied warranty of
644
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
645
Lesser General Public License for more details.
646
647
You should have received a copy of the GNU Lesser General Public
648
License along with this library; if not, write to the
649
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
650
Boston, MA 02110-1301 USA
651
*/
652
653
/*
654
extended.h
655
656
This file defines interfaces to Apple's extended floating-point
657
conversion routines.
658
*/
659
660
#ifndef EXTENDED_H
661
#define EXTENDED_H
662
663
#ifdef __cplusplus
664
extern "C" {
665
#endif
666
667
void _af_convert_to_ieee_extended (double num, unsigned char *bytes);
668
double _af_convert_from_ieee_extended (const unsigned char *bytes);
669
670
#ifdef __cplusplus
671
}
672
#endif
673
674
#endif
675
676
// file: compression.h
677
/*
678
Audio File Library
679
Copyright (C) 1999, Michael Pruett <[email protected]>
680
Copyright (C) 2000, Silicon Graphics, Inc.
681
682
This library is free software; you can redistribute it and/or
683
modify it under the terms of the GNU Lesser General Public
684
License as published by the Free Software Foundation; either
685
version 2.1 of the License, or (at your option) any later version.
686
687
This library is distributed in the hope that it will be useful,
688
but WITHOUT ANY WARRANTY; without even the implied warranty of
689
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
690
Lesser General Public License for more details.
691
692
You should have received a copy of the GNU Lesser General Public
693
License along with this library; if not, write to the
694
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
695
Boston, MA 02110-1301 USA
696
*/
697
698
/*
699
compression.h
700
*/
701
702
#ifndef COMPRESSION_H
703
#define COMPRESSION_H
704
705
struct CompressionUnit;
706
707
const CompressionUnit *_af_compression_unit_from_id (int compressionid);
708
709
#endif
710
711
// file: aupvinternal.h
712
/*
713
Audio File Library
714
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
715
716
This library is free software; you can redistribute it and/or
717
modify it under the terms of the GNU Lesser General Public
718
License as published by the Free Software Foundation; either
719
version 2.1 of the License, or (at your option) any later version.
720
721
This library is distributed in the hope that it will be useful,
722
but WITHOUT ANY WARRANTY; without even the implied warranty of
723
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
724
Lesser General Public License for more details.
725
726
You should have received a copy of the GNU Lesser General Public
727
License along with this library; if not, write to the
728
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
729
Boston, MA 02110-1301 USA
730
*/
731
732
/*
733
aupvinternal.h
734
735
This file contains the private data structures for the parameter
736
value list data types.
737
*/
738
739
#ifndef AUPVINTERNAL_H
740
#define AUPVINTERNAL_H
741
742
struct _AUpvitem
743
{
744
int valid;
745
int type;
746
int parameter;
747
748
union
749
{
750
long l;
751
double d;
752
void *v;
753
}
754
value;
755
};
756
757
struct _AUpvlist
758
{
759
int valid;
760
size_t count;
761
struct _AUpvitem *items;
762
};
763
764
enum
765
{
766
_AU_VALID_PVLIST = 30932,
767
_AU_VALID_PVITEM = 30933
768
};
769
770
enum
771
{
772
AU_BAD_PVLIST = -5,
773
AU_BAD_PVITEM = -6,
774
AU_BAD_PVTYPE = -7,
775
AU_BAD_ALLOC = -8
776
};
777
778
enum
779
{
780
_AU_FAIL = -1,
781
_AU_SUCCESS = 0
782
};
783
784
#define _AU_NULL_PVITEM ((struct _AUpvitem *) NULL)
785
786
#endif
787
788
// file: aupvlist.h
789
/*
790
Audio File Library
791
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
792
793
This library is free software; you can redistribute it and/or
794
modify it under the terms of the GNU Lesser General Public
795
License as published by the Free Software Foundation; either
796
version 2.1 of the License, or (at your option) any later version.
797
798
This library is distributed in the hope that it will be useful,
799
but WITHOUT ANY WARRANTY; without even the implied warranty of
800
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
801
Lesser General Public License for more details.
802
803
You should have received a copy of the GNU Lesser General Public
804
License along with this library; if not, write to the
805
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
806
Boston, MA 02110-1301 USA
807
*/
808
809
/*
810
aupvlist.h
811
812
This file contains the interface to the parameter value list data
813
structures and routines.
814
*/
815
816
#ifndef AUPVLIST_H
817
#define AUPVLIST_H
818
819
#ifdef __cplusplus
820
extern "C" {
821
#endif
822
823
#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
824
#define AFAPI __attribute__((visibility("default")))
825
#else
826
#define AFAPI
827
#endif
828
829
enum
830
{
831
AU_PVTYPE_LONG = 1,
832
AU_PVTYPE_DOUBLE = 2,
833
AU_PVTYPE_PTR = 3
834
};
835
836
typedef struct _AUpvlist *AUpvlist;
837
838
#define AU_NULL_PVLIST ((struct _AUpvlist *) 0)
839
840
AFAPI AUpvlist AUpvnew (int maxItems);
841
AFAPI int AUpvgetmaxitems (AUpvlist);
842
AFAPI int AUpvfree (AUpvlist);
843
AFAPI int AUpvsetparam (AUpvlist, int item, int param);
844
AFAPI int AUpvsetvaltype (AUpvlist, int item, int type);
845
AFAPI int AUpvsetval (AUpvlist, int item, void *val);
846
AFAPI int AUpvgetparam (AUpvlist, int item, int *param);
847
AFAPI int AUpvgetvaltype (AUpvlist, int item, int *type);
848
AFAPI int AUpvgetval (AUpvlist, int item, void *val);
849
850
#undef AFAPI
851
852
#ifdef __cplusplus
853
}
854
#endif
855
856
#endif /* AUPVLIST_H */
857
858
// file: audiofile.h
859
/*
860
Audio File Library
861
Copyright (C) 1998-2000, 2010-2013 Michael Pruett <[email protected]>
862
863
This library is free software; you can redistribute it and/or
864
modify it under the terms of the GNU Lesser General Public
865
License as published by the Free Software Foundation; either
866
version 2.1 of the License, or (at your option) any later version.
867
868
This library is distributed in the hope that it will be useful,
869
but WITHOUT ANY WARRANTY; without even the implied warranty of
870
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
871
Lesser General Public License for more details.
872
873
You should have received a copy of the GNU Lesser General Public
874
License along with this library; if not, write to the
875
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
876
Boston, MA 02110-1301 USA
877
*/
878
879
/*
880
audiofile.h
881
882
This file contains the public interfaces to the Audio File Library.
883
*/
884
885
#ifndef AUDIOFILE_H
886
#define AUDIOFILE_H
887
888
#include <aupvlist.h>
889
#include <stdint.h>
890
#include <sys/types.h>
891
892
#define LIBAUDIOFILE_MAJOR_VERSION 0
893
#define LIBAUDIOFILE_MINOR_VERSION 3
894
#define LIBAUDIOFILE_MICRO_VERSION 6
895
896
#ifdef __cplusplus
897
extern "C" {
898
#endif
899
900
#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
901
#define AFAPI __attribute__((visibility("default")))
902
#else
903
#define AFAPI
904
#endif
905
906
typedef struct _AFvirtualfile AFvirtualfile;
907
908
typedef struct _AFfilesetup *AFfilesetup;
909
typedef struct _AFfilehandle *AFfilehandle;
910
typedef void (*AFerrfunc)(long, const char *);
911
912
// Define AFframecount and AFfileoffset as 64-bit signed integers.
913
#if defined(__FreeBSD__) || \
914
defined(__DragonFly__) || \
915
defined(__NetBSD__) || \
916
defined(__OpenBSD__) || \
917
defined(__APPLE__) || \
918
defined(__sgi) || \
919
(defined(__linux__) && defined(__LP64__))
920
// BSD and IRIX systems define off_t as a 64-bit signed integer.
921
// Linux defines off_t as a 64-bit signed integer in LP64 mode.
922
typedef off_t AFframecount;
923
typedef off_t AFfileoffset;
924
#else
925
// For all other systems, use int64_t.
926
typedef int64_t AFframecount;
927
typedef int64_t AFfileoffset;
928
#endif
929
930
#define AF_NULL_FILESETUP ((struct _AFfilesetup *) 0)
931
#define AF_NULL_FILEHANDLE ((struct _AFfilehandle *) 0)
932
933
#define AF_ERR_BASE 3000
934
935
enum
936
{
937
AF_DEFAULT_TRACK = 1001
938
};
939
940
enum
941
{
942
AF_DEFAULT_INST = 2001
943
};
944
945
enum
946
{
947
AF_NUM_UNLIMITED = 99999
948
};
949
950
enum
951
{
952
AF_BYTEORDER_BIGENDIAN = 501,
953
AF_BYTEORDER_LITTLEENDIAN = 502
954
};
955
956
enum
957
{
958
AF_FILE_UNKNOWN = -1,
959
AF_FILE_RAWDATA = 0,
960
AF_FILE_AIFFC = 1,
961
AF_FILE_AIFF = 2,
962
AF_FILE_NEXTSND = 3,
963
AF_FILE_WAVE = 4,
964
AF_FILE_BICSF = 5,
965
AF_FILE_IRCAM = AF_FILE_BICSF,
966
AF_FILE_MPEG1BITSTREAM = 6, /* not implemented */
967
AF_FILE_SOUNDDESIGNER1 = 7, /* not implemented */
968
AF_FILE_SOUNDDESIGNER2 = 8, /* not implemented */
969
AF_FILE_AVR = 9,
970
AF_FILE_IFF_8SVX = 10,
971
AF_FILE_SAMPLEVISION = 11,
972
AF_FILE_VOC = 12,
973
AF_FILE_NIST_SPHERE = 13,
974
AF_FILE_SOUNDFONT2 = 14, /* not implemented */
975
AF_FILE_CAF = 15,
976
AF_FILE_FLAC = 16
977
};
978
979
enum
980
{
981
AF_LOOP_MODE_NOLOOP = 0,
982
AF_LOOP_MODE_FORW = 1,
983
AF_LOOP_MODE_FORWBAKW = 2
984
};
985
986
enum
987
{
988
AF_SAMPFMT_TWOSCOMP = 401, /* linear two's complement */
989
AF_SAMPFMT_UNSIGNED = 402, /* unsigned integer */
990
AF_SAMPFMT_FLOAT = 403, /* 32-bit IEEE floating-point */
991
AF_SAMPFMT_DOUBLE = 404 /* 64-bit IEEE double-precision floating-point */
992
};
993
994
enum
995
{
996
AF_INST_LOOP_OFF = 0, /* no looping */
997
AF_INST_LOOP_CONTINUOUS = 1, /* loop continuously through decay */
998
AF_INST_LOOP_SUSTAIN = 3 /* loop during sustain, then continue */
999
};
1000
1001
enum
1002
{
1003
AF_INST_MIDI_BASENOTE = 301,
1004
AF_INST_NUMCENTS_DETUNE = 302,
1005
AF_INST_MIDI_LONOTE = 303,
1006
AF_INST_MIDI_HINOTE = 304,
1007
AF_INST_MIDI_LOVELOCITY = 305,
1008
AF_INST_MIDI_HIVELOCITY = 306,
1009
AF_INST_NUMDBS_GAIN = 307,
1010
AF_INST_SUSLOOPID = 308, /* loop id for AIFF sustain loop */
1011
AF_INST_RELLOOPID = 309, /* loop id for AIFF release loop */
1012
AF_INST_SAMP_STARTFRAME = 310, /* start sample for this inst */
1013
AF_INST_SAMP_ENDFRAME = 311, /* end sample for this inst */
1014
AF_INST_SAMP_MODE = 312, /* looping mode for this inst */
1015
AF_INST_TRACKID = 313,
1016
AF_INST_NAME = 314, /* name of this inst */
1017
AF_INST_SAMP_RATE = 315, /* sample rate of this inst's sample */
1018
AF_INST_PRESETID = 316, /* ID of preset containing this inst */
1019
AF_INST_PRESET_NAME = 317 /* name of preset containing this inst */
1020
};
1021
1022
enum
1023
{
1024
AF_MISC_UNRECOGNIZED = 0, /* unrecognized data chunk */
1025
AF_MISC_COPY = 201, /* copyright string */
1026
AF_MISC_AUTH = 202, /* author string */
1027
AF_MISC_NAME = 203, /* name string */
1028
AF_MISC_ANNO = 204, /* annotation string */
1029
AF_MISC_APPL = 205, /* application-specific data */
1030
AF_MISC_MIDI = 206, /* MIDI exclusive data */
1031
AF_MISC_PCMMAP = 207, /* PCM mapping information (future use) */
1032
AF_MISC_NeXT = 208, /* misc binary data appended to NeXT header */
1033
AF_MISC_IRCAM_PEAKAMP = 209, /* peak amplitude information */
1034
AF_MISC_IRCAM_COMMENT = 210, /* BICSF text comment */
1035
AF_MISC_COMMENT = 210, /* general text comment */
1036
1037
AF_MISC_ICMT = AF_MISC_COMMENT, /* comments chunk (WAVE format) */
1038
AF_MISC_ICRD = 211, /* creation date (WAVE format) */
1039
AF_MISC_ISFT = 212 /* software name (WAVE format) */
1040
};
1041
1042
enum
1043
{
1044
/* supported compression schemes */
1045
AF_COMPRESSION_UNKNOWN = -1,
1046
AF_COMPRESSION_NONE = 0,
1047
AF_COMPRESSION_G722 = 501,
1048
AF_COMPRESSION_G711_ULAW = 502,
1049
AF_COMPRESSION_G711_ALAW = 503,
1050
1051
/* Apple proprietary AIFF-C compression schemes (not supported) */
1052
AF_COMPRESSION_APPLE_ACE2 = 504,
1053
AF_COMPRESSION_APPLE_ACE8 = 505,
1054
AF_COMPRESSION_APPLE_MAC3 = 506,
1055
AF_COMPRESSION_APPLE_MAC6 = 507,
1056
1057
AF_COMPRESSION_G726 = 517,
1058
AF_COMPRESSION_G728 = 518,
1059
AF_COMPRESSION_DVI_AUDIO = 519,
1060
AF_COMPRESSION_IMA = AF_COMPRESSION_DVI_AUDIO,
1061
AF_COMPRESSION_GSM = 520,
1062
AF_COMPRESSION_FS1016 = 521,
1063
AF_COMPRESSION_DV = 522,
1064
AF_COMPRESSION_MS_ADPCM = 523,
1065
1066
AF_COMPRESSION_FLAC = 530,
1067
AF_COMPRESSION_ALAC = 540
1068
};
1069
1070
/* tokens for afQuery() -- see the man page for instructions */
1071
/* level 1 selectors */
1072
enum
1073
{
1074
AF_QUERYTYPE_INSTPARAM = 500,
1075
AF_QUERYTYPE_FILEFMT = 501,
1076
AF_QUERYTYPE_COMPRESSION = 502,
1077
AF_QUERYTYPE_COMPRESSIONPARAM = 503,
1078
AF_QUERYTYPE_MISC = 504,
1079
AF_QUERYTYPE_INST = 505,
1080
AF_QUERYTYPE_MARK = 506,
1081
AF_QUERYTYPE_LOOP = 507
1082
};
1083
1084
/* level 2 selectors */
1085
enum
1086
{
1087
AF_QUERY_NAME = 600, /* get name (1-3 words) */
1088
AF_QUERY_DESC = 601, /* get description */
1089
AF_QUERY_LABEL = 602, /* get 4- or 5-char label */
1090
AF_QUERY_TYPE = 603, /* get type token */
1091
AF_QUERY_DEFAULT = 604, /* dflt. value for param */
1092
AF_QUERY_ID_COUNT = 605, /* get number of ids avail. */
1093
AF_QUERY_IDS = 606, /* get array of id tokens */
1094
AF_QUERY_IMPLEMENTED = 613, /* boolean */
1095
AF_QUERY_TYPE_COUNT = 607, /* get number of types av. */
1096
AF_QUERY_TYPES = 608, /* get array of types */
1097
AF_QUERY_NATIVE_SAMPFMT = 609, /* for compression */
1098
AF_QUERY_NATIVE_SAMPWIDTH = 610,
1099
AF_QUERY_SQUISHFAC = 611, /* 1.0 means variable */
1100
AF_QUERY_MAX_NUMBER = 612, /* max allowed in file */
1101
AF_QUERY_SUPPORTED = 613 /* insts, loops, etc., supported? */
1102
};
1103
1104
/* level 2 selectors which have sub-selectors */
1105
enum
1106
{
1107
AF_QUERY_TRACKS = 620,
1108
AF_QUERY_CHANNELS = 621,
1109
AF_QUERY_SAMPLE_SIZES = 622,
1110
AF_QUERY_SAMPLE_FORMATS = 623,
1111
AF_QUERY_COMPRESSION_TYPES = 624
1112
};
1113
1114
/* level 3 sub-selectors */
1115
enum
1116
{
1117
AF_QUERY_VALUE_COUNT = 650, /* number of values of the above */
1118
AF_QUERY_VALUES = 651 /* array of those values */
1119
};
1120
1121
1122
/*
1123
Old Audio File Library error codes. These are still returned by the
1124
AFerrorhandler calls, but are not used by the new digital media library
1125
error reporting routines. See the bottom of this file for the new error
1126
tokens.
1127
*/
1128
1129
enum
1130
{
1131
AF_BAD_NOT_IMPLEMENTED = 0, /* not implemented yet */
1132
AF_BAD_FILEHANDLE = 1, /* tried to use invalid filehandle */
1133
AF_BAD_OPEN = 3, /* unix open failed */
1134
AF_BAD_CLOSE = 4, /* unix close failed */
1135
AF_BAD_READ = 5, /* unix read failed */
1136
AF_BAD_WRITE = 6, /* unix write failed */
1137
AF_BAD_LSEEK = 7, /* unix lseek failed */
1138
AF_BAD_NO_FILEHANDLE = 8, /* failed to allocate a filehandle struct */
1139
AF_BAD_ACCMODE = 10, /* unrecognized audio file access mode */
1140
AF_BAD_NOWRITEACC = 11, /* file not open for writing */
1141
AF_BAD_NOREADACC = 12, /* file not open for reading */
1142
AF_BAD_FILEFMT = 13, /* unrecognized audio file format */
1143
AF_BAD_RATE = 14, /* invalid sample rate */
1144
AF_BAD_CHANNELS = 15, /* invalid number of channels*/
1145
AF_BAD_SAMPCNT = 16, /* invalid sample count */
1146
AF_BAD_WIDTH = 17, /* invalid sample width */
1147
AF_BAD_SEEKMODE = 18, /* invalid seek mode */
1148
AF_BAD_NO_LOOPDATA = 19, /* failed to allocate loop struct */
1149
AF_BAD_MALLOC = 20, /* malloc failed somewhere */
1150
AF_BAD_LOOPID = 21,
1151
AF_BAD_SAMPFMT = 22, /* bad sample format */
1152
AF_BAD_FILESETUP = 23, /* bad file setup structure*/
1153
AF_BAD_TRACKID = 24, /* no track corresponding to id */
1154
AF_BAD_NUMTRACKS = 25, /* wrong number of tracks for file format */
1155
AF_BAD_NO_FILESETUP = 26, /* failed to allocate a filesetup struct*/
1156
AF_BAD_LOOPMODE = 27, /* unrecognized loop mode value */
1157
AF_BAD_INSTID = 28, /* invalid instrument id */
1158
AF_BAD_NUMLOOPS = 29, /* bad number of loops */
1159
AF_BAD_NUMMARKS = 30, /* bad number of markers */
1160
AF_BAD_MARKID = 31, /* bad marker id */
1161
AF_BAD_MARKPOS = 32, /* invalid marker position value */
1162
AF_BAD_NUMINSTS = 33, /* invalid number of instruments */
1163
AF_BAD_NOAESDATA = 34,
1164
AF_BAD_MISCID = 35,
1165
AF_BAD_NUMMISC = 36,
1166
AF_BAD_MISCSIZE = 37,
1167
AF_BAD_MISCTYPE = 38,
1168
AF_BAD_MISCSEEK = 39,
1169
AF_BAD_STRLEN = 40, /* invalid string length */
1170
AF_BAD_RATECONV = 45,
1171
AF_BAD_SYNCFILE = 46,
1172
AF_BAD_CODEC_CONFIG = 47, /* improperly configured codec */
1173
AF_BAD_CODEC_STATE = 48, /* invalid codec state: can't recover */
1174
AF_BAD_CODEC_LICENSE = 49, /* no license available for codec */
1175
AF_BAD_CODEC_TYPE = 50, /* unsupported codec type */
1176
AF_BAD_COMPRESSION = AF_BAD_CODEC_CONFIG, /* for back compat */
1177
AF_BAD_COMPTYPE = AF_BAD_CODEC_TYPE, /* for back compat */
1178
1179
AF_BAD_INSTPTYPE = 51, /* invalid instrument parameter type */
1180
AF_BAD_INSTPID = 52, /* invalid instrument parameter id */
1181
AF_BAD_BYTEORDER = 53,
1182
AF_BAD_FILEFMT_PARAM = 54, /* unrecognized file format parameter */
1183
AF_BAD_COMP_PARAM = 55, /* unrecognized compression parameter */
1184
AF_BAD_DATAOFFSET = 56, /* bad data offset */
1185
AF_BAD_FRAMECNT = 57, /* bad frame count */
1186
AF_BAD_QUERYTYPE = 58, /* bad query type */
1187
AF_BAD_QUERY = 59, /* bad argument to afQuery() */
1188
AF_WARNING_CODEC_RATE = 60, /* using 8k instead of codec rate 8012 */
1189
AF_WARNING_RATECVT = 61, /* warning about rate conversion used */
1190
1191
AF_BAD_HEADER = 62, /* failed to parse header */
1192
AF_BAD_FRAME = 63, /* bad frame number */
1193
AF_BAD_LOOPCOUNT = 64, /* bad loop count */
1194
AF_BAD_DMEDIA_CALL = 65, /* error in dmedia subsystem call */
1195
1196
/* AIFF/AIFF-C specific errors when parsing file header */
1197
AF_BAD_AIFF_HEADER = 108, /* failed to parse chunk header */
1198
AF_BAD_AIFF_FORM = 109, /* failed to parse FORM chunk */
1199
AF_BAD_AIFF_SSND = 110, /* failed to parse SSND chunk */
1200
AF_BAD_AIFF_CHUNKID = 111, /* unrecognized AIFF/AIFF-C chunk id */
1201
AF_BAD_AIFF_COMM = 112, /* failed to parse COMM chunk */
1202
AF_BAD_AIFF_INST = 113, /* failed to parse INST chunk */
1203
AF_BAD_AIFF_MARK = 114, /* failed to parse MARK chunk */
1204
AF_BAD_AIFF_SKIP = 115, /* failed to skip unsupported chunk */
1205
AF_BAD_AIFF_LOOPMODE = 116 /* unrecognized loop mode (forw, etc)*/
1206
};
1207
1208
/* new error codes which may be retrieved via dmGetError() */
1209
/* The old error tokens continue to be retrievable via the AFerrorhandler */
1210
/* AF_ERR_BASE is #defined in dmedia/dmedia.h */
1211
1212
enum
1213
{
1214
AF_ERR_NOT_IMPLEMENTED = 0+AF_ERR_BASE, /* not implemented yet */
1215
AF_ERR_BAD_FILEHANDLE = 1+AF_ERR_BASE, /* invalid filehandle */
1216
AF_ERR_BAD_READ = 5+AF_ERR_BASE, /* unix read failed */
1217
AF_ERR_BAD_WRITE = 6+AF_ERR_BASE, /* unix write failed */
1218
AF_ERR_BAD_LSEEK = 7+AF_ERR_BASE, /* unix lseek failed */
1219
AF_ERR_BAD_ACCMODE = 10+AF_ERR_BASE, /* unrecognized audio file access mode */
1220
AF_ERR_NO_WRITEACC = 11+AF_ERR_BASE, /* file not open for writing */
1221
AF_ERR_NO_READACC = 12+AF_ERR_BASE, /* file not open for reading */
1222
AF_ERR_BAD_FILEFMT = 13+AF_ERR_BASE, /* unrecognized audio file format */
1223
AF_ERR_BAD_RATE = 14+AF_ERR_BASE, /* invalid sample rate */
1224
AF_ERR_BAD_CHANNELS = 15+AF_ERR_BASE, /* invalid # channels*/
1225
AF_ERR_BAD_SAMPCNT = 16+AF_ERR_BASE, /* invalid sample count */
1226
AF_ERR_BAD_WIDTH = 17+AF_ERR_BASE, /* invalid sample width */
1227
AF_ERR_BAD_SEEKMODE = 18+AF_ERR_BASE, /* invalid seek mode */
1228
AF_ERR_BAD_LOOPID = 21+AF_ERR_BASE, /* invalid loop id */
1229
AF_ERR_BAD_SAMPFMT = 22+AF_ERR_BASE, /* bad sample format */
1230
AF_ERR_BAD_FILESETUP = 23+AF_ERR_BASE, /* bad file setup structure*/
1231
AF_ERR_BAD_TRACKID = 24+AF_ERR_BASE, /* no track corresponding to id */
1232
AF_ERR_BAD_NUMTRACKS = 25+AF_ERR_BASE, /* wrong number of tracks for file format */
1233
AF_ERR_BAD_LOOPMODE = 27+AF_ERR_BASE, /* unrecognized loop mode symbol */
1234
AF_ERR_BAD_INSTID = 28+AF_ERR_BASE, /* invalid instrument id */
1235
AF_ERR_BAD_NUMLOOPS = 29+AF_ERR_BASE, /* bad number of loops */
1236
AF_ERR_BAD_NUMMARKS = 30+AF_ERR_BASE, /* bad number of markers */
1237
AF_ERR_BAD_MARKID = 31+AF_ERR_BASE, /* bad marker id */
1238
AF_ERR_BAD_MARKPOS = 32+AF_ERR_BASE, /* invalid marker position value */
1239
AF_ERR_BAD_NUMINSTS = 33+AF_ERR_BASE, /* invalid number of instruments */
1240
AF_ERR_BAD_NOAESDATA = 34+AF_ERR_BASE,
1241
AF_ERR_BAD_MISCID = 35+AF_ERR_BASE,
1242
AF_ERR_BAD_NUMMISC = 36+AF_ERR_BASE,
1243
AF_ERR_BAD_MISCSIZE = 37+AF_ERR_BASE,
1244
AF_ERR_BAD_MISCTYPE = 38+AF_ERR_BASE,
1245
AF_ERR_BAD_MISCSEEK = 39+AF_ERR_BASE,
1246
AF_ERR_BAD_STRLEN = 40+AF_ERR_BASE, /* invalid string length */
1247
AF_ERR_BAD_RATECONV = 45+AF_ERR_BASE,
1248
AF_ERR_BAD_SYNCFILE = 46+AF_ERR_BASE,
1249
AF_ERR_BAD_CODEC_CONFIG = 47+AF_ERR_BASE, /* improperly configured codec */
1250
AF_ERR_BAD_CODEC_TYPE = 50+AF_ERR_BASE, /* unsupported codec type */
1251
AF_ERR_BAD_INSTPTYPE = 51+AF_ERR_BASE, /* invalid instrument parameter type */
1252
AF_ERR_BAD_INSTPID = 52+AF_ERR_BASE, /* invalid instrument parameter id */
1253
1254
AF_ERR_BAD_BYTEORDER = 53+AF_ERR_BASE,
1255
AF_ERR_BAD_FILEFMT_PARAM = 54+AF_ERR_BASE, /* unrecognized file format parameter */
1256
AF_ERR_BAD_COMP_PARAM = 55+AF_ERR_BASE, /* unrecognized compression parameter */
1257
AF_ERR_BAD_DATAOFFSET = 56+AF_ERR_BASE, /* bad data offset */
1258
AF_ERR_BAD_FRAMECNT = 57+AF_ERR_BASE, /* bad frame count */
1259
1260
AF_ERR_BAD_QUERYTYPE = 58+AF_ERR_BASE, /* bad query type */
1261
AF_ERR_BAD_QUERY = 59+AF_ERR_BASE, /* bad argument to afQuery() */
1262
AF_ERR_BAD_HEADER = 62+AF_ERR_BASE, /* failed to parse header */
1263
AF_ERR_BAD_FRAME = 63+AF_ERR_BASE, /* bad frame number */
1264
AF_ERR_BAD_LOOPCOUNT = 64+AF_ERR_BASE, /* bad loop count */
1265
1266
/* AIFF/AIFF-C specific errors when parsing file header */
1267
1268
AF_ERR_BAD_AIFF_HEADER = 66+AF_ERR_BASE, /* failed to parse chunk header */
1269
AF_ERR_BAD_AIFF_FORM = 67+AF_ERR_BASE, /* failed to parse FORM chunk */
1270
AF_ERR_BAD_AIFF_SSND = 68+AF_ERR_BASE, /* failed to parse SSND chunk */
1271
AF_ERR_BAD_AIFF_CHUNKID = 69+AF_ERR_BASE, /* unrecognized AIFF/AIFF-C chunk id */
1272
AF_ERR_BAD_AIFF_COMM = 70+AF_ERR_BASE, /* failed to parse COMM chunk */
1273
AF_ERR_BAD_AIFF_INST = 71+AF_ERR_BASE, /* failed to parse INST chunk */
1274
AF_ERR_BAD_AIFF_MARK = 72+AF_ERR_BASE, /* failed to parse MARK chunk */
1275
AF_ERR_BAD_AIFF_SKIP = 73+AF_ERR_BASE, /* failed to skip unsupported chunk */
1276
AF_ERR_BAD_AIFF_LOOPMODE = 74+AF_ERR_BASE /* unrecognized loop mode (forw, etc) */
1277
};
1278
1279
1280
/* global routines */
1281
AFAPI AFerrfunc afSetErrorHandler (AFerrfunc efunc);
1282
1283
/* query routines */
1284
AFAPI AUpvlist afQuery (int querytype, int arg1, int arg2, int arg3, int arg4);
1285
AFAPI long afQueryLong (int querytype, int arg1, int arg2, int arg3, int arg4);
1286
AFAPI double afQueryDouble (int querytype, int arg1, int arg2, int arg3, int arg4);
1287
AFAPI void *afQueryPointer (int querytype, int arg1, int arg2, int arg3, int arg4);
1288
1289
/* basic operations on file handles and file setups */
1290
AFAPI AFfilesetup afNewFileSetup (void);
1291
AFAPI void afFreeFileSetup (AFfilesetup);
1292
AFAPI int afIdentifyFD (int);
1293
AFAPI int afIdentifyNamedFD (int, const char *filename, int *implemented);
1294
1295
AFAPI AFfilehandle afOpenFile (const char *filename, const char *mode,
1296
AFfilesetup setup);
1297
AFAPI AFfilehandle afOpenVirtualFile (AFvirtualfile *vfile, const char *mode,
1298
AFfilesetup setup);
1299
AFAPI AFfilehandle afOpenFD (int fd, const char *mode, AFfilesetup setup);
1300
AFAPI AFfilehandle afOpenNamedFD (int fd, const char *mode, AFfilesetup setup,
1301
const char *filename);
1302
1303
AFAPI void afSaveFilePosition (AFfilehandle file);
1304
AFAPI void afRestoreFilePosition (AFfilehandle file);
1305
AFAPI int afSyncFile (AFfilehandle file);
1306
AFAPI int afCloseFile (AFfilehandle file);
1307
1308
AFAPI void afInitFileFormat (AFfilesetup, int format);
1309
AFAPI int afGetFileFormat (AFfilehandle, int *version);
1310
1311
/* track */
1312
AFAPI void afInitTrackIDs (AFfilesetup, const int *trackids, int trackCount);
1313
AFAPI int afGetTrackIDs (AFfilehandle, int *trackids);
1314
1315
/* track data: reading, writng, seeking, sizing frames */
1316
AFAPI int afReadFrames (AFfilehandle, int track, void *buffer, int frameCount);
1317
AFAPI int afWriteFrames (AFfilehandle, int track, const void *buffer, int frameCount);
1318
AFAPI AFframecount afSeekFrame (AFfilehandle, int track, AFframecount frameoffset);
1319
AFAPI AFframecount afTellFrame (AFfilehandle, int track);
1320
AFAPI AFfileoffset afGetTrackBytes (AFfilehandle, int track);
1321
AFAPI float afGetFrameSize (AFfilehandle, int track, int expand3to4);
1322
AFAPI float afGetVirtualFrameSize (AFfilehandle, int track, int expand3to4);
1323
1324
/* track data: AES data */
1325
/* afInitAESChannelData is obsolete -- use afInitAESChannelDataTo() */
1326
AFAPI void afInitAESChannelData (AFfilesetup, int track); /* obsolete */
1327
AFAPI void afInitAESChannelDataTo (AFfilesetup, int track, int willBeData);
1328
AFAPI int afGetAESChannelData (AFfilehandle, int track, unsigned char buf[24]);
1329
AFAPI void afSetAESChannelData (AFfilehandle, int track, unsigned char buf[24]);
1330
1331
/* track data: byte order */
1332
AFAPI void afInitByteOrder (AFfilesetup, int track, int byteOrder);
1333
AFAPI int afGetByteOrder (AFfilehandle, int track);
1334
AFAPI int afSetVirtualByteOrder (AFfilehandle, int track, int byteOrder);
1335
AFAPI int afGetVirtualByteOrder (AFfilehandle, int track);
1336
1337
/* track data: number of channels */
1338
AFAPI void afInitChannels (AFfilesetup, int track, int nchannels);
1339
AFAPI int afGetChannels (AFfilehandle, int track);
1340
AFAPI int afSetVirtualChannels (AFfilehandle, int track, int channelCount);
1341
AFAPI int afGetVirtualChannels (AFfilehandle, int track);
1342
AFAPI void afSetChannelMatrix (AFfilehandle, int track, double *matrix);
1343
1344
/* track data: sample format and sample width */
1345
AFAPI void afInitSampleFormat (AFfilesetup, int track, int sampleFormat,
1346
int sampleWidth);
1347
AFAPI void afGetSampleFormat (AFfilehandle file, int track, int *sampleFormat,
1348
int *sampleWidth);
1349
AFAPI int afSetVirtualSampleFormat (AFfilehandle, int track,
1350
int sampleFormat, int sampleWidth);
1351
AFAPI void afGetVirtualSampleFormat (AFfilehandle, int track,
1352
int *sampleFormat, int *sampleWidth);
1353
1354
/* track data: sampling rate */
1355
AFAPI void afInitRate (AFfilesetup, int track, double rate);
1356
AFAPI double afGetRate (AFfilehandle, int track);
1357
1358
#if 0
1359
int afSetVirtualRate (AFfilehandle, int track, double rate);
1360
double afGetVirtualRate (AFfilehandle, int track);
1361
#endif
1362
1363
/* track data: compression */
1364
AFAPI void afInitCompression (AFfilesetup, int track, int compression);
1365
#if 0
1366
void afInitCompressionParams (AFfilesetup, int track, int compression
1367
AUpvlist params, int parameterCount);
1368
#endif
1369
1370
AFAPI int afGetCompression (AFfilehandle, int track);
1371
#if 0
1372
void afGetCompressionParams (AFfilehandle, int track, int *compression,
1373
AUpvlist params, int parameterCount);
1374
1375
int afSetVirtualCompression (AFfilesetup, int track, int compression);
1376
void afSetVirtualCompressionParams (AFfilehandle, int track, int compression,
1377
AUpvlist params, int parameterCount);
1378
1379
int afGetVirtualCompression (AFfilesetup, int track, int compression);
1380
void afGetVirtualCompressionParams (AFfilehandle, int track, int *compression,
1381
AUpvlist params, int parameterCount);
1382
#endif
1383
1384
/* track data: pcm mapping */
1385
AFAPI void afInitPCMMapping (AFfilesetup filesetup, int track,
1386
double slope, double intercept, double minClip, double maxClip);
1387
AFAPI void afGetPCMMapping (AFfilehandle file, int track,
1388
double *slope, double *intercept, double *minClip, double *maxClip);
1389
/* NOTE: afSetTrackPCMMapping() is special--it does not set the virtual */
1390
/* format; it changes what the AF thinks the track format is! Be careful. */
1391
AFAPI int afSetTrackPCMMapping (AFfilehandle file, int track,
1392
double slope, double intercept, double minClip, double maxClip);
1393
/* NOTE: afSetVirtualPCMMapping() is different from afSetTrackPCMMapping(): */
1394
/* see comment for afSetTrackPCMMapping(). */
1395
AFAPI int afSetVirtualPCMMapping (AFfilehandle file, int track,
1396
double slope, double intercept, double minClip, double maxClip);
1397
AFAPI void afGetVirtualPCMMapping (AFfilehandle file, int track,
1398
double *slope, double *intercept, double *minClip, double *maxClip);
1399
1400
/* track data: data offset within the file */
1401
/* initialize for raw reading only */
1402
AFAPI void afInitDataOffset(AFfilesetup, int track, AFfileoffset offset);
1403
AFAPI AFfileoffset afGetDataOffset (AFfilehandle, int track);
1404
1405
/* track data: count of frames in file */
1406
AFAPI void afInitFrameCount (AFfilesetup, int track, AFframecount frameCount);
1407
AFAPI AFframecount afGetFrameCount (AFfilehandle file, int track);
1408
1409
/* loop operations */
1410
AFAPI void afInitLoopIDs (AFfilesetup, int instid, const int *ids, int nids);
1411
AFAPI int afGetLoopIDs (AFfilehandle, int instid, int loopids[]);
1412
AFAPI void afSetLoopMode (AFfilehandle, int instid, int loop, int mode);
1413
AFAPI int afGetLoopMode (AFfilehandle, int instid, int loopid);
1414
AFAPI int afSetLoopCount (AFfilehandle, int instid, int loop, int count);
1415
AFAPI int afGetLoopCount (AFfilehandle, int instid, int loopid);
1416
AFAPI void afSetLoopStart (AFfilehandle, int instid, int loopid, int markerid);
1417
AFAPI int afGetLoopStart (AFfilehandle, int instid, int loopid);
1418
AFAPI void afSetLoopEnd (AFfilehandle, int instid, int loopid, int markerid);
1419
AFAPI int afGetLoopEnd (AFfilehandle, int instid, int loopid);
1420
1421
AFAPI int afSetLoopStartFrame (AFfilehandle, int instid, int loop,
1422
AFframecount startFrame);
1423
AFAPI AFframecount afGetLoopStartFrame (AFfilehandle, int instid, int loop);
1424
AFAPI int afSetLoopEndFrame (AFfilehandle, int instid, int loop,
1425
AFframecount startFrame);
1426
AFAPI AFframecount afGetLoopEndFrame (AFfilehandle, int instid, int loop);
1427
1428
AFAPI void afSetLoopTrack (AFfilehandle, int instid, int loopid, int trackid);
1429
AFAPI int afGetLoopTrack (AFfilehandle, int instid, int loopid);
1430
1431
/* marker operations */
1432
AFAPI void afInitMarkIDs (AFfilesetup, int trackid, const int *ids, int nids);
1433
AFAPI int afGetMarkIDs (AFfilehandle file, int trackid, int markids[]);
1434
AFAPI void afSetMarkPosition (AFfilehandle file, int trackid, int markid,
1435
AFframecount markpos);
1436
AFAPI AFframecount afGetMarkPosition (AFfilehandle file, int trackid, int markid);
1437
AFAPI void afInitMarkName (AFfilesetup, int trackid, int marker, const char *name);
1438
AFAPI void afInitMarkComment (AFfilesetup, int trackid, int marker,
1439
const char *comment);
1440
AFAPI char *afGetMarkName (AFfilehandle file, int trackid, int markid);
1441
AFAPI char *afGetMarkComment (AFfilehandle file, int trackid, int markid);
1442
1443
/* instrument operations */
1444
AFAPI void afInitInstIDs (AFfilesetup, const int *ids, int nids);
1445
AFAPI int afGetInstIDs (AFfilehandle file, int *instids);
1446
AFAPI void afGetInstParams (AFfilehandle file, int instid, AUpvlist pvlist,
1447
int nparams);
1448
AFAPI void afSetInstParams (AFfilehandle file, int instid, AUpvlist pvlist,
1449
int nparams);
1450
AFAPI long afGetInstParamLong (AFfilehandle file, int instid, int param);
1451
AFAPI void afSetInstParamLong (AFfilehandle file, int instid, int param, long value);
1452
1453
/* miscellaneous data operations */
1454
AFAPI void afInitMiscIDs (AFfilesetup, const int *ids, int nids);
1455
AFAPI int afGetMiscIDs (AFfilehandle, int *ids);
1456
AFAPI void afInitMiscType (AFfilesetup, int miscellaneousid, int type);
1457
AFAPI int afGetMiscType (AFfilehandle, int miscellaneousid);
1458
AFAPI void afInitMiscSize (AFfilesetup, int miscellaneousid, int size);
1459
AFAPI int afGetMiscSize (AFfilehandle, int miscellaneousid);
1460
AFAPI int afWriteMisc (AFfilehandle, int miscellaneousid, const void *buf, int bytes);
1461
AFAPI int afReadMisc (AFfilehandle, int miscellaneousid, void *buf, int bytes);
1462
AFAPI int afSeekMisc (AFfilehandle, int miscellaneousid, int offset);
1463
1464
#undef AFAPI
1465
1466
#ifdef __cplusplus
1467
}
1468
#endif
1469
1470
#endif /* AUDIOFILE_H */
1471
1472
// file: afinternal.h
1473
/*
1474
Audio File Library
1475
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
1476
Copyright (C) 2000, Silicon Graphics, Inc.
1477
1478
This library is free software; you can redistribute it and/or
1479
modify it under the terms of the GNU Lesser General Public
1480
License as published by the Free Software Foundation; either
1481
version 2.1 of the License, or (at your option) any later version.
1482
1483
This library is distributed in the hope that it will be useful,
1484
but WITHOUT ANY WARRANTY; without even the implied warranty of
1485
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1486
Lesser General Public License for more details.
1487
1488
You should have received a copy of the GNU Lesser General Public
1489
License along with this library; if not, write to the
1490
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1491
Boston, MA 02110-1301 USA
1492
*/
1493
1494
/*
1495
afinternal.h
1496
1497
This file defines the internal structures for the Audio File Library.
1498
*/
1499
1500
#ifndef AFINTERNAL_H
1501
#define AFINTERNAL_H
1502
1503
#include <sys/types.h>
1504
1505
enum status
1506
{
1507
AF_SUCCEED = 0,
1508
AF_FAIL = -1
1509
};
1510
1511
union AFPVu
1512
{
1513
long l;
1514
double d;
1515
void *v;
1516
};
1517
1518
struct InstParamInfo
1519
{
1520
int id;
1521
int type;
1522
const char *name;
1523
AFPVu defaultValue;
1524
};
1525
1526
struct Loop
1527
{
1528
int id;
1529
int mode; /* AF_LOOP_MODE_... */
1530
int count; /* how many times the loop is played */
1531
int beginMarker, endMarker;
1532
int trackid;
1533
};
1534
1535
struct LoopSetup
1536
{
1537
int id;
1538
};
1539
1540
struct Miscellaneous
1541
{
1542
int id;
1543
int type;
1544
int size;
1545
1546
void *buffer;
1547
1548
int position; // offset within the miscellaneous chunk
1549
};
1550
1551
struct MiscellaneousSetup
1552
{
1553
int id;
1554
int type;
1555
int size;
1556
};
1557
1558
struct TrackSetup;
1559
1560
class File;
1561
struct Track;
1562
1563
enum
1564
{
1565
_AF_VALID_FILEHANDLE = 38212,
1566
_AF_VALID_FILESETUP = 38213
1567
};
1568
1569
enum
1570
{
1571
_AF_READ_ACCESS = 1,
1572
_AF_WRITE_ACCESS = 2
1573
};
1574
1575
// The following are tokens for compression parameters in PV lists.
1576
enum
1577
{
1578
_AF_MS_ADPCM_NUM_COEFFICIENTS = 800, /* type: long */
1579
_AF_MS_ADPCM_COEFFICIENTS = 801, /* type: array of int16_t[2] */
1580
_AF_IMA_ADPCM_TYPE = 810,
1581
_AF_IMA_ADPCM_TYPE_WAVE = 1,
1582
_AF_IMA_ADPCM_TYPE_QT = 2,
1583
_AF_CODEC_DATA = 900, // type: pointer
1584
_AF_CODEC_DATA_SIZE = 901 // type: long
1585
};
1586
1587
/* NeXT/Sun sampling rate */
1588
#define _AF_SRATE_CODEC (8012.8210513)
1589
1590
#endif
1591
1592
// file: byteorder.h
1593
/*
1594
Audio File Library
1595
Copyright (C) 1998-1999, 2010-2011, Michael Pruett <[email protected]>
1596
1597
This library is free software; you can redistribute it and/or
1598
modify it under the terms of the GNU Lesser General Public
1599
License as published by the Free Software Foundation; either
1600
version 2.1 of the License, or (at your option) any later version.
1601
1602
This library is distributed in the hope that it will be useful,
1603
but WITHOUT ANY WARRANTY; without even the implied warranty of
1604
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1605
Lesser General Public License for more details.
1606
1607
You should have received a copy of the GNU Lesser General Public
1608
License along with this library; if not, write to the
1609
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1610
Boston, MA 02110-1301 USA
1611
*/
1612
1613
#ifndef BYTEORDER_H
1614
#define BYTEORDER_H
1615
1616
1617
#include <stdint.h>
1618
1619
#if WORDS_BIGENDIAN
1620
#define _AF_BYTEORDER_NATIVE (AF_BYTEORDER_BIGENDIAN)
1621
#else
1622
#define _AF_BYTEORDER_NATIVE (AF_BYTEORDER_LITTLEENDIAN)
1623
#endif
1624
1625
inline uint16_t _af_byteswap_int16 (uint16_t x)
1626
{
1627
return (x >> 8) | (x << 8);
1628
}
1629
1630
inline uint32_t _af_byteswap_int32 (uint32_t x)
1631
{
1632
return ((x & 0x000000ffU) << 24) |
1633
((x & 0x0000ff00U) << 8) |
1634
((x & 0x00ff0000U) >> 8) |
1635
((x & 0xff000000U) >> 24);
1636
}
1637
1638
inline uint64_t _af_byteswap_int64 (uint64_t x)
1639
{
1640
return ((x & 0x00000000000000ffULL) << 56) |
1641
((x & 0x000000000000ff00ULL) << 40) |
1642
((x & 0x0000000000ff0000ULL) << 24) |
1643
((x & 0x00000000ff000000ULL) << 8) |
1644
((x & 0x000000ff00000000ULL) >> 8) |
1645
((x & 0x0000ff0000000000ULL) >> 24) |
1646
((x & 0x00ff000000000000ULL) >> 40) |
1647
((x & 0xff00000000000000ULL) >> 56);
1648
}
1649
1650
inline float _af_byteswap_float32 (float x)
1651
{
1652
union
1653
{
1654
uint32_t i;
1655
float f;
1656
} u;
1657
u.f = x;
1658
u.i = _af_byteswap_int32(u.i);
1659
return u.f;
1660
}
1661
1662
inline double _af_byteswap_float64 (double x)
1663
{
1664
union
1665
{
1666
uint64_t i;
1667
double f;
1668
} u;
1669
u.f = x;
1670
u.i = _af_byteswap_int64(u.i);
1671
return u.f;
1672
}
1673
1674
inline uint64_t byteswap(uint64_t value) { return _af_byteswap_int64(value); }
1675
inline int64_t byteswap(int64_t value) { return _af_byteswap_int64(value); }
1676
inline uint32_t byteswap(uint32_t value) { return _af_byteswap_int32(value); }
1677
inline int32_t byteswap(int32_t value) { return _af_byteswap_int32(value); }
1678
inline uint16_t byteswap(uint16_t value) { return _af_byteswap_int16(value); }
1679
inline int16_t byteswap(int16_t value) { return _af_byteswap_int16(value); }
1680
1681
inline double byteswap(double value) { return _af_byteswap_float64(value); }
1682
inline float byteswap(float value) { return _af_byteswap_float32(value); }
1683
1684
template <typename T>
1685
T bigToHost(T value)
1686
{
1687
return _AF_BYTEORDER_NATIVE == AF_BYTEORDER_BIGENDIAN ? value : byteswap(value);
1688
}
1689
1690
template <typename T>
1691
T littleToHost(T value)
1692
{
1693
return _AF_BYTEORDER_NATIVE == AF_BYTEORDER_LITTLEENDIAN ? value : byteswap(value);
1694
}
1695
1696
template <typename T>
1697
T hostToBig(T value)
1698
{
1699
return _AF_BYTEORDER_NATIVE == AF_BYTEORDER_BIGENDIAN ? value : byteswap(value);
1700
}
1701
1702
template <typename T>
1703
T hostToLittle(T value)
1704
{
1705
return _AF_BYTEORDER_NATIVE == AF_BYTEORDER_LITTLEENDIAN ? value : byteswap(value);
1706
}
1707
1708
#endif
1709
1710
// file: AudioFormat.h
1711
/*
1712
Audio File Library
1713
Copyright (C) 2010, Michael Pruett <[email protected]>
1714
1715
This library is free software; you can redistribute it and/or
1716
modify it under the terms of the GNU Lesser General Public
1717
License as published by the Free Software Foundation; either
1718
version 2.1 of the License, or (at your option) any later version.
1719
1720
This library is distributed in the hope that it will be useful,
1721
but WITHOUT ANY WARRANTY; without even the implied warranty of
1722
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1723
Lesser General Public License for more details.
1724
1725
You should have received a copy of the GNU Lesser General Public
1726
License along with this library; if not, write to the
1727
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1728
Boston, MA 02110-1301 USA
1729
*/
1730
1731
#ifndef AUDIOFORMAT_H
1732
#define AUDIOFORMAT_H
1733
1734
1735
#include <sys/types.h>
1736
#include <string>
1737
1738
struct PCMInfo
1739
{
1740
double slope, intercept, minClip, maxClip;
1741
};
1742
1743
struct AudioFormat
1744
{
1745
double sampleRate; /* sampling rate in Hz */
1746
int sampleFormat; /* AF_SAMPFMT_... */
1747
int sampleWidth; /* sample width in bits */
1748
int byteOrder; /* AF_BYTEORDER_... */
1749
1750
PCMInfo pcm; /* parameters of PCM data */
1751
1752
int channelCount; /* number of channels */
1753
1754
int compressionType; /* AF_COMPRESSION_... */
1755
AUpvlist compressionParams; /* NULL if no compression */
1756
1757
bool packed : 1;
1758
1759
size_t framesPerPacket;
1760
size_t bytesPerPacket;
1761
1762
size_t bytesPerSample(bool stretch3to4) const;
1763
size_t bytesPerFrame(bool stretch3to4) const;
1764
size_t bytesPerSample() const;
1765
size_t bytesPerFrame() const;
1766
bool isInteger() const;
1767
bool isSigned() const;
1768
bool isUnsigned() const;
1769
bool isFloat() const;
1770
bool isCompressed() const;
1771
bool isUncompressed() const;
1772
bool isPacked() const { return packed; }
1773
bool isByteOrderSignificant() const { return sampleWidth > 8; }
1774
1775
void computeBytesPerPacketPCM();
1776
1777
std::string description() const;
1778
};
1779
1780
#endif
1781
1782
// file: debug.h
1783
/*
1784
Audio File Library
1785
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
1786
1787
This library is free software; you can redistribute it and/or
1788
modify it under the terms of the GNU Lesser General Public
1789
License as published by the Free Software Foundation; either
1790
version 2.1 of the License, or (at your option) any later version.
1791
1792
This library is distributed in the hope that it will be useful,
1793
but WITHOUT ANY WARRANTY; without even the implied warranty of
1794
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1795
Lesser General Public License for more details.
1796
1797
You should have received a copy of the GNU Lesser General Public
1798
License along with this library; if not, write to the
1799
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1800
Boston, MA 02110-1301 USA
1801
*/
1802
1803
/*
1804
debug.h
1805
1806
This header file declares debugging functions for the Audio
1807
File Library.
1808
*/
1809
1810
#ifndef DEBUG_H
1811
#define DEBUG_H
1812
1813
#include <stdint.h>
1814
1815
void _af_print_filehandle (AFfilehandle filehandle);
1816
void _af_print_tracks (AFfilehandle filehandle);
1817
void _af_print_channel_matrix (double *matrix, int fchans, int vchans);
1818
void _af_print_pvlist (AUpvlist list);
1819
1820
void _af_print_audioformat (AudioFormat *format);
1821
void _af_print_frame (AFframecount frameno, double *frame, int nchannels,
1822
char *formatstring, int numberwidth,
1823
double slope, double intercept, double minclip, double maxclip);
1824
1825
#endif
1826
1827
// file: util.h
1828
/*
1829
Audio File Library
1830
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
1831
1832
This library is free software; you can redistribute it and/or
1833
modify it under the terms of the GNU Lesser General Public
1834
License as published by the Free Software Foundation; either
1835
version 2.1 of the License, or (at your option) any later version.
1836
1837
This library is distributed in the hope that it will be useful,
1838
but WITHOUT ANY WARRANTY; without even the implied warranty of
1839
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1840
Lesser General Public License for more details.
1841
1842
You should have received a copy of the GNU Lesser General Public
1843
License along with this library; if not, write to the
1844
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1845
Boston, MA 02110-1301 USA
1846
*/
1847
1848
/*
1849
util.h
1850
1851
This file contains some general utility functions for the Audio
1852
File Library.
1853
*/
1854
1855
#ifndef UTIL_H
1856
#define UTIL_H
1857
1858
#include <stdint.h>
1859
#include <stdlib.h>
1860
1861
1862
struct AudioFormat;
1863
1864
bool _af_filesetup_ok (AFfilesetup setup);
1865
bool _af_filehandle_ok (AFfilehandle file);
1866
1867
void *_af_malloc (size_t size);
1868
void *_af_realloc (void *ptr, size_t size);
1869
void *_af_calloc (size_t nmemb, size_t size);
1870
char *_af_strdup (const char *s);
1871
1872
AUpvlist _af_pv_long (long val);
1873
AUpvlist _af_pv_double (double val);
1874
AUpvlist _af_pv_pointer (void *val);
1875
1876
bool _af_pv_getlong (AUpvlist pvlist, int param, long *l);
1877
bool _af_pv_getdouble (AUpvlist pvlist, int param, double *d);
1878
bool _af_pv_getptr (AUpvlist pvlist, int param, void **v);
1879
1880
bool _af_unique_ids (const int *ids, int nids, const char *idname, int iderr);
1881
1882
float _af_format_frame_size (const AudioFormat *format, bool stretch3to4);
1883
int _af_format_frame_size_uncompressed (const AudioFormat *format, bool stretch3to4);
1884
float _af_format_sample_size (const AudioFormat *format, bool stretch3to4);
1885
int _af_format_sample_size_uncompressed (const AudioFormat *format, bool stretch3to4);
1886
1887
status _af_set_sample_format (AudioFormat *f, int sampleFormat, int sampleWidth);
1888
1889
#endif
1890
1891
// file: units.h
1892
/*
1893
Audio File Library
1894
Copyright (C) 2000, Michael Pruett <[email protected]>
1895
1896
This library is free software; you can redistribute it and/or
1897
modify it under the terms of the GNU Lesser General Public
1898
License as published by the Free Software Foundation; either
1899
version 2.1 of the License, or (at your option) any later version.
1900
1901
This library is distributed in the hope that it will be useful,
1902
but WITHOUT ANY WARRANTY; without even the implied warranty of
1903
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1904
Lesser General Public License for more details.
1905
1906
You should have received a copy of the GNU Lesser General Public
1907
License along with this library; if not, write to the
1908
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
1909
Boston, MA 02110-1301 USA
1910
*/
1911
1912
/*
1913
units.h
1914
1915
This file defines the internal Unit and CompressionUnit
1916
structures for the Audio File Library.
1917
*/
1918
1919
#ifndef UNIT_H
1920
#define UNIT_H
1921
1922
1923
struct AudioFormat;
1924
class FileModule;
1925
1926
struct Unit
1927
{
1928
int fileFormat; /* AF_FILEFMT_... */
1929
const char *name; /* a 2-3 word name of the file format */
1930
const char *description; /* a more descriptive name for the format */
1931
const char *label; /* a 4-character label for the format */
1932
bool implemented; /* if implemented */
1933
1934
AFfilesetup (*completesetup) (AFfilesetup setup);
1935
bool (*recognize) (File *fh);
1936
1937
int defaultSampleFormat;
1938
int defaultSampleWidth;
1939
1940
int compressionTypeCount;
1941
const int *compressionTypes;
1942
1943
int markerCount;
1944
1945
int instrumentCount;
1946
int loopPerInstrumentCount;
1947
1948
int instrumentParameterCount;
1949
const InstParamInfo *instrumentParameters;
1950
};
1951
1952
struct CompressionUnit
1953
{
1954
int compressionID; /* AF_COMPRESSION_... */
1955
bool implemented;
1956
const char *label; /* 4-character (approximately) label */
1957
const char *shortname; /* short name in English */
1958
const char *name; /* long name in English */
1959
double squishFactor; /* compression ratio */
1960
int nativeSampleFormat; /* AF_SAMPFMT_... */
1961
int nativeSampleWidth; /* sample width in bits */
1962
bool needsRebuffer; /* if there are chunk boundary requirements */
1963
bool multiple_of; /* can accept any multiple of chunksize */
1964
bool (*fmtok) (AudioFormat *format);
1965
1966
FileModule *(*initcompress) (Track *track, File *fh,
1967
bool seekok, bool headerless, AFframecount *chunkframes);
1968
FileModule *(*initdecompress) (Track *track, File *fh,
1969
bool seekok, bool headerless, AFframecount *chunkframes);
1970
};
1971
1972
#define _AF_NUM_UNITS 17
1973
#define _AF_NUM_COMPRESSION 7
1974
1975
extern const Unit _af_units[_AF_NUM_UNITS];
1976
extern const CompressionUnit _af_compression[_AF_NUM_COMPRESSION];
1977
1978
#endif /* UNIT_H */
1979
1980
// file: UUID.h
1981
/*
1982
Copyright (C) 2011, Michael Pruett. All rights reserved.
1983
1984
Redistribution and use in source and binary forms, with or without
1985
modification, are permitted provided that the following conditions
1986
are met:
1987
1988
1. Redistributions of source code must retain the above copyright
1989
notice, this list of conditions and the following disclaimer.
1990
1991
2. Redistributions in binary form must reproduce the above copyright
1992
notice, this list of conditions and the following disclaimer in the
1993
documentation and/or other materials provided with the distribution.
1994
1995
3. The name of the author may not be used to endorse or promote products
1996
derived from this software without specific prior written permission.
1997
1998
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1999
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2000
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2001
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2002
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2003
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2004
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2005
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2006
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2007
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2008
*/
2009
2010
#ifndef UUID_H
2011
#define UUID_H
2012
2013
#include <stdint.h>
2014
#include <string>
2015
2016
struct UUID
2017
{
2018
uint8_t data[16];
2019
2020
bool operator==(const UUID &) const;
2021
bool operator!=(const UUID &) const;
2022
std::string name() const;
2023
};
2024
2025
#endif
2026
2027
// file: Shared.h
2028
/*
2029
Copyright (C) 2010, Michael Pruett. All rights reserved.
2030
2031
Redistribution and use in source and binary forms, with or without
2032
modification, are permitted provided that the following conditions
2033
are met:
2034
2035
1. Redistributions of source code must retain the above copyright
2036
notice, this list of conditions and the following disclaimer.
2037
2038
2. Redistributions in binary form must reproduce the above copyright
2039
notice, this list of conditions and the following disclaimer in the
2040
documentation and/or other materials provided with the distribution.
2041
2042
3. The name of the author may not be used to endorse or promote products
2043
derived from this software without specific prior written permission.
2044
2045
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2046
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2047
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2048
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2049
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2050
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2051
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2052
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2053
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2054
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2055
*/
2056
2057
#ifndef SHARED_H
2058
#define SHARED_H
2059
2060
template <typename T>
2061
class Shared
2062
{
2063
public:
2064
Shared() : m_refCount(0)
2065
{
2066
}
2067
void retain() { m_refCount++; }
2068
void release() { if (--m_refCount == 0) delete static_cast<T *>(this); }
2069
2070
protected:
2071
~Shared()
2072
{
2073
}
2074
2075
private:
2076
int m_refCount;
2077
2078
Shared(const Shared &);
2079
Shared &operator =(const Shared &);
2080
};
2081
2082
template <typename T>
2083
class SharedPtr
2084
{
2085
public:
2086
SharedPtr() : m_ptr(0)
2087
{
2088
}
2089
SharedPtr(T *ptr) : m_ptr(ptr)
2090
{
2091
if (m_ptr) m_ptr->retain();
2092
}
2093
SharedPtr(const SharedPtr &p) : m_ptr(p.m_ptr)
2094
{
2095
if (m_ptr) m_ptr->retain();
2096
}
2097
~SharedPtr()
2098
{
2099
if (T *p = m_ptr) p->release();
2100
}
2101
2102
SharedPtr &operator =(T *ptr)
2103
{
2104
if (m_ptr != ptr)
2105
{
2106
if (ptr) ptr->retain();
2107
if (m_ptr) m_ptr->release();
2108
m_ptr = ptr;
2109
}
2110
return *this;
2111
}
2112
SharedPtr &operator =(const SharedPtr &p)
2113
{
2114
if (m_ptr != p.m_ptr)
2115
{
2116
if (p.m_ptr) p.m_ptr->retain();
2117
if (m_ptr) m_ptr->release();
2118
m_ptr = p.m_ptr;
2119
}
2120
return *this;
2121
}
2122
2123
T *get() const { return m_ptr; }
2124
T &operator *() const { return *m_ptr; }
2125
T *operator ->() const { return m_ptr; }
2126
2127
typedef T *SharedPtr::*UnspecifiedBoolType;
2128
operator UnspecifiedBoolType() const { return m_ptr ? &SharedPtr::m_ptr : 0; }
2129
2130
bool operator !() const { return !m_ptr; }
2131
2132
private:
2133
T *m_ptr;
2134
};
2135
2136
#endif
2137
2138
// file: Buffer.h
2139
/*
2140
Audio File Library
2141
Copyright (C) 2013 Michael Pruett <[email protected]>
2142
2143
This library is free software; you can redistribute it and/or
2144
modify it under the terms of the GNU Lesser General Public
2145
License as published by the Free Software Foundation; either
2146
version 2.1 of the License, or (at your option) any later version.
2147
2148
This library is distributed in the hope that it will be useful,
2149
but WITHOUT ANY WARRANTY; without even the implied warranty of
2150
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2151
Lesser General Public License for more details.
2152
2153
You should have received a copy of the GNU Lesser General Public
2154
License along with this library; if not, write to the
2155
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2156
Boston, MA 02110-1301 USA
2157
*/
2158
2159
#ifndef Buffer_h
2160
#define Buffer_h
2161
2162
2163
#include <sys/types.h>
2164
2165
class Buffer : public Shared<Buffer>
2166
{
2167
public:
2168
Buffer();
2169
Buffer(size_t size);
2170
Buffer(const void *data, size_t size);
2171
~Buffer();
2172
2173
void *data() { return m_data; }
2174
const void *data() const { return m_data; }
2175
2176
size_t size() const { return m_size; }
2177
2178
private:
2179
void *m_data;
2180
size_t m_size;
2181
};
2182
2183
#endif
2184
2185
// file: File.h
2186
/*
2187
Copyright (C) 2010, Michael Pruett. All rights reserved.
2188
2189
Redistribution and use in source and binary forms, with or without
2190
modification, are permitted provided that the following conditions
2191
are met:
2192
2193
1. Redistributions of source code must retain the above copyright
2194
notice, this list of conditions and the following disclaimer.
2195
2196
2. Redistributions in binary form must reproduce the above copyright
2197
notice, this list of conditions and the following disclaimer in the
2198
documentation and/or other materials provided with the distribution.
2199
2200
3. The name of the author may not be used to endorse or promote products
2201
derived from this software without specific prior written permission.
2202
2203
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2204
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2205
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2206
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2207
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2208
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2209
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2210
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2211
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2212
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2213
*/
2214
2215
#ifndef FILE_H
2216
#define FILE_H
2217
2218
#include <sys/types.h>
2219
2220
typedef struct _AFvirtualfile AFvirtualfile;
2221
2222
class File : public Shared<File>
2223
{
2224
public:
2225
enum AccessMode
2226
{
2227
ReadAccess,
2228
WriteAccess
2229
};
2230
2231
enum SeekOrigin
2232
{
2233
SeekFromBeginning,
2234
SeekFromCurrent,
2235
SeekFromEnd
2236
};
2237
2238
static File *open(const char *path, AccessMode mode);
2239
static File *create(int fd, AccessMode mode);
2240
static File *create(AFvirtualfile *vf, AccessMode mode);
2241
2242
virtual ~File();
2243
virtual int close() = 0;
2244
virtual ssize_t read(void *data, size_t nbytes) = 0;
2245
virtual ssize_t write(const void *data, size_t nbytes) = 0;
2246
virtual off_t length() = 0;
2247
virtual off_t seek(off_t offset, SeekOrigin origin) = 0;
2248
virtual off_t tell() = 0;
2249
2250
bool canSeek();
2251
2252
AccessMode accessMode() const { return m_accessMode; }
2253
2254
private:
2255
AccessMode m_accessMode;
2256
2257
protected:
2258
File(AccessMode mode) : m_accessMode(mode) { }
2259
};
2260
2261
#endif // FILE_H
2262
2263
// file: FileHandle.h
2264
/*
2265
Audio File Library
2266
Copyright (C) 2010-2011, Michael Pruett <[email protected]>
2267
2268
This library is free software; you can redistribute it and/or
2269
modify it under the terms of the GNU Lesser General Public
2270
License as published by the Free Software Foundation; either
2271
version 2.1 of the License, or (at your option) any later version.
2272
2273
This library is distributed in the hope that it will be useful,
2274
but WITHOUT ANY WARRANTY; without even the implied warranty of
2275
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2276
Lesser General Public License for more details.
2277
2278
You should have received a copy of the GNU Lesser General Public
2279
License along with this library; if not, write to the
2280
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2281
Boston, MA 02110-1301 USA
2282
*/
2283
2284
#ifndef FILEHANDLE_H
2285
#define FILEHANDLE_H
2286
2287
#include <stdint.h>
2288
2289
class File;
2290
class Tag;
2291
struct Instrument;
2292
struct Miscellaneous;
2293
struct Track;
2294
2295
struct _AFfilehandle
2296
{
2297
static _AFfilehandle *create(int fileFormat);
2298
2299
int m_valid; // _AF_VALID_FILEHANDLE
2300
int m_access; // _AF_READ_ACCESS or _AF_WRITE_ACCESS
2301
2302
bool m_seekok;
2303
2304
File *m_fh;
2305
2306
char *m_fileName;
2307
2308
int m_fileFormat;
2309
2310
int m_trackCount;
2311
Track *m_tracks;
2312
2313
int m_instrumentCount;
2314
Instrument *m_instruments;
2315
2316
int m_miscellaneousCount;
2317
Miscellaneous *m_miscellaneous;
2318
2319
private:
2320
int m_formatByteOrder;
2321
2322
status copyTracksFromSetup(AFfilesetup setup);
2323
status copyInstrumentsFromSetup(AFfilesetup setup);
2324
status copyMiscellaneousFromSetup(AFfilesetup setup);
2325
2326
public:
2327
virtual ~_AFfilehandle();
2328
2329
virtual int getVersion() { return 0; }
2330
virtual status readInit(AFfilesetup) = 0;
2331
virtual status writeInit(AFfilesetup) = 0;
2332
virtual status update() = 0;
2333
virtual bool isInstrumentParameterValid(AUpvlist, int) { return false; }
2334
2335
bool checkCanRead();
2336
bool checkCanWrite();
2337
2338
Track *allocateTrack();
2339
Track *getTrack(int trackID = AF_DEFAULT_TRACK);
2340
Instrument *getInstrument(int instrumentID);
2341
Miscellaneous *getMiscellaneous(int miscellaneousID);
2342
2343
protected:
2344
_AFfilehandle();
2345
2346
status initFromSetup(AFfilesetup setup);
2347
2348
void setFormatByteOrder(int byteOrder) { m_formatByteOrder = byteOrder; }
2349
2350
bool readU8(uint8_t *);
2351
bool readS8(int8_t *);
2352
bool readU16(uint16_t *);
2353
bool readS16(int16_t *);
2354
bool readU32(uint32_t *);
2355
bool readS32(int32_t *);
2356
bool readU64(uint64_t *);
2357
bool readS64(int64_t *);
2358
bool readFloat(float *);
2359
bool readDouble(double *);
2360
2361
bool writeU8(const uint8_t *);
2362
bool writeS8(const int8_t *);
2363
bool writeU16(const uint16_t *);
2364
bool writeS16(const int16_t *);
2365
bool writeU32(const uint32_t *);
2366
bool writeS32(const int32_t *);
2367
bool writeU64(const uint64_t *);
2368
bool writeS64(const int64_t *);
2369
bool writeFloat(const float *);
2370
bool writeDouble(const double *);
2371
2372
bool readTag(Tag *t);
2373
bool writeTag(const Tag *t);
2374
};
2375
2376
#endif
2377
2378
// file: Instrument.h
2379
/*
2380
Audio File Library
2381
Copyright (C) 2000, Michael Pruett <[email protected]>
2382
2383
This library is free software; you can redistribute it and/or
2384
modify it under the terms of the GNU Lesser General Public
2385
License as published by the Free Software Foundation; either
2386
version 2.1 of the License, or (at your option) any later version.
2387
2388
This library is distributed in the hope that it will be useful,
2389
but WITHOUT ANY WARRANTY; without even the implied warranty of
2390
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2391
Lesser General Public License for more details.
2392
2393
You should have received a copy of the GNU Lesser General Public
2394
License along with this library; if not, write to the
2395
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2396
Boston, MA 02110-1301 USA
2397
*/
2398
2399
/*
2400
Instrument.h
2401
2402
This file declares routines for dealing with instruments.
2403
*/
2404
2405
#ifndef INSTRUMENT_H
2406
#define INSTRUMENT_H
2407
2408
2409
struct LoopSetup;
2410
struct Loop;
2411
2412
struct InstrumentSetup
2413
{
2414
int id;
2415
2416
int loopCount;
2417
LoopSetup *loops;
2418
2419
bool loopSet;
2420
2421
bool allocateLoops(int count);
2422
void freeLoops();
2423
};
2424
2425
struct Instrument
2426
{
2427
int id;
2428
2429
int loopCount;
2430
Loop *loops;
2431
2432
AFPVu *values;
2433
2434
Loop *getLoop(int loopID);
2435
};
2436
2437
void _af_instparam_get (AFfilehandle file, int instid, AUpvlist pvlist,
2438
int npv, bool forceLong);
2439
2440
void _af_instparam_set (AFfilehandle file, int instid, AUpvlist pvlist,
2441
int npv);
2442
2443
int _af_instparam_index_from_id (int fileFormat, int id);
2444
2445
#endif /* INSTRUMENT_H */
2446
2447
// file: Track.h
2448
/*
2449
Audio File Library
2450
Copyright (C) 2000, Silicon Graphics, Inc.
2451
2452
This library is free software; you can redistribute it and/or
2453
modify it under the terms of the GNU Lesser General Public
2454
License as published by the Free Software Foundation; either
2455
version 2.1 of the License, or (at your option) any later version.
2456
2457
This library is distributed in the hope that it will be useful,
2458
but WITHOUT ANY WARRANTY; without even the implied warranty of
2459
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2460
Lesser General Public License for more details.
2461
2462
You should have received a copy of the GNU Lesser General Public
2463
License along with this library; if not, write to the
2464
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2465
Boston, MA 02110-1301 USA
2466
*/
2467
2468
/*
2469
track.h
2470
*/
2471
2472
#ifndef TRACK_H
2473
#define TRACK_H
2474
2475
2476
class ModuleState;
2477
class PacketTable;
2478
struct Marker;
2479
struct MarkerSetup;
2480
2481
struct TrackSetup
2482
{
2483
int id;
2484
2485
AudioFormat f;
2486
2487
bool rateSet, sampleFormatSet, sampleWidthSet, byteOrderSet,
2488
channelCountSet, compressionSet, aesDataSet, markersSet,
2489
dataOffsetSet, frameCountSet;
2490
2491
int markerCount;
2492
MarkerSetup *markers;
2493
2494
AFfileoffset dataOffset;
2495
AFframecount frameCount;
2496
};
2497
2498
struct Track
2499
{
2500
Track();
2501
~Track();
2502
2503
int id; /* usually AF_DEFAULT_TRACKID */
2504
2505
AudioFormat f, v; /* file and virtual audio formats */
2506
2507
SharedPtr<PacketTable> m_packetTable;
2508
2509
double *channelMatrix;
2510
2511
int markerCount;
2512
Marker *markers;
2513
2514
bool hasAESData; /* Is AES nonaudio data present? */
2515
unsigned char aesData[24]; /* AES nonaudio data */
2516
2517
AFframecount totalfframes; /* frameCount */
2518
AFframecount nextfframe; /* currentFrame */
2519
AFframecount frames2ignore;
2520
AFfileoffset fpos_first_frame; /* dataStart */
2521
AFfileoffset fpos_next_frame;
2522
AFfileoffset fpos_after_data;
2523
AFframecount totalvframes;
2524
AFframecount nextvframe;
2525
AFfileoffset data_size; /* trackBytes */
2526
2527
SharedPtr<ModuleState> ms;
2528
2529
double taper, dynamic_range;
2530
bool ratecvt_filter_params_set;
2531
2532
bool filemodhappy;
2533
2534
void print();
2535
2536
Marker *getMarker(int markerID);
2537
status copyMarkers(TrackSetup *setup);
2538
2539
void computeTotalFileFrames();
2540
};
2541
2542
#endif
2543
2544
// file: Marker.h
2545
/*
2546
Audio File Library
2547
Copyright (C) 2000, Silicon Graphics, Inc.
2548
2549
This library is free software; you can redistribute it and/or
2550
modify it under the terms of the GNU Lesser General Public
2551
License as published by the Free Software Foundation; either
2552
version 2.1 of the License, or (at your option) any later version.
2553
2554
This library is distributed in the hope that it will be useful,
2555
but WITHOUT ANY WARRANTY; without even the implied warranty of
2556
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2557
Lesser General Public License for more details.
2558
2559
You should have received a copy of the GNU Lesser General Public
2560
License along with this library; if not, write to the
2561
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2562
Boston, MA 02110-1301 USA
2563
*/
2564
2565
#ifndef MARKER_H
2566
#define MARKER_H
2567
2568
struct MarkerSetup
2569
{
2570
int id;
2571
char *name, *comment;
2572
};
2573
2574
struct Marker
2575
{
2576
short id;
2577
unsigned long position;
2578
char *name;
2579
char *comment;
2580
};
2581
2582
struct Track;
2583
2584
Marker *_af_marker_new (int count);
2585
Marker *_af_marker_find_by_id (Track *track, int id);
2586
2587
#endif /* MARKER_H */
2588
2589
// file: Setup.h
2590
/*
2591
Audio File Library
2592
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
2593
2594
This library is free software; you can redistribute it and/or
2595
modify it under the terms of the GNU Lesser General Public
2596
License as published by the Free Software Foundation; either
2597
version 2.1 of the License, or (at your option) any later version.
2598
2599
This library is distributed in the hope that it will be useful,
2600
but WITHOUT ANY WARRANTY; without even the implied warranty of
2601
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2602
Lesser General Public License for more details.
2603
2604
You should have received a copy of the GNU Lesser General Public
2605
License along with this library; if not, write to the
2606
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2607
Boston, MA 02110-1301 USA
2608
*/
2609
2610
#ifndef SETUP_H
2611
#define SETUP_H
2612
2613
2614
struct InstrumentSetup;
2615
struct MiscellaneousSetup;
2616
struct TrackSetup;
2617
2618
struct _AFfilesetup
2619
{
2620
int valid;
2621
2622
int fileFormat;
2623
2624
bool trackSet, instrumentSet, miscellaneousSet;
2625
2626
int trackCount;
2627
TrackSetup *tracks;
2628
2629
int instrumentCount;
2630
InstrumentSetup *instruments;
2631
2632
int miscellaneousCount;
2633
MiscellaneousSetup *miscellaneous;
2634
2635
TrackSetup *getTrack(int trackID = AF_DEFAULT_TRACK);
2636
InstrumentSetup *getInstrument(int instrumentID);
2637
MiscellaneousSetup *getMiscellaneous(int miscellaneousID);
2638
};
2639
2640
void _af_setup_free_markers (AFfilesetup setup, int trackno);
2641
void _af_setup_free_tracks (AFfilesetup setup);
2642
void _af_setup_free_instruments (AFfilesetup setup);
2643
2644
AFfilesetup _af_filesetup_copy (const _AFfilesetup *setup,
2645
const _AFfilesetup *defaultSetup, bool copyMarks);
2646
2647
InstrumentSetup *_af_instsetup_new (int count);
2648
2649
#endif
2650
2651
// file: Tag.h
2652
/*
2653
Audio File Library
2654
Copyright (C) 2011, Michael Pruett <[email protected]>
2655
2656
This library is free software; you can redistribute it and/or
2657
modify it under the terms of the GNU Lesser General Public
2658
License as published by the Free Software Foundation; either
2659
version 2.1 of the License, or (at your option) any later version.
2660
2661
This library is distributed in the hope that it will be useful,
2662
but WITHOUT ANY WARRANTY; without even the implied warranty of
2663
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2664
Lesser General Public License for more details.
2665
2666
You should have received a copy of the GNU Lesser General Public
2667
License along with this library; if not, write to the
2668
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2669
Boston, MA 02110-1301 USA
2670
*/
2671
2672
#ifndef TAG_H
2673
#define TAG_H
2674
2675
#include <assert.h>
2676
#include <stdint.h>
2677
#include <string.h>
2678
#include <string>
2679
2680
class Tag
2681
{
2682
public:
2683
Tag() : m_value(0) { }
2684
Tag(uint32_t value) : m_value(value) { }
2685
Tag(const char *s)
2686
{
2687
assert(strlen(s) == 4);
2688
memcpy(&m_value, s, 4);
2689
}
2690
2691
uint32_t value() const { return m_value; }
2692
2693
bool operator==(const Tag &t) const { return m_value == t.m_value; }
2694
bool operator!=(const Tag &t) const { return m_value != t.m_value; }
2695
2696
std::string name() const
2697
{
2698
char s[5];
2699
memcpy(s, &m_value, 4);
2700
s[4] = '\0';
2701
return std::string(s);
2702
}
2703
2704
private:
2705
uint32_t m_value;
2706
};
2707
2708
#endif
2709
2710
// file: PacketTable.h
2711
/*
2712
Audio File Library
2713
Copyright (C) 2013 Michael Pruett <[email protected]>
2714
2715
This library is free software; you can redistribute it and/or
2716
modify it under the terms of the GNU Lesser General Public
2717
License as published by the Free Software Foundation; either
2718
version 2.1 of the License, or (at your option) any later version.
2719
2720
This library is distributed in the hope that it will be useful,
2721
but WITHOUT ANY WARRANTY; without even the implied warranty of
2722
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2723
Lesser General Public License for more details.
2724
2725
You should have received a copy of the GNU Lesser General Public
2726
License along with this library; if not, write to the
2727
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2728
Boston, MA 02110-1301 USA
2729
*/
2730
2731
#ifndef PacketTable_h
2732
#define PacketTable_h
2733
2734
2735
#include <audiofile.h>
2736
2737
#include <stdint.h>
2738
#include <sys/types.h>
2739
#include <vector>
2740
2741
class PacketTable : public Shared<PacketTable>
2742
{
2743
public:
2744
PacketTable();
2745
PacketTable(int64_t numValidFrames,
2746
int32_t primingFrames,
2747
int32_t remainderFrames);
2748
~PacketTable();
2749
2750
size_t numPackets() const { return m_bytesPerPacket.size(); }
2751
int64_t numValidFrames() const { return m_numValidFrames; }
2752
void setNumValidFrames(int64_t numValidFrames);
2753
int32_t primingFrames() const { return m_primingFrames; }
2754
void setPrimingFrames(int32_t primingFrames);
2755
int32_t remainderFrames() const { return m_remainderFrames; }
2756
void setRemainderFrames(int32_t remainderFrames);
2757
2758
void append(size_t bytesPerPacket);
2759
size_t bytesPerPacket(size_t packet) const { return m_bytesPerPacket[packet]; }
2760
AFfileoffset startOfPacket(size_t packet) const;
2761
2762
private:
2763
int64_t m_numValidFrames;
2764
int32_t m_primingFrames;
2765
int32_t m_remainderFrames;
2766
2767
std::vector<size_t> m_bytesPerPacket;
2768
};
2769
2770
#endif
2771
2772
// file: pcm.h
2773
/*
2774
Audio File Library
2775
Copyright (C) 2000, Silicon Graphics, Inc.
2776
2777
This library is free software; you can redistribute it and/or
2778
modify it under the terms of the GNU Lesser General Public
2779
License as published by the Free Software Foundation; either
2780
version 2.1 of the License, or (at your option) any later version.
2781
2782
This library is distributed in the hope that it will be useful,
2783
but WITHOUT ANY WARRANTY; without even the implied warranty of
2784
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2785
Lesser General Public License for more details.
2786
2787
You should have received a copy of the GNU Lesser General Public
2788
License along with this library; if not, write to the
2789
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2790
Boston, MA 02110-1301 USA
2791
*/
2792
2793
/*
2794
pcm.h
2795
2796
This file defines various constants for PCM mapping.
2797
*/
2798
2799
#ifndef PCM_H
2800
#define PCM_H
2801
2802
/*
2803
SLOPE_INTN = 2^(N-1)
2804
*/
2805
#define SLOPE_INT8 (128.0)
2806
#define SLOPE_INT16 (32768.0)
2807
#define SLOPE_INT24 (8388608.0)
2808
#define SLOPE_INT32 (2147483648.0)
2809
2810
/*
2811
INTERCEPT_U_INTN = 2^(N-1)
2812
*/
2813
#define INTERCEPT_U_INT8 (128.0)
2814
#define INTERCEPT_U_INT16 (32768.0)
2815
#define INTERCEPT_U_INT24 (8388608.0)
2816
#define INTERCEPT_U_INT32 (2147483648.0)
2817
2818
/*
2819
MIN_INTN = -(2^(N-1))
2820
*/
2821
#define MIN_INT8 (-128.0)
2822
#define MIN_INT16 (-32768.0)
2823
#define MIN_INT24 (-8388608.0)
2824
#define MIN_INT32 (-2147483648.0)
2825
2826
/*
2827
MAX_INTN = 2^(N-1) - 1
2828
*/
2829
#define MAX_INT8 127.0
2830
#define MAX_INT16 32767.0
2831
#define MAX_INT24 8388607.0
2832
#define MAX_INT32 2147483647.0
2833
2834
/*
2835
MAX_U_INTN = 2^N - 1
2836
*/
2837
#define MAX_U_INT8 255.0
2838
#define MAX_U_INT16 65535.0
2839
#define MAX_U_INT24 16777215.0
2840
#define MAX_U_INT32 4294967295.0
2841
2842
extern const PCMInfo _af_default_signed_integer_pcm_mappings[];
2843
extern const PCMInfo _af_default_unsigned_integer_pcm_mappings[];
2844
extern const PCMInfo _af_default_float_pcm_mapping;
2845
extern const PCMInfo _af_default_double_pcm_mapping;
2846
2847
#endif
2848
2849
// file: g711.h
2850
/*
2851
* This source code is a product of Sun Microsystems, Inc. and is provided
2852
* for unrestricted use. Users may copy or modify this source code without
2853
* charge.
2854
*
2855
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
2856
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
2857
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
2858
*
2859
* Sun source code is provided with no support and without any obligation on
2860
* the part of Sun Microsystems, Inc. to assist in its use, correction,
2861
* modification or enhancement.
2862
*
2863
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
2864
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
2865
* OR ANY PART THEREOF.
2866
*
2867
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
2868
* or profits or other special, indirect and consequential damages, even if
2869
* Sun has been advised of the possibility of such damages.
2870
*
2871
* Sun Microsystems, Inc.
2872
* 2550 Garcia Avenue
2873
* Mountain View, California 94043
2874
*/
2875
2876
/*
2877
* g711.h
2878
*
2879
* u-law, A-law and linear PCM conversions.
2880
*/
2881
2882
#ifndef G711_H
2883
#define G711_H
2884
2885
#ifdef __cplusplus
2886
extern "C" {
2887
#endif
2888
2889
/*
2890
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
2891
*
2892
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
2893
*
2894
* Linear Input Code Compressed Code
2895
* ------------------------ ---------------
2896
* 0000000wxyza 000wxyz
2897
* 0000001wxyza 001wxyz
2898
* 000001wxyzab 010wxyz
2899
* 00001wxyzabc 011wxyz
2900
* 0001wxyzabcd 100wxyz
2901
* 001wxyzabcde 101wxyz
2902
* 01wxyzabcdef 110wxyz
2903
* 1wxyzabcdefg 111wxyz
2904
*
2905
* For further information see John C. Bellamy's Digital Telephony, 1982,
2906
* John Wiley & Sons, pps 98-111 and 472-476.
2907
*/
2908
2909
/* pcm_val is 2's complement (16-bit range) */
2910
unsigned char _af_linear2alaw (int pcm_val);
2911
2912
/*
2913
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
2914
*
2915
*/
2916
2917
int _af_alaw2linear (unsigned char a_val);
2918
2919
/*
2920
* linear2ulaw() - Convert a linear PCM value to u-law
2921
*
2922
* In order to simplify the encoding process, the original linear magnitude
2923
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
2924
* (33 - 8191). The result can be seen in the following encoding table:
2925
*
2926
* Biased Linear Input Code Compressed Code
2927
* ------------------------ ---------------
2928
* 00000001wxyza 000wxyz
2929
* 0000001wxyzab 001wxyz
2930
* 000001wxyzabc 010wxyz
2931
* 00001wxyzabcd 011wxyz
2932
* 0001wxyzabcde 100wxyz
2933
* 001wxyzabcdef 101wxyz
2934
* 01wxyzabcdefg 110wxyz
2935
* 1wxyzabcdefgh 111wxyz
2936
*
2937
* Each biased linear code has a leading 1 which identifies the segment
2938
* number. The value of the segment number is equal to 7 minus the number
2939
* of leading 0's. The quantization interval is directly available as the
2940
* four bits wxyz. * The trailing bits (a - h) are ignored.
2941
*
2942
* Ordinarily the complement of the resulting code word is used for
2943
* transmission, and so the code word is complemented before it is returned.
2944
*
2945
* For further information see John C. Bellamy's Digital Telephony, 1982,
2946
* John Wiley & Sons, pps 98-111 and 472-476.
2947
*/
2948
2949
/* pcm_val is 2's complement (16-bit range) */
2950
unsigned char _af_linear2ulaw (int pcm_val);
2951
2952
/*
2953
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
2954
*
2955
* First, a biased linear code is derived from the code word. An unbiased
2956
* output can then be obtained by subtracting 33 from the biased code.
2957
*
2958
* Note that this function expects to be passed the complement of the
2959
* original code word. This is in keeping with ISDN conventions.
2960
*/
2961
2962
int _af_ulaw2linear (unsigned char u_val);
2963
2964
#ifdef __cplusplus
2965
}
2966
#endif
2967
2968
#endif /* G711_H */
2969
2970
// file: af_vfs.h
2971
/*
2972
Audio File Library
2973
Copyright (C) 1999, Elliot Lee <[email protected]>
2974
2975
This library is free software; you can redistribute it and/or
2976
modify it under the terms of the GNU Lesser General Public
2977
License as published by the Free Software Foundation; either
2978
version 2.1 of the License, or (at your option) any later version.
2979
2980
This library is distributed in the hope that it will be useful,
2981
but WITHOUT ANY WARRANTY; without even the implied warranty of
2982
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2983
Lesser General Public License for more details.
2984
2985
You should have received a copy of the GNU Lesser General Public
2986
License along with this library; if not, write to the
2987
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
2988
Boston, MA 02110-1301 USA
2989
*/
2990
2991
/*
2992
af_vfs.h
2993
2994
Virtual file operations for the Audio File Library.
2995
*/
2996
2997
#ifndef AUDIOFILE_VFS_H
2998
#define AUDIOFILE_VFS_H
2999
3000
#include <audiofile.h>
3001
#include <sys/types.h>
3002
3003
#ifdef __cplusplus
3004
extern "C" {
3005
#endif
3006
3007
#if (defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)
3008
#define AFAPI __attribute__((visibility("default")))
3009
#else
3010
#define AFAPI
3011
#endif
3012
3013
struct _AFvirtualfile
3014
{
3015
ssize_t (*read) (AFvirtualfile *vfile, void *data, size_t nbytes);
3016
AFfileoffset (*length) (AFvirtualfile *vfile);
3017
ssize_t (*write) (AFvirtualfile *vfile, const void *data, size_t nbytes);
3018
void (*destroy) (AFvirtualfile *vfile);
3019
AFfileoffset (*seek) (AFvirtualfile *vfile, AFfileoffset offset, int is_relative);
3020
AFfileoffset (*tell) (AFvirtualfile *vfile);
3021
3022
void *closure;
3023
};
3024
3025
AFAPI AFvirtualfile *af_virtual_file_new (void);
3026
AFAPI void af_virtual_file_destroy (AFvirtualfile *vfile);
3027
3028
#undef AFAPI
3029
3030
#ifdef __cplusplus
3031
}
3032
#endif
3033
3034
#endif
3035
3036
// file: Raw.h
3037
/*
3038
Audio File Library
3039
Copyright (C) 2000, Silicon Graphics, Inc.
3040
3041
This library is free software; you can redistribute it and/or
3042
modify it under the terms of the GNU Lesser General Public
3043
License as published by the Free Software Foundation; either
3044
version 2.1 of the License, or (at your option) any later version.
3045
3046
This library is distributed in the hope that it will be useful,
3047
but WITHOUT ANY WARRANTY; without even the implied warranty of
3048
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3049
Lesser General Public License for more details.
3050
3051
You should have received a copy of the GNU Lesser General Public
3052
License along with this library; if not, write to the
3053
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3054
Boston, MA 02110-1301 USA
3055
*/
3056
3057
/*
3058
Raw.h
3059
*/
3060
3061
#ifndef RAW_H
3062
#define RAW_H
3063
3064
3065
#define _AF_RAW_NUM_COMPTYPES 2
3066
extern const int _af_raw_compression_types[_AF_RAW_NUM_COMPTYPES];
3067
3068
class RawFile : public _AFfilehandle
3069
{
3070
public:
3071
static bool recognize(File *fh);
3072
static AFfilesetup completeSetup(AFfilesetup);
3073
3074
status readInit(AFfilesetup setup) OVERRIDE;
3075
status writeInit(AFfilesetup setup) OVERRIDE;
3076
status update() OVERRIDE;
3077
};
3078
3079
#endif
3080
3081
// file: WAVE.h
3082
/*
3083
Audio File Library
3084
Copyright (C) 1998-2000, 2003, 2010-2012, Michael Pruett <[email protected]>
3085
Copyright (C) 2002-2003, Davy Durham
3086
Copyright (C) 2000-2001, Silicon Graphics, Inc.
3087
3088
This library is free software; you can redistribute it and/or
3089
modify it under the terms of the GNU Lesser General Public
3090
License as published by the Free Software Foundation; either
3091
version 2.1 of the License, or (at your option) any later version.
3092
3093
This library is distributed in the hope that it will be useful,
3094
but WITHOUT ANY WARRANTY; without even the implied warranty of
3095
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3096
Lesser General Public License for more details.
3097
3098
You should have received a copy of the GNU Lesser General Public
3099
License along with this library; if not, write to the
3100
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3101
Boston, MA 02110-1301 USA
3102
*/
3103
3104
/*
3105
WAVE.h
3106
3107
This file contains structures and constants related to the RIFF
3108
WAVE sound file format.
3109
*/
3110
3111
#ifndef WAVE_H
3112
#define WAVE_H
3113
3114
#include <stdint.h>
3115
3116
#define _AF_WAVE_NUM_INSTPARAMS 7
3117
extern const InstParamInfo _af_wave_inst_params[_AF_WAVE_NUM_INSTPARAMS];
3118
#define _AF_WAVE_NUM_COMPTYPES 4
3119
extern const int _af_wave_compression_types[_AF_WAVE_NUM_COMPTYPES];
3120
3121
struct UUID;
3122
3123
class WAVEFile : public _AFfilehandle
3124
{
3125
public:
3126
static bool recognize(File *fh);
3127
static AFfilesetup completeSetup(AFfilesetup);
3128
3129
WAVEFile();
3130
3131
status readInit(AFfilesetup) OVERRIDE;
3132
status writeInit(AFfilesetup) OVERRIDE;
3133
3134
status update() OVERRIDE;
3135
3136
bool isInstrumentParameterValid(AUpvlist, int) OVERRIDE;
3137
3138
private:
3139
AFfileoffset m_factOffset; // start of fact (frame count) chunk
3140
AFfileoffset m_miscellaneousOffset;
3141
AFfileoffset m_markOffset;
3142
AFfileoffset m_dataSizeOffset;
3143
3144
/*
3145
The index into the coefficient array is of type
3146
uint8_t, so we can safely limit msadpcmCoefficients to
3147
be 256 coefficient pairs.
3148
*/
3149
int m_msadpcmNumCoefficients;
3150
int16_t m_msadpcmCoefficients[256][2];
3151
3152
status parseFrameCount(const Tag &type, uint32_t size);
3153
status parseFormat(const Tag &type, uint32_t size);
3154
status parseData(const Tag &type, uint32_t size);
3155
status parsePlayList(const Tag &type, uint32_t size);
3156
status parseCues(const Tag &type, uint32_t size);
3157
status parseADTLSubChunk(const Tag &type, uint32_t size);
3158
status parseINFOSubChunk(const Tag &type, uint32_t size);
3159
status parseList(const Tag &type, uint32_t size);
3160
status parseInstrument(const Tag &type, uint32_t size);
3161
3162
status writeFormat();
3163
status writeFrameCount();
3164
status writeMiscellaneous();
3165
status writeCues();
3166
status writeData();
3167
3168
bool readUUID(UUID *g);
3169
bool writeUUID(const UUID *g);
3170
3171
bool writeZString(const char *);
3172
size_t zStringLength(const char *);
3173
3174
void initCompressionParams();
3175
void initIMACompressionParams();
3176
void initMSADPCMCompressionParams();
3177
};
3178
3179
#endif
3180
3181
// file: SampleVision.h
3182
/*
3183
Audio File Library
3184
Copyright (C) 2012, Michael Pruett <[email protected]>
3185
3186
This library is free software; you can redistribute it and/or
3187
modify it under the terms of the GNU Lesser General Public
3188
License as published by the Free Software Foundation; either
3189
version 2.1 of the License, or (at your option) any later version.
3190
3191
This library is distributed in the hope that it will be useful,
3192
but WITHOUT ANY WARRANTY; without even the implied warranty of
3193
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3194
Lesser General Public License for more details.
3195
3196
You should have received a copy of the GNU Lesser General Public
3197
License along with this library; if not, write to the
3198
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3199
Boston, MA 02110-1301 USA
3200
*/
3201
3202
#ifndef SAMPLE_VISION_H
3203
#define SAMPLE_VISION_H
3204
3205
3206
class SampleVisionFile : public _AFfilehandle
3207
{
3208
public:
3209
SampleVisionFile();
3210
virtual ~SampleVisionFile();
3211
3212
static bool recognize(File *fh);
3213
3214
static AFfilesetup completeSetup(AFfilesetup);
3215
3216
status readInit(AFfilesetup) OVERRIDE;
3217
status writeInit(AFfilesetup) OVERRIDE;
3218
3219
status update() OVERRIDE;
3220
3221
private:
3222
AFfileoffset m_frameCountOffset;
3223
3224
status parseLoops();
3225
status parseMarkers();
3226
status writeTrailer();
3227
status writeLoops();
3228
status writeMarkers();
3229
3230
void addMiscellaneous(int type, const char *data);
3231
};
3232
3233
#endif
3234
3235
// file: modules/Module.h
3236
/*
3237
Audio File Library
3238
Copyright (C) 2000, Silicon Graphics, Inc.
3239
Copyright (C) 2010, Michael Pruett <[email protected]>
3240
3241
This library is free software; you can redistribute it and/or
3242
modify it under the terms of the GNU Lesser General Public
3243
License as published by the Free Software Foundation; either
3244
version 2.1 of the License, or (at your option) any later version.
3245
3246
This library is distributed in the hope that it will be useful,
3247
but WITHOUT ANY WARRANTY; without even the implied warranty of
3248
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3249
Lesser General Public License for more details.
3250
3251
You should have received a copy of the GNU Lesser General Public
3252
License along with this library; if not, write to the
3253
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3254
Boston, MA 02110-1301 USA
3255
*/
3256
3257
#ifndef MODULE_H
3258
#define MODULE_H
3259
3260
3261
#include <vector>
3262
3263
enum FormatCode
3264
{
3265
kUndefined = -1,
3266
kInt8,
3267
kInt16,
3268
kInt24,
3269
kInt32,
3270
kFloat,
3271
kDouble,
3272
};
3273
3274
class Chunk : public Shared<Chunk>
3275
{
3276
public:
3277
void *buffer;
3278
size_t frameCount;
3279
AudioFormat f;
3280
bool ownsMemory;
3281
3282
Chunk() : buffer(NULL), frameCount(0), ownsMemory(false) { }
3283
~Chunk()
3284
{
3285
deallocate();
3286
}
3287
void allocate(size_t capacity)
3288
{
3289
deallocate();
3290
ownsMemory = true;
3291
buffer = ::operator new(capacity);
3292
}
3293
void deallocate()
3294
{
3295
if (ownsMemory)
3296
::operator delete(buffer);
3297
ownsMemory = false;
3298
buffer = NULL;
3299
}
3300
};
3301
3302
class Module : public Shared<Module>
3303
{
3304
public:
3305
Module();
3306
virtual ~Module();
3307
3308
void setSink(Module *);
3309
void setSource(Module *);
3310
Chunk *inChunk() const { return m_inChunk.get(); }
3311
void setInChunk(Chunk *chunk) { m_inChunk = chunk; }
3312
Chunk *outChunk() const { return m_outChunk.get(); }
3313
void setOutChunk(Chunk *chunk) { m_outChunk = chunk; }
3314
3315
virtual const char *name() const;
3316
/*
3317
Set format of m_outChunk based on how this module transforms m_inChunk.
3318
*/
3319
virtual void describe();
3320
/*
3321
Set frame count of m_inChunk to the maximum number of frames needed to
3322
produce frame count of m_outChunk.
3323
*/
3324
virtual void maxPull();
3325
/*
3326
Set frame count of m_outChunk to the maximum number of frames needed to
3327
produce frame count of m_inChunk.
3328
*/
3329
virtual void maxPush();
3330
virtual void runPull();
3331
virtual void reset1() { }
3332
virtual void reset2() { }
3333
virtual void runPush();
3334
virtual void sync1() { }
3335
virtual void sync2() { }
3336
3337
protected:
3338
SharedPtr<Chunk> m_inChunk, m_outChunk;
3339
union
3340
{
3341
Module *m_sink;
3342
Module *m_source;
3343
};
3344
3345
void pull(size_t frames);
3346
void push(size_t frames);
3347
};
3348
3349
/*
3350
_AF_ATOMIC_NVFRAMES is NOT the maximum number of frames a module
3351
can be requested to produce.
3352
3353
This IS the maximum number of virtual (user) frames that will
3354
be produced or processed per run of the modules.
3355
3356
Modules can be requested more frames than this because of rate
3357
conversion and rebuffering.
3358
*/
3359
3360
#define _AF_ATOMIC_NVFRAMES 1024
3361
3362
#endif // MODULE_H
3363
3364
// file: modules/ModuleState.h
3365
/*
3366
Audio File Library
3367
Copyright (C) 2000, Silicon Graphics, Inc.
3368
Copyright (C) 2010, Michael Pruett <[email protected]>
3369
3370
This library is free software; you can redistribute it and/or
3371
modify it under the terms of the GNU Lesser General Public
3372
License as published by the Free Software Foundation; either
3373
version 2.1 of the License, or (at your option) any later version.
3374
3375
This library is distributed in the hope that it will be useful,
3376
but WITHOUT ANY WARRANTY; without even the implied warranty of
3377
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3378
Lesser General Public License for more details.
3379
3380
You should have received a copy of the GNU Lesser General Public
3381
License along with this library; if not, write to the
3382
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3383
Boston, MA 02110-1301 USA
3384
*/
3385
3386
#ifndef MODULESTATE_H
3387
#define MODULESTATE_H
3388
3389
#include <vector>
3390
3391
class FileModule;
3392
class Module;
3393
3394
class ModuleState : public Shared<ModuleState>
3395
{
3396
public:
3397
ModuleState();
3398
virtual ~ModuleState();
3399
3400
bool isDirty() const { return m_isDirty; }
3401
void setDirty() { m_isDirty = true; }
3402
status init(AFfilehandle file, Track *track);
3403
status setup(AFfilehandle file, Track *track);
3404
status reset(AFfilehandle file, Track *track);
3405
status sync(AFfilehandle file, Track *track);
3406
3407
int numModules() const { return m_modules.size(); }
3408
const std::vector<SharedPtr<Module> > &modules() const;
3409
const std::vector<SharedPtr<Chunk> > &chunks() const;
3410
3411
bool mustUseAtomicNVFrames() const { return true; }
3412
3413
void print();
3414
3415
bool fileModuleHandlesSeeking() const;
3416
3417
private:
3418
std::vector<SharedPtr<Module> > m_modules;
3419
std::vector<SharedPtr<Chunk> > m_chunks;
3420
bool m_isDirty;
3421
3422
SharedPtr<FileModule> m_fileModule;
3423
SharedPtr<Module> m_fileRebufferModule;
3424
3425
status initFileModule(AFfilehandle file, Track *track);
3426
3427
status arrange(AFfilehandle file, Track *track);
3428
3429
void addModule(Module *module);
3430
3431
void addConvertIntToInt(FormatCode input, FormatCode output);
3432
void addConvertIntToFloat(FormatCode input, FormatCode output);
3433
void addConvertFloatToInt(FormatCode input, FormatCode output,
3434
const PCMInfo &inputMapping, const PCMInfo &outputMapping);
3435
void addConvertFloatToFloat(FormatCode input, FormatCode output);
3436
};
3437
3438
#endif
3439
3440
// file: modules/SimpleModule.h
3441
/*
3442
Audio File Library
3443
Copyright (C) 2010, Michael Pruett <[email protected]>
3444
3445
This library is free software; you can redistribute it and/or
3446
modify it under the terms of the GNU Lesser General Public
3447
License as published by the Free Software Foundation; either
3448
version 2.1 of the License, or (at your option) any later version.
3449
3450
This library is distributed in the hope that it will be useful,
3451
but WITHOUT ANY WARRANTY; without even the implied warranty of
3452
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3453
Lesser General Public License for more details.
3454
3455
You should have received a copy of the GNU Lesser General Public
3456
License along with this library; if not, write to the
3457
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
3458
Boston, MA 02110-1301 USA
3459
*/
3460
3461
#ifndef SIMPLE_MODULE_H
3462
#define SIMPLE_MODULE_H
3463
3464
3465
3466
#include <algorithm>
3467
#include <cassert>
3468
#include <climits>
3469
#include <functional>
3470
3471
class SimpleModule : public Module
3472
{
3473
public:
3474
virtual void runPull() OVERRIDE;
3475
virtual void runPush() OVERRIDE;
3476
virtual void run(Chunk &inChunk, Chunk &outChunk) = 0;
3477
};
3478
3479
struct SwapModule : public SimpleModule
3480
{
3481
public:
3482
virtual const char *name() const OVERRIDE { return "swap"; }
3483
virtual void describe() OVERRIDE
3484
{
3485
m_outChunk->f.byteOrder = m_inChunk->f.byteOrder == AF_BYTEORDER_BIGENDIAN ?
3486
AF_BYTEORDER_LITTLEENDIAN : AF_BYTEORDER_BIGENDIAN;
3487
}
3488
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3489
{
3490
switch (m_inChunk->f.bytesPerSample(false))
3491
{
3492
case 2:
3493
run<2, int16_t>(inChunk, outChunk); break;
3494
case 3:
3495
run<3, char>(inChunk, outChunk); break;
3496
case 4:
3497
run<4, int32_t>(inChunk, outChunk); break;
3498
case 8:
3499
run<8, int64_t>(inChunk, outChunk); break;
3500
default:
3501
assert(false); break;
3502
}
3503
}
3504
3505
private:
3506
template <int N, typename T>
3507
void run(Chunk &inChunk, Chunk &outChunk)
3508
{
3509
int sampleCount = inChunk.f.channelCount * inChunk.frameCount;
3510
runSwap<N, T>(reinterpret_cast<const T *>(inChunk.buffer),
3511
reinterpret_cast<T *>(outChunk.buffer),
3512
sampleCount);
3513
}
3514
template <int N, typename T>
3515
void runSwap(const T *input, T *output, int sampleCount)
3516
{
3517
for (int i=0; i<sampleCount; i++)
3518
output[i] = byteswap(input[i]);
3519
}
3520
};
3521
3522
template <>
3523
inline void SwapModule::runSwap<3, char>(const char *input, char *output, int count)
3524
{
3525
for (int i=0; i<count; i++)
3526
{
3527
output[3*i] = input[3*i+2];
3528
output[3*i+1] = input[3*i+1];
3529
output[3*i+2] = input[3*i];
3530
}
3531
}
3532
3533
template <typename UnaryFunction>
3534
void transform(const void *srcData, void *dstData, size_t count)
3535
{
3536
typedef typename UnaryFunction::argument_type InputType;
3537
typedef typename UnaryFunction::result_type OutputType;
3538
const InputType *src = reinterpret_cast<const InputType *>(srcData);
3539
OutputType *dst = reinterpret_cast<OutputType *>(dstData);
3540
std::transform(src, src + count, dst, UnaryFunction());
3541
}
3542
3543
template <FormatCode>
3544
struct IntTypes;
3545
3546
template <>
3547
struct IntTypes<kInt8> { typedef int8_t SignedType; typedef uint8_t UnsignedType; };
3548
template <>
3549
struct IntTypes<kInt16> { typedef int16_t SignedType; typedef uint16_t UnsignedType; };
3550
template <>
3551
struct IntTypes<kInt24> { typedef int32_t SignedType; typedef uint32_t UnsignedType; };
3552
template <>
3553
struct IntTypes<kInt32> { typedef int32_t SignedType; typedef uint32_t UnsignedType; };
3554
3555
template <FormatCode Format>
3556
struct signConverter
3557
{
3558
typedef typename IntTypes<Format>::SignedType SignedType;
3559
typedef typename IntTypes<Format>::UnsignedType UnsignedType;
3560
3561
static const int kScaleBits = (Format + 1) * CHAR_BIT - 1;
3562
static const int kMaxSignedValue = (((1 << (kScaleBits - 1)) - 1) << 1) + 1;
3563
static const int kMinSignedValue = -kMaxSignedValue - 1;
3564
3565
struct signedToUnsigned : public std::unary_function<SignedType, UnsignedType>
3566
{
3567
UnsignedType operator()(SignedType x) { return x - kMinSignedValue; }
3568
};
3569
3570
struct unsignedToSigned : public std::unary_function<SignedType, UnsignedType>
3571
{
3572
SignedType operator()(UnsignedType x) { return x + kMinSignedValue; }
3573
};
3574
};
3575
3576
class ConvertSign : public SimpleModule
3577
{
3578
public:
3579
ConvertSign(FormatCode format, bool fromSigned) :
3580
m_format(format),
3581
m_fromSigned(fromSigned)
3582
{
3583
}
3584
virtual const char *name() const OVERRIDE { return "sign"; }
3585
virtual void describe() OVERRIDE
3586
{
3587
const int scaleBits = m_inChunk->f.bytesPerSample(false) * CHAR_BIT;
3588
m_outChunk->f.sampleFormat =
3589
m_fromSigned ? AF_SAMPFMT_UNSIGNED : AF_SAMPFMT_TWOSCOMP;
3590
double shift = -(1 << (scaleBits - 1));
3591
if (m_fromSigned)
3592
shift = -shift;
3593
m_outChunk->f.pcm.intercept += shift;
3594
m_outChunk->f.pcm.minClip += shift;
3595
m_outChunk->f.pcm.maxClip += shift;
3596
}
3597
virtual void run(Chunk &input, Chunk &output) OVERRIDE
3598
{
3599
size_t count = input.frameCount * m_inChunk->f.channelCount;
3600
if (m_fromSigned)
3601
convertSignedToUnsigned(input.buffer, output.buffer, count);
3602
else
3603
convertUnsignedToSigned(input.buffer, output.buffer, count);
3604
}
3605
3606
private:
3607
FormatCode m_format;
3608
bool m_fromSigned;
3609
3610
template <FormatCode Format>
3611
static void convertSignedToUnsigned(const void *src, void *dst, size_t count)
3612
{
3613
transform<typename signConverter<Format>::signedToUnsigned>(src, dst, count);
3614
}
3615
void convertSignedToUnsigned(const void *src, void *dst, size_t count)
3616
{
3617
switch (m_format)
3618
{
3619
case kInt8:
3620
convertSignedToUnsigned<kInt8>(src, dst, count);
3621
break;
3622
case kInt16:
3623
convertSignedToUnsigned<kInt16>(src, dst, count);
3624
break;
3625
case kInt24:
3626
convertSignedToUnsigned<kInt24>(src, dst, count);
3627
break;
3628
case kInt32:
3629
convertSignedToUnsigned<kInt32>(src, dst, count);
3630
break;
3631
default:
3632
assert(false);
3633
}
3634
}
3635
3636
template <FormatCode Format>
3637
static void convertUnsignedToSigned(const void *src, void *dst, size_t count)
3638
{
3639
transform<typename signConverter<Format>::unsignedToSigned>(src, dst, count);
3640
}
3641
void convertUnsignedToSigned(const void *src, void *dst, size_t count)
3642
{
3643
switch (m_format)
3644
{
3645
case kInt8:
3646
convertUnsignedToSigned<kInt8>(src, dst, count);
3647
break;
3648
case kInt16:
3649
convertUnsignedToSigned<kInt16>(src, dst, count);
3650
break;
3651
case kInt24:
3652
convertUnsignedToSigned<kInt24>(src, dst, count);
3653
break;
3654
case kInt32:
3655
convertUnsignedToSigned<kInt32>(src, dst, count);
3656
break;
3657
default:
3658
assert(false);
3659
}
3660
}
3661
};
3662
3663
struct Expand3To4Module : public SimpleModule
3664
{
3665
public:
3666
Expand3To4Module(bool isSigned) : m_isSigned(isSigned)
3667
{
3668
}
3669
virtual const char *name() const OVERRIDE { return "expand3to4"; }
3670
virtual void describe() OVERRIDE
3671
{
3672
m_outChunk->f.packed = false;
3673
}
3674
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3675
{
3676
int count = inChunk.f.channelCount * inChunk.frameCount;
3677
if (m_isSigned)
3678
run<int32_t>(reinterpret_cast<const uint8_t *>(inChunk.buffer),
3679
reinterpret_cast<int32_t *>(outChunk.buffer),
3680
count);
3681
else
3682
run<uint32_t>(reinterpret_cast<const uint8_t *>(inChunk.buffer),
3683
reinterpret_cast<uint32_t *>(outChunk.buffer),
3684
count);
3685
}
3686
3687
private:
3688
bool m_isSigned;
3689
3690
template <typename T>
3691
void run(const uint8_t *input, T *output, int sampleCount)
3692
{
3693
for (int i=0; i<sampleCount; i++)
3694
{
3695
T t =
3696
#ifdef WORDS_BIGENDIAN
3697
(input[3*i] << 24) |
3698
(input[3*i+1] << 16) |
3699
input[3*i+2] << 8;
3700
#else
3701
(input[3*i+2] << 24) |
3702
(input[3*i+1] << 16) |
3703
input[3*i] << 8;
3704
#endif
3705
output[i] = t >> 8;
3706
}
3707
}
3708
};
3709
3710
struct Compress4To3Module : public SimpleModule
3711
{
3712
public:
3713
Compress4To3Module(bool isSigned) : m_isSigned(isSigned)
3714
{
3715
}
3716
virtual const char *name() const OVERRIDE { return "compress4to3"; }
3717
virtual void describe() OVERRIDE
3718
{
3719
m_outChunk->f.packed = true;
3720
}
3721
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3722
{
3723
int count = inChunk.f.channelCount * inChunk.frameCount;
3724
if (m_isSigned)
3725
run<int32_t>(inChunk.buffer, outChunk.buffer, count);
3726
else
3727
run<uint32_t>(inChunk.buffer, outChunk.buffer, count);
3728
}
3729
3730
private:
3731
bool m_isSigned;
3732
3733
template <typename T>
3734
void run(const void *input, void *output, int count)
3735
{
3736
const T *in = reinterpret_cast<const T *>(input);
3737
uint8_t *out = reinterpret_cast<uint8_t *>(output);
3738
for (int i=0; i<count; i++)
3739
{
3740
uint8_t c0, c1, c2;
3741
extract3(in[i], c0, c1, c2);
3742
out[3*i] = c0;
3743
out[3*i+1] = c1;
3744
out[3*i+2] = c2;
3745
}
3746
}
3747
template <typename T>
3748
void extract3(T in, uint8_t &c0, uint8_t &c1, uint8_t &c2)
3749
{
3750
#ifdef WORDS_BIGENDIAN
3751
c0 = (in >> 16) & 0xff;
3752
c1 = (in >> 8) & 0xff;
3753
c2 = in & 0xff;
3754
#else
3755
c2 = (in >> 16) & 0xff;
3756
c1 = (in >> 8) & 0xff;
3757
c0 = in & 0xff;
3758
#endif
3759
}
3760
};
3761
3762
template <typename Arg, typename Result>
3763
struct intToFloat : public std::unary_function<Arg, Result>
3764
{
3765
Result operator()(Arg x) const { return x; }
3766
};
3767
3768
struct ConvertIntToFloat : public SimpleModule
3769
{
3770
ConvertIntToFloat(FormatCode inFormat, FormatCode outFormat) :
3771
m_inFormat(inFormat), m_outFormat(outFormat)
3772
{
3773
}
3774
virtual const char *name() const OVERRIDE { return "intToFloat"; }
3775
virtual void describe() OVERRIDE
3776
{
3777
m_outChunk->f.sampleFormat = m_outFormat == kDouble ?
3778
AF_SAMPFMT_DOUBLE : AF_SAMPFMT_FLOAT;
3779
m_outChunk->f.sampleWidth = m_outFormat == kDouble ? 64 : 32;
3780
}
3781
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3782
{
3783
const void *src = inChunk.buffer;
3784
void *dst = outChunk.buffer;
3785
int count = inChunk.frameCount * inChunk.f.channelCount;
3786
if (m_outFormat == kFloat)
3787
{
3788
switch (m_inFormat)
3789
{
3790
case kInt8:
3791
run<int8_t, float>(src, dst, count); break;
3792
case kInt16:
3793
run<int16_t, float>(src, dst, count); break;
3794
case kInt24:
3795
case kInt32:
3796
run<int32_t, float>(src, dst, count); break;
3797
default:
3798
assert(false);
3799
}
3800
}
3801
else if (m_outFormat == kDouble)
3802
{
3803
switch (m_inFormat)
3804
{
3805
case kInt8:
3806
run<int8_t, double>(src, dst, count); break;
3807
case kInt16:
3808
run<int16_t, double>(src, dst, count); break;
3809
case kInt24:
3810
case kInt32:
3811
run<int32_t, double>(src, dst, count); break;
3812
default:
3813
assert(false);
3814
}
3815
}
3816
}
3817
3818
private:
3819
FormatCode m_inFormat, m_outFormat;
3820
3821
template <typename Arg, typename Result>
3822
static void run(const void *src, void *dst, int count)
3823
{
3824
transform<intToFloat<Arg, Result> >(src, dst, count);
3825
}
3826
};
3827
3828
template <typename Arg, typename Result, unsigned shift>
3829
struct lshift : public std::unary_function<Arg, Result>
3830
{
3831
Result operator()(const Arg &x) const { return x << shift; }
3832
};
3833
3834
template <typename Arg, typename Result, unsigned shift>
3835
struct rshift : public std::unary_function<Arg, Result>
3836
{
3837
Result operator()(const Arg &x) const { return x >> shift; }
3838
};
3839
3840
struct ConvertInt : public SimpleModule
3841
{
3842
ConvertInt(FormatCode inFormat, FormatCode outFormat) :
3843
m_inFormat(inFormat),
3844
m_outFormat(outFormat)
3845
{
3846
assert(isInteger(m_inFormat));
3847
assert(isInteger(m_outFormat));
3848
}
3849
virtual const char *name() const OVERRIDE { return "convertInt"; }
3850
virtual void describe() OVERRIDE
3851
{
3852
getDefaultPCMMapping(m_outChunk->f.sampleWidth,
3853
m_outChunk->f.pcm.slope,
3854
m_outChunk->f.pcm.intercept,
3855
m_outChunk->f.pcm.minClip,
3856
m_outChunk->f.pcm.maxClip);
3857
}
3858
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3859
{
3860
const void *src = inChunk.buffer;
3861
void *dst = outChunk.buffer;
3862
size_t count = inChunk.frameCount * inChunk.f.channelCount;
3863
3864
#define MASK(N, M) (((N)<<3) | (M))
3865
#define HANDLE(N, M) \
3866
case MASK(N, M): convertInt<N, M>(src, dst, count); break;
3867
switch (MASK(m_inFormat, m_outFormat))
3868
{
3869
HANDLE(kInt8, kInt16)
3870
HANDLE(kInt8, kInt24)
3871
HANDLE(kInt8, kInt32)
3872
HANDLE(kInt16, kInt8)
3873
HANDLE(kInt16, kInt24)
3874
HANDLE(kInt16, kInt32)
3875
HANDLE(kInt24, kInt8)
3876
HANDLE(kInt24, kInt16)
3877
HANDLE(kInt24, kInt32)
3878
HANDLE(kInt32, kInt8)
3879
HANDLE(kInt32, kInt16)
3880
HANDLE(kInt32, kInt24)
3881
}
3882
#undef MASK
3883
#undef HANDLE
3884
}
3885
3886
private:
3887
FormatCode m_inFormat, m_outFormat;
3888
3889
void getDefaultPCMMapping(int &bits, double &slope, double &intercept,
3890
double &minClip, double &maxClip)
3891
{
3892
bits = (m_outFormat + 1) * CHAR_BIT;
3893
slope = (1LL << (bits - 1));
3894
intercept = 0;
3895
minClip = -(1 << (bits - 1));
3896
maxClip = (1LL << (bits - 1)) - 1;
3897
}
3898
3899
static bool isInteger(FormatCode code)
3900
{
3901
return code >= kInt8 && code <= kInt32;
3902
}
3903
3904
template <FormatCode Input, FormatCode Output, bool = (Input > Output)>
3905
struct shift;
3906
3907
template <FormatCode Input, FormatCode Output>
3908
struct shift<Input, Output, true> :
3909
public rshift<typename IntTypes<Input>::SignedType,
3910
typename IntTypes<Output>::SignedType,
3911
(Input - Output) * CHAR_BIT>
3912
{
3913
};
3914
3915
template <FormatCode Input, FormatCode Output>
3916
struct shift<Input, Output, false> :
3917
public lshift<typename IntTypes<Input>::SignedType,
3918
typename IntTypes<Output>::SignedType,
3919
(Output - Input) * CHAR_BIT>
3920
{
3921
};
3922
3923
template <FormatCode Input, FormatCode Output>
3924
static void convertInt(const void *src, void *dst, int count)
3925
{
3926
transform<shift<Input, Output> >(src, dst, count);
3927
}
3928
};
3929
3930
template <typename Arg, typename Result>
3931
struct floatToFloat : public std::unary_function<Arg, Result>
3932
{
3933
Result operator()(Arg x) const { return x; }
3934
};
3935
3936
struct ConvertFloat : public SimpleModule
3937
{
3938
ConvertFloat(FormatCode inFormat, FormatCode outFormat) :
3939
m_inFormat(inFormat), m_outFormat(outFormat)
3940
{
3941
assert((m_inFormat == kFloat && m_outFormat == kDouble) ||
3942
(m_inFormat == kDouble && m_outFormat == kFloat));
3943
}
3944
virtual const char *name() const OVERRIDE { return "convertFloat"; }
3945
virtual void describe() OVERRIDE
3946
{
3947
switch (m_outFormat)
3948
{
3949
case kFloat:
3950
m_outChunk->f.sampleFormat = AF_SAMPFMT_FLOAT;
3951
m_outChunk->f.sampleWidth = 32;
3952
break;
3953
case kDouble:
3954
m_outChunk->f.sampleFormat = AF_SAMPFMT_DOUBLE;
3955
m_outChunk->f.sampleWidth = 64;
3956
break;
3957
default:
3958
assert(false);
3959
}
3960
}
3961
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3962
{
3963
const void *src = inChunk.buffer;
3964
void *dst = outChunk.buffer;
3965
size_t count = inChunk.frameCount * inChunk.f.channelCount;
3966
3967
switch (m_outFormat)
3968
{
3969
case kFloat:
3970
transform<floatToFloat<double, float> >(src, dst, count);
3971
break;
3972
case kDouble:
3973
transform<floatToFloat<float, double> >(src, dst, count);
3974
break;
3975
default:
3976
assert(false);
3977
}
3978
}
3979
3980
private:
3981
FormatCode m_inFormat, m_outFormat;
3982
};
3983
3984
struct Clip : public SimpleModule
3985
{
3986
Clip(FormatCode format, const PCMInfo &outputMapping) :
3987
m_format(format),
3988
m_outputMapping(outputMapping)
3989
{
3990
}
3991
virtual const char *name() const OVERRIDE { return "clip"; }
3992
virtual void describe() OVERRIDE
3993
{
3994
m_outChunk->f.pcm = m_outputMapping;
3995
}
3996
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
3997
{
3998
const void *src = inChunk.buffer;
3999
void *dst = outChunk.buffer;
4000
int count = inChunk.frameCount * inChunk.f.channelCount;
4001
4002
switch (m_format)
4003
{
4004
case kInt8:
4005
run<int8_t>(src, dst, count); break;
4006
case kInt16:
4007
run<int16_t>(src, dst, count); break;
4008
case kInt24:
4009
case kInt32:
4010
run<int32_t>(src, dst, count); break;
4011
case kFloat:
4012
run<float>(src, dst, count); break;
4013
case kDouble:
4014
run<double>(src, dst, count); break;
4015
default:
4016
assert(false);
4017
}
4018
}
4019
4020
private:
4021
FormatCode m_format;
4022
PCMInfo m_outputMapping;
4023
4024
template <typename T>
4025
void run(const void *srcData, void *dstData, int count)
4026
{
4027
const T minValue = m_outputMapping.minClip;
4028
const T maxValue = m_outputMapping.maxClip;
4029
4030
const T *src = reinterpret_cast<const T *>(srcData);
4031
T *dst = reinterpret_cast<T *>(dstData);
4032
4033
for (int i=0; i<count; i++)
4034
{
4035
T t = src[i];
4036
t = std::min(t, maxValue);
4037
t = std::max(t, minValue);
4038
dst[i] = t;
4039
}
4040
}
4041
};
4042
4043
struct ConvertFloatToIntClip : public SimpleModule
4044
{
4045
ConvertFloatToIntClip(FormatCode inputFormat, FormatCode outputFormat,
4046
const PCMInfo &inputMapping, const PCMInfo &outputMapping) :
4047
m_inputFormat(inputFormat),
4048
m_outputFormat(outputFormat),
4049
m_inputMapping(inputMapping),
4050
m_outputMapping(outputMapping)
4051
{
4052
assert(m_inputFormat == kFloat || m_inputFormat == kDouble);
4053
assert(m_outputFormat == kInt8 ||
4054
m_outputFormat == kInt16 ||
4055
m_outputFormat == kInt24 ||
4056
m_outputFormat == kInt32);
4057
}
4058
virtual const char *name() const OVERRIDE { return "convertPCMMapping"; }
4059
virtual void describe() OVERRIDE
4060
{
4061
m_outChunk->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
4062
m_outChunk->f.sampleWidth = (m_outputFormat + 1) * CHAR_BIT;
4063
m_outChunk->f.pcm = m_outputMapping;
4064
}
4065
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
4066
{
4067
const void *src = inChunk.buffer;
4068
void *dst = outChunk.buffer;
4069
int count = inChunk.frameCount * inChunk.f.channelCount;
4070
4071
if (m_inputFormat == kFloat)
4072
{
4073
switch (m_outputFormat)
4074
{
4075
case kInt8:
4076
run<float, int8_t>(src, dst, count); break;
4077
case kInt16:
4078
run<float, int16_t>(src, dst, count); break;
4079
case kInt24:
4080
case kInt32:
4081
run<float, int32_t>(src, dst, count); break;
4082
default:
4083
assert(false);
4084
}
4085
}
4086
else if (m_inputFormat == kDouble)
4087
{
4088
switch (m_outputFormat)
4089
{
4090
case kInt8:
4091
run<double, int8_t>(src, dst, count); break;
4092
case kInt16:
4093
run<double, int16_t>(src, dst, count); break;
4094
case kInt24:
4095
case kInt32:
4096
run<double, int32_t>(src, dst, count); break;
4097
default:
4098
assert(false);
4099
}
4100
}
4101
}
4102
4103
private:
4104
FormatCode m_inputFormat, m_outputFormat;
4105
PCMInfo m_inputMapping, m_outputMapping;
4106
4107
template <typename Input, typename Output>
4108
void run(const void *srcData, void *dstData, int count)
4109
{
4110
const Input *src = reinterpret_cast<const Input *>(srcData);
4111
Output *dst = reinterpret_cast<Output *>(dstData);
4112
4113
double m = m_outputMapping.slope / m_inputMapping.slope;
4114
double b = m_outputMapping.intercept - m * m_inputMapping.intercept;
4115
double minValue = m_outputMapping.minClip;
4116
double maxValue = m_outputMapping.maxClip;
4117
4118
for (int i=0; i<count; i++)
4119
{
4120
double t = m * src[i] + b;
4121
t = std::min(t, maxValue);
4122
t = std::max(t, minValue);
4123
dst[i] = static_cast<Output>(t);
4124
}
4125
}
4126
};
4127
4128
struct ApplyChannelMatrix : public SimpleModule
4129
{
4130
public:
4131
ApplyChannelMatrix(FormatCode format, bool isReading,
4132
int inChannels, int outChannels,
4133
double minClip, double maxClip, const double *matrix);
4134
virtual ~ApplyChannelMatrix();
4135
virtual const char *name() const OVERRIDE;
4136
virtual void describe() OVERRIDE;
4137
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE;
4138
4139
private:
4140
FormatCode m_format;
4141
int m_inChannels, m_outChannels;
4142
double m_minClip, m_maxClip;
4143
double *m_matrix;
4144
4145
void initDefaultMatrix();
4146
template <typename T>
4147
void run(const void *input, void *output, int frameCount);
4148
};
4149
4150
struct Transform : public SimpleModule
4151
{
4152
public:
4153
Transform(FormatCode format,
4154
const PCMInfo &inputMapping,
4155
const PCMInfo &outputMapping) :
4156
m_format(format),
4157
m_inputMapping(inputMapping),
4158
m_outputMapping(outputMapping)
4159
{
4160
assert(m_format == kFloat || m_format == kDouble);
4161
}
4162
virtual const char *name() const OVERRIDE { return "transform"; }
4163
virtual void describe() OVERRIDE
4164
{
4165
m_outChunk->f.pcm = m_outputMapping;
4166
}
4167
virtual void run(Chunk &inChunk, Chunk &outChunk) OVERRIDE
4168
{
4169
int count = inChunk.frameCount * inChunk.f.channelCount;
4170
if (m_format == kFloat)
4171
run<float>(inChunk.buffer, outChunk.buffer, count);
4172
else if (m_format == kDouble)
4173
run<double>(inChunk.buffer, outChunk.buffer, count);
4174
else
4175
assert(false);
4176
}
4177
4178
private:
4179
FormatCode m_format;
4180
PCMInfo m_inputMapping, m_outputMapping;
4181
4182
template <typename T>
4183
void run(const void *srcData, void *dstData, int count)
4184
{
4185
const T *src = reinterpret_cast<const T *>(srcData);
4186
T *dst = reinterpret_cast<T *>(dstData);
4187
4188
double m = m_outputMapping.slope / m_inputMapping.slope;
4189
double b = m_outputMapping.intercept - m * m_inputMapping.intercept;
4190
4191
for (int i=0; i<count; i++)
4192
dst[i] = m * src[i] + b;
4193
}
4194
};
4195
4196
#endif // SIMPLE_MODULE_H
4197
4198
// file: modules/FileModule.h
4199
/*
4200
Audio File Library
4201
Copyright (C) 2010-2012, Michael Pruett <[email protected]>
4202
4203
This library is free software; you can redistribute it and/or
4204
modify it under the terms of the GNU Lesser General Public
4205
License as published by the Free Software Foundation; either
4206
version 2.1 of the License, or (at your option) any later version.
4207
4208
This library is distributed in the hope that it will be useful,
4209
but WITHOUT ANY WARRANTY; without even the implied warranty of
4210
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4211
Lesser General Public License for more details.
4212
4213
You should have received a copy of the GNU Lesser General Public
4214
License along with this library; if not, write to the
4215
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4216
Boston, MA 02110-1301 USA
4217
*/
4218
4219
#ifndef FILE_MODULE_H
4220
#define FILE_MODULE_H
4221
4222
4223
class FileModule : public Module
4224
{
4225
public:
4226
virtual bool handlesSeeking() const { return false; }
4227
4228
virtual int bufferSize() const;
4229
4230
protected:
4231
enum Mode { Compress, Decompress };
4232
FileModule(Mode, Track *, File *fh, bool canSeek);
4233
4234
Mode mode() const { return m_mode; }
4235
bool canSeek() const { return m_canSeek; }
4236
4237
ssize_t read(void *data, size_t nbytes);
4238
ssize_t write(const void *data, size_t nbytes);
4239
off_t seek(off_t offset);
4240
off_t tell();
4241
off_t length();
4242
4243
private:
4244
Mode m_mode;
4245
4246
protected:
4247
Track *m_track;
4248
4249
void reportReadError(AFframecount framesRead, AFframecount framesRequested);
4250
void reportWriteError(AFframecount framesWritten, AFframecount framesRequested);
4251
4252
private:
4253
File *m_fh;
4254
bool m_canSeek;
4255
};
4256
4257
#endif // FILE_MODULE_H
4258
4259
// file: modules/RebufferModule.h
4260
/*
4261
Audio File Library
4262
Copyright (C) 2000, Silicon Graphics, Inc.
4263
Copyright (C) 2010, Michael Pruett <[email protected]>
4264
4265
This library is free software; you can redistribute it and/or
4266
modify it under the terms of the GNU Lesser General Public
4267
License as published by the Free Software Foundation; either
4268
version 2.1 of the License, or (at your option) any later version.
4269
4270
This library is distributed in the hope that it will be useful,
4271
but WITHOUT ANY WARRANTY; without even the implied warranty of
4272
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4273
Lesser General Public License for more details.
4274
4275
You should have received a copy of the GNU Lesser General Public
4276
License along with this library; if not, write to the
4277
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4278
Boston, MA 02110-1301 USA
4279
*/
4280
4281
#ifndef REBUFFER_MODULE_H
4282
#define REBUFFER_MODULE_H
4283
4284
4285
class RebufferModule : public Module
4286
{
4287
public:
4288
enum Direction
4289
{
4290
FixedToVariable,
4291
VariableToFixed
4292
};
4293
4294
RebufferModule(Direction, int bytesPerFrame, int numFrames, bool multipleOf);
4295
virtual ~RebufferModule();
4296
4297
virtual const char *name() const OVERRIDE { return "rebuffer"; }
4298
4299
virtual void maxPull() OVERRIDE;
4300
virtual void maxPush() OVERRIDE;
4301
4302
virtual void runPull() OVERRIDE;
4303
virtual void reset1() OVERRIDE;
4304
virtual void reset2() OVERRIDE;
4305
virtual void runPush() OVERRIDE;
4306
virtual void sync1() OVERRIDE;
4307
virtual void sync2() OVERRIDE;
4308
4309
private:
4310
Direction m_direction;
4311
int m_bytesPerFrame;
4312
int m_numFrames;
4313
bool m_multipleOf; // buffer to multiple of m_numFrames
4314
bool m_eof; // end of input stream reached
4315
bool m_sentShortChunk; // end of input stream indicated
4316
char *m_buffer;
4317
int m_offset;
4318
char *m_savedBuffer;
4319
int m_savedOffset;
4320
4321
void initFixedToVariable();
4322
void initVariableToFixed();
4323
};
4324
4325
#endif // REBUFFER_MODULE_H
4326
4327
// file: modules/BlockCodec.h
4328
/*
4329
Audio File Library
4330
Copyright (C) 2013 Michael Pruett <[email protected]>
4331
4332
This library is free software; you can redistribute it and/or
4333
modify it under the terms of the GNU Lesser General Public
4334
License as published by the Free Software Foundation; either
4335
version 2.1 of the License, or (at your option) any later version.
4336
4337
This library is distributed in the hope that it will be useful,
4338
but WITHOUT ANY WARRANTY; without even the implied warranty of
4339
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4340
Lesser General Public License for more details.
4341
4342
You should have received a copy of the GNU Lesser General Public
4343
License along with this library; if not, write to the
4344
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4345
Boston, MA 02110-1301 USA
4346
*/
4347
4348
// BlockCodec is a base class for codecs with fixed-size packets.
4349
4350
#ifndef BlockCodec_h
4351
#define BlockCodec_h
4352
4353
4354
class BlockCodec : public FileModule
4355
{
4356
public:
4357
virtual void runPull() OVERRIDE;
4358
virtual void reset1() OVERRIDE;
4359
virtual void reset2() OVERRIDE;
4360
virtual void runPush() OVERRIDE;
4361
virtual void sync1() OVERRIDE;
4362
virtual void sync2() OVERRIDE;
4363
4364
protected:
4365
int m_bytesPerPacket, m_framesPerPacket;
4366
AFframecount m_framesToIgnore;
4367
AFfileoffset m_savedPositionNextFrame;
4368
AFframecount m_savedNextFrame;
4369
4370
BlockCodec(Mode, Track *, File *, bool canSeek);
4371
4372
virtual int decodeBlock(const uint8_t *encoded, int16_t *decoded) = 0;
4373
virtual int encodeBlock(const int16_t *decoded, uint8_t *encoded) = 0;
4374
};
4375
4376
#endif
4377
4378
// file: modules/BlockCodec.cpp
4379
/*
4380
Audio File Library
4381
Copyright (C) 2013 Michael Pruett <[email protected]>
4382
4383
This library is free software; you can redistribute it and/or
4384
modify it under the terms of the GNU Lesser General Public
4385
License as published by the Free Software Foundation; either
4386
version 2.1 of the License, or (at your option) any later version.
4387
4388
This library is distributed in the hope that it will be useful,
4389
but WITHOUT ANY WARRANTY; without even the implied warranty of
4390
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4391
Lesser General Public License for more details.
4392
4393
You should have received a copy of the GNU Lesser General Public
4394
License along with this library; if not, write to the
4395
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4396
Boston, MA 02110-1301 USA
4397
*/
4398
4399
4400
4401
#include <assert.h>
4402
4403
BlockCodec::BlockCodec(Mode mode, Track *track, File *fh, bool canSeek) :
4404
FileModule(mode, track, fh, canSeek),
4405
m_bytesPerPacket(-1),
4406
m_framesPerPacket(-1),
4407
m_framesToIgnore(-1),
4408
m_savedPositionNextFrame(-1),
4409
m_savedNextFrame(-1)
4410
{
4411
m_framesPerPacket = track->f.framesPerPacket;
4412
m_bytesPerPacket = track->f.bytesPerPacket;
4413
}
4414
4415
void BlockCodec::runPull()
4416
{
4417
AFframecount framesToRead = m_outChunk->frameCount;
4418
AFframecount framesRead = 0;
4419
4420
assert(framesToRead % m_framesPerPacket == 0);
4421
int blockCount = framesToRead / m_framesPerPacket;
4422
4423
// Read the compressed data.
4424
ssize_t bytesRead = read(m_inChunk->buffer, m_bytesPerPacket * blockCount);
4425
int blocksRead = bytesRead >= 0 ? bytesRead / m_bytesPerPacket : 0;
4426
4427
// Decompress into m_outChunk.
4428
for (int i=0; i<blocksRead; i++)
4429
{
4430
decodeBlock(static_cast<const uint8_t *>(m_inChunk->buffer) + i * m_bytesPerPacket,
4431
static_cast<int16_t *>(m_outChunk->buffer) + i * m_framesPerPacket * m_track->f.channelCount);
4432
4433
framesRead += m_framesPerPacket;
4434
}
4435
4436
m_track->nextfframe += framesRead;
4437
4438
assert(tell() == m_track->fpos_next_frame);
4439
4440
if (framesRead < framesToRead)
4441
reportReadError(framesRead, framesToRead);
4442
4443
m_outChunk->frameCount = framesRead;
4444
}
4445
4446
void BlockCodec::reset1()
4447
{
4448
AFframecount nextTrackFrame = m_track->nextfframe;
4449
m_track->nextfframe = (nextTrackFrame / m_framesPerPacket) *
4450
m_framesPerPacket;
4451
4452
m_framesToIgnore = nextTrackFrame - m_track->nextfframe;
4453
}
4454
4455
void BlockCodec::reset2()
4456
{
4457
m_track->fpos_next_frame = m_track->fpos_first_frame +
4458
m_bytesPerPacket * (m_track->nextfframe / m_framesPerPacket);
4459
m_track->frames2ignore += m_framesToIgnore;
4460
4461
assert(m_track->nextfframe % m_framesPerPacket == 0);
4462
}
4463
4464
void BlockCodec::runPush()
4465
{
4466
AFframecount framesToWrite = m_inChunk->frameCount;
4467
int channelCount = m_inChunk->f.channelCount;
4468
4469
int blockCount = (framesToWrite + m_framesPerPacket - 1) / m_framesPerPacket;
4470
for (int i=0; i<blockCount; i++)
4471
{
4472
encodeBlock(static_cast<const int16_t *>(m_inChunk->buffer) + i * m_framesPerPacket * channelCount,
4473
static_cast<uint8_t *>(m_outChunk->buffer) + i * m_bytesPerPacket);
4474
}
4475
4476
ssize_t bytesWritten = write(m_outChunk->buffer, m_bytesPerPacket * blockCount);
4477
ssize_t blocksWritten = bytesWritten >= 0 ? bytesWritten / m_bytesPerPacket : 0;
4478
AFframecount framesWritten = std::min((AFframecount) blocksWritten * m_framesPerPacket, framesToWrite);
4479
4480
m_track->nextfframe += framesWritten;
4481
m_track->totalfframes = m_track->nextfframe;
4482
4483
assert(tell() == m_track->fpos_next_frame);
4484
4485
if (framesWritten < framesToWrite)
4486
reportWriteError(framesWritten, framesToWrite);
4487
}
4488
4489
void BlockCodec::sync1()
4490
{
4491
m_savedPositionNextFrame = m_track->fpos_next_frame;
4492
m_savedNextFrame = m_track->nextfframe;
4493
}
4494
4495
void BlockCodec::sync2()
4496
{
4497
assert(tell() == m_track->fpos_next_frame);
4498
m_track->fpos_after_data = tell();
4499
m_track->fpos_next_frame = m_savedPositionNextFrame;
4500
m_track->nextfframe = m_savedNextFrame;
4501
}
4502
4503
// file: modules/FileModule.cpp
4504
/*
4505
Audio File Library
4506
Copyright (C) 2010-2012, Michael Pruett <[email protected]>
4507
4508
This library is free software; you can redistribute it and/or
4509
modify it under the terms of the GNU Lesser General Public
4510
License as published by the Free Software Foundation; either
4511
version 2.1 of the License, or (at your option) any later version.
4512
4513
This library is distributed in the hope that it will be useful,
4514
but WITHOUT ANY WARRANTY; without even the implied warranty of
4515
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4516
Lesser General Public License for more details.
4517
4518
You should have received a copy of the GNU Lesser General Public
4519
License along with this library; if not, write to the
4520
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4521
Boston, MA 02110-1301 USA
4522
*/
4523
4524
4525
4526
#include <errno.h>
4527
#include <string.h>
4528
4529
FileModule::FileModule(Mode mode, Track *track, File *fh, bool canSeek) :
4530
m_mode(mode),
4531
m_track(track),
4532
m_fh(fh),
4533
m_canSeek(canSeek)
4534
{
4535
track->fpos_next_frame = track->fpos_first_frame;
4536
track->frames2ignore = 0;
4537
}
4538
4539
ssize_t FileModule::read(void *data, size_t nbytes)
4540
{
4541
ssize_t bytesRead = m_fh->read(data, nbytes);
4542
if (bytesRead > 0)
4543
{
4544
m_track->fpos_next_frame += bytesRead;
4545
}
4546
return bytesRead;
4547
}
4548
4549
ssize_t FileModule::write(const void *data, size_t nbytes)
4550
{
4551
ssize_t bytesWritten = m_fh->write(data, nbytes);
4552
if (bytesWritten > 0)
4553
{
4554
m_track->fpos_next_frame += bytesWritten;
4555
m_track->data_size += bytesWritten;
4556
}
4557
return bytesWritten;
4558
}
4559
4560
off_t FileModule::seek(off_t offset)
4561
{
4562
return m_fh->seek(offset, File::SeekFromBeginning);
4563
}
4564
4565
off_t FileModule::tell()
4566
{
4567
return m_fh->tell();
4568
}
4569
4570
off_t FileModule::length()
4571
{
4572
return m_fh->length();
4573
}
4574
4575
void FileModule::reportReadError(AFframecount framesRead,
4576
AFframecount framesToRead)
4577
{
4578
// Report error if we haven't already.
4579
if (!m_track->filemodhappy)
4580
return;
4581
4582
_af_error(AF_BAD_READ,
4583
"file missing data -- read %jd frames, should be %jd",
4584
static_cast<intmax_t>(m_track->nextfframe),
4585
static_cast<intmax_t>(m_track->totalfframes));
4586
m_track->filemodhappy = false;
4587
}
4588
4589
void FileModule::reportWriteError(AFframecount framesWritten,
4590
AFframecount framesToWrite)
4591
{
4592
// Report error if we haven't already.
4593
if (!m_track->filemodhappy)
4594
return;
4595
4596
if (framesWritten < 0)
4597
{
4598
// Signal I/O error.
4599
_af_error(AF_BAD_WRITE,
4600
"unable to write data (%s) -- wrote %jd out of %jd frames",
4601
strerror(errno),
4602
static_cast<intmax_t>(m_track->nextfframe),
4603
static_cast<intmax_t>(m_track->nextfframe + framesToWrite));
4604
}
4605
else
4606
{
4607
// Signal disk full error.
4608
_af_error(AF_BAD_WRITE,
4609
"unable to write data (disk full) -- "
4610
"wrote %jd out of %jd frames",
4611
static_cast<intmax_t>(m_track->nextfframe + framesWritten),
4612
static_cast<intmax_t>(m_track->nextfframe + framesToWrite));
4613
}
4614
4615
m_track->filemodhappy = false;
4616
}
4617
4618
int FileModule::bufferSize() const
4619
{
4620
if (mode() == Compress)
4621
return outChunk()->frameCount * inChunk()->f.bytesPerFrame(true);
4622
else
4623
return inChunk()->frameCount * outChunk()->f.bytesPerFrame(true);
4624
}
4625
4626
// file: modules/G711.h
4627
/*
4628
Audio File Library
4629
Copyright (C) 2000, Silicon Graphics, Inc.
4630
Copyright (C) 2010, Michael Pruett <[email protected]>
4631
4632
This library is free software; you can redistribute it and/or
4633
modify it under the terms of the GNU Lesser General Public
4634
License as published by the Free Software Foundation; either
4635
version 2.1 of the License, or (at your option) any later version.
4636
4637
This library is distributed in the hope that it will be useful,
4638
but WITHOUT ANY WARRANTY; without even the implied warranty of
4639
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4640
Lesser General Public License for more details.
4641
4642
You should have received a copy of the GNU Lesser General Public
4643
License along with this library; if not, write to the
4644
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4645
Boston, MA 02110-1301 USA
4646
*/
4647
4648
/*
4649
g711.h
4650
*/
4651
4652
#ifndef MODULES_G711_H
4653
#define MODULES_G711_H
4654
4655
4656
class File;
4657
class FileModule;
4658
struct AudioFormat;
4659
struct Track;
4660
4661
bool _af_g711_format_ok (AudioFormat *f);
4662
4663
FileModule *_AFg711initcompress (Track *, File *, bool canSeek,
4664
bool headerless, AFframecount *chunkframes);
4665
4666
FileModule *_AFg711initdecompress (Track *, File *, bool canSeek,
4667
bool headerless, AFframecount *chunkframes);
4668
4669
#endif /* MODULES_G711_H */
4670
4671
// file: modules/G711.cpp
4672
/*
4673
Audio File Library
4674
Copyright (C) 2000-2001, Silicon Graphics, Inc.
4675
Copyright (C) 2010-2013, Michael Pruett <[email protected]>
4676
4677
This library is free software; you can redistribute it and/or
4678
modify it under the terms of the GNU Lesser General Public
4679
License as published by the Free Software Foundation; either
4680
version 2.1 of the License, or (at your option) any later version.
4681
4682
This library is distributed in the hope that it will be useful,
4683
but WITHOUT ANY WARRANTY; without even the implied warranty of
4684
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4685
Lesser General Public License for more details.
4686
4687
You should have received a copy of the GNU Lesser General Public
4688
License along with this library; if not, write to the
4689
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4690
Boston, MA 02110-1301 USA
4691
*/
4692
4693
4694
#include <assert.h>
4695
4696
4697
4698
static void ulaw2linear_buf (const uint8_t *ulaw, int16_t *linear, int nsamples)
4699
{
4700
for (int i=0; i < nsamples; i++)
4701
linear[i] = _af_ulaw2linear(ulaw[i]);
4702
}
4703
4704
static void linear2ulaw_buf (const int16_t *linear, uint8_t *ulaw, int nsamples)
4705
{
4706
for (int i=0; i < nsamples; i++)
4707
ulaw[i] = _af_linear2ulaw(linear[i]);
4708
}
4709
4710
static void alaw2linear_buf (const uint8_t *alaw, int16_t *linear, int nsamples)
4711
{
4712
for (int i=0; i < nsamples; i++)
4713
linear[i] = _af_alaw2linear(alaw[i]);
4714
}
4715
4716
static void linear2alaw_buf (const int16_t *linear, uint8_t *alaw, int nsamples)
4717
{
4718
for (int i=0; i < nsamples; i++)
4719
alaw[i] = _af_linear2alaw(linear[i]);
4720
}
4721
4722
bool _af_g711_format_ok (AudioFormat *f)
4723
{
4724
if (f->sampleFormat != AF_SAMPFMT_TWOSCOMP || f->sampleWidth != 16)
4725
{
4726
_af_error(AF_BAD_COMPRESSION,
4727
"G.711 compression requires 16-bit signed integer format");
4728
return false;
4729
}
4730
4731
if (f->byteOrder != _AF_BYTEORDER_NATIVE)
4732
{
4733
_af_error(AF_BAD_COMPRESSION,
4734
"G.711 compression requires native byte order");
4735
return false;
4736
}
4737
4738
return true;
4739
}
4740
4741
class G711 : public FileModule
4742
{
4743
public:
4744
static G711 *createCompress(Track *trk, File *fh, bool canSeek,
4745
bool headerless, AFframecount *chunkframes);
4746
static G711 *createDecompress(Track *trk, File *fh, bool canSeek,
4747
bool headerless, AFframecount *chunkframes);
4748
4749
virtual const char *name() const OVERRIDE
4750
{
4751
return mode() == Compress ? "g711compress" : "g711decompress";
4752
}
4753
virtual void describe() OVERRIDE;
4754
virtual void runPull() OVERRIDE;
4755
virtual void reset2() OVERRIDE;
4756
virtual void runPush() OVERRIDE;
4757
virtual void sync1() OVERRIDE;
4758
virtual void sync2() OVERRIDE;
4759
4760
private:
4761
G711(Mode mode, Track *track, File *fh, bool canSeek);
4762
4763
AFfileoffset m_savedPositionNextFrame;
4764
AFframecount m_savedNextFrame;
4765
};
4766
4767
G711::G711(Mode mode, Track *track, File *fh, bool canSeek) :
4768
FileModule(mode, track, fh, canSeek),
4769
m_savedPositionNextFrame(-1),
4770
m_savedNextFrame(-1)
4771
{
4772
if (mode == Decompress)
4773
track->f.compressionParams = AU_NULL_PVLIST;
4774
}
4775
4776
G711 *G711::createCompress(Track *track, File *fh,
4777
bool canSeek, bool headerless, AFframecount *chunkframes)
4778
{
4779
return new G711(Compress, track, fh, canSeek);
4780
}
4781
4782
void G711::runPush()
4783
{
4784
AFframecount framesToWrite = m_inChunk->frameCount;
4785
AFframecount samplesToWrite = m_inChunk->frameCount * m_inChunk->f.channelCount;
4786
int framesize = m_inChunk->f.channelCount;
4787
4788
assert(m_track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
4789
m_track->f.compressionType == AF_COMPRESSION_G711_ALAW);
4790
4791
/* Compress frames into i->outc. */
4792
4793
if (m_track->f.compressionType == AF_COMPRESSION_G711_ULAW)
4794
linear2ulaw_buf(static_cast<const int16_t *>(m_inChunk->buffer),
4795
static_cast<uint8_t *>(m_outChunk->buffer), samplesToWrite);
4796
else
4797
linear2alaw_buf(static_cast<const int16_t *>(m_inChunk->buffer),
4798
static_cast<uint8_t *>(m_outChunk->buffer), samplesToWrite);
4799
4800
/* Write the compressed data. */
4801
4802
ssize_t bytesWritten = write(m_outChunk->buffer, framesize * framesToWrite);
4803
AFframecount framesWritten = bytesWritten >= 0 ? bytesWritten / framesize : 0;
4804
4805
if (framesWritten != framesToWrite)
4806
reportWriteError(framesWritten, framesToWrite);
4807
4808
m_track->nextfframe += framesWritten;
4809
m_track->totalfframes = m_track->nextfframe;
4810
4811
assert(!canSeek() || (tell() == m_track->fpos_next_frame));
4812
}
4813
4814
void G711::sync1()
4815
{
4816
m_savedPositionNextFrame = m_track->fpos_next_frame;
4817
m_savedNextFrame = m_track->nextfframe;
4818
}
4819
4820
void G711::sync2()
4821
{
4822
/* sanity check. */
4823
assert(!canSeek() || (tell() == m_track->fpos_next_frame));
4824
4825
/* We can afford to do an lseek just in case because sync2 is rare. */
4826
m_track->fpos_after_data = tell();
4827
4828
m_track->fpos_next_frame = m_savedPositionNextFrame;
4829
m_track->nextfframe = m_savedNextFrame;
4830
}
4831
4832
void G711::describe()
4833
{
4834
if (mode() == Compress)
4835
{
4836
m_outChunk->f.compressionType = m_track->f.compressionType;
4837
}
4838
else
4839
{
4840
m_outChunk->f.byteOrder = _AF_BYTEORDER_NATIVE;
4841
m_outChunk->f.compressionType = AF_COMPRESSION_NONE;
4842
}
4843
}
4844
4845
G711 *G711::createDecompress(Track *track, File *fh,
4846
bool canSeek, bool headerless, AFframecount *chunkframes)
4847
{
4848
return new G711(Decompress, track, fh, canSeek);
4849
}
4850
4851
void G711::runPull()
4852
{
4853
AFframecount framesToRead = m_outChunk->frameCount;
4854
AFframecount samplesToRead = m_outChunk->frameCount * m_outChunk->f.channelCount;
4855
int framesize = m_outChunk->f.channelCount;
4856
4857
/* Read the compressed frames. */
4858
4859
ssize_t bytesRead = read(m_inChunk->buffer, framesize * framesToRead);
4860
AFframecount framesRead = bytesRead >= 0 ? bytesRead / framesize : 0;
4861
4862
/* Decompress into i->outc. */
4863
4864
if (m_track->f.compressionType == AF_COMPRESSION_G711_ULAW)
4865
ulaw2linear_buf(static_cast<const uint8_t *>(m_inChunk->buffer),
4866
static_cast<int16_t *>(m_outChunk->buffer), samplesToRead);
4867
else
4868
alaw2linear_buf(static_cast<const uint8_t *>(m_inChunk->buffer),
4869
static_cast<int16_t *>(m_outChunk->buffer), samplesToRead);
4870
4871
m_track->nextfframe += framesRead;
4872
assert(!canSeek() || (tell() == m_track->fpos_next_frame));
4873
4874
/*
4875
If we got EOF from read, then we return the actual amount read.
4876
4877
Complain only if there should have been more frames in the file.
4878
*/
4879
4880
if (m_track->totalfframes != -1 && framesRead != framesToRead)
4881
reportReadError(framesRead, framesToRead);
4882
4883
m_outChunk->frameCount = framesRead;
4884
}
4885
4886
void G711::reset2()
4887
{
4888
int framesize = m_inChunk->f.channelCount;
4889
4890
m_track->fpos_next_frame = m_track->fpos_first_frame +
4891
framesize * m_track->nextfframe;
4892
4893
m_track->frames2ignore = 0;
4894
}
4895
4896
FileModule *_AFg711initcompress(Track *track, File *fh, bool canSeek,
4897
bool headerless, AFframecount *chunkFrames)
4898
{
4899
return G711::createCompress(track, fh, canSeek, headerless, chunkFrames);
4900
}
4901
4902
FileModule *_AFg711initdecompress(Track *track, File *fh, bool canSeek,
4903
bool headerless, AFframecount *chunkFrames)
4904
{
4905
return G711::createDecompress(track, fh, canSeek, headerless, chunkFrames);
4906
}
4907
4908
// file: modules/Module.cpp
4909
/*
4910
Audio File Library
4911
Copyright (C) 2000, Silicon Graphics, Inc.
4912
Copyright (C) 2010, Michael Pruett <[email protected]>
4913
4914
This library is free software; you can redistribute it and/or
4915
modify it under the terms of the GNU Lesser General Public
4916
License as published by the Free Software Foundation; either
4917
version 2.1 of the License, or (at your option) any later version.
4918
4919
This library is distributed in the hope that it will be useful,
4920
but WITHOUT ANY WARRANTY; without even the implied warranty of
4921
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4922
Lesser General Public License for more details.
4923
4924
You should have received a copy of the GNU Lesser General Public
4925
License along with this library; if not, write to the
4926
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4927
Boston, MA 02110-1301 USA
4928
*/
4929
4930
4931
4932
Module::Module() :
4933
m_sink(NULL)
4934
{
4935
}
4936
4937
Module::~Module()
4938
{
4939
}
4940
4941
void Module::setSink(Module *module) { m_sink = module; }
4942
void Module::setSource(Module *module) { m_source = module; }
4943
4944
const char *Module::name() const { return ""; }
4945
4946
void Module::describe()
4947
{
4948
}
4949
4950
void Module::maxPull()
4951
{
4952
m_inChunk->frameCount = m_outChunk->frameCount;
4953
}
4954
4955
void Module::maxPush()
4956
{
4957
m_outChunk->frameCount = m_inChunk->frameCount;
4958
}
4959
4960
void Module::runPull()
4961
{
4962
}
4963
4964
void Module::runPush()
4965
{
4966
}
4967
4968
void Module::pull(size_t frames)
4969
{
4970
m_inChunk->frameCount = frames;
4971
m_source->runPull();
4972
}
4973
4974
void Module::push(size_t frames)
4975
{
4976
m_outChunk->frameCount = frames;
4977
m_sink->runPush();
4978
}
4979
4980
// file: modules/ModuleState.cpp
4981
/*
4982
Audio File Library
4983
Copyright (C) 2000, Silicon Graphics, Inc.
4984
Copyright (C) 2010-2013, Michael Pruett <[email protected]>
4985
4986
This library is free software; you can redistribute it and/or
4987
modify it under the terms of the GNU Lesser General Public
4988
License as published by the Free Software Foundation; either
4989
version 2.1 of the License, or (at your option) any later version.
4990
4991
This library is distributed in the hope that it will be useful,
4992
but WITHOUT ANY WARRANTY; without even the implied warranty of
4993
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4994
Lesser General Public License for more details.
4995
4996
You should have received a copy of the GNU Lesser General Public
4997
License along with this library; if not, write to the
4998
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
4999
Boston, MA 02110-1301 USA
5000
*/
5001
5002
5003
5004
#include <algorithm>
5005
#include <cassert>
5006
#include <cmath>
5007
#include <functional>
5008
#include <stdio.h>
5009
5010
ModuleState::ModuleState() :
5011
m_isDirty(true)
5012
{
5013
}
5014
5015
ModuleState::~ModuleState()
5016
{
5017
}
5018
5019
status ModuleState::initFileModule(AFfilehandle file, Track *track)
5020
{
5021
const CompressionUnit *unit = _af_compression_unit_from_id(track->f.compressionType);
5022
if (!unit)
5023
return AF_FAIL;
5024
5025
// Validate compression format and parameters.
5026
if (!unit->fmtok(&track->f))
5027
return AF_FAIL;
5028
5029
if (file->m_seekok &&
5030
file->m_fh->seek(track->fpos_first_frame, File::SeekFromBeginning) !=
5031
track->fpos_first_frame)
5032
{
5033
_af_error(AF_BAD_LSEEK, "unable to position file handle at beginning of sound data");
5034
return AF_FAIL;
5035
}
5036
5037
AFframecount chunkFrames;
5038
if (file->m_access == _AF_READ_ACCESS)
5039
m_fileModule = unit->initdecompress(track, file->m_fh, file->m_seekok,
5040
file->m_fileFormat == AF_FILE_RAWDATA, &chunkFrames);
5041
else
5042
m_fileModule = unit->initcompress(track, file->m_fh, file->m_seekok,
5043
file->m_fileFormat == AF_FILE_RAWDATA, &chunkFrames);
5044
5045
if (unit->needsRebuffer)
5046
{
5047
assert(unit->nativeSampleFormat == AF_SAMPFMT_TWOSCOMP);
5048
5049
RebufferModule::Direction direction =
5050
file->m_access == _AF_WRITE_ACCESS ?
5051
RebufferModule::VariableToFixed : RebufferModule::FixedToVariable;
5052
5053
m_fileRebufferModule = new RebufferModule(direction,
5054
track->f.bytesPerFrame(false), chunkFrames,
5055
unit->multiple_of);
5056
}
5057
5058
track->filemodhappy = true;
5059
5060
return AF_SUCCEED;
5061
}
5062
5063
status ModuleState::init(AFfilehandle file, Track *track)
5064
{
5065
if (initFileModule(file, track) == AF_FAIL)
5066
return AF_FAIL;
5067
5068
return AF_SUCCEED;
5069
}
5070
5071
bool ModuleState::fileModuleHandlesSeeking() const
5072
{
5073
return m_fileModule->handlesSeeking();
5074
}
5075
5076
status ModuleState::setup(AFfilehandle file, Track *track)
5077
{
5078
AFframecount fframepos = std::llrint(track->nextvframe * track->f.sampleRate / track->v.sampleRate);
5079
bool isReading = file->m_access == _AF_READ_ACCESS;
5080
5081
if (!track->v.isUncompressed())
5082
{
5083
_af_error(AF_BAD_NOT_IMPLEMENTED,
5084
"library does not support compression in virtual format yet");
5085
return AF_FAIL;
5086
}
5087
5088
if (arrange(file, track) == AF_FAIL)
5089
return AF_FAIL;
5090
5091
track->filemodhappy = true;
5092
int maxbufsize = 0;
5093
if (isReading)
5094
{
5095
m_chunks.back()->frameCount = _AF_ATOMIC_NVFRAMES;
5096
for (int i=m_modules.size() - 1; i >= 0; i--)
5097
{
5098
SharedPtr<Chunk> inChunk = m_chunks[i];
5099
SharedPtr<Chunk> outChunk = m_chunks[i+1];
5100
int bufsize = outChunk->frameCount * outChunk->f.bytesPerFrame(true);
5101
if (bufsize > maxbufsize)
5102
maxbufsize = bufsize;
5103
if (i != 0)
5104
m_modules[i]->setSource(m_modules[i-1].get());
5105
m_modules[i]->maxPull();
5106
}
5107
5108
if (!track->filemodhappy)
5109
return AF_FAIL;
5110
int bufsize = m_fileModule->bufferSize();
5111
if (bufsize > maxbufsize)
5112
maxbufsize = bufsize;
5113
}
5114
else
5115
{
5116
m_chunks.front()->frameCount = _AF_ATOMIC_NVFRAMES;
5117
for (size_t i=0; i<m_modules.size(); i++)
5118
{
5119
SharedPtr<Chunk> inChunk = m_chunks[i];
5120
SharedPtr<Chunk> outChunk = m_chunks[i+1];
5121
int bufsize = inChunk->frameCount * inChunk->f.bytesPerFrame(true);
5122
if (bufsize > maxbufsize)
5123
maxbufsize = bufsize;
5124
if (i != m_modules.size() - 1)
5125
m_modules[i]->setSink(m_modules[i+1].get());
5126
m_modules[i]->maxPush();
5127
}
5128
5129
if (!track->filemodhappy)
5130
return AF_FAIL;
5131
5132
int bufsize = m_fileModule->bufferSize();
5133
if (bufsize > maxbufsize)
5134
maxbufsize = bufsize;
5135
}
5136
5137
for (size_t i=0; i<m_chunks.size(); i++)
5138
{
5139
if ((isReading && i==m_chunks.size() - 1) || (!isReading && i==0))
5140
continue;
5141
m_chunks[i]->allocate(maxbufsize);
5142
}
5143
5144
if (isReading)
5145
{
5146
if (track->totalfframes == -1)
5147
track->totalvframes = -1;
5148
else
5149
track->totalvframes = std::llrint(track->totalfframes *
5150
(track->v.sampleRate / track->f.sampleRate));
5151
5152
track->nextfframe = fframepos;
5153
track->nextvframe = std::llrint(fframepos * track->v.sampleRate / track->f.sampleRate);
5154
5155
m_isDirty = false;
5156
5157
if (reset(file, track) == AF_FAIL)
5158
return AF_FAIL;
5159
}
5160
else
5161
{
5162
track->nextvframe = track->totalvframes =
5163
(AFframecount) (fframepos * track->v.sampleRate / track->f.sampleRate);
5164
m_isDirty = false;
5165
}
5166
5167
return AF_SUCCEED;
5168
}
5169
5170
const std::vector<SharedPtr<Module> > &ModuleState::modules() const
5171
{
5172
return m_modules;
5173
}
5174
5175
const std::vector<SharedPtr<Chunk> > &ModuleState::chunks() const
5176
{
5177
return m_chunks;
5178
}
5179
5180
status ModuleState::reset(AFfilehandle file, Track *track)
5181
{
5182
track->filemodhappy = true;
5183
for (std::vector<SharedPtr<Module> >::reverse_iterator i=m_modules.rbegin();
5184
i != m_modules.rend(); ++i)
5185
(*i)->reset1();
5186
track->frames2ignore = 0;
5187
if (!track->filemodhappy)
5188
return AF_FAIL;
5189
for (std::vector<SharedPtr<Module> >::iterator i=m_modules.begin();
5190
i != m_modules.end(); ++i)
5191
(*i)->reset2();
5192
if (!track->filemodhappy)
5193
return AF_FAIL;
5194
return AF_SUCCEED;
5195
}
5196
5197
status ModuleState::sync(AFfilehandle file, Track *track)
5198
{
5199
track->filemodhappy = true;
5200
for (std::vector<SharedPtr<Module> >::reverse_iterator i=m_modules.rbegin();
5201
i != m_modules.rend(); ++i)
5202
(*i)->sync1();
5203
if (!track->filemodhappy)
5204
return AF_FAIL;
5205
for (std::vector<SharedPtr<Module> >::iterator i=m_modules.begin();
5206
i != m_modules.end(); ++i)
5207
(*i)->sync2();
5208
return AF_SUCCEED;
5209
}
5210
5211
static const PCMInfo * const intmappings[6] =
5212
{
5213
&_af_default_signed_integer_pcm_mappings[1],
5214
&_af_default_signed_integer_pcm_mappings[2],
5215
&_af_default_signed_integer_pcm_mappings[3],
5216
&_af_default_signed_integer_pcm_mappings[4],
5217
NULL,
5218
NULL
5219
};
5220
5221
static FormatCode getFormatCode(const AudioFormat &format)
5222
{
5223
if (format.sampleFormat == AF_SAMPFMT_FLOAT)
5224
return kFloat;
5225
if (format.sampleFormat == AF_SAMPFMT_DOUBLE)
5226
return kDouble;
5227
if (format.isInteger())
5228
{
5229
switch (format.bytesPerSample(false))
5230
{
5231
case 1: return kInt8;
5232
case 2: return kInt16;
5233
case 3: return kInt24;
5234
case 4: return kInt32;
5235
}
5236
}
5237
5238
/* NOTREACHED */
5239
assert(false);
5240
return kUndefined;
5241
}
5242
5243
static bool isInteger(FormatCode code) { return code >= kInt8 && code <= kInt32; }
5244
static bool isFloat(FormatCode code) { return code >= kFloat && code <= kDouble; }
5245
5246
static bool isTrivialIntMapping(const AudioFormat &format, FormatCode code)
5247
{
5248
return intmappings[code] != NULL &&
5249
format.pcm.slope == intmappings[code]->slope &&
5250
format.pcm.intercept == intmappings[code]->intercept;
5251
}
5252
5253
static bool isTrivialIntClip(const AudioFormat &format, FormatCode code)
5254
{
5255
return intmappings[code] != NULL &&
5256
format.pcm.minClip == intmappings[code]->minClip &&
5257
format.pcm.maxClip == intmappings[code]->maxClip;
5258
}
5259
5260
status ModuleState::arrange(AFfilehandle file, Track *track)
5261
{
5262
bool isReading = file->m_access == _AF_READ_ACCESS;
5263
AudioFormat in, out;
5264
if (isReading)
5265
{
5266
in = track->f;
5267
out = track->v;
5268
}
5269
else
5270
{
5271
in = track->v;
5272
out = track->f;
5273
}
5274
5275
FormatCode infc = getFormatCode(in);
5276
FormatCode outfc = getFormatCode(out);
5277
if (infc == kUndefined || outfc == kUndefined)
5278
return AF_FAIL;
5279
5280
m_chunks.clear();
5281
m_chunks.push_back(new Chunk());
5282
m_chunks.back()->f = in;
5283
5284
m_modules.clear();
5285
5286
if (isReading)
5287
{
5288
addModule(m_fileModule.get());
5289
addModule(m_fileRebufferModule.get());
5290
}
5291
5292
// Convert to native byte order.
5293
if (in.byteOrder != _AF_BYTEORDER_NATIVE)
5294
{
5295
size_t bytesPerSample = in.bytesPerSample(!isReading);
5296
if (bytesPerSample > 1 && in.compressionType == AF_COMPRESSION_NONE)
5297
addModule(new SwapModule());
5298
else
5299
in.byteOrder = _AF_BYTEORDER_NATIVE;
5300
}
5301
5302
// Handle 24-bit integer input format.
5303
if (in.isInteger() && in.bytesPerSample(false) == 3)
5304
{
5305
if (isReading || in.compressionType != AF_COMPRESSION_NONE)
5306
addModule(new Expand3To4Module(in.isSigned()));
5307
}
5308
5309
// Make data signed.
5310
if (in.isUnsigned())
5311
addModule(new ConvertSign(infc, false));
5312
5313
in.pcm = m_chunks.back()->f.pcm;
5314
5315
// Reverse the unsigned shift for output.
5316
if (out.isUnsigned())
5317
{
5318
const double shift = intmappings[outfc]->minClip;
5319
out.pcm.intercept += shift;
5320
out.pcm.minClip += shift;
5321
out.pcm.maxClip += shift;
5322
}
5323
5324
// Clip input samples if necessary.
5325
if (in.pcm.minClip < in.pcm.maxClip && !isTrivialIntClip(in, infc))
5326
addModule(new Clip(infc, in.pcm));
5327
5328
bool alreadyClippedOutput = false;
5329
bool alreadyTransformedOutput = false;
5330
// Perform range transformation if input and output PCM mappings differ.
5331
bool transforming = (in.pcm.slope != out.pcm.slope ||
5332
in.pcm.intercept != out.pcm.intercept) &&
5333
!(isTrivialIntMapping(in, infc) &&
5334
isTrivialIntMapping(out, outfc));
5335
5336
// Range transformation requires input to be floating-point.
5337
if (isInteger(infc) && transforming)
5338
{
5339
if (infc == kInt32 || outfc == kDouble || outfc == kInt32)
5340
{
5341
addConvertIntToFloat(infc, kDouble);
5342
infc = kDouble;
5343
}
5344
else
5345
{
5346
addConvertIntToFloat(infc, kFloat);
5347
infc = kFloat;
5348
}
5349
}
5350
5351
if (transforming && infc == kDouble && isFloat(outfc))
5352
addModule(new Transform(infc, in.pcm, out.pcm));
5353
5354
// Add format conversion if needed.
5355
if (isInteger(infc) && isInteger(outfc))
5356
addConvertIntToInt(infc, outfc);
5357
else if (isInteger(infc) && isFloat(outfc))
5358
addConvertIntToFloat(infc, outfc);
5359
else if (isFloat(infc) && isInteger(outfc))
5360
{
5361
addConvertFloatToInt(infc, outfc, in.pcm, out.pcm);
5362
alreadyClippedOutput = true;
5363
alreadyTransformedOutput = true;
5364
}
5365
else if (isFloat(infc) && isFloat(outfc))
5366
addConvertFloatToFloat(infc, outfc);
5367
5368
if (transforming && !alreadyTransformedOutput && infc != kDouble)
5369
addModule(new Transform(outfc, in.pcm, out.pcm));
5370
5371
if (in.channelCount != out.channelCount)
5372
addModule(new ApplyChannelMatrix(outfc, isReading,
5373
in.channelCount, out.channelCount,
5374
in.pcm.minClip, in.pcm.maxClip,
5375
track->channelMatrix));
5376
5377
// Perform clipping if necessary.
5378
if (!alreadyClippedOutput)
5379
{
5380
if (out.pcm.minClip < out.pcm.maxClip && !isTrivialIntClip(out, outfc))
5381
addModule(new Clip(outfc, out.pcm));
5382
}
5383
5384
// Make data unsigned if necessary.
5385
if (out.isUnsigned())
5386
addModule(new ConvertSign(outfc, true));
5387
5388
// Handle 24-bit integer output format.
5389
if (out.isInteger() && out.bytesPerSample(false) == 3)
5390
{
5391
if (!isReading || out.compressionType != AF_COMPRESSION_NONE)
5392
addModule(new Compress4To3Module(out.isSigned()));
5393
}
5394
5395
if (out.byteOrder != _AF_BYTEORDER_NATIVE)
5396
{
5397
size_t bytesPerSample = out.bytesPerSample(isReading);
5398
if (bytesPerSample > 1 && out.compressionType == AF_COMPRESSION_NONE)
5399
addModule(new SwapModule());
5400
else
5401
out.byteOrder = _AF_BYTEORDER_NATIVE;
5402
}
5403
5404
if (!isReading)
5405
{
5406
addModule(m_fileRebufferModule.get());
5407
addModule(m_fileModule.get());
5408
}
5409
5410
return AF_SUCCEED;
5411
}
5412
5413
void ModuleState::addModule(Module *module)
5414
{
5415
if (!module)
5416
return;
5417
5418
m_modules.push_back(module);
5419
module->setInChunk(m_chunks.back().get());
5420
Chunk *chunk = new Chunk();
5421
chunk->f = m_chunks.back()->f;
5422
m_chunks.push_back(chunk);
5423
module->setOutChunk(chunk);
5424
module->describe();
5425
}
5426
5427
void ModuleState::addConvertIntToInt(FormatCode input, FormatCode output)
5428
{
5429
if (input == output)
5430
return;
5431
5432
assert(isInteger(input));
5433
assert(isInteger(output));
5434
addModule(new ConvertInt(input, output));
5435
}
5436
5437
void ModuleState::addConvertIntToFloat(FormatCode input, FormatCode output)
5438
{
5439
addModule(new ConvertIntToFloat(input, output));
5440
}
5441
5442
void ModuleState::addConvertFloatToInt(FormatCode input, FormatCode output,
5443
const PCMInfo &inputMapping, const PCMInfo &outputMapping)
5444
{
5445
addModule(new ConvertFloatToIntClip(input, output, inputMapping, outputMapping));
5446
}
5447
5448
void ModuleState::addConvertFloatToFloat(FormatCode input, FormatCode output)
5449
{
5450
if (input == output)
5451
return;
5452
5453
assert((input == kFloat && output == kDouble) ||
5454
(input == kDouble && output == kFloat));
5455
addModule(new ConvertFloat(input, output));
5456
}
5457
5458
void ModuleState::print()
5459
{
5460
fprintf(stderr, "modules:\n");
5461
for (size_t i=0; i<m_modules.size(); i++)
5462
fprintf(stderr, " %s (%p) in %p out %p\n",
5463
m_modules[i]->name(), m_modules[i].get(),
5464
m_modules[i]->inChunk(),
5465
m_modules[i]->outChunk());
5466
fprintf(stderr, "chunks:\n");
5467
for (size_t i=0; i<m_chunks.size(); i++)
5468
fprintf(stderr, " %p %s\n",
5469
m_chunks[i].get(),
5470
m_chunks[i]->f.description().c_str());
5471
}
5472
5473
// file: modules/MSADPCM.h
5474
/*
5475
Audio File Library
5476
Copyright (C) 2001, Silicon Graphics, Inc.
5477
Copyright (C) 2010, Michael Pruett <[email protected]>
5478
5479
This library is free software; you can redistribute it and/or
5480
modify it under the terms of the GNU Lesser General Public
5481
License as published by the Free Software Foundation; either
5482
version 2.1 of the License, or (at your option) any later version.
5483
5484
This library is distributed in the hope that it will be useful,
5485
but WITHOUT ANY WARRANTY; without even the implied warranty of
5486
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5487
Lesser General Public License for more details.
5488
5489
You should have received a copy of the GNU Lesser General Public
5490
License along with this library; if not, write to the
5491
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
5492
Boston, MA 02110-1301 USA
5493
*/
5494
5495
/*
5496
msadpcm.h
5497
5498
This module declares the interface for the Microsoft ADPCM
5499
compression module.
5500
*/
5501
5502
#ifndef MSADPCM_H
5503
#define MSADPCM_H
5504
5505
5506
class File;
5507
class FileModule;
5508
struct AudioFormat;
5509
struct Track;
5510
5511
bool _af_ms_adpcm_format_ok (AudioFormat *f);
5512
5513
FileModule *_af_ms_adpcm_init_decompress(Track *, File *,
5514
bool canSeek, bool headerless, AFframecount *chunkframes);
5515
5516
FileModule *_af_ms_adpcm_init_compress(Track *, File *,
5517
bool canSeek, bool headerless, AFframecount *chunkframes);
5518
5519
#endif
5520
5521
// file: modules/MSADPCM.cpp
5522
/*
5523
Audio File Library
5524
Copyright (C) 2010-2013, Michael Pruett <[email protected]>
5525
Copyright (C) 2001, Silicon Graphics, Inc.
5526
5527
This library is free software; you can redistribute it and/or
5528
modify it under the terms of the GNU Lesser General Public
5529
License as published by the Free Software Foundation; either
5530
version 2.1 of the License, or (at your option) any later version.
5531
5532
This library is distributed in the hope that it will be useful,
5533
but WITHOUT ANY WARRANTY; without even the implied warranty of
5534
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5535
Lesser General Public License for more details.
5536
5537
You should have received a copy of the GNU Lesser General Public
5538
License along with this library; if not, write to the
5539
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
5540
Boston, MA 02110-1301 USA
5541
*/
5542
5543
/*
5544
This module implements Microsoft ADPCM compression.
5545
*/
5546
5547
5548
#include <assert.h>
5549
#include <cstdlib>
5550
#include <limits>
5551
#include <string.h>
5552
5553
5554
struct ms_adpcm_state
5555
{
5556
uint8_t predictorIndex;
5557
int delta;
5558
int16_t sample1, sample2;
5559
5560
ms_adpcm_state()
5561
{
5562
predictorIndex = 0;
5563
delta = 16;
5564
sample1 = 0;
5565
sample2 = 0;
5566
}
5567
};
5568
5569
class MSADPCM : public BlockCodec
5570
{
5571
public:
5572
static MSADPCM *createDecompress(Track *, File *, bool canSeek,
5573
bool headerless, AFframecount *chunkFrames);
5574
static MSADPCM *createCompress(Track *, File *, bool canSeek,
5575
bool headerless, AFframecount *chunkFrames);
5576
5577
virtual ~MSADPCM();
5578
5579
bool initializeCoefficients();
5580
5581
virtual const char *name() const OVERRIDE
5582
{
5583
return mode() == Compress ? "ms_adpcm_compress" : "ms_adpcm_decompress";
5584
}
5585
virtual void describe() OVERRIDE;
5586
5587
private:
5588
// m_coefficients is an array of m_numCoefficients ADPCM coefficient pairs.
5589
int m_numCoefficients;
5590
int16_t m_coefficients[256][2];
5591
5592
ms_adpcm_state *m_state;
5593
5594
MSADPCM(Mode mode, Track *track, File *fh, bool canSeek);
5595
5596
int decodeBlock(const uint8_t *encoded, int16_t *decoded) OVERRIDE;
5597
int encodeBlock(const int16_t *decoded, uint8_t *encoded) OVERRIDE;
5598
void choosePredictorForBlock(const int16_t *decoded);
5599
};
5600
5601
static inline int clamp(int x, int low, int high)
5602
{
5603
if (x < low) return low;
5604
if (x > high) return high;
5605
return x;
5606
}
5607
5608
static const int16_t adaptationTable[] =
5609
{
5610
230, 230, 230, 230, 307, 409, 512, 614,
5611
768, 614, 512, 409, 307, 230, 230, 230
5612
};
5613
5614
// Compute a linear PCM value from the given differential coded value.
5615
static int16_t decodeSample(ms_adpcm_state &state,
5616
uint8_t code, const int16_t *coefficient)
5617
{
5618
int linearSample = (state.sample1 * coefficient[0] +
5619
state.sample2 * coefficient[1]) >> 8;
5620
5621
linearSample += ((code & 0x08) ? (code - 0x10) : code) * state.delta;
5622
5623
linearSample = clamp(linearSample, MIN_INT16, MAX_INT16);
5624
5625
int delta = (state.delta * adaptationTable[code]) >> 8;
5626
if (delta < 16)
5627
delta = 16;
5628
5629
state.delta = delta;
5630
state.sample2 = state.sample1;
5631
state.sample1 = linearSample;
5632
5633
return static_cast<int16_t>(linearSample);
5634
}
5635
5636
// Compute a differential coded value from the given linear PCM sample.
5637
static uint8_t encodeSample(ms_adpcm_state &state, int16_t sample,
5638
const int16_t *coefficient)
5639
{
5640
int predictor = (state.sample1 * coefficient[0] +
5641
state.sample2 * coefficient[1]) >> 8;
5642
int code = sample - predictor;
5643
int bias = state.delta / 2;
5644
if (code < 0)
5645
bias = -bias;
5646
code = (code + bias) / state.delta;
5647
code = clamp(code, -8, 7) & 0xf;
5648
5649
predictor += ((code & 0x8) ? (code - 0x10) : code) * state.delta;
5650
5651
state.sample2 = state.sample1;
5652
state.sample1 = clamp(predictor, MIN_INT16, MAX_INT16);
5653
state.delta = (adaptationTable[code] * state.delta) >> 8;
5654
if (state.delta < 16)
5655
state.delta = 16;
5656
return code;
5657
}
5658
5659
// Decode one block of MS ADPCM data.
5660
int MSADPCM::decodeBlock(const uint8_t *encoded, int16_t *decoded)
5661
{
5662
ms_adpcm_state decoderState[2];
5663
ms_adpcm_state *state[2];
5664
5665
int channelCount = m_track->f.channelCount;
5666
5667
// Calculate the number of bytes needed for decoded data.
5668
int outputLength = m_framesPerPacket * sizeof (int16_t) * channelCount;
5669
5670
state[0] = &decoderState[0];
5671
if (channelCount == 2)
5672
state[1] = &decoderState[1];
5673
else
5674
state[1] = &decoderState[0];
5675
5676
// Initialize block predictor.
5677
for (int i=0; i<channelCount; i++)
5678
{
5679
state[i]->predictorIndex = *encoded++;
5680
assert(state[i]->predictorIndex < m_numCoefficients);
5681
}
5682
5683
// Initialize delta.
5684
for (int i=0; i<channelCount; i++)
5685
{
5686
state[i]->delta = (encoded[1]<<8) | encoded[0];
5687
encoded += sizeof (uint16_t);
5688
}
5689
5690
// Initialize first two samples.
5691
for (int i=0; i<channelCount; i++)
5692
{
5693
state[i]->sample1 = (encoded[1]<<8) | encoded[0];
5694
encoded += sizeof (uint16_t);
5695
}
5696
5697
for (int i=0; i<channelCount; i++)
5698
{
5699
state[i]->sample2 = (encoded[1]<<8) | encoded[0];
5700
encoded += sizeof (uint16_t);
5701
}
5702
5703
const int16_t *coefficient[2] =
5704
{
5705
m_coefficients[state[0]->predictorIndex],
5706
m_coefficients[state[1]->predictorIndex]
5707
};
5708
5709
for (int i=0; i<channelCount; i++)
5710
*decoded++ = state[i]->sample2;
5711
5712
for (int i=0; i<channelCount; i++)
5713
*decoded++ = state[i]->sample1;
5714
5715
/*
5716
The first two samples have already been 'decoded' in
5717
the block header.
5718
*/
5719
int samplesRemaining = (m_framesPerPacket - 2) * m_track->f.channelCount;
5720
5721
while (samplesRemaining > 0)
5722
{
5723
uint8_t code;
5724
int16_t newSample;
5725
5726
code = *encoded >> 4;
5727
newSample = decodeSample(*state[0], code, coefficient[0]);
5728
*decoded++ = newSample;
5729
5730
code = *encoded & 0x0f;
5731
newSample = decodeSample(*state[1], code, coefficient[1]);
5732
*decoded++ = newSample;
5733
5734
encoded++;
5735
samplesRemaining -= 2;
5736
}
5737
5738
return outputLength;
5739
}
5740
5741
int MSADPCM::encodeBlock(const int16_t *decoded, uint8_t *encoded)
5742
{
5743
choosePredictorForBlock(decoded);
5744
5745
int channelCount = m_track->f.channelCount;
5746
5747
// Encode predictor.
5748
for (int c=0; c<channelCount; c++)
5749
*encoded++ = m_state[c].predictorIndex;
5750
5751
// Encode delta.
5752
for (int c=0; c<channelCount; c++)
5753
{
5754
*encoded++ = m_state[c].delta & 0xff;
5755
*encoded++ = m_state[c].delta >> 8;
5756
}
5757
5758
// Enccode first two samples.
5759
for (int c=0; c<channelCount; c++)
5760
m_state[c].sample2 = *decoded++;
5761
5762
for (int c=0; c<channelCount; c++)
5763
m_state[c].sample1 = *decoded++;
5764
5765
for (int c=0; c<channelCount; c++)
5766
{
5767
*encoded++ = m_state[c].sample1 & 0xff;
5768
*encoded++ = m_state[c].sample1 >> 8;
5769
}
5770
5771
for (int c=0; c<channelCount; c++)
5772
{
5773
*encoded++ = m_state[c].sample2 & 0xff;
5774
*encoded++ = m_state[c].sample2 >> 8;
5775
}
5776
5777
ms_adpcm_state *state[2] = { &m_state[0], &m_state[channelCount - 1] };
5778
const int16_t *coefficient[2] =
5779
{
5780
m_coefficients[state[0]->predictorIndex],
5781
m_coefficients[state[1]->predictorIndex]
5782
};
5783
5784
int samplesRemaining = (m_framesPerPacket - 2) * m_track->f.channelCount;
5785
while (samplesRemaining > 0)
5786
{
5787
uint8_t code1 = encodeSample(*state[0], *decoded++, coefficient[0]);
5788
uint8_t code2 = encodeSample(*state[1], *decoded++, coefficient[1]);
5789
5790
*encoded++ = (code1 << 4) | code2;
5791
samplesRemaining -= 2;
5792
}
5793
5794
return m_bytesPerPacket;
5795
}
5796
5797
void MSADPCM::choosePredictorForBlock(const int16_t *decoded)
5798
{
5799
const int kPredictorSampleLength = 3;
5800
5801
int channelCount = m_track->f.channelCount;
5802
5803
for (int c=0; c<channelCount; c++)
5804
{
5805
int bestPredictorIndex = 0;
5806
int bestPredictorError = std::numeric_limits<int>::max();
5807
for (int k=0; k<m_numCoefficients; k++)
5808
{
5809
int a0 = m_coefficients[k][0];
5810
int a1 = m_coefficients[k][1];
5811
5812
int currentPredictorError = 0;
5813
for (int i=2; i<2+kPredictorSampleLength; i++)
5814
{
5815
int error = std::abs(decoded[i*channelCount + c] -
5816
((a0 * decoded[(i-1)*channelCount + c] +
5817
a1 * decoded[(i-2)*channelCount + c]) >> 8));
5818
currentPredictorError += error;
5819
}
5820
5821
currentPredictorError /= 4 * kPredictorSampleLength;
5822
5823
if (currentPredictorError < bestPredictorError)
5824
{
5825
bestPredictorError = currentPredictorError;
5826
bestPredictorIndex = k;
5827
}
5828
5829
if (!currentPredictorError)
5830
break;
5831
}
5832
5833
if (bestPredictorError < 16)
5834
bestPredictorError = 16;
5835
5836
m_state[c].predictorIndex = bestPredictorIndex;
5837
m_state[c].delta = bestPredictorError;
5838
}
5839
}
5840
5841
void MSADPCM::describe()
5842
{
5843
m_outChunk->f.byteOrder = _AF_BYTEORDER_NATIVE;
5844
m_outChunk->f.compressionType = AF_COMPRESSION_NONE;
5845
m_outChunk->f.compressionParams = AU_NULL_PVLIST;
5846
}
5847
5848
MSADPCM::MSADPCM(Mode mode, Track *track, File *fh, bool canSeek) :
5849
BlockCodec(mode, track, fh, canSeek),
5850
m_numCoefficients(0),
5851
m_state(NULL)
5852
{
5853
m_state = new ms_adpcm_state[m_track->f.channelCount];
5854
}
5855
5856
MSADPCM::~MSADPCM()
5857
{
5858
delete [] m_state;
5859
}
5860
5861
bool MSADPCM::initializeCoefficients()
5862
{
5863
AUpvlist pv = m_track->f.compressionParams;
5864
5865
long l;
5866
if (_af_pv_getlong(pv, _AF_MS_ADPCM_NUM_COEFFICIENTS, &l))
5867
{
5868
m_numCoefficients = l;
5869
}
5870
else
5871
{
5872
_af_error(AF_BAD_CODEC_CONFIG, "number of coefficients not set");
5873
return false;
5874
}
5875
5876
void *v;
5877
if (_af_pv_getptr(pv, _AF_MS_ADPCM_COEFFICIENTS, &v))
5878
{
5879
memcpy(m_coefficients, v, m_numCoefficients * 2 * sizeof (int16_t));
5880
}
5881
else
5882
{
5883
_af_error(AF_BAD_CODEC_CONFIG, "coefficient array not set");
5884
return false;
5885
}
5886
5887
return true;
5888
}
5889
5890
MSADPCM *MSADPCM::createDecompress(Track *track, File *fh,
5891
bool canSeek, bool headerless, AFframecount *chunkFrames)
5892
{
5893
assert(fh->tell() == track->fpos_first_frame);
5894
5895
MSADPCM *msadpcm = new MSADPCM(Decompress, track, fh, canSeek);
5896
5897
if (!msadpcm->initializeCoefficients())
5898
{
5899
delete msadpcm;
5900
return NULL;
5901
}
5902
5903
*chunkFrames = msadpcm->m_framesPerPacket;
5904
5905
return msadpcm;
5906
}
5907
5908
MSADPCM *MSADPCM::createCompress(Track *track, File *fh,
5909
bool canSeek, bool headerless, AFframecount *chunkFrames)
5910
{
5911
assert(fh->tell() == track->fpos_first_frame);
5912
5913
MSADPCM *msadpcm = new MSADPCM(Compress, track, fh, canSeek);
5914
5915
if (!msadpcm->initializeCoefficients())
5916
{
5917
delete msadpcm;
5918
return NULL;
5919
}
5920
5921
*chunkFrames = msadpcm->m_framesPerPacket;
5922
5923
return msadpcm;
5924
}
5925
5926
bool _af_ms_adpcm_format_ok (AudioFormat *f)
5927
{
5928
if (f->channelCount != 1 && f->channelCount != 2)
5929
{
5930
_af_error(AF_BAD_COMPRESSION,
5931
"MS ADPCM compression requires 1 or 2 channels");
5932
return false;
5933
}
5934
5935
if (f->sampleFormat != AF_SAMPFMT_TWOSCOMP || f->sampleWidth != 16)
5936
{
5937
_af_error(AF_BAD_COMPRESSION,
5938
"MS ADPCM compression requires 16-bit signed integer format");
5939
return false;
5940
}
5941
5942
if (f->byteOrder != _AF_BYTEORDER_NATIVE)
5943
{
5944
_af_error(AF_BAD_COMPRESSION,
5945
"MS ADPCM compression requires native byte order");
5946
return false;
5947
}
5948
5949
return true;
5950
}
5951
5952
FileModule *_af_ms_adpcm_init_decompress (Track *track, File *fh,
5953
bool canSeek, bool headerless, AFframecount *chunkFrames)
5954
{
5955
return MSADPCM::createDecompress(track, fh, canSeek, headerless, chunkFrames);
5956
}
5957
5958
FileModule *_af_ms_adpcm_init_compress (Track *track, File *fh,
5959
bool canSeek, bool headerless, AFframecount *chunkFrames)
5960
{
5961
return MSADPCM::createCompress(track, fh, canSeek, headerless, chunkFrames);
5962
}
5963
5964
// file: modules/PCM.h
5965
/*
5966
Audio File Library
5967
Copyright (C) 2000, Silicon Graphics, Inc.
5968
Copyright (C) 2010, Michael Pruett <[email protected]>
5969
5970
This library is free software; you can redistribute it and/or
5971
modify it under the terms of the GNU Lesser General Public
5972
License as published by the Free Software Foundation; either
5973
version 2.1 of the License, or (at your option) any later version.
5974
5975
This library is distributed in the hope that it will be useful,
5976
but WITHOUT ANY WARRANTY; without even the implied warranty of
5977
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5978
Lesser General Public License for more details.
5979
5980
You should have received a copy of the GNU Lesser General Public
5981
License along with this library; if not, write to the
5982
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
5983
Boston, MA 02110-1301 USA
5984
*/
5985
5986
/*
5987
PCM.h
5988
*/
5989
5990
#ifndef MODULES_PCM_H
5991
#define MODULES_PCM_H
5992
5993
5994
class File;
5995
class FileModule;
5996
struct AudioFormat;
5997
struct Track;
5998
5999
bool _af_pcm_format_ok (AudioFormat *f);
6000
6001
FileModule *_AFpcminitcompress(Track *, File *, bool seekok,
6002
bool headerless, AFframecount *chunkframes);
6003
6004
FileModule *_AFpcminitdecompress(Track *, File *, bool seekok,
6005
bool headerless, AFframecount *chunkframes);
6006
6007
#endif /* MODULES_PCM_H */
6008
6009
// file: modules/PCM.cpp
6010
/*
6011
Audio File Library
6012
Copyright (C) 2000, Silicon Graphics, Inc.
6013
Copyright (C) 2010, Michael Pruett <[email protected]>
6014
6015
This library is free software; you can redistribute it and/or
6016
modify it under the terms of the GNU Lesser General Public
6017
License as published by the Free Software Foundation; either
6018
version 2.1 of the License, or (at your option) any later version.
6019
6020
This library is distributed in the hope that it will be useful,
6021
but WITHOUT ANY WARRANTY; without even the implied warranty of
6022
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6023
Lesser General Public License for more details.
6024
6025
You should have received a copy of the GNU Lesser General Public
6026
License along with this library; if not, write to the
6027
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
6028
Boston, MA 02110-1301 USA
6029
*/
6030
6031
/*
6032
PCM.cpp - read and file write module for uncompressed data
6033
*/
6034
6035
6036
#include <assert.h>
6037
#include <math.h>
6038
6039
6040
bool _af_pcm_format_ok (AudioFormat *f)
6041
{
6042
assert(!isnan(f->pcm.slope));
6043
assert(!isnan(f->pcm.intercept));
6044
assert(!isnan(f->pcm.minClip));
6045
assert(!isnan(f->pcm.maxClip));
6046
6047
return true;
6048
}
6049
6050
class PCM : public FileModule
6051
{
6052
public:
6053
static PCM *createCompress(Track *track, File *fh, bool canSeek,
6054
bool headerless, AFframecount *chunkFrames);
6055
static PCM *createDecompress(Track *track, File *fh, bool canSeek,
6056
bool headerless, AFframecount *chunkFrames);
6057
6058
virtual const char *name() const OVERRIDE { return "pcm"; }
6059
virtual void runPull() OVERRIDE;
6060
virtual void reset2() OVERRIDE;
6061
virtual void runPush() OVERRIDE;
6062
virtual void sync1() OVERRIDE;
6063
virtual void sync2() OVERRIDE;
6064
6065
private:
6066
int m_bytesPerFrame;
6067
6068
/* saved_fpos_next_frame and saved_nextfframe apply only to writing. */
6069
int m_saved_fpos_next_frame;
6070
int m_saved_nextfframe;
6071
6072
PCM(Mode, Track *, File *, bool canSeek);
6073
};
6074
6075
PCM::PCM(Mode mode, Track *track, File *fh, bool canSeek) :
6076
FileModule(mode, track, fh, canSeek),
6077
m_bytesPerFrame(track->f.bytesPerFrame(false)),
6078
m_saved_fpos_next_frame(-1),
6079
m_saved_nextfframe(-1)
6080
{
6081
if (mode == Decompress)
6082
track->f.compressionParams = AU_NULL_PVLIST;
6083
}
6084
6085
PCM *PCM::createCompress(Track *track, File *fh, bool canSeek,
6086
bool headerless, AFframecount *chunkframes)
6087
{
6088
return new PCM(Compress, track, fh, canSeek);
6089
}
6090
6091
void PCM::runPush()
6092
{
6093
AFframecount frames2write = m_inChunk->frameCount;
6094
AFframecount n;
6095
6096
/*
6097
WARNING: due to the optimization explained at the end
6098
of arrangemodules(), the pcm file module cannot depend
6099
on the presence of the intermediate working buffer
6100
which _AFsetupmodules usually allocates for file
6101
modules in their input or output chunk (for reading or
6102
writing, respectively).
6103
6104
Fortunately, the pcm module has no need for such a buffer.
6105
*/
6106
6107
ssize_t bytesWritten = write(m_inChunk->buffer, m_bytesPerFrame * frames2write);
6108
n = bytesWritten >= 0 ? bytesWritten / m_bytesPerFrame : 0;
6109
6110
if (n != frames2write)
6111
reportWriteError(n, frames2write);
6112
6113
m_track->nextfframe += n;
6114
m_track->totalfframes = m_track->nextfframe;
6115
assert(!canSeek() || (tell() == m_track->fpos_next_frame));
6116
}
6117
6118
void PCM::sync1()
6119
{
6120
m_saved_fpos_next_frame = m_track->fpos_next_frame;
6121
m_saved_nextfframe = m_track->nextfframe;
6122
}
6123
6124
void PCM::sync2()
6125
{
6126
assert(!canSeek() || (tell() == m_track->fpos_next_frame));
6127
6128
/* We can afford to seek because sync2 is rare. */
6129
m_track->fpos_after_data = tell();
6130
6131
m_track->fpos_next_frame = m_saved_fpos_next_frame;
6132
m_track->nextfframe = m_saved_nextfframe;
6133
}
6134
6135
PCM *PCM::createDecompress(Track *track, File *fh, bool canSeek,
6136
bool headerless, AFframecount *chunkframes)
6137
{
6138
return new PCM(Decompress, track, fh, canSeek);
6139
}
6140
6141
void PCM::runPull()
6142
{
6143
AFframecount framesToRead = m_outChunk->frameCount;
6144
6145
/*
6146
WARNING: Due to the optimization explained at the end of
6147
arrangemodules(), the pcm file module cannot depend on
6148
the presence of the intermediate working buffer which
6149
_AFsetupmodules usually allocates for file modules in
6150
their input or output chunk (for reading or writing,
6151
respectively).
6152
6153
Fortunately, the pcm module has no need for such a buffer.
6154
*/
6155
6156
/*
6157
Limit the number of frames to be read to the number of
6158
frames left in the track.
6159
*/
6160
if (m_track->totalfframes != -1 &&
6161
m_track->nextfframe + framesToRead > m_track->totalfframes)
6162
{
6163
framesToRead = m_track->totalfframes - m_track->nextfframe;
6164
}
6165
6166
ssize_t bytesRead = read(m_outChunk->buffer, m_bytesPerFrame * framesToRead);
6167
AFframecount framesRead = bytesRead >= 0 ? bytesRead / m_bytesPerFrame : 0;
6168
6169
m_track->nextfframe += framesRead;
6170
assert(!canSeek() || (tell() == m_track->fpos_next_frame));
6171
6172
/*
6173
If we got EOF from read, then we return the actual amount read.
6174
6175
Complain only if there should have been more frames in the file.
6176
*/
6177
6178
if (framesRead != framesToRead && m_track->totalfframes != -1)
6179
reportReadError(framesRead, framesToRead);
6180
6181
m_outChunk->frameCount = framesRead;
6182
}
6183
6184
void PCM::reset2()
6185
{
6186
m_track->fpos_next_frame = m_track->fpos_first_frame +
6187
m_bytesPerFrame * m_track->nextfframe;
6188
6189
m_track->frames2ignore = 0;
6190
}
6191
6192
FileModule *_AFpcminitcompress (Track *track, File *fh, bool canSeek,
6193
bool headerless, AFframecount *chunkFrames)
6194
{
6195
return PCM::createCompress(track, fh, canSeek, headerless, chunkFrames);
6196
}
6197
6198
FileModule *_AFpcminitdecompress (Track *track, File *fh, bool canSeek,
6199
bool headerless, AFframecount *chunkFrames)
6200
{
6201
return PCM::createDecompress(track, fh, canSeek, headerless, chunkFrames);
6202
}
6203
6204
// file: modules/SimpleModule.cpp
6205
/*
6206
Audio File Library
6207
Copyright (C) 2010, Michael Pruett <[email protected]>
6208
6209
This library is free software; you can redistribute it and/or
6210
modify it under the terms of the GNU Lesser General Public
6211
License as published by the Free Software Foundation; either
6212
version 2.1 of the License, or (at your option) any later version.
6213
6214
This library is distributed in the hope that it will be useful,
6215
but WITHOUT ANY WARRANTY; without even the implied warranty of
6216
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6217
Lesser General Public License for more details.
6218
6219
You should have received a copy of the GNU Lesser General Public
6220
License along with this library; if not, write to the
6221
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
6222
Boston, MA 02110-1301 USA
6223
*/
6224
6225
6226
#include <algorithm>
6227
6228
void SimpleModule::runPull()
6229
{
6230
pull(m_outChunk->frameCount);
6231
run(*m_inChunk, *m_outChunk);
6232
}
6233
6234
void SimpleModule::runPush()
6235
{
6236
m_outChunk->frameCount = m_inChunk->frameCount;
6237
run(*m_inChunk, *m_outChunk);
6238
push(m_outChunk->frameCount);
6239
}
6240
6241
ApplyChannelMatrix::ApplyChannelMatrix(FormatCode format, bool isReading,
6242
int inChannels, int outChannels,
6243
double minClip, double maxClip, const double *matrix) :
6244
m_format(format),
6245
m_inChannels(inChannels),
6246
m_outChannels(outChannels),
6247
m_minClip(minClip),
6248
m_maxClip(maxClip),
6249
m_matrix(NULL)
6250
{
6251
m_matrix = new double[m_inChannels * m_outChannels];
6252
if (matrix)
6253
{
6254
if (isReading)
6255
{
6256
// Copy channel matrix for reading.
6257
std::copy(matrix, matrix + m_inChannels * m_outChannels, m_matrix);
6258
}
6259
else
6260
{
6261
// Transpose channel matrix for writing.
6262
for (int i=0; i < inChannels; i++)
6263
for (int j=0; j < outChannels; j++)
6264
m_matrix[j*inChannels + i] = matrix[i*outChannels + j];
6265
}
6266
}
6267
else
6268
{
6269
initDefaultMatrix();
6270
}
6271
}
6272
6273
ApplyChannelMatrix::~ApplyChannelMatrix()
6274
{
6275
delete [] m_matrix;
6276
}
6277
6278
const char *ApplyChannelMatrix::name() const { return "channelMatrix"; }
6279
6280
void ApplyChannelMatrix::describe()
6281
{
6282
m_outChunk->f.channelCount = m_outChannels;
6283
m_outChunk->f.pcm.minClip = m_minClip;
6284
m_outChunk->f.pcm.maxClip = m_maxClip;
6285
}
6286
6287
void ApplyChannelMatrix::run(Chunk &inChunk, Chunk &outChunk)
6288
{
6289
switch (m_format)
6290
{
6291
case kInt8:
6292
run<int8_t>(inChunk.buffer, outChunk.buffer, inChunk.frameCount);
6293
break;
6294
case kInt16:
6295
run<int16_t>(inChunk.buffer, outChunk.buffer, inChunk.frameCount);
6296
break;
6297
case kInt24:
6298
case kInt32:
6299
run<int32_t>(inChunk.buffer, outChunk.buffer, inChunk.frameCount);
6300
break;
6301
case kFloat:
6302
run<float>(inChunk.buffer, outChunk.buffer, inChunk.frameCount);
6303
break;
6304
case kDouble:
6305
run<double>(inChunk.buffer, outChunk.buffer, inChunk.frameCount);
6306
break;
6307
default:
6308
assert(false);
6309
}
6310
}
6311
6312
template <typename T>
6313
void ApplyChannelMatrix::run(const void *inputData, void *outputData, int frameCount)
6314
{
6315
const T *input = reinterpret_cast<const T *>(inputData);
6316
T *output = reinterpret_cast<T *>(outputData);
6317
for (int frame=0; frame<frameCount; frame++)
6318
{
6319
const T *inputSave = input;
6320
const double *m = m_matrix;
6321
for (int outChannel=0; outChannel < m_outChannels; outChannel++)
6322
{
6323
input = inputSave;
6324
double t = 0;
6325
for (int inChannel=0; inChannel < m_inChannels; inChannel++)
6326
t += *input++ * *m++;
6327
*output++ = t;
6328
}
6329
}
6330
}
6331
6332
void ApplyChannelMatrix::initDefaultMatrix()
6333
{
6334
const double *matrix = NULL;
6335
if (m_inChannels==1 && m_outChannels==2)
6336
{
6337
static const double m[]={1,1};
6338
matrix = m;
6339
}
6340
else if (m_inChannels==1 && m_outChannels==4)
6341
{
6342
static const double m[]={1,1,0,0};
6343
matrix = m;
6344
}
6345
else if (m_inChannels==2 && m_outChannels==1)
6346
{
6347
static const double m[]={.5,.5};
6348
matrix = m;
6349
}
6350
else if (m_inChannels==2 && m_outChannels==4)
6351
{
6352
static const double m[]={1,0,0,1,0,0,0,0};
6353
matrix = m;
6354
}
6355
else if (m_inChannels==4 && m_outChannels==1)
6356
{
6357
static const double m[]={.5,.5,.5,.5};
6358
matrix = m;
6359
}
6360
else if (m_inChannels==4 && m_outChannels==2)
6361
{
6362
static const double m[]={1,0,1,0,0,1,0,1};
6363
matrix = m;
6364
}
6365
6366
if (matrix)
6367
{
6368
std::copy(matrix, matrix + m_inChannels * m_outChannels, m_matrix);
6369
}
6370
else
6371
{
6372
for (int i=0; i < m_inChannels; i++)
6373
for (int j=0; j < m_outChannels; j++)
6374
m_matrix[j*m_inChannels + i] = (i==j) ? 1 : 0;
6375
}
6376
}
6377
6378
// file: modules/RebufferModule.cpp
6379
/*
6380
Audio File Library
6381
Copyright (C) 2000, Silicon Graphics, Inc.
6382
Copyright (C) 2010, Michael Pruett <[email protected]>
6383
6384
This library is free software; you can redistribute it and/or
6385
modify it under the terms of the GNU Lesser General Public
6386
License as published by the Free Software Foundation; either
6387
version 2.1 of the License, or (at your option) any later version.
6388
6389
This library is distributed in the hope that it will be useful,
6390
but WITHOUT ANY WARRANTY; without even the implied warranty of
6391
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6392
Lesser General Public License for more details.
6393
6394
You should have received a copy of the GNU Lesser General Public
6395
License along with this library; if not, write to the
6396
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
6397
Boston, MA 02110-1301 USA
6398
*/
6399
6400
6401
#include <algorithm>
6402
#include <assert.h>
6403
#include <string.h>
6404
6405
RebufferModule::RebufferModule(Direction direction, int bytesPerFrame,
6406
int numFrames, bool multipleOf) :
6407
m_direction(direction),
6408
m_bytesPerFrame(bytesPerFrame),
6409
m_numFrames(numFrames),
6410
m_multipleOf(multipleOf),
6411
m_eof(false),
6412
m_sentShortChunk(false),
6413
m_buffer(NULL),
6414
m_offset(-1),
6415
m_savedBuffer(NULL),
6416
m_savedOffset(-1)
6417
{
6418
if (m_direction == FixedToVariable)
6419
initFixedToVariable();
6420
else
6421
initVariableToFixed();
6422
}
6423
6424
RebufferModule::~RebufferModule()
6425
{
6426
delete [] m_buffer;
6427
delete [] m_savedBuffer;
6428
}
6429
6430
void RebufferModule::initFixedToVariable()
6431
{
6432
m_offset = m_numFrames;
6433
m_buffer = new char[m_numFrames * m_bytesPerFrame];
6434
}
6435
6436
void RebufferModule::initVariableToFixed()
6437
{
6438
m_offset = 0;
6439
m_buffer = new char[m_numFrames * m_bytesPerFrame];
6440
m_savedBuffer = new char[m_numFrames * m_bytesPerFrame];
6441
}
6442
6443
void RebufferModule::maxPull()
6444
{
6445
assert(m_direction == FixedToVariable);
6446
if (m_multipleOf)
6447
m_inChunk->frameCount = m_outChunk->frameCount + m_numFrames;
6448
else
6449
m_inChunk->frameCount = m_numFrames;
6450
}
6451
6452
void RebufferModule::maxPush()
6453
{
6454
assert(m_direction == VariableToFixed);
6455
if (m_multipleOf)
6456
m_outChunk->frameCount = m_inChunk->frameCount + m_numFrames;
6457
else
6458
m_outChunk->frameCount = m_numFrames;
6459
}
6460
6461
void RebufferModule::runPull()
6462
{
6463
int framesToPull = m_outChunk->frameCount;
6464
const char *inBuffer = static_cast<const char *>(m_inChunk->buffer);
6465
char *outBuffer = static_cast<char *>(m_outChunk->buffer);
6466
6467
assert(m_offset > 0 && m_offset <= m_numFrames);
6468
6469
/*
6470
A module should not pull more frames from its input
6471
after receiving a short chunk.
6472
*/
6473
assert(!m_sentShortChunk);
6474
6475
if (m_offset < m_numFrames)
6476
{
6477
int buffered = m_numFrames - m_offset;
6478
int n = std::min(framesToPull, buffered);
6479
memcpy(outBuffer, m_buffer + m_offset * m_bytesPerFrame,
6480
n * m_bytesPerFrame);
6481
outBuffer += buffered * m_bytesPerFrame;
6482
framesToPull -= buffered;
6483
m_offset += n;
6484
}
6485
6486
// Try to pull more frames from the source.
6487
while (!m_eof && framesToPull > 0)
6488
{
6489
int framesRequested;
6490
if (m_multipleOf)
6491
// Round framesToPull up to nearest multiple of m_numFrames.
6492
framesRequested = ((framesToPull - 1) / m_numFrames + 1) * m_numFrames;
6493
else
6494
framesRequested = m_numFrames;
6495
6496
assert(framesRequested > 0);
6497
6498
pull(framesRequested);
6499
6500
int framesReceived = m_inChunk->frameCount;
6501
6502
if (framesReceived != framesRequested)
6503
m_eof = true;
6504
6505
memcpy(outBuffer, inBuffer,
6506
std::min(framesToPull, framesReceived) * m_bytesPerFrame);
6507
6508
outBuffer += framesReceived * m_bytesPerFrame;
6509
framesToPull -= framesReceived;
6510
6511
if (m_multipleOf)
6512
assert(m_eof || framesToPull <= 0);
6513
6514
if (framesToPull < 0)
6515
{
6516
assert(m_offset == m_numFrames);
6517
6518
m_offset = m_numFrames + framesToPull;
6519
6520
assert(m_offset > 0 && m_offset <= m_numFrames);
6521
6522
memcpy(m_buffer + m_offset * m_bytesPerFrame,
6523
inBuffer + (framesReceived + framesToPull) * m_bytesPerFrame,
6524
(m_numFrames - m_offset) * m_bytesPerFrame);
6525
}
6526
else
6527
{
6528
assert(m_offset == m_numFrames);
6529
}
6530
}
6531
6532
if (m_eof && framesToPull > 0)
6533
{
6534
// Output short chunk.
6535
m_outChunk->frameCount -= framesToPull;
6536
m_sentShortChunk = true;
6537
assert(m_offset == m_numFrames);
6538
}
6539
else
6540
{
6541
assert(framesToPull <= 0);
6542
assert(m_offset == m_numFrames + framesToPull);
6543
}
6544
assert(m_offset > 0 && m_offset <= m_numFrames);
6545
}
6546
6547
void RebufferModule::reset1()
6548
{
6549
m_offset = m_numFrames;
6550
m_eof = false;
6551
m_sentShortChunk = false;
6552
assert(m_offset > 0 && m_offset <= m_numFrames);
6553
}
6554
6555
void RebufferModule::reset2()
6556
{
6557
assert(m_offset > 0 && m_offset <= m_numFrames);
6558
}
6559
6560
void RebufferModule::runPush()
6561
{
6562
int framesToPush = m_inChunk->frameCount;
6563
const char *inBuffer = static_cast<const char *>(m_inChunk->buffer);
6564
char *outBuffer = static_cast<char *>(m_outChunk->buffer);
6565
6566
assert(m_offset >= 0 && m_offset < m_numFrames);
6567
6568
// Check that we will be able to push even one block.
6569
if (m_offset + framesToPush >= m_numFrames)
6570
{
6571
if (m_offset > 0)
6572
memcpy(m_outChunk->buffer, m_buffer, m_offset * m_bytesPerFrame);
6573
6574
if (m_multipleOf)
6575
{
6576
// Round down to nearest multiple of m_numFrames.
6577
int n = ((m_offset + framesToPush) / m_numFrames) * m_numFrames;
6578
6579
assert(n > m_offset);
6580
memcpy(outBuffer + m_offset * m_bytesPerFrame,
6581
inBuffer,
6582
(n - m_offset) * m_bytesPerFrame);
6583
6584
push(n);
6585
6586
inBuffer += (n - m_offset) * m_bytesPerFrame;
6587
framesToPush -= n - m_offset;
6588
assert(framesToPush >= 0);
6589
m_offset = 0;
6590
}
6591
else
6592
{
6593
while (m_offset + framesToPush >= m_numFrames)
6594
{
6595
int n = m_numFrames - m_offset;
6596
memcpy(outBuffer + m_offset * m_bytesPerFrame,
6597
inBuffer,
6598
n * m_bytesPerFrame);
6599
6600
push(m_numFrames);
6601
6602
inBuffer += n * m_bytesPerFrame;
6603
framesToPush -= n;
6604
assert(framesToPush >= 0);
6605
m_offset = 0;
6606
}
6607
}
6608
6609
assert(m_offset == 0);
6610
}
6611
6612
assert(m_offset + framesToPush < m_numFrames);
6613
6614
// Save remaining samples in buffer.
6615
if (framesToPush > 0)
6616
{
6617
memcpy(m_buffer + m_offset * m_bytesPerFrame,
6618
inBuffer,
6619
framesToPush * m_bytesPerFrame);
6620
m_offset += framesToPush;
6621
}
6622
6623
assert(m_offset >= 0 && m_offset < m_numFrames);
6624
}
6625
6626
void RebufferModule::sync1()
6627
{
6628
assert(m_offset >= 0 && m_offset < m_numFrames);
6629
6630
// Save all the frames and the offset so we can restore our state later.
6631
memcpy(m_savedBuffer, m_buffer, m_numFrames * m_bytesPerFrame);
6632
m_savedOffset = m_offset;
6633
}
6634
6635
void RebufferModule::sync2()
6636
{
6637
assert(m_offset >= 0 && m_offset < m_numFrames);
6638
6639
memcpy(m_outChunk->buffer, m_buffer, m_offset * m_bytesPerFrame);
6640
6641
push(m_offset);
6642
6643
memcpy(m_buffer, m_savedBuffer, m_numFrames * m_bytesPerFrame);
6644
m_offset = m_savedOffset;
6645
6646
assert(m_offset >= 0 && m_offset < m_numFrames);
6647
}
6648
6649
// file: AIFF.h
6650
/*
6651
Audio File Library
6652
Copyright (C) 1998-2000, 2003-2004, 2010-2012, Michael Pruett <[email protected]>
6653
6654
This library is free software; you can redistribute it and/or
6655
modify it under the terms of the GNU Lesser General Public
6656
License as published by the Free Software Foundation; either
6657
version 2.1 of the License, or (at your option) any later version.
6658
6659
This library is distributed in the hope that it will be useful,
6660
but WITHOUT ANY WARRANTY; without even the implied warranty of
6661
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6662
Lesser General Public License for more details.
6663
6664
You should have received a copy of the GNU Lesser General Public
6665
License along with this library; if not, write to the
6666
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
6667
Boston, MA 02110-1301 USA
6668
*/
6669
6670
/*
6671
AIFF.h
6672
6673
This file contains structures and constants related to the AIFF
6674
and AIFF-C formats.
6675
*/
6676
6677
#ifndef AIFF_H
6678
#define AIFF_H
6679
6680
6681
#define _AF_AIFF_NUM_INSTPARAMS 9
6682
extern const InstParamInfo _af_aiff_inst_params[_AF_AIFF_NUM_INSTPARAMS];
6683
#define _AF_AIFFC_NUM_COMPTYPES 3
6684
extern const int _af_aiffc_compression_types[_AF_AIFFC_NUM_COMPTYPES];
6685
6686
class AIFFFile : public _AFfilehandle
6687
{
6688
public:
6689
AIFFFile();
6690
6691
static bool recognizeAIFF(File *fh);
6692
static bool recognizeAIFFC(File *fh);
6693
6694
static AFfilesetup completeSetup(AFfilesetup);
6695
6696
int getVersion() OVERRIDE;
6697
6698
status readInit(AFfilesetup) OVERRIDE;
6699
status writeInit(AFfilesetup) OVERRIDE;
6700
6701
status update() OVERRIDE;
6702
6703
bool isInstrumentParameterValid(AUpvlist, int) OVERRIDE;
6704
6705
private:
6706
AFfileoffset m_miscellaneousPosition;
6707
AFfileoffset m_FVER_offset;
6708
AFfileoffset m_COMM_offset;
6709
AFfileoffset m_MARK_offset;
6710
AFfileoffset m_INST_offset;
6711
AFfileoffset m_AESD_offset;
6712
AFfileoffset m_SSND_offset;
6713
6714
status parseFVER(const Tag &type, size_t size);
6715
status parseAESD(const Tag &type, size_t size);
6716
status parseMiscellaneous(const Tag &type, size_t size);
6717
status parseINST(const Tag &type, size_t size);
6718
status parseMARK(const Tag &type, size_t size);
6719
status parseCOMM(const Tag &type, size_t size);
6720
status parseSSND(const Tag &type, size_t size);
6721
6722
status writeCOMM();
6723
status writeSSND();
6724
status writeMARK();
6725
status writeINST();
6726
status writeFVER();
6727
status writeAESD();
6728
status writeMiscellaneous();
6729
6730
void initCompressionParams();
6731
void initIMACompressionParams();
6732
6733
bool isAIFFC() const { return m_fileFormat == AF_FILE_AIFFC; }
6734
6735
bool readPString(char s[256]);
6736
bool writePString(const char *);
6737
};
6738
6739
#endif
6740
6741
// file: AIFF.cpp
6742
/*
6743
Audio File Library
6744
Copyright (C) 1998-2000, 2003-2004, 2010-2013, Michael Pruett <[email protected]>
6745
Copyright (C) 2000-2001, Silicon Graphics, Inc.
6746
6747
This library is free software; you can redistribute it and/or
6748
modify it under the terms of the GNU Lesser General Public
6749
License as published by the Free Software Foundation; either
6750
version 2.1 of the License, or (at your option) any later version.
6751
6752
This library is distributed in the hope that it will be useful,
6753
but WITHOUT ANY WARRANTY; without even the implied warranty of
6754
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6755
Lesser General Public License for more details.
6756
6757
You should have received a copy of the GNU Lesser General Public
6758
License along with this library; if not, write to the
6759
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
6760
Boston, MA 02110-1301 USA
6761
*/
6762
6763
/*
6764
AIFF.cpp
6765
6766
This file contains routines for reading and writing AIFF and
6767
AIFF-C sound files.
6768
*/
6769
6770
6771
#include <assert.h>
6772
#include <stdint.h>
6773
#include <stdlib.h>
6774
#include <string.h>
6775
6776
6777
const InstParamInfo _af_aiff_inst_params[_AF_AIFF_NUM_INSTPARAMS] =
6778
{
6779
{ AF_INST_MIDI_BASENOTE, AU_PVTYPE_LONG, "MIDI base note", {60} },
6780
{ AF_INST_NUMCENTS_DETUNE, AU_PVTYPE_LONG, "Detune in cents", {0} },
6781
{ AF_INST_MIDI_LOVELOCITY, AU_PVTYPE_LONG, "Low velocity", {1} },
6782
{ AF_INST_MIDI_HIVELOCITY, AU_PVTYPE_LONG, "High velocity", {127} },
6783
{ AF_INST_MIDI_LONOTE, AU_PVTYPE_LONG, "Low note", {0} },
6784
{ AF_INST_MIDI_HINOTE, AU_PVTYPE_LONG, "High note", {127} },
6785
{ AF_INST_NUMDBS_GAIN, AU_PVTYPE_LONG, "Gain in dB", {0} },
6786
{ AF_INST_SUSLOOPID, AU_PVTYPE_LONG, "Sustain loop id", {0} },
6787
{ AF_INST_RELLOOPID, AU_PVTYPE_LONG, "Release loop id", {0} }
6788
};
6789
6790
const int _af_aiffc_compression_types[_AF_AIFFC_NUM_COMPTYPES] =
6791
{
6792
AF_COMPRESSION_G711_ULAW,
6793
AF_COMPRESSION_G711_ALAW,
6794
AF_COMPRESSION_IMA
6795
};
6796
6797
static const _AFfilesetup aiffDefaultFileSetup =
6798
{
6799
_AF_VALID_FILESETUP, /* valid */
6800
AF_FILE_AIFF, /* fileFormat */
6801
true, /* trackSet */
6802
true, /* instrumentSet */
6803
true, /* miscellaneousSet */
6804
1, /* trackCount */
6805
NULL, /* tracks */
6806
1, /* instrumentCount */
6807
NULL, /* instruments */
6808
0, /* miscellaneousCount */
6809
NULL /* miscellaneous */
6810
};
6811
6812
#define AIFC_VERSION_1 0xa2805140
6813
6814
struct _INST
6815
{
6816
uint8_t baseNote;
6817
int8_t detune;
6818
uint8_t lowNote, highNote;
6819
uint8_t lowVelocity, highVelocity;
6820
int16_t gain;
6821
6822
uint16_t sustainLoopPlayMode;
6823
uint16_t sustainLoopBegin;
6824
uint16_t sustainLoopEnd;
6825
6826
uint16_t releaseLoopPlayMode;
6827
uint16_t releaseLoopBegin;
6828
uint16_t releaseLoopEnd;
6829
};
6830
6831
AIFFFile::AIFFFile()
6832
{
6833
setFormatByteOrder(AF_BYTEORDER_BIGENDIAN);
6834
6835
m_miscellaneousPosition = 0;
6836
m_FVER_offset = 0;
6837
m_COMM_offset = 0;
6838
m_MARK_offset = 0;
6839
m_INST_offset = 0;
6840
m_AESD_offset = 0;
6841
m_SSND_offset = 0;
6842
}
6843
6844
/*
6845
FVER chunks are only present in AIFF-C files.
6846
*/
6847
status AIFFFile::parseFVER(const Tag &type, size_t size)
6848
{
6849
assert(type == "FVER");
6850
6851
uint32_t timestamp;
6852
readU32(&timestamp);
6853
/* timestamp holds the number of seconds since January 1, 1904. */
6854
6855
return AF_SUCCEED;
6856
}
6857
6858
/*
6859
Parse AES recording data.
6860
*/
6861
status AIFFFile::parseAESD(const Tag &type, size_t size)
6862
{
6863
unsigned char aesChannelStatusData[24];
6864
6865
assert(type == "AESD");
6866
assert(size == 24);
6867
6868
Track *track = getTrack();
6869
6870
track->hasAESData = true;
6871
6872
/*
6873
Try to read 24 bytes of AES nonaudio data from the file.
6874
Fail if the file disappoints.
6875
*/
6876
if (m_fh->read(aesChannelStatusData, 24) != 24)
6877
return AF_FAIL;
6878
6879
memcpy(track->aesData, aesChannelStatusData, 24);
6880
6881
return AF_SUCCEED;
6882
}
6883
6884
/*
6885
Parse miscellaneous data chunks such as name, author, copyright,
6886
and annotation chunks.
6887
*/
6888
status AIFFFile::parseMiscellaneous(const Tag &type, size_t size)
6889
{
6890
int misctype = AF_MISC_UNRECOGNIZED;
6891
6892
assert(type == "NAME" ||
6893
type == "AUTH" ||
6894
type == "(c) " ||
6895
type == "ANNO" ||
6896
type == "APPL" ||
6897
type == "MIDI");
6898
6899
/* Skip zero-length miscellaneous chunks. */
6900
if (size == 0)
6901
return AF_FAIL;
6902
6903
m_miscellaneousCount++;
6904
m_miscellaneous = (Miscellaneous *) _af_realloc(m_miscellaneous,
6905
m_miscellaneousCount * sizeof (Miscellaneous));
6906
6907
if (type == "NAME")
6908
misctype = AF_MISC_NAME;
6909
else if (type == "AUTH")
6910
misctype = AF_MISC_AUTH;
6911
else if (type == "(c) ")
6912
misctype = AF_MISC_COPY;
6913
else if (type == "ANNO")
6914
misctype = AF_MISC_ANNO;
6915
else if (type == "APPL")
6916
misctype = AF_MISC_APPL;
6917
else if (type == "MIDI")
6918
misctype = AF_MISC_MIDI;
6919
6920
m_miscellaneous[m_miscellaneousCount - 1].id = m_miscellaneousCount;
6921
m_miscellaneous[m_miscellaneousCount - 1].type = misctype;
6922
m_miscellaneous[m_miscellaneousCount - 1].size = size;
6923
m_miscellaneous[m_miscellaneousCount - 1].position = 0;
6924
m_miscellaneous[m_miscellaneousCount - 1].buffer = _af_malloc(size);
6925
m_fh->read(m_miscellaneous[m_miscellaneousCount - 1].buffer, size);
6926
6927
return AF_SUCCEED;
6928
}
6929
6930
/*
6931
Parse instrument chunks, which contain information about using
6932
sound data as a sampled instrument.
6933
*/
6934
status AIFFFile::parseINST(const Tag &type, size_t size)
6935
{
6936
uint8_t baseNote;
6937
int8_t detune;
6938
uint8_t lowNote, highNote, lowVelocity, highVelocity;
6939
int16_t gain;
6940
6941
uint16_t sustainLoopPlayMode, sustainLoopBegin, sustainLoopEnd;
6942
uint16_t releaseLoopPlayMode, releaseLoopBegin, releaseLoopEnd;
6943
6944
Instrument *instrument = (Instrument *) _af_calloc(1, sizeof (Instrument));
6945
instrument->id = AF_DEFAULT_INST;
6946
instrument->values = (AFPVu *) _af_calloc(_AF_AIFF_NUM_INSTPARAMS, sizeof (AFPVu));
6947
instrument->loopCount = 2;
6948
instrument->loops = (Loop *) _af_calloc(2, sizeof (Loop));
6949
6950
m_instrumentCount = 1;
6951
m_instruments = instrument;
6952
6953
readU8(&baseNote);
6954
readS8(&detune);
6955
readU8(&lowNote);
6956
readU8(&highNote);
6957
readU8(&lowVelocity);
6958
readU8(&highVelocity);
6959
readS16(&gain);
6960
6961
instrument->values[0].l = baseNote;
6962
instrument->values[1].l = detune;
6963
instrument->values[2].l = lowVelocity;
6964
instrument->values[3].l = highVelocity;
6965
instrument->values[4].l = lowNote;
6966
instrument->values[5].l = highNote;
6967
instrument->values[6].l = gain;
6968
6969
instrument->values[7].l = 1; /* sustain loop id */
6970
instrument->values[8].l = 2; /* release loop id */
6971
6972
readU16(&sustainLoopPlayMode);
6973
readU16(&sustainLoopBegin);
6974
readU16(&sustainLoopEnd);
6975
6976
readU16(&releaseLoopPlayMode);
6977
readU16(&releaseLoopBegin);
6978
readU16(&releaseLoopEnd);
6979
6980
instrument->loops[0].id = 1;
6981
instrument->loops[0].mode = sustainLoopPlayMode;
6982
instrument->loops[0].beginMarker = sustainLoopBegin;
6983
instrument->loops[0].endMarker = sustainLoopEnd;
6984
instrument->loops[0].trackid = AF_DEFAULT_TRACK;
6985
6986
instrument->loops[1].id = 2;
6987
instrument->loops[1].mode = releaseLoopPlayMode;
6988
instrument->loops[1].beginMarker = releaseLoopBegin;
6989
instrument->loops[1].endMarker = releaseLoopEnd;
6990
instrument->loops[1].trackid = AF_DEFAULT_TRACK;
6991
6992
return AF_SUCCEED;
6993
}
6994
6995
/*
6996
Parse marker chunks, which contain the positions and names of loop markers.
6997
*/
6998
status AIFFFile::parseMARK(const Tag &type, size_t size)
6999
{
7000
assert(type == "MARK");
7001
7002
Track *track = getTrack();
7003
7004
uint16_t numMarkers;
7005
readU16(&numMarkers);
7006
7007
track->markerCount = numMarkers;
7008
if (numMarkers)
7009
track->markers = _af_marker_new(numMarkers);
7010
7011
for (unsigned i=0; i<numMarkers; i++)
7012
{
7013
uint16_t markerID = 0;
7014
uint32_t markerPosition = 0;
7015
uint8_t sizeByte = 0;
7016
char *markerName = NULL;
7017
7018
readU16(&markerID);
7019
readU32(&markerPosition);
7020
m_fh->read(&sizeByte, 1);
7021
markerName = (char *) _af_malloc(sizeByte + 1);
7022
m_fh->read(markerName, sizeByte);
7023
7024
markerName[sizeByte] = '\0';
7025
7026
/*
7027
If sizeByte is even, then 1+sizeByte (the length
7028
of the string) is odd. Skip an extra byte to
7029
make it even.
7030
*/
7031
7032
if ((sizeByte % 2) == 0)
7033
m_fh->seek(1, File::SeekFromCurrent);
7034
7035
track->markers[i].id = markerID;
7036
track->markers[i].position = markerPosition;
7037
track->markers[i].name = markerName;
7038
track->markers[i].comment = _af_strdup("");
7039
}
7040
7041
return AF_SUCCEED;
7042
}
7043
7044
/*
7045
Parse common data chunks, which contain information regarding the
7046
sampling rate, the number of sample frames, and the number of
7047
sound channels.
7048
*/
7049
status AIFFFile::parseCOMM(const Tag &type, size_t size)
7050
{
7051
assert(type == "COMM");
7052
7053
Track *track = getTrack();
7054
7055
uint16_t numChannels;
7056
uint32_t numSampleFrames;
7057
uint16_t sampleSize;
7058
unsigned char sampleRate[10];
7059
7060
readU16(&numChannels);
7061
track->f.channelCount = numChannels;
7062
7063
if (!numChannels)
7064
{
7065
_af_error(AF_BAD_CHANNELS, "invalid file with 0 channels");
7066
return AF_FAIL;
7067
}
7068
7069
readU32(&numSampleFrames);
7070
track->totalfframes = numSampleFrames;
7071
7072
readU16(&sampleSize);
7073
track->f.sampleWidth = sampleSize;
7074
7075
m_fh->read(sampleRate, 10);
7076
track->f.sampleRate = _af_convert_from_ieee_extended(sampleRate);
7077
7078
track->f.compressionType = AF_COMPRESSION_NONE;
7079
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
7080
track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
7081
7082
track->f.framesPerPacket = 1;
7083
7084
if (isAIFFC())
7085
{
7086
Tag compressionID;
7087
// Pascal strings are at most 255 bytes long.
7088
char compressionName[256];
7089
7090
readTag(&compressionID);
7091
7092
// Read the Pascal-style string containing the name.
7093
readPString(compressionName);
7094
7095
if (compressionID == "NONE" || compressionID == "twos")
7096
{
7097
track->f.compressionType = AF_COMPRESSION_NONE;
7098
}
7099
else if (compressionID == "in24")
7100
{
7101
track->f.compressionType = AF_COMPRESSION_NONE;
7102
track->f.sampleWidth = 24;
7103
}
7104
else if (compressionID == "in32")
7105
{
7106
track->f.compressionType = AF_COMPRESSION_NONE;
7107
track->f.sampleWidth = 32;
7108
}
7109
else if (compressionID == "ACE2" ||
7110
compressionID == "ACE8" ||
7111
compressionID == "MAC3" ||
7112
compressionID == "MAC6")
7113
{
7114
_af_error(AF_BAD_NOT_IMPLEMENTED, "AIFF-C format does not support Apple's proprietary %s compression format", compressionName);
7115
return AF_FAIL;
7116
}
7117
else if (compressionID == "ulaw" || compressionID == "ULAW")
7118
{
7119
track->f.compressionType = AF_COMPRESSION_G711_ULAW;
7120
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
7121
track->f.sampleWidth = 16;
7122
track->f.bytesPerPacket = track->f.channelCount;
7123
}
7124
else if (compressionID == "alaw" || compressionID == "ALAW")
7125
{
7126
track->f.compressionType = AF_COMPRESSION_G711_ALAW;
7127
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
7128
track->f.sampleWidth = 16;
7129
track->f.bytesPerPacket = track->f.channelCount;
7130
}
7131
else if (compressionID == "fl32" || compressionID == "FL32")
7132
{
7133
track->f.sampleFormat = AF_SAMPFMT_FLOAT;
7134
track->f.sampleWidth = 32;
7135
track->f.compressionType = AF_COMPRESSION_NONE;
7136
}
7137
else if (compressionID == "fl64" || compressionID == "FL64")
7138
{
7139
track->f.sampleFormat = AF_SAMPFMT_DOUBLE;
7140
track->f.sampleWidth = 64;
7141
track->f.compressionType = AF_COMPRESSION_NONE;
7142
}
7143
else if (compressionID == "sowt")
7144
{
7145
track->f.compressionType = AF_COMPRESSION_NONE;
7146
track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
7147
}
7148
else if (compressionID == "ima4")
7149
{
7150
track->f.sampleWidth = 16;
7151
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
7152
track->f.compressionType = AF_COMPRESSION_IMA;
7153
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
7154
7155
initIMACompressionParams();
7156
7157
track->totalfframes *= 64;
7158
}
7159
else
7160
{
7161
_af_error(AF_BAD_NOT_IMPLEMENTED, "AIFF-C compression type '%s' not currently supported",
7162
compressionID.name().c_str());
7163
return AF_FAIL;
7164
}
7165
}
7166
7167
if (track->f.isUncompressed())
7168
track->f.computeBytesPerPacketPCM();
7169
7170
if (_af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth) == AF_FAIL)
7171
return AF_FAIL;
7172
7173
return AF_SUCCEED;
7174
}
7175
7176
/*
7177
Parse the stored sound chunk, which usually contains little more
7178
than the sound data.
7179
*/
7180
status AIFFFile::parseSSND(const Tag &type, size_t size)
7181
{
7182
assert(type == "SSND");
7183
7184
Track *track = getTrack();
7185
7186
uint32_t offset, blockSize;
7187
readU32(&offset);
7188
readU32(&blockSize);
7189
7190
track->data_size = size - 8 - offset;
7191
7192
track->fpos_first_frame = m_fh->tell() + offset;
7193
7194
return AF_SUCCEED;
7195
}
7196
7197
status AIFFFile::readInit(AFfilesetup setup)
7198
{
7199
uint32_t type, size, formtype;
7200
7201
bool hasCOMM = false;
7202
bool hasFVER = false;
7203
bool hasSSND = false;
7204
7205
m_fh->seek(0, File::SeekFromBeginning);
7206
7207
m_fh->read(&type, 4);
7208
readU32(&size);
7209
m_fh->read(&formtype, 4);
7210
7211
if (memcmp(&type, "FORM", 4) != 0 ||
7212
(memcmp(&formtype, "AIFF", 4) && memcmp(&formtype, "AIFC", 4)))
7213
return AF_FAIL;
7214
7215
if (!allocateTrack())
7216
return AF_FAIL;
7217
7218
/* Include the offset of the form type. */
7219
size_t index = 4;
7220
while (index < size)
7221
{
7222
Tag chunkid;
7223
uint32_t chunksize = 0;
7224
status result = AF_SUCCEED;
7225
7226
readTag(&chunkid);
7227
readU32(&chunksize);
7228
7229
if (chunkid == "COMM")
7230
{
7231
hasCOMM = true;
7232
result = parseCOMM(chunkid, chunksize);
7233
}
7234
else if (chunkid == "FVER")
7235
{
7236
hasFVER = true;
7237
parseFVER(chunkid, chunksize);
7238
}
7239
else if (chunkid == "INST")
7240
{
7241
parseINST(chunkid, chunksize);
7242
}
7243
else if (chunkid == "MARK")
7244
{
7245
parseMARK(chunkid, chunksize);
7246
}
7247
else if (chunkid == "AESD")
7248
{
7249
parseAESD(chunkid, chunksize);
7250
}
7251
else if (chunkid == "NAME" ||
7252
chunkid == "AUTH" ||
7253
chunkid == "(c) " ||
7254
chunkid == "ANNO" ||
7255
chunkid == "APPL" ||
7256
chunkid == "MIDI")
7257
{
7258
parseMiscellaneous(chunkid, chunksize);
7259
}
7260
/*
7261
The sound data chunk is required if there are more than
7262
zero sample frames.
7263
*/
7264
else if (chunkid == "SSND")
7265
{
7266
if (hasSSND)
7267
{
7268
_af_error(AF_BAD_AIFF_SSND, "AIFF file has more than one SSND chunk");
7269
return AF_FAIL;
7270
}
7271
hasSSND = true;
7272
result = parseSSND(chunkid, chunksize);
7273
}
7274
7275
if (result == AF_FAIL)
7276
return AF_FAIL;
7277
7278
index += chunksize + 8;
7279
7280
/* all chunks must be aligned on an even number of bytes */
7281
if ((index % 2) != 0)
7282
index++;
7283
7284
m_fh->seek(index + 8, File::SeekFromBeginning);
7285
}
7286
7287
if (!hasCOMM)
7288
{
7289
_af_error(AF_BAD_AIFF_COMM, "bad AIFF COMM chunk");
7290
}
7291
7292
if (isAIFFC() && !hasFVER)
7293
{
7294
_af_error(AF_BAD_HEADER, "FVER chunk is required in AIFF-C");
7295
}
7296
7297
/* The file has been successfully parsed. */
7298
return AF_SUCCEED;
7299
}
7300
7301
bool AIFFFile::recognizeAIFF(File *fh)
7302
{
7303
uint8_t buffer[8];
7304
7305
fh->seek(0, File::SeekFromBeginning);
7306
7307
if (fh->read(buffer, 8) != 8 || memcmp(buffer, "FORM", 4) != 0)
7308
return false;
7309
if (fh->read(buffer, 4) != 4 || memcmp(buffer, "AIFF", 4) != 0)
7310
return false;
7311
7312
return true;
7313
}
7314
7315
bool AIFFFile::recognizeAIFFC(File *fh)
7316
{
7317
uint8_t buffer[8];
7318
7319
fh->seek(0, File::SeekFromBeginning);
7320
7321
if (fh->read(buffer, 8) != 8 || memcmp(buffer, "FORM", 4) != 0)
7322
return false;
7323
if (fh->read(buffer, 4) != 4 || memcmp(buffer, "AIFC", 4) != 0)
7324
return false;
7325
7326
return true;
7327
}
7328
7329
AFfilesetup AIFFFile::completeSetup(AFfilesetup setup)
7330
{
7331
bool isAIFF = setup->fileFormat == AF_FILE_AIFF;
7332
7333
if (setup->trackSet && setup->trackCount != 1)
7334
{
7335
_af_error(AF_BAD_NUMTRACKS, "AIFF/AIFF-C file must have 1 track");
7336
return AF_NULL_FILESETUP;
7337
}
7338
7339
TrackSetup *track = setup->getTrack();
7340
if (!track)
7341
return AF_NULL_FILESETUP;
7342
7343
if (track->sampleFormatSet)
7344
{
7345
if (track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
7346
{
7347
_af_error(AF_BAD_FILEFMT, "AIFF/AIFF-C format does not support unsigned data");
7348
return AF_NULL_FILESETUP;
7349
}
7350
else if (isAIFF && track->f.sampleFormat != AF_SAMPFMT_TWOSCOMP)
7351
{
7352
_af_error(AF_BAD_FILEFMT, "AIFF format supports only two's complement integer data");
7353
return AF_NULL_FILESETUP;
7354
}
7355
}
7356
else
7357
_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP,
7358
track->f.sampleWidth);
7359
7360
/* Check sample width if writing two's complement. Otherwise ignore. */
7361
if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP &&
7362
(track->f.sampleWidth < 1 || track->f.sampleWidth > 32))
7363
{
7364
_af_error(AF_BAD_WIDTH,
7365
"invalid sample width %d for AIFF/AIFF-C file "
7366
"(must be 1-32)", track->f.sampleWidth);
7367
return AF_NULL_FILESETUP;
7368
}
7369
7370
if (isAIFF && track->f.compressionType != AF_COMPRESSION_NONE)
7371
{
7372
_af_error(AF_BAD_FILESETUP,
7373
"AIFF does not support compression; use AIFF-C");
7374
return AF_NULL_FILESETUP;
7375
}
7376
7377
if (track->f.compressionType != AF_COMPRESSION_NONE &&
7378
track->f.compressionType != AF_COMPRESSION_G711_ULAW &&
7379
track->f.compressionType != AF_COMPRESSION_G711_ALAW &&
7380
track->f.compressionType != AF_COMPRESSION_IMA)
7381
{
7382
_af_error(AF_BAD_NOT_IMPLEMENTED, "compression format not supported in AIFF-C");
7383
return AF_NULL_FILESETUP;
7384
}
7385
7386
if (track->f.isUncompressed() &&
7387
track->byteOrderSet &&
7388
track->f.byteOrder != AF_BYTEORDER_BIGENDIAN &&
7389
track->f.isByteOrderSignificant())
7390
{
7391
_af_error(AF_BAD_BYTEORDER,
7392
"AIFF/AIFF-C format supports only big-endian data");
7393
return AF_NULL_FILESETUP;
7394
}
7395
7396
if (track->f.isUncompressed())
7397
track->f.byteOrder = AF_BYTEORDER_BIGENDIAN;
7398
7399
if (setup->instrumentSet)
7400
{
7401
if (setup->instrumentCount != 0 && setup->instrumentCount != 1)
7402
{
7403
_af_error(AF_BAD_NUMINSTS, "AIFF/AIFF-C file must have 0 or 1 instrument chunk");
7404
return AF_NULL_FILESETUP;
7405
}
7406
if (setup->instruments != 0 &&
7407
setup->instruments[0].loopCount != 2)
7408
{
7409
_af_error(AF_BAD_NUMLOOPS, "AIFF/AIFF-C file with instrument must also have 2 loops");
7410
return AF_NULL_FILESETUP;
7411
}
7412
}
7413
7414
if (setup->miscellaneousSet)
7415
{
7416
for (int i=0; i<setup->miscellaneousCount; i++)
7417
{
7418
switch (setup->miscellaneous[i].type)
7419
{
7420
case AF_MISC_COPY:
7421
case AF_MISC_AUTH:
7422
case AF_MISC_NAME:
7423
case AF_MISC_ANNO:
7424
case AF_MISC_APPL:
7425
case AF_MISC_MIDI:
7426
break;
7427
7428
default:
7429
_af_error(AF_BAD_MISCTYPE, "invalid miscellaneous type %d for AIFF/AIFF-C file", setup->miscellaneous[i].type);
7430
return AF_NULL_FILESETUP;
7431
}
7432
}
7433
}
7434
7435
return _af_filesetup_copy(setup, &aiffDefaultFileSetup, true);
7436
}
7437
7438
bool AIFFFile::isInstrumentParameterValid(AUpvlist list, int i)
7439
{
7440
int param, type;
7441
7442
AUpvgetparam(list, i, &param);
7443
AUpvgetvaltype(list, i, &type);
7444
if (type != AU_PVTYPE_LONG)
7445
return false;
7446
7447
long lval;
7448
AUpvgetval(list, i, &lval);
7449
7450
switch (param)
7451
{
7452
case AF_INST_MIDI_BASENOTE:
7453
return ((lval >= 0) && (lval <= 127));
7454
7455
case AF_INST_NUMCENTS_DETUNE:
7456
return ((lval >= -50) && (lval <= 50));
7457
7458
case AF_INST_MIDI_LOVELOCITY:
7459
return ((lval >= 1) && (lval <= 127));
7460
7461
case AF_INST_MIDI_HIVELOCITY:
7462
return ((lval >= 1) && (lval <= 127));
7463
7464
case AF_INST_MIDI_LONOTE:
7465
return ((lval >= 0) && (lval <= 127));
7466
7467
case AF_INST_MIDI_HINOTE:
7468
return ((lval >= 0) && (lval <= 127));
7469
7470
case AF_INST_NUMDBS_GAIN:
7471
case AF_INST_SUSLOOPID:
7472
case AF_INST_RELLOOPID:
7473
return true;
7474
7475
default:
7476
return false;
7477
break;
7478
}
7479
7480
return true;
7481
}
7482
7483
int AIFFFile::getVersion()
7484
{
7485
if (isAIFFC())
7486
return AIFC_VERSION_1;
7487
return 0;
7488
}
7489
7490
status AIFFFile::writeInit(AFfilesetup setup)
7491
{
7492
if (initFromSetup(setup) == AF_FAIL)
7493
return AF_FAIL;
7494
7495
initCompressionParams();
7496
7497
uint32_t fileSize = 0;
7498
m_fh->write("FORM", 4);
7499
writeU32(&fileSize);
7500
7501
if (isAIFFC())
7502
m_fh->write("AIFC", 4);
7503
else
7504
m_fh->write("AIFF", 4);
7505
7506
if (isAIFFC())
7507
writeFVER();
7508
7509
writeCOMM();
7510
writeMARK();
7511
writeINST();
7512
writeAESD();
7513
writeMiscellaneous();
7514
writeSSND();
7515
7516
return AF_SUCCEED;
7517
}
7518
7519
status AIFFFile::update()
7520
{
7521
/* Get the length of the file. */
7522
uint32_t length = m_fh->length();
7523
length -= 8;
7524
7525
/* Set the length of the FORM chunk. */
7526
m_fh->seek(4, File::SeekFromBeginning);
7527
writeU32(&length);
7528
7529
if (isAIFFC())
7530
writeFVER();
7531
7532
writeCOMM();
7533
writeMARK();
7534
writeINST();
7535
writeAESD();
7536
writeMiscellaneous();
7537
writeSSND();
7538
7539
return AF_SUCCEED;
7540
}
7541
7542
status AIFFFile::writeCOMM()
7543
{
7544
/*
7545
If COMM_offset hasn't been set yet, set it to the
7546
current offset.
7547
*/
7548
if (m_COMM_offset == 0)
7549
m_COMM_offset = m_fh->tell();
7550
else
7551
m_fh->seek(m_COMM_offset, File::SeekFromBeginning);
7552
7553
Track *track = getTrack();
7554
7555
Tag compressionTag;
7556
/* Pascal strings can occupy only 255 bytes (+ a size byte). */
7557
char compressionName[256];
7558
7559
if (isAIFFC())
7560
{
7561
if (track->f.compressionType == AF_COMPRESSION_NONE)
7562
{
7563
if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP)
7564
{
7565
compressionTag = "NONE";
7566
strcpy(compressionName, "not compressed");
7567
}
7568
else if (track->f.sampleFormat == AF_SAMPFMT_FLOAT)
7569
{
7570
compressionTag = "fl32";
7571
strcpy(compressionName, "32-bit Floating Point");
7572
}
7573
else if (track->f.sampleFormat == AF_SAMPFMT_DOUBLE)
7574
{
7575
compressionTag = "fl64";
7576
strcpy(compressionName, "64-bit Floating Point");
7577
}
7578
/*
7579
We disallow unsigned sample data for
7580
AIFF files in _af_aiff_complete_setup,
7581
so the next condition should never be
7582
satisfied.
7583
*/
7584
else if (track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
7585
{
7586
_af_error(AF_BAD_SAMPFMT,
7587
"AIFF/AIFF-C format does not support unsigned data");
7588
assert(0);
7589
return AF_FAIL;
7590
}
7591
}
7592
else if (track->f.compressionType == AF_COMPRESSION_G711_ULAW)
7593
{
7594
compressionTag = "ulaw";
7595
strcpy(compressionName, "CCITT G.711 u-law");
7596
}
7597
else if (track->f.compressionType == AF_COMPRESSION_G711_ALAW)
7598
{
7599
compressionTag = "alaw";
7600
strcpy(compressionName, "CCITT G.711 A-law");
7601
}
7602
else if (track->f.compressionType == AF_COMPRESSION_IMA)
7603
{
7604
compressionTag = "ima4";
7605
strcpy(compressionName, "IMA 4:1 compression");
7606
}
7607
}
7608
7609
m_fh->write("COMM", 4);
7610
7611
/*
7612
For AIFF-C files, the length of the COMM chunk is 22
7613
plus the length of the compression name plus the size
7614
byte. If the length of the data is an odd number of
7615
bytes, add a zero pad byte at the end, but don't
7616
include the pad byte in the chunk's size.
7617
*/
7618
uint32_t chunkSize;
7619
if (isAIFFC())
7620
chunkSize = 22 + strlen(compressionName) + 1;
7621
else
7622
chunkSize = 18;
7623
writeU32(&chunkSize);
7624
7625
/* number of channels, 2 bytes */
7626
uint16_t channelCount = track->f.channelCount;
7627
writeU16(&channelCount);
7628
7629
/* number of sample frames, 4 bytes */
7630
uint32_t frameCount = track->totalfframes;
7631
if (track->f.compressionType == AF_COMPRESSION_IMA)
7632
frameCount = track->totalfframes / track->f.framesPerPacket;
7633
writeU32(&frameCount);
7634
7635
/* sample size, 2 bytes */
7636
uint16_t sampleSize = track->f.sampleWidth;
7637
writeU16(&sampleSize);
7638
7639
/* sample rate, 10 bytes */
7640
uint8_t sampleRate[10];
7641
_af_convert_to_ieee_extended(track->f.sampleRate, sampleRate);
7642
m_fh->write(sampleRate, 10);
7643
7644
if (isAIFFC())
7645
{
7646
writeTag(&compressionTag);
7647
writePString(compressionName);
7648
}
7649
7650
return AF_SUCCEED;
7651
}
7652
7653
/*
7654
The AESD chunk contains information pertinent to audio recording
7655
devices.
7656
*/
7657
status AIFFFile::writeAESD()
7658
{
7659
Track *track = getTrack();
7660
7661
if (!track->hasAESData)
7662
return AF_SUCCEED;
7663
7664
if (m_AESD_offset == 0)
7665
m_AESD_offset = m_fh->tell();
7666
else
7667
m_fh->seek(m_AESD_offset, File::SeekFromBeginning);
7668
7669
if (m_fh->write("AESD", 4) < 4)
7670
return AF_FAIL;
7671
7672
uint32_t size = 24;
7673
if (!writeU32(&size))
7674
return AF_FAIL;
7675
7676
if (m_fh->write(track->aesData, 24) < 24)
7677
return AF_FAIL;
7678
7679
return AF_SUCCEED;
7680
}
7681
7682
status AIFFFile::writeSSND()
7683
{
7684
Track *track = getTrack();
7685
7686
if (m_SSND_offset == 0)
7687
m_SSND_offset = m_fh->tell();
7688
else
7689
m_fh->seek(m_SSND_offset, File::SeekFromBeginning);
7690
7691
m_fh->write("SSND", 4);
7692
7693
uint32_t chunkSize = track->data_size + 8;
7694
writeU32(&chunkSize);
7695
7696
uint32_t zero = 0;
7697
/* data offset */
7698
writeU32(&zero);
7699
/* block size */
7700
writeU32(&zero);
7701
7702
if (track->fpos_first_frame == 0)
7703
track->fpos_first_frame = m_fh->tell();
7704
7705
return AF_SUCCEED;
7706
}
7707
7708
status AIFFFile::writeINST()
7709
{
7710
uint32_t length = 20;
7711
7712
struct _INST instrumentdata;
7713
7714
instrumentdata.sustainLoopPlayMode =
7715
afGetLoopMode(this, AF_DEFAULT_INST, 1);
7716
instrumentdata.sustainLoopBegin =
7717
afGetLoopStart(this, AF_DEFAULT_INST, 1);
7718
instrumentdata.sustainLoopEnd =
7719
afGetLoopEnd(this, AF_DEFAULT_INST, 1);
7720
7721
instrumentdata.releaseLoopPlayMode =
7722
afGetLoopMode(this, AF_DEFAULT_INST, 2);
7723
instrumentdata.releaseLoopBegin =
7724
afGetLoopStart(this, AF_DEFAULT_INST, 2);
7725
instrumentdata.releaseLoopEnd =
7726
afGetLoopEnd(this, AF_DEFAULT_INST, 2);
7727
7728
m_fh->write("INST", 4);
7729
writeU32(&length);
7730
7731
instrumentdata.baseNote =
7732
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_MIDI_BASENOTE);
7733
writeU8(&instrumentdata.baseNote);
7734
instrumentdata.detune =
7735
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_NUMCENTS_DETUNE);
7736
writeS8(&instrumentdata.detune);
7737
instrumentdata.lowNote =
7738
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_MIDI_LONOTE);
7739
writeU8(&instrumentdata.lowNote);
7740
instrumentdata.highNote =
7741
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_MIDI_HINOTE);
7742
writeU8(&instrumentdata.highNote);
7743
instrumentdata.lowVelocity =
7744
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_MIDI_LOVELOCITY);
7745
writeU8(&instrumentdata.lowVelocity);
7746
instrumentdata.highVelocity =
7747
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_MIDI_HIVELOCITY);
7748
writeU8(&instrumentdata.highVelocity);
7749
7750
instrumentdata.gain =
7751
afGetInstParamLong(this, AF_DEFAULT_INST, AF_INST_NUMDBS_GAIN);
7752
writeS16(&instrumentdata.gain);
7753
7754
writeU16(&instrumentdata.sustainLoopPlayMode);
7755
writeU16(&instrumentdata.sustainLoopBegin);
7756
writeU16(&instrumentdata.sustainLoopEnd);
7757
7758
writeU16(&instrumentdata.releaseLoopPlayMode);
7759
writeU16(&instrumentdata.releaseLoopBegin);
7760
writeU16(&instrumentdata.releaseLoopEnd);
7761
7762
return AF_SUCCEED;
7763
}
7764
7765
status AIFFFile::writeMARK()
7766
{
7767
Track *track = getTrack();
7768
if (!track->markerCount)
7769
return AF_SUCCEED;
7770
7771
if (m_MARK_offset == 0)
7772
m_MARK_offset = m_fh->tell();
7773
else
7774
m_fh->seek(m_MARK_offset, File::SeekFromBeginning);
7775
7776
Tag markTag("MARK");
7777
uint32_t length = 0;
7778
7779
writeTag(&markTag);
7780
writeU32(&length);
7781
7782
AFfileoffset chunkStartPosition = m_fh->tell();
7783
7784
uint16_t numMarkers = track->markerCount;
7785
writeU16(&numMarkers);
7786
7787
for (unsigned i=0; i<numMarkers; i++)
7788
{
7789
uint16_t id = track->markers[i].id;
7790
writeU16(&id);
7791
7792
uint32_t position = track->markers[i].position;
7793
writeU32(&position);
7794
7795
const char *name = track->markers[i].name;
7796
assert(name);
7797
7798
// Write the name as a Pascal-style string.
7799
writePString(name);
7800
}
7801
7802
AFfileoffset chunkEndPosition = m_fh->tell();
7803
length = chunkEndPosition - chunkStartPosition;
7804
7805
m_fh->seek(chunkStartPosition - 4, File::SeekFromBeginning);
7806
7807
writeU32(&length);
7808
m_fh->seek(chunkEndPosition, File::SeekFromBeginning);
7809
7810
return AF_SUCCEED;
7811
}
7812
7813
/*
7814
The FVER chunk, if present, is always the first chunk in the file.
7815
*/
7816
status AIFFFile::writeFVER()
7817
{
7818
uint32_t chunkSize, timeStamp;
7819
7820
assert(isAIFFC());
7821
7822
if (m_FVER_offset == 0)
7823
m_FVER_offset = m_fh->tell();
7824
else
7825
m_fh->seek(m_FVER_offset, File::SeekFromBeginning);
7826
7827
m_fh->write("FVER", 4);
7828
7829
chunkSize = 4;
7830
writeU32(&chunkSize);
7831
7832
timeStamp = AIFC_VERSION_1;
7833
writeU32(&timeStamp);
7834
7835
return AF_SUCCEED;
7836
}
7837
7838
/*
7839
WriteMiscellaneous writes all the miscellaneous data chunks in a
7840
file handle structure to an AIFF or AIFF-C file.
7841
*/
7842
status AIFFFile::writeMiscellaneous()
7843
{
7844
if (m_miscellaneousPosition == 0)
7845
m_miscellaneousPosition = m_fh->tell();
7846
else
7847
m_fh->seek(m_miscellaneousPosition, File::SeekFromBeginning);
7848
7849
for (int i=0; i<m_miscellaneousCount; i++)
7850
{
7851
Miscellaneous *misc = &m_miscellaneous[i];
7852
Tag chunkType;
7853
uint32_t chunkSize;
7854
uint8_t padByte = 0;
7855
7856
switch (misc->type)
7857
{
7858
case AF_MISC_NAME:
7859
chunkType = "NAME"; break;
7860
case AF_MISC_AUTH:
7861
chunkType = "AUTH"; break;
7862
case AF_MISC_COPY:
7863
chunkType = "(c) "; break;
7864
case AF_MISC_ANNO:
7865
chunkType = "ANNO"; break;
7866
case AF_MISC_MIDI:
7867
chunkType = "MIDI"; break;
7868
case AF_MISC_APPL:
7869
chunkType = "APPL"; break;
7870
}
7871
7872
writeTag(&chunkType);
7873
7874
chunkSize = misc->size;
7875
writeU32(&chunkSize);
7876
/*
7877
Write the miscellaneous buffer and then a pad byte
7878
if necessary. If the buffer is null, skip the space
7879
for now.
7880
*/
7881
if (misc->buffer != NULL)
7882
m_fh->write(misc->buffer, misc->size);
7883
else
7884
m_fh->seek(misc->size, File::SeekFromCurrent);
7885
7886
if (misc->size % 2 != 0)
7887
writeU8(&padByte);
7888
}
7889
7890
return AF_SUCCEED;
7891
}
7892
7893
void AIFFFile::initCompressionParams()
7894
{
7895
Track *track = getTrack();
7896
if (track->f.compressionType == AF_COMPRESSION_IMA)
7897
initIMACompressionParams();
7898
}
7899
7900
void AIFFFile::initIMACompressionParams()
7901
{
7902
Track *track = getTrack();
7903
7904
track->f.bytesPerPacket = 34 * track->f.channelCount;
7905
track->f.framesPerPacket = 64;
7906
7907
AUpvlist pv = AUpvnew(1);
7908
AUpvsetparam(pv, 0, _AF_IMA_ADPCM_TYPE);
7909
AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG);
7910
long l = _AF_IMA_ADPCM_TYPE_QT;
7911
AUpvsetval(pv, 0, &l);
7912
7913
track->f.compressionParams = pv;
7914
}
7915
7916
// Read a Pascal-style string.
7917
bool AIFFFile::readPString(char s[256])
7918
{
7919
uint8_t length;
7920
if (m_fh->read(&length, 1) != 1)
7921
return false;
7922
if (m_fh->read(s, length) != static_cast<ssize_t>(length))
7923
return false;
7924
s[length] = '\0';
7925
return true;
7926
}
7927
7928
// Write a Pascal-style string.
7929
bool AIFFFile::writePString(const char *s)
7930
{
7931
size_t length = strlen(s);
7932
if (length > 255)
7933
return false;
7934
uint8_t sizeByte = static_cast<uint8_t>(length);
7935
if (m_fh->write(&sizeByte, 1) != 1)
7936
return false;
7937
if (m_fh->write(s, length) != (ssize_t) length)
7938
return false;
7939
/*
7940
Add a pad byte if the length of the Pascal-style string
7941
(including the size byte) is odd.
7942
*/
7943
if ((length % 2) == 0)
7944
{
7945
uint8_t zero = 0;
7946
if (m_fh->write(&zero, 1) != 1)
7947
return false;
7948
}
7949
return true;
7950
}
7951
7952
// file: AudioFormat.cpp
7953
/*
7954
Audio File Library
7955
Copyright (C) 2010, Michael Pruett <[email protected]>
7956
7957
This library is free software; you can redistribute it and/or
7958
modify it under the terms of the GNU Lesser General Public
7959
License as published by the Free Software Foundation; either
7960
version 2.1 of the License, or (at your option) any later version.
7961
7962
This library is distributed in the hope that it will be useful,
7963
but WITHOUT ANY WARRANTY; without even the implied warranty of
7964
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7965
Lesser General Public License for more details.
7966
7967
You should have received a copy of the GNU Lesser General Public
7968
License along with this library; if not, write to the
7969
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
7970
Boston, MA 02110-1301 USA
7971
*/
7972
7973
7974
#include <assert.h>
7975
#include <stdio.h>
7976
7977
size_t AudioFormat::bytesPerSample(bool stretch3to4) const
7978
{
7979
switch (sampleFormat)
7980
{
7981
case AF_SAMPFMT_FLOAT:
7982
return sizeof (float);
7983
case AF_SAMPFMT_DOUBLE:
7984
return sizeof (double);
7985
default:
7986
{
7987
int size = (sampleWidth + 7) / 8;
7988
if (compressionType == AF_COMPRESSION_NONE &&
7989
size == 3 && stretch3to4)
7990
size = 4;
7991
return size;
7992
}
7993
}
7994
}
7995
7996
size_t AudioFormat::bytesPerFrame(bool stretch3to4) const
7997
{
7998
return bytesPerSample(stretch3to4) * channelCount;
7999
}
8000
8001
size_t AudioFormat::bytesPerSample() const
8002
{
8003
return bytesPerSample(!isPacked());
8004
}
8005
8006
size_t AudioFormat::bytesPerFrame() const
8007
{
8008
return bytesPerFrame(!isPacked());
8009
}
8010
8011
bool AudioFormat::isInteger() const
8012
{
8013
return sampleFormat == AF_SAMPFMT_TWOSCOMP ||
8014
sampleFormat == AF_SAMPFMT_UNSIGNED;
8015
}
8016
8017
bool AudioFormat::isSigned() const
8018
{
8019
return sampleFormat == AF_SAMPFMT_TWOSCOMP;
8020
}
8021
8022
bool AudioFormat::isUnsigned() const
8023
{
8024
return sampleFormat == AF_SAMPFMT_UNSIGNED;
8025
}
8026
8027
bool AudioFormat::isFloat() const
8028
{
8029
return sampleFormat == AF_SAMPFMT_FLOAT ||
8030
sampleFormat == AF_SAMPFMT_DOUBLE;
8031
}
8032
8033
bool AudioFormat::isCompressed() const
8034
{
8035
return compressionType != AF_COMPRESSION_NONE;
8036
}
8037
8038
bool AudioFormat::isUncompressed() const
8039
{
8040
return compressionType == AF_COMPRESSION_NONE;
8041
}
8042
8043
void AudioFormat::computeBytesPerPacketPCM()
8044
{
8045
assert(isUncompressed());
8046
int bytesPerSample = (sampleWidth + 7) / 8;
8047
bytesPerPacket = bytesPerSample * channelCount;
8048
}
8049
8050
std::string AudioFormat::description() const
8051
{
8052
std::string d;
8053
char s[1024];
8054
/* sampleRate, channelCount */
8055
sprintf(s, "{ %7.2f Hz %d ch ", sampleRate, channelCount);
8056
d += s;
8057
8058
/* sampleFormat, sampleWidth */
8059
switch (sampleFormat)
8060
{
8061
case AF_SAMPFMT_TWOSCOMP:
8062
sprintf(s, "%db 2 ", sampleWidth);
8063
break;
8064
case AF_SAMPFMT_UNSIGNED:
8065
sprintf(s, "%db u ", sampleWidth);
8066
break;
8067
case AF_SAMPFMT_FLOAT:
8068
sprintf(s, "flt ");
8069
break;
8070
case AF_SAMPFMT_DOUBLE:
8071
sprintf(s, "dbl ");
8072
break;
8073
default:
8074
assert(false);
8075
break;
8076
}
8077
8078
d += s;
8079
8080
/* pcm */
8081
sprintf(s, "(%.30g+-%.30g [%.30g,%.30g]) ",
8082
pcm.intercept, pcm.slope,
8083
pcm.minClip, pcm.maxClip);
8084
d += s;
8085
8086
/* byteOrder */
8087
switch (byteOrder)
8088
{
8089
case AF_BYTEORDER_BIGENDIAN:
8090
d += "big ";
8091
break;
8092
case AF_BYTEORDER_LITTLEENDIAN:
8093
d += "little ";
8094
break;
8095
default:
8096
assert(false);
8097
break;
8098
}
8099
8100
if (isCompressed())
8101
{
8102
const CompressionUnit *unit = _af_compression_unit_from_id(compressionType);
8103
assert(unit);
8104
d += "compression: ";
8105
d += unit->label;
8106
}
8107
8108
return d;
8109
}
8110
8111
// file: Buffer.cpp
8112
/*
8113
Audio File Library
8114
Copyright (C) 2013 Michael Pruett <[email protected]>
8115
8116
This library is free software; you can redistribute it and/or
8117
modify it under the terms of the GNU Lesser General Public
8118
License as published by the Free Software Foundation; either
8119
version 2.1 of the License, or (at your option) any later version.
8120
8121
This library is distributed in the hope that it will be useful,
8122
but WITHOUT ANY WARRANTY; without even the implied warranty of
8123
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8124
Lesser General Public License for more details.
8125
8126
You should have received a copy of the GNU Lesser General Public
8127
License along with this library; if not, write to the
8128
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
8129
Boston, MA 02110-1301 USA
8130
*/
8131
8132
8133
#include <string.h>
8134
8135
Buffer::Buffer() : m_data(0), m_size(0)
8136
{
8137
}
8138
8139
Buffer::Buffer(size_t size) : m_data(0), m_size(0)
8140
{
8141
if (size)
8142
m_data = ::operator new(size);
8143
if (m_data)
8144
{
8145
m_size = size;
8146
}
8147
}
8148
8149
Buffer::Buffer(const void *data, size_t size) : m_data(0), m_size(0)
8150
{
8151
if (size)
8152
m_data = ::operator new(size);
8153
if (m_data)
8154
{
8155
::memcpy(m_data, data, m_size);
8156
m_size = size;
8157
}
8158
}
8159
8160
Buffer::~Buffer()
8161
{
8162
::operator delete(m_data);
8163
}
8164
8165
// file: File.cpp
8166
/*
8167
Copyright (C) 2010, Michael Pruett. All rights reserved.
8168
8169
Redistribution and use in source and binary forms, with or without
8170
modification, are permitted provided that the following conditions
8171
are met:
8172
8173
1. Redistributions of source code must retain the above copyright
8174
notice, this list of conditions and the following disclaimer.
8175
8176
2. Redistributions in binary form must reproduce the above copyright
8177
notice, this list of conditions and the following disclaimer in the
8178
documentation and/or other materials provided with the distribution.
8179
8180
3. The name of the author may not be used to endorse or promote products
8181
derived from this software without specific prior written permission.
8182
8183
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
8184
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
8185
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
8186
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
8187
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
8188
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
8189
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
8190
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8191
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
8192
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8193
*/
8194
8195
8196
8197
#include <assert.h>
8198
#include <fcntl.h>
8199
#include <stdlib.h>
8200
#include <sys/stat.h>
8201
#include <sys/types.h>
8202
#include <unistd.h>
8203
#include <stdio.h>
8204
8205
class FilePOSIX : public File
8206
{
8207
public:
8208
FilePOSIX(int fd, AccessMode mode) : File(mode), m_fd(fd) { }
8209
virtual ~FilePOSIX() { close(); }
8210
8211
virtual int close() OVERRIDE;
8212
virtual ssize_t read(void *data, size_t nbytes) OVERRIDE;
8213
virtual ssize_t write(const void *data, size_t nbytes) OVERRIDE;
8214
virtual off_t length() OVERRIDE;
8215
virtual off_t seek(off_t offset, SeekOrigin origin) OVERRIDE;
8216
virtual off_t tell() OVERRIDE;
8217
8218
private:
8219
int m_fd;
8220
};
8221
8222
class FileVF : public File
8223
{
8224
public:
8225
FileVF(AFvirtualfile *vf, AccessMode mode) : File(mode), m_vf(vf) { }
8226
virtual ~FileVF() { close(); }
8227
8228
virtual int close() OVERRIDE;
8229
virtual ssize_t read(void *data, size_t nbytes) OVERRIDE;
8230
virtual ssize_t write(const void *data, size_t nbytes) OVERRIDE;
8231
virtual off_t length() OVERRIDE;
8232
virtual off_t seek(off_t offset, SeekOrigin origin) OVERRIDE;
8233
virtual off_t tell() OVERRIDE;
8234
8235
private:
8236
AFvirtualfile *m_vf;
8237
};
8238
8239
File *File::open(const char *path, File::AccessMode mode)
8240
{
8241
int flags = 0;
8242
if (mode == ReadAccess)
8243
flags = O_RDONLY;
8244
else if (mode == WriteAccess)
8245
flags = O_CREAT | O_WRONLY | O_TRUNC;
8246
#if defined(WIN32) || defined(__CYGWIN__)
8247
flags |= O_BINARY;
8248
#endif
8249
int fd = ::open(path, flags, 0666);
8250
if (fd == -1)
8251
return NULL;
8252
File *file = new FilePOSIX(fd, mode);
8253
return file;
8254
}
8255
8256
File *File::create(int fd, File::AccessMode mode)
8257
{
8258
return new FilePOSIX(fd, mode);
8259
}
8260
8261
File *File::create(AFvirtualfile *vf, File::AccessMode mode)
8262
{
8263
return new FileVF(vf, mode);
8264
}
8265
8266
File::~File()
8267
{
8268
}
8269
8270
bool File::canSeek()
8271
{
8272
return seek(0, File::SeekFromCurrent) != -1;
8273
}
8274
8275
int FilePOSIX::close()
8276
{
8277
if (m_fd == -1)
8278
return 0;
8279
8280
int result = ::close(m_fd);
8281
m_fd = -1;
8282
return result;
8283
}
8284
8285
ssize_t FilePOSIX::read(void *data, size_t nbytes)
8286
{
8287
return ::read(m_fd, data, nbytes);
8288
}
8289
8290
ssize_t FilePOSIX::write(const void *data, size_t nbytes)
8291
{
8292
return ::write(m_fd, data, nbytes);
8293
}
8294
8295
off_t FilePOSIX::length()
8296
{
8297
off_t current = tell();
8298
if (current == -1)
8299
return -1;
8300
off_t length = seek(0, SeekFromEnd);
8301
if (length == -1)
8302
return -1;
8303
seek(current, SeekFromBeginning);
8304
return length;
8305
}
8306
8307
off_t FilePOSIX::seek(off_t offset, File::SeekOrigin origin)
8308
{
8309
int whence;
8310
switch (origin)
8311
{
8312
case SeekFromBeginning: whence = SEEK_SET; break;
8313
case SeekFromCurrent: whence = SEEK_CUR; break;
8314
case SeekFromEnd: whence = SEEK_END; break;
8315
default: assert(false); return -1;
8316
}
8317
return ::lseek(m_fd, offset, whence);
8318
}
8319
8320
off_t FilePOSIX::tell()
8321
{
8322
return seek(0, File::SeekFromCurrent);
8323
}
8324
8325
int FileVF::close()
8326
{
8327
if (m_vf)
8328
af_virtual_file_destroy(m_vf);
8329
m_vf = 0;
8330
return 0;
8331
}
8332
8333
ssize_t FileVF::read(void *data, size_t nbytes)
8334
{
8335
return m_vf->read(m_vf, data, nbytes);
8336
}
8337
8338
ssize_t FileVF::write(const void *data, size_t nbytes)
8339
{
8340
return m_vf->write(m_vf, data, nbytes);
8341
}
8342
8343
off_t FileVF::length()
8344
{
8345
return m_vf->length(m_vf);
8346
}
8347
8348
off_t FileVF::seek(off_t offset, SeekOrigin origin)
8349
{
8350
if (origin == SeekFromEnd)
8351
offset += length();
8352
return m_vf->seek(m_vf, offset, origin == SeekFromCurrent);
8353
}
8354
8355
off_t FileVF::tell()
8356
{
8357
return m_vf->tell(m_vf);
8358
}
8359
8360
// file: FileHandle.cpp
8361
/*
8362
Audio File Library
8363
Copyright (C) 2010-2012, Michael Pruett <[email protected]>
8364
Copyright (C) 2000-2001, Silicon Graphics, Inc.
8365
8366
This library is free software; you can redistribute it and/or
8367
modify it under the terms of the GNU Lesser General Public
8368
License as published by the Free Software Foundation; either
8369
version 2.1 of the License, or (at your option) any later version.
8370
8371
This library is distributed in the hope that it will be useful,
8372
but WITHOUT ANY WARRANTY; without even the implied warranty of
8373
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8374
Lesser General Public License for more details.
8375
8376
You should have received a copy of the GNU Lesser General Public
8377
License along with this library; if not, write to the
8378
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
8379
Boston, MA 02110-1301 USA
8380
*/
8381
8382
8383
#include <stdlib.h>
8384
#include <assert.h>
8385
8386
8387
8388
static void freeInstParams (AFPVu *values, int fileFormat)
8389
{
8390
if (!values)
8391
return;
8392
8393
int parameterCount = _af_units[fileFormat].instrumentParameterCount;
8394
8395
for (int i=0; i<parameterCount; i++)
8396
{
8397
if (_af_units[fileFormat].instrumentParameters[i].type == AU_PVTYPE_PTR)
8398
free(values[i].v);
8399
}
8400
8401
free(values);
8402
}
8403
8404
_AFfilehandle *_AFfilehandle::create(int fileFormat)
8405
{
8406
switch (fileFormat)
8407
{
8408
case AF_FILE_RAWDATA:
8409
return new RawFile();
8410
case AF_FILE_AIFF:
8411
case AF_FILE_AIFFC:
8412
return new AIFFFile();
8413
case AF_FILE_WAVE:
8414
return new WAVEFile();
8415
default:
8416
return NULL;
8417
}
8418
}
8419
8420
_AFfilehandle::_AFfilehandle()
8421
{
8422
m_valid = _AF_VALID_FILEHANDLE;
8423
m_access = 0;
8424
m_seekok = false;
8425
m_fh = NULL;
8426
m_fileName = NULL;
8427
m_fileFormat = AF_FILE_UNKNOWN;
8428
m_trackCount = 0;
8429
m_tracks = NULL;
8430
m_instrumentCount = 0;
8431
m_instruments = NULL;
8432
m_miscellaneousCount = 0;
8433
m_miscellaneous = NULL;
8434
m_formatByteOrder = 0;
8435
}
8436
8437
_AFfilehandle::~_AFfilehandle()
8438
{
8439
m_valid = 0;
8440
8441
free(m_fileName);
8442
8443
delete [] m_tracks;
8444
m_tracks = NULL;
8445
m_trackCount = 0;
8446
8447
if (m_instruments)
8448
{
8449
for (int i=0; i<m_instrumentCount; i++)
8450
{
8451
free(m_instruments[i].loops);
8452
m_instruments[i].loops = NULL;
8453
m_instruments[i].loopCount = 0;
8454
8455
freeInstParams(m_instruments[i].values, m_fileFormat);
8456
m_instruments[i].values = NULL;
8457
}
8458
8459
free(m_instruments);
8460
m_instruments = NULL;
8461
}
8462
m_instrumentCount = 0;
8463
8464
if (m_miscellaneous)
8465
{
8466
for (int i=0; i<m_miscellaneousCount; i++)
8467
free(m_miscellaneous[i].buffer);
8468
free(m_miscellaneous);
8469
m_miscellaneous = NULL;
8470
}
8471
m_miscellaneousCount = 0;
8472
}
8473
8474
Track *_AFfilehandle::allocateTrack()
8475
{
8476
assert(!m_trackCount);
8477
assert(!m_tracks);
8478
8479
m_trackCount = 1;
8480
m_tracks = new Track[1];
8481
return m_tracks;
8482
}
8483
8484
Track *_AFfilehandle::getTrack(int trackID)
8485
{
8486
for (int i=0; i<m_trackCount; i++)
8487
if (m_tracks[i].id == trackID)
8488
return &m_tracks[i];
8489
8490
_af_error(AF_BAD_TRACKID, "bad track id %d", trackID);
8491
8492
return NULL;
8493
}
8494
8495
bool _AFfilehandle::checkCanRead()
8496
{
8497
if (m_access != _AF_READ_ACCESS)
8498
{
8499
_af_error(AF_BAD_NOREADACC, "file not opened for read access");
8500
return false;
8501
}
8502
8503
return true;
8504
}
8505
8506
bool _AFfilehandle::checkCanWrite()
8507
{
8508
if (m_access != _AF_WRITE_ACCESS)
8509
{
8510
_af_error(AF_BAD_NOWRITEACC, "file not opened for write access");
8511
return false;
8512
}
8513
8514
return true;
8515
}
8516
8517
Instrument *_AFfilehandle::getInstrument(int instrumentID)
8518
{
8519
for (int i = 0; i < m_instrumentCount; i++)
8520
if (m_instruments[i].id == instrumentID)
8521
return &m_instruments[i];
8522
8523
_af_error(AF_BAD_INSTID, "invalid instrument id %d", instrumentID);
8524
return NULL;
8525
}
8526
8527
Miscellaneous *_AFfilehandle::getMiscellaneous(int miscellaneousID)
8528
{
8529
for (int i=0; i<m_miscellaneousCount; i++)
8530
{
8531
if (m_miscellaneous[i].id == miscellaneousID)
8532
return &m_miscellaneous[i];
8533
}
8534
8535
_af_error(AF_BAD_MISCID, "bad miscellaneous id %d", miscellaneousID);
8536
8537
return NULL;
8538
}
8539
8540
status _AFfilehandle::initFromSetup(AFfilesetup setup)
8541
{
8542
if (copyTracksFromSetup(setup) == AF_FAIL)
8543
return AF_FAIL;
8544
if (copyInstrumentsFromSetup(setup) == AF_FAIL)
8545
return AF_FAIL;
8546
if (copyMiscellaneousFromSetup(setup) == AF_FAIL)
8547
return AF_FAIL;
8548
return AF_SUCCEED;
8549
}
8550
8551
status _AFfilehandle::copyTracksFromSetup(AFfilesetup setup)
8552
{
8553
if ((m_trackCount = setup->trackCount) == 0)
8554
{
8555
m_tracks = NULL;
8556
return AF_SUCCEED;
8557
}
8558
8559
m_tracks = new Track[m_trackCount];
8560
if (!m_tracks)
8561
return AF_FAIL;
8562
8563
for (int i=0; i<m_trackCount; i++)
8564
{
8565
Track *track = &m_tracks[i];
8566
TrackSetup *trackSetup = &setup->tracks[i];
8567
8568
track->id = trackSetup->id;
8569
track->f = trackSetup->f;
8570
8571
if (track->copyMarkers(trackSetup) == AF_FAIL)
8572
return AF_FAIL;
8573
8574
track->hasAESData = trackSetup->aesDataSet;
8575
}
8576
8577
return AF_SUCCEED;
8578
}
8579
8580
status _AFfilehandle::copyInstrumentsFromSetup(AFfilesetup setup)
8581
{
8582
if ((m_instrumentCount = setup->instrumentCount) == 0)
8583
{
8584
m_instruments = NULL;
8585
return AF_SUCCEED;
8586
}
8587
8588
m_instruments = static_cast<Instrument *>(_af_calloc(m_instrumentCount,
8589
sizeof (Instrument)));
8590
if (!m_instruments)
8591
return AF_FAIL;
8592
8593
for (int i=0; i<m_instrumentCount; i++)
8594
{
8595
m_instruments[i].id = setup->instruments[i].id;
8596
8597
// Copy loops.
8598
if ((m_instruments[i].loopCount = setup->instruments[i].loopCount) == 0)
8599
{
8600
m_instruments[i].loops = NULL;
8601
}
8602
else
8603
{
8604
m_instruments[i].loops =
8605
static_cast<Loop *>(_af_calloc(m_instruments[i].loopCount,
8606
sizeof (Loop)));
8607
if (!m_instruments[i].loops)
8608
return AF_FAIL;
8609
for (int j=0; j<m_instruments[i].loopCount; j++)
8610
{
8611
Loop *loop = &m_instruments[i].loops[j];
8612
loop->id = setup->instruments[i].loops[j].id;
8613
loop->mode = AF_LOOP_MODE_NOLOOP;
8614
loop->count = 0;
8615
loop->trackid = AF_DEFAULT_TRACK;
8616
loop->beginMarker = 2*j + 1;
8617
loop->endMarker = 2*j + 2;
8618
}
8619
}
8620
8621
int instParamCount;
8622
// Copy instrument parameters.
8623
if ((instParamCount = _af_units[setup->fileFormat].instrumentParameterCount) == 0)
8624
{
8625
m_instruments[i].values = NULL;
8626
}
8627
else
8628
{
8629
m_instruments[i].values =
8630
static_cast<AFPVu *>(_af_calloc(instParamCount, sizeof (AFPVu)));
8631
if (!m_instruments[i].values)
8632
return AF_FAIL;
8633
for (int j=0; j<instParamCount; j++)
8634
{
8635
m_instruments[i].values[j] = _af_units[setup->fileFormat].instrumentParameters[j].defaultValue;
8636
}
8637
}
8638
}
8639
8640
return AF_SUCCEED;
8641
}
8642
8643
status _AFfilehandle::copyMiscellaneousFromSetup(AFfilesetup setup)
8644
{
8645
if ((m_miscellaneousCount = setup->miscellaneousCount) == 0)
8646
{
8647
m_miscellaneous = NULL;
8648
return AF_SUCCEED;
8649
}
8650
8651
m_miscellaneous = static_cast<Miscellaneous *>(_af_calloc(m_miscellaneousCount,
8652
sizeof (Miscellaneous)));
8653
if (!m_miscellaneous)
8654
return AF_FAIL;
8655
8656
for (int i=0; i<m_miscellaneousCount; i++)
8657
{
8658
m_miscellaneous[i].id = setup->miscellaneous[i].id;
8659
m_miscellaneous[i].type = setup->miscellaneous[i].type;
8660
m_miscellaneous[i].size = setup->miscellaneous[i].size;
8661
m_miscellaneous[i].position = 0;
8662
m_miscellaneous[i].buffer = NULL;
8663
}
8664
8665
return AF_SUCCEED;
8666
}
8667
8668
template <typename T>
8669
static bool readValue(File *f, T *value)
8670
{
8671
return f->read(value, sizeof (*value)) == sizeof (*value);
8672
}
8673
8674
template <typename T>
8675
static bool writeValue(File *f, const T *value)
8676
{
8677
return f->write(value, sizeof (*value)) == sizeof (*value);
8678
}
8679
8680
template <typename T>
8681
static T swapValue(T value, int order)
8682
{
8683
if (order == AF_BYTEORDER_BIGENDIAN)
8684
return bigToHost(value);
8685
else if (order == AF_BYTEORDER_LITTLEENDIAN)
8686
return littleToHost(value);
8687
return value;
8688
}
8689
8690
template <typename T>
8691
static bool readSwap(File *f, T *value, int order)
8692
{
8693
if (!readValue(f, value)) return false;
8694
*value = swapValue(*value, order);
8695
return true;
8696
}
8697
8698
template <typename T>
8699
static bool writeSwap(File *f, const T *value, int order)
8700
{
8701
T t = swapValue(*value, order);
8702
return writeValue(f, &t);
8703
}
8704
8705
bool _AFfilehandle::readU8(uint8_t *v) { return readValue(m_fh, v); }
8706
bool _AFfilehandle::readS8(int8_t *v) { return readValue(m_fh, v); }
8707
8708
bool _AFfilehandle::readU16(uint16_t *v)
8709
{
8710
return readSwap(m_fh, v, m_formatByteOrder);
8711
}
8712
8713
bool _AFfilehandle::readS16(int16_t *v)
8714
{
8715
return readSwap(m_fh, v, m_formatByteOrder);
8716
}
8717
8718
bool _AFfilehandle::readU32(uint32_t *v)
8719
{
8720
return readSwap(m_fh, v, m_formatByteOrder);
8721
}
8722
8723
bool _AFfilehandle::readS32(int32_t *v)
8724
{
8725
return readSwap(m_fh, v, m_formatByteOrder);
8726
}
8727
8728
bool _AFfilehandle::readU64(uint64_t *v)
8729
{
8730
return readSwap(m_fh, v, m_formatByteOrder);
8731
}
8732
8733
bool _AFfilehandle::readS64(int64_t *v)
8734
{
8735
return readSwap(m_fh, v, m_formatByteOrder);
8736
}
8737
8738
bool _AFfilehandle::readFloat(float *v)
8739
{
8740
return readSwap(m_fh, v, m_formatByteOrder);
8741
}
8742
8743
bool _AFfilehandle::readDouble(double *v)
8744
{
8745
return readSwap(m_fh, v, m_formatByteOrder);
8746
}
8747
8748
bool _AFfilehandle::writeU8(const uint8_t *v) { return writeValue(m_fh, v); }
8749
bool _AFfilehandle::writeS8(const int8_t *v) { return writeValue(m_fh, v); }
8750
8751
bool _AFfilehandle::writeU16(const uint16_t *v)
8752
{
8753
return writeSwap(m_fh, v, m_formatByteOrder);
8754
}
8755
8756
bool _AFfilehandle::writeS16(const int16_t *v)
8757
{
8758
return writeSwap(m_fh, v, m_formatByteOrder);
8759
}
8760
8761
bool _AFfilehandle::writeU32(const uint32_t *v)
8762
{
8763
return writeSwap(m_fh, v, m_formatByteOrder);
8764
}
8765
8766
bool _AFfilehandle::writeS32(const int32_t *v)
8767
{
8768
return writeSwap(m_fh, v, m_formatByteOrder);
8769
}
8770
8771
bool _AFfilehandle::writeU64(const uint64_t *v)
8772
{
8773
return writeSwap(m_fh, v, m_formatByteOrder);
8774
}
8775
8776
bool _AFfilehandle::writeS64(const int64_t *v)
8777
{
8778
return writeSwap(m_fh, v, m_formatByteOrder);
8779
}
8780
8781
bool _AFfilehandle::writeFloat(const float *v)
8782
{
8783
return writeSwap(m_fh, v, m_formatByteOrder);
8784
}
8785
8786
bool _AFfilehandle::writeDouble(const double *v)
8787
{
8788
return writeSwap(m_fh, v, m_formatByteOrder);
8789
}
8790
8791
bool _AFfilehandle::readTag(Tag *t)
8792
{
8793
uint32_t v;
8794
if (m_fh->read(&v, sizeof (v)) == sizeof (v))
8795
{
8796
*t = Tag(v);
8797
return true;
8798
}
8799
return false;
8800
}
8801
8802
bool _AFfilehandle::writeTag(const Tag *t)
8803
{
8804
uint32_t v = t->value();
8805
return m_fh->write(&v, sizeof (v)) == sizeof (v);
8806
}
8807
8808
// file: Instrument.cpp
8809
/*
8810
Audio File Library
8811
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
8812
Copyright (C) 2000, Silicon Graphics, Inc.
8813
8814
This library is free software; you can redistribute it and/or
8815
modify it under the terms of the GNU Lesser General Public
8816
License as published by the Free Software Foundation; either
8817
version 2.1 of the License, or (at your option) any later version.
8818
8819
This library is distributed in the hope that it will be useful,
8820
but WITHOUT ANY WARRANTY; without even the implied warranty of
8821
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8822
Lesser General Public License for more details.
8823
8824
You should have received a copy of the GNU Lesser General Public
8825
License along with this library; if not, write to the
8826
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
8827
Boston, MA 02110-1301 USA
8828
*/
8829
8830
/*
8831
Instrument.cpp
8832
8833
Info about instrument parameters:
8834
8835
Each unit has an array of _InstParamInfo structures, one for
8836
each instrument parameter. Each of these structures describes
8837
the inst parameters.
8838
8839
id: a 4-byte id as in AIFF file
8840
type: data type AU_PVLIST_*
8841
name: text name
8842
defaultValue: default value, to which it is set when a file with
8843
instruments is first opened for writing.
8844
8845
Each inst has only an array of values (_AFPVu's). Each value in the
8846
instrument's array is the value of the corresponding index into the
8847
unit's instparaminfo array.
8848
8849
So for a unit u and an instrument i, u.instparam[N] describes
8850
the parameter whose value is given in i.value[N].
8851
*/
8852
8853
8854
8855
#include <stdlib.h>
8856
8857
bool InstrumentSetup::allocateLoops(int count)
8858
{
8859
freeLoops();
8860
loops = (LoopSetup *) _af_calloc(count, sizeof (LoopSetup));
8861
if (loops)
8862
{
8863
loopCount = count;
8864
return true;
8865
}
8866
return false;
8867
}
8868
8869
void InstrumentSetup::freeLoops()
8870
{
8871
if (loops)
8872
free(loops);
8873
loops = NULL;
8874
loopCount = 0;
8875
}
8876
8877
/*
8878
Initialize instrument id list for audio file.
8879
*/
8880
void afInitInstIDs (AFfilesetup setup, const int *instids, int ninsts)
8881
{
8882
if (!_af_filesetup_ok(setup))
8883
return;
8884
8885
if (!_af_unique_ids(instids, ninsts, "instrument", AF_BAD_INSTID))
8886
return;
8887
8888
_af_setup_free_instruments(setup);
8889
8890
setup->instrumentCount = ninsts;
8891
setup->instrumentSet = true;
8892
8893
setup->instruments = _af_instsetup_new(setup->instrumentCount);
8894
8895
for (int i=0; i < setup->instrumentCount; i++)
8896
setup->instruments[i].id = instids[i];
8897
}
8898
8899
int afGetInstIDs (AFfilehandle file, int *instids)
8900
{
8901
if (!_af_filehandle_ok(file))
8902
return -1;
8903
8904
if (instids)
8905
for (int i=0; i < file->m_instrumentCount; i++)
8906
instids[i] = file->m_instruments[i].id;
8907
8908
return file->m_instrumentCount;
8909
}
8910
8911
/*
8912
This routine checks and sets instrument parameters.
8913
npv is number of valid AUpvlist pairs.
8914
*/
8915
void _af_instparam_set (AFfilehandle file, int instid, AUpvlist pvlist, int npv)
8916
{
8917
if (!_af_filehandle_ok(file))
8918
return;
8919
8920
if (!file->checkCanWrite())
8921
return;
8922
8923
Instrument *instrument = file->getInstrument(instid);
8924
if (!instrument)
8925
return;
8926
8927
if (AUpvgetmaxitems(pvlist) < npv)
8928
npv = AUpvgetmaxitems(pvlist);
8929
8930
for (int i=0; i < npv; i++)
8931
{
8932
int param;
8933
8934
AUpvgetparam(pvlist, i, &param);
8935
8936
int j;
8937
if ((j = _af_instparam_index_from_id(file->m_fileFormat, param)) == -1)
8938
/* no parameter with that id; ignore */
8939
continue;
8940
8941
if (!file->isInstrumentParameterValid(pvlist, i))
8942
/* bad parameter value; ignore */
8943
continue;
8944
8945
int type = _af_units[file->m_fileFormat].instrumentParameters[j].type;
8946
8947
switch (type)
8948
{
8949
case AU_PVTYPE_LONG:
8950
AUpvgetval(pvlist, i, &instrument->values[j].l);
8951
break;
8952
case AU_PVTYPE_DOUBLE:
8953
AUpvgetval(pvlist, i, &instrument->values[j].d);
8954
break;
8955
case AU_PVTYPE_PTR:
8956
AUpvgetval(pvlist, i, &instrument->values[j].v);
8957
break;
8958
default:
8959
return;
8960
}
8961
}
8962
}
8963
8964
void afSetInstParams (AFfilehandle file, int instid, AUpvlist pvlist, int npv)
8965
{
8966
_af_instparam_set(file, instid, pvlist, npv);
8967
}
8968
8969
void afSetInstParamLong (AFfilehandle file, int instid, int param, long value)
8970
{
8971
AUpvlist pvlist = AUpvnew(1);
8972
8973
AUpvsetparam(pvlist, 0, param);
8974
AUpvsetvaltype(pvlist, 0, AU_PVTYPE_LONG);
8975
AUpvsetval(pvlist, 0, &value);
8976
8977
_af_instparam_set(file, instid, pvlist, 1);
8978
8979
AUpvfree(pvlist);
8980
}
8981
8982
/*
8983
This routine gets instrument parameters.
8984
npv is number of valid AUpvlist pairs
8985
*/
8986
void _af_instparam_get (AFfilehandle file, int instid, AUpvlist pvlist, int npv,
8987
bool forceLong)
8988
{
8989
if (!_af_filehandle_ok(file))
8990
return;
8991
8992
Instrument *instrument = file->getInstrument(instid);
8993
if (!instrument)
8994
return;
8995
8996
if (AUpvgetmaxitems(pvlist) < npv)
8997
npv = AUpvgetmaxitems(pvlist);
8998
8999
for (int i=0; i < npv; i++)
9000
{
9001
int param;
9002
AUpvgetparam(pvlist, i, &param);
9003
9004
int j;
9005
if ((j = _af_instparam_index_from_id(file->m_fileFormat, param)) == -1)
9006
/* no parameter with that id; ignore */
9007
continue;
9008
9009
int type = _af_units[file->m_fileFormat].instrumentParameters[j].type;
9010
9011
/*
9012
forceLong is true when this routine called by
9013
afGetInstParamLong().
9014
*/
9015
if (forceLong && type != AU_PVTYPE_LONG)
9016
{
9017
_af_error(AF_BAD_INSTPTYPE, "type of instrument parameter %d is not AU_PVTYPE_LONG", param);
9018
continue;
9019
}
9020
9021
AUpvsetvaltype(pvlist, i, type);
9022
9023
switch (type)
9024
{
9025
case AU_PVTYPE_LONG:
9026
AUpvsetval(pvlist, i, &instrument->values[j].l);
9027
break;
9028
case AU_PVTYPE_DOUBLE:
9029
AUpvsetval(pvlist, i, &instrument->values[j].d);
9030
break;
9031
case AU_PVTYPE_PTR:
9032
AUpvsetval(pvlist, i, &instrument->values[j].v);
9033
break;
9034
9035
default:
9036
_af_error(AF_BAD_INSTPTYPE, "invalid instrument parameter type %d", type);
9037
return;
9038
}
9039
}
9040
}
9041
9042
/*
9043
afGetInstParams -- get a parameter-value array containing
9044
instrument parameters for the specified instrument chunk
9045
*/
9046
void afGetInstParams (AFfilehandle file, int inst, AUpvlist pvlist, int npv)
9047
{
9048
_af_instparam_get(file, inst, pvlist, npv, false);
9049
}
9050
9051
long afGetInstParamLong (AFfilehandle file, int inst, int param)
9052
{
9053
long val;
9054
AUpvlist pvlist = AUpvnew(1);
9055
9056
AUpvsetparam(pvlist, 0, param);
9057
AUpvsetvaltype(pvlist, 0, AU_PVTYPE_LONG);
9058
9059
_af_instparam_get(file, inst, pvlist, 1, true);
9060
9061
AUpvgetval(pvlist, 0, &val);
9062
AUpvfree(pvlist);
9063
9064
return(val);
9065
}
9066
9067
/*
9068
Search _af_units[fileFormat].instrumentParameters for the instrument
9069
parameter with the specified id.
9070
9071
Report an error and return -1 if no such instrument parameter
9072
exists.
9073
*/
9074
9075
int _af_instparam_index_from_id (int filefmt, int id)
9076
{
9077
int i;
9078
9079
for (i = 0; i < _af_units[filefmt].instrumentParameterCount; i++)
9080
if (_af_units[filefmt].instrumentParameters[i].id == id)
9081
break;
9082
9083
if (i == _af_units[filefmt].instrumentParameterCount)
9084
{
9085
_af_error(AF_BAD_INSTPID, "invalid instrument parameter id %d",
9086
id);
9087
return -1;
9088
}
9089
9090
return i;
9091
}
9092
9093
Loop *Instrument::getLoop(int loopID)
9094
{
9095
for (int i=0; i<loopCount; i++)
9096
if (loops[i].id == loopID)
9097
return &loops[i];
9098
9099
_af_error(AF_BAD_LOOPID, "no loop with id %d for instrument %d\n",
9100
loopID, id);
9101
return NULL;
9102
}
9103
9104
// file: Loop.cpp
9105
/*
9106
Audio File Library
9107
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
9108
Copyright (C) 2000, Silicon Graphics, Inc.
9109
9110
This library is free software; you can redistribute it and/or
9111
modify it under the terms of the GNU Lesser General Public
9112
License as published by the Free Software Foundation; either
9113
version 2.1 of the License, or (at your option) any later version.
9114
9115
This library is distributed in the hope that it will be useful,
9116
but WITHOUT ANY WARRANTY; without even the implied warranty of
9117
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9118
Lesser General Public License for more details.
9119
9120
You should have received a copy of the GNU Lesser General Public
9121
License along with this library; if not, write to the
9122
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
9123
Boston, MA 02110-1301 USA
9124
*/
9125
9126
/*
9127
Loop.cpp
9128
9129
All routines that operate on loops.
9130
*/
9131
9132
9133
9134
void afInitLoopIDs (AFfilesetup setup, int instid, const int *loopids, int nloops)
9135
{
9136
if (!_af_filesetup_ok(setup))
9137
return;
9138
9139
if (!_af_unique_ids(loopids, nloops, "loop", AF_BAD_LOOPID))
9140
return;
9141
9142
InstrumentSetup *instrument = setup->getInstrument(instid);
9143
if (!instrument)
9144
return;
9145
9146
instrument->freeLoops();
9147
if (!instrument->allocateLoops(nloops))
9148
return;
9149
9150
for (int i=0; i < nloops; i++)
9151
instrument->loops[i].id = loopids[i];
9152
}
9153
9154
int afGetLoopIDs (AFfilehandle file, int instid, int *loopids)
9155
{
9156
if (!_af_filehandle_ok(file))
9157
return AF_FAIL;
9158
9159
Instrument *instrument = file->getInstrument(instid);
9160
if (!instrument)
9161
return AF_FAIL;
9162
9163
if (loopids)
9164
for (int i=0; i < instrument->loopCount; i++)
9165
loopids[i] = instrument->loops[i].id;
9166
9167
return instrument->loopCount;
9168
}
9169
9170
/*
9171
getLoop returns pointer to requested loop if it exists, and if
9172
mustWrite is true, only if handle is writable.
9173
*/
9174
9175
static Loop *getLoop (AFfilehandle handle, int instid, int loopid,
9176
bool mustWrite)
9177
{
9178
if (!_af_filehandle_ok(handle))
9179
return NULL;
9180
9181
if (mustWrite && !handle->checkCanWrite())
9182
return NULL;
9183
9184
Instrument *instrument = handle->getInstrument(instid);
9185
if (!instrument)
9186
return NULL;
9187
9188
return instrument->getLoop(loopid);
9189
}
9190
9191
/*
9192
Set loop mode (as in AF_LOOP_MODE_...).
9193
*/
9194
void afSetLoopMode (AFfilehandle file, int instid, int loopid, int mode)
9195
{
9196
Loop *loop = getLoop(file, instid, loopid, true);
9197
9198
if (!loop)
9199
return;
9200
9201
if (mode != AF_LOOP_MODE_NOLOOP &&
9202
mode != AF_LOOP_MODE_FORW &&
9203
mode != AF_LOOP_MODE_FORWBAKW)
9204
{
9205
_af_error(AF_BAD_LOOPMODE, "unrecognized loop mode %d", mode);
9206
return;
9207
}
9208
9209
loop->mode = mode;
9210
}
9211
9212
/*
9213
Get loop mode (as in AF_LOOP_MODE_...).
9214
*/
9215
int afGetLoopMode (AFfilehandle file, int instid, int loopid)
9216
{
9217
Loop *loop = getLoop(file, instid, loopid, false);
9218
9219
if (!loop)
9220
return -1;
9221
9222
return loop->mode;
9223
}
9224
9225
/*
9226
Set loop count.
9227
*/
9228
int afSetLoopCount (AFfilehandle file, int instid, int loopid, int count)
9229
{
9230
Loop *loop = getLoop(file, instid, loopid, true);
9231
9232
if (!loop)
9233
return AF_FAIL;
9234
9235
if (count < 1)
9236
{
9237
_af_error(AF_BAD_LOOPCOUNT, "invalid loop count: %d", count);
9238
return AF_FAIL;
9239
}
9240
9241
loop->count = count;
9242
return AF_SUCCEED;
9243
}
9244
9245
/*
9246
Get loop count.
9247
*/
9248
int afGetLoopCount(AFfilehandle file, int instid, int loopid)
9249
{
9250
Loop *loop = getLoop(file, instid, loopid, false);
9251
9252
if (!loop)
9253
return -1;
9254
9255
return loop->count;
9256
}
9257
9258
/*
9259
Set loop start marker id in the file structure
9260
*/
9261
void afSetLoopStart(AFfilehandle file, int instid, int loopid, int markid)
9262
{
9263
Loop *loop = getLoop(file, instid, loopid, true);
9264
9265
if (!loop)
9266
return;
9267
9268
loop->beginMarker = markid;
9269
}
9270
9271
/*
9272
Get loop start marker id.
9273
*/
9274
int afGetLoopStart (AFfilehandle file, int instid, int loopid)
9275
{
9276
Loop *loop = getLoop(file, instid, loopid, false);
9277
9278
if (!loop)
9279
return -1;
9280
9281
return loop->beginMarker;
9282
}
9283
9284
/*
9285
Set loop start frame in the file structure.
9286
*/
9287
int afSetLoopStartFrame (AFfilehandle file, int instid, int loopid, AFframecount startFrame)
9288
{
9289
Loop *loop = getLoop(file, instid, loopid, true);
9290
9291
if (!loop)
9292
return -1;
9293
9294
if (startFrame < 0)
9295
{
9296
_af_error(AF_BAD_FRAME, "loop start frame must not be negative");
9297
return AF_FAIL;
9298
}
9299
9300
int trackid = loop->trackid;
9301
int beginMarker = loop->beginMarker;
9302
9303
afSetMarkPosition(file, trackid, beginMarker, startFrame);
9304
return AF_SUCCEED;
9305
}
9306
9307
/*
9308
Get loop start frame.
9309
*/
9310
AFframecount afGetLoopStartFrame (AFfilehandle file, int instid, int loopid)
9311
{
9312
Loop *loop = getLoop(file, instid, loopid, false);
9313
if (!loop)
9314
return -1;
9315
9316
int trackid = loop->trackid;
9317
int beginMarker = loop->beginMarker;
9318
9319
return afGetMarkPosition(file, trackid, beginMarker);
9320
}
9321
9322
/*
9323
Set loop track id.
9324
*/
9325
void afSetLoopTrack (AFfilehandle file, int instid, int loopid, int track)
9326
{
9327
Loop *loop = getLoop(file, instid, loopid, true);
9328
9329
if (!loop) return;
9330
9331
loop->trackid = track;
9332
}
9333
9334
/*
9335
Get loop track.
9336
*/
9337
int afGetLoopTrack (AFfilehandle file, int instid, int loopid)
9338
{
9339
Loop *loop = getLoop(file, instid, loopid, false);
9340
9341
if (!loop)
9342
return -1;
9343
9344
return loop->trackid;
9345
}
9346
9347
/*
9348
Set loop end frame marker id.
9349
*/
9350
void afSetLoopEnd (AFfilehandle file, int instid, int loopid, int markid)
9351
{
9352
Loop *loop = getLoop(file, instid, loopid, true);
9353
9354
if (!loop)
9355
return;
9356
9357
loop->endMarker = markid;
9358
}
9359
9360
/*
9361
Get loop end frame marker id.
9362
*/
9363
int afGetLoopEnd (AFfilehandle file, int instid, int loopid)
9364
{
9365
Loop *loop = getLoop(file, instid, loopid, false);
9366
9367
if (!loop)
9368
return -1;
9369
9370
return loop->endMarker;
9371
}
9372
9373
/*
9374
Set loop end frame.
9375
*/
9376
int afSetLoopEndFrame (AFfilehandle file, int instid, int loopid, AFframecount endFrame)
9377
{
9378
Loop *loop = getLoop(file, instid, loopid, true);
9379
if (!loop)
9380
return -1;
9381
9382
if (endFrame < 0)
9383
{
9384
_af_error(AF_BAD_FRAME, "loop end frame must not be negative");
9385
return AF_FAIL;
9386
}
9387
9388
int trackid = loop->trackid;
9389
int endMarker = loop->endMarker;
9390
9391
afSetMarkPosition(file, trackid, endMarker, endFrame);
9392
return AF_SUCCEED;
9393
}
9394
9395
/*
9396
Get loop end frame.
9397
*/
9398
9399
AFframecount afGetLoopEndFrame (AFfilehandle file, int instid, int loopid)
9400
{
9401
Loop *loop = getLoop(file, instid, loopid, false);
9402
9403
if (!loop)
9404
return -1;
9405
9406
int trackid = loop->trackid;
9407
int endMarker = loop->endMarker;
9408
9409
return afGetMarkPosition(file, trackid, endMarker);
9410
}
9411
9412
// file: Marker.cpp
9413
/*
9414
Audio File Library
9415
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
9416
Copyright (C) 2000, Silicon Graphics, Inc.
9417
9418
This library is free software; you can redistribute it and/or
9419
modify it under the terms of the GNU Lesser General Public
9420
License as published by the Free Software Foundation; either
9421
version 2.1 of the License, or (at your option) any later version.
9422
9423
This library is distributed in the hope that it will be useful,
9424
but WITHOUT ANY WARRANTY; without even the implied warranty of
9425
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9426
Lesser General Public License for more details.
9427
9428
You should have received a copy of the GNU Lesser General Public
9429
License along with this library; if not, write to the
9430
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
9431
Boston, MA 02110-1301 USA
9432
*/
9433
9434
/*
9435
Marker.cpp
9436
9437
This file contains routines for dealing with loop markers.
9438
*/
9439
9440
9441
#include <string.h>
9442
#include <stdlib.h>
9443
#include <assert.h>
9444
9445
9446
void afInitMarkIDs(AFfilesetup setup, int trackid, const int *markids, int nmarks)
9447
{
9448
if (!_af_filesetup_ok(setup))
9449
return;
9450
9451
TrackSetup *track = setup->getTrack(trackid);
9452
if (!track)
9453
return;
9454
9455
if (track->markers != NULL)
9456
{
9457
for (int i=0; i<track->markerCount; i++)
9458
{
9459
if (track->markers[i].name != NULL)
9460
free(track->markers[i].name);
9461
if (track->markers[i].comment != NULL)
9462
free(track->markers[i].comment);
9463
}
9464
free(track->markers);
9465
}
9466
9467
track->markers = (MarkerSetup *) _af_calloc(nmarks, sizeof (struct MarkerSetup));
9468
track->markerCount = nmarks;
9469
9470
for (int i=0; i<nmarks; i++)
9471
{
9472
track->markers[i].id = markids[i];
9473
track->markers[i].name = _af_strdup("");
9474
track->markers[i].comment = _af_strdup("");
9475
}
9476
9477
track->markersSet = true;
9478
}
9479
9480
void afInitMarkName(AFfilesetup setup, int trackid, int markid,
9481
const char *namestr)
9482
{
9483
int markno;
9484
int length;
9485
9486
if (!_af_filesetup_ok(setup))
9487
return;
9488
9489
TrackSetup *track = setup->getTrack(trackid);
9490
if (!track)
9491
return;
9492
9493
for (markno=0; markno<track->markerCount; markno++)
9494
{
9495
if (track->markers[markno].id == markid)
9496
break;
9497
}
9498
9499
if (markno == track->markerCount)
9500
{
9501
_af_error(AF_BAD_MARKID, "no marker id %d for file setup", markid);
9502
return;
9503
}
9504
9505
length = strlen(namestr);
9506
if (length > 255)
9507
{
9508
_af_error(AF_BAD_STRLEN,
9509
"warning: marker name truncated to 255 characters");
9510
length = 255;
9511
}
9512
9513
if (track->markers[markno].name)
9514
free(track->markers[markno].name);
9515
if ((track->markers[markno].name = (char *) _af_malloc(length+1)) == NULL)
9516
return;
9517
strncpy(track->markers[markno].name, namestr, length);
9518
/*
9519
The null terminator is not set by strncpy if
9520
strlen(namestr) > length. Set it here.
9521
*/
9522
track->markers[markno].name[length] = '\0';
9523
}
9524
9525
void afInitMarkComment(AFfilesetup setup, int trackid, int markid,
9526
const char *commstr)
9527
{
9528
int markno;
9529
int length;
9530
9531
if (!_af_filesetup_ok(setup))
9532
return;
9533
9534
TrackSetup *track = setup->getTrack(trackid);
9535
if (!track)
9536
return;
9537
9538
for (markno=0; markno<track->markerCount; markno++)
9539
{
9540
if (track->markers[markno].id == markid)
9541
break;
9542
}
9543
9544
if (markno == track->markerCount)
9545
{
9546
_af_error(AF_BAD_MARKID, "no marker id %d for file setup", markid);
9547
return;
9548
}
9549
9550
length = strlen(commstr);
9551
9552
if (track->markers[markno].comment)
9553
free(track->markers[markno].comment);
9554
if ((track->markers[markno].comment = (char *) _af_malloc(length+1)) == NULL)
9555
return;
9556
strcpy(track->markers[markno].comment, commstr);
9557
}
9558
9559
char *afGetMarkName (AFfilehandle file, int trackid, int markid)
9560
{
9561
if (!_af_filehandle_ok(file))
9562
return NULL;
9563
9564
Track *track = file->getTrack(trackid);
9565
if (!track)
9566
return NULL;
9567
9568
Marker *marker = track->getMarker(markid);
9569
if (!marker)
9570
return NULL;
9571
9572
return marker->name;
9573
}
9574
9575
char *afGetMarkComment (AFfilehandle file, int trackid, int markid)
9576
{
9577
if (!_af_filehandle_ok(file))
9578
return NULL;
9579
9580
Track *track = file->getTrack(trackid);
9581
if (!track)
9582
return NULL;
9583
9584
Marker *marker = track->getMarker(markid);
9585
if (!marker)
9586
return NULL;
9587
9588
return marker->comment;
9589
}
9590
9591
void afSetMarkPosition (AFfilehandle file, int trackid, int markid,
9592
AFframecount position)
9593
{
9594
if (!_af_filehandle_ok(file))
9595
return;
9596
9597
if (!file->checkCanWrite())
9598
return;
9599
9600
Track *track = file->getTrack(trackid);
9601
if (!track)
9602
return;
9603
9604
Marker *marker = track->getMarker(markid);
9605
if (!marker)
9606
return;
9607
9608
if (position < 0)
9609
{
9610
_af_error(AF_BAD_MARKPOS, "invalid marker position %jd",
9611
static_cast<intmax_t>(position));
9612
position = 0;
9613
}
9614
9615
marker->position = position;
9616
}
9617
9618
int afGetMarkIDs (AFfilehandle file, int trackid, int markids[])
9619
{
9620
if (!_af_filehandle_ok(file))
9621
return -1;
9622
9623
Track *track = file->getTrack(trackid);
9624
if (!track)
9625
return -1;
9626
9627
if (markids != NULL)
9628
{
9629
for (int i=0; i<track->markerCount; i++)
9630
{
9631
markids[i] = track->markers[i].id;
9632
}
9633
}
9634
9635
return track->markerCount;
9636
}
9637
9638
AFframecount afGetMarkPosition (AFfilehandle file, int trackid, int markid)
9639
{
9640
if (!_af_filehandle_ok(file))
9641
return 0L;
9642
9643
Track *track = file->getTrack(trackid);
9644
if (!track)
9645
return 0L;
9646
9647
Marker *marker = track->getMarker(markid);
9648
if (!marker)
9649
return 0L;
9650
9651
return marker->position;
9652
}
9653
9654
Marker *_af_marker_new (int count)
9655
{
9656
Marker *markers = (Marker *) _af_calloc(count, sizeof (Marker));
9657
if (markers == NULL)
9658
return NULL;
9659
9660
return markers;
9661
}
9662
9663
// file: Miscellaneous.cpp
9664
/*
9665
Audio File Library
9666
Copyright (C) 1998, Michael Pruett <[email protected]>
9667
9668
This library is free software; you can redistribute it and/or
9669
modify it under the terms of the GNU Lesser General Public
9670
License as published by the Free Software Foundation; either
9671
version 2.1 of the License, or (at your option) any later version.
9672
9673
This library is distributed in the hope that it will be useful,
9674
but WITHOUT ANY WARRANTY; without even the implied warranty of
9675
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9676
Lesser General Public License for more details.
9677
9678
You should have received a copy of the GNU Lesser General Public
9679
License along with this library; if not, write to the
9680
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
9681
Boston, MA 02110-1301 USA
9682
*/
9683
9684
/*
9685
Miscellaneous.cpp
9686
9687
This file contains routines for dealing with the Audio File
9688
Library's internal miscellaneous data types.
9689
*/
9690
9691
9692
#include <algorithm>
9693
#include <stdint.h>
9694
#include <stdlib.h>
9695
#include <string.h>
9696
9697
9698
void afInitMiscIDs (AFfilesetup setup, const int *ids, int nids)
9699
{
9700
if (!_af_filesetup_ok(setup))
9701
return;
9702
9703
if (setup->miscellaneous != NULL)
9704
{
9705
free(setup->miscellaneous);
9706
}
9707
9708
setup->miscellaneousCount = nids;
9709
9710
if (nids == 0)
9711
setup->miscellaneous = NULL;
9712
else
9713
{
9714
setup->miscellaneous = (MiscellaneousSetup *) _af_calloc(nids,
9715
sizeof (MiscellaneousSetup));
9716
9717
if (setup->miscellaneous == NULL)
9718
return;
9719
9720
for (int i=0; i<nids; i++)
9721
{
9722
setup->miscellaneous[i].id = ids[i];
9723
setup->miscellaneous[i].type = 0;
9724
setup->miscellaneous[i].size = 0;
9725
}
9726
}
9727
9728
setup->miscellaneousSet = true;
9729
}
9730
9731
int afGetMiscIDs (AFfilehandle file, int *ids)
9732
{
9733
if (!_af_filehandle_ok(file))
9734
return -1;
9735
9736
if (ids != NULL)
9737
{
9738
for (int i=0; i<file->m_miscellaneousCount; i++)
9739
{
9740
ids[i] = file->m_miscellaneous[i].id;
9741
}
9742
}
9743
9744
return file->m_miscellaneousCount;
9745
}
9746
9747
void afInitMiscType (AFfilesetup setup, int miscellaneousid, int type)
9748
{
9749
if (!_af_filesetup_ok(setup))
9750
return;
9751
9752
MiscellaneousSetup *miscellaneous = setup->getMiscellaneous(miscellaneousid);
9753
if (miscellaneous)
9754
miscellaneous->type = type;
9755
}
9756
9757
int afGetMiscType (AFfilehandle file, int miscellaneousid)
9758
{
9759
if (!_af_filehandle_ok(file))
9760
return -1;
9761
9762
Miscellaneous *miscellaneous = file->getMiscellaneous(miscellaneousid);
9763
if (miscellaneous)
9764
return miscellaneous->type;
9765
return -1;
9766
}
9767
9768
void afInitMiscSize (AFfilesetup setup, int miscellaneousid, int size)
9769
{
9770
if (!_af_filesetup_ok(setup))
9771
return;
9772
9773
MiscellaneousSetup *miscellaneous = setup->getMiscellaneous(miscellaneousid);
9774
if (miscellaneous)
9775
miscellaneous->size = size;
9776
}
9777
9778
int afGetMiscSize (AFfilehandle file, int miscellaneousid)
9779
{
9780
if (!_af_filehandle_ok(file))
9781
return -1;
9782
9783
Miscellaneous *miscellaneous = file->getMiscellaneous(miscellaneousid);
9784
if (miscellaneous)
9785
return miscellaneous->size;
9786
return -1;
9787
}
9788
9789
int afWriteMisc (AFfilehandle file, int miscellaneousid, const void *buf, int bytes)
9790
{
9791
if (!_af_filehandle_ok(file))
9792
return -1;
9793
9794
if (!file->checkCanWrite())
9795
return -1;
9796
9797
Miscellaneous *miscellaneous = file->getMiscellaneous(miscellaneousid);
9798
if (!miscellaneous)
9799
return -1;
9800
9801
if (bytes <= 0)
9802
{
9803
_af_error(AF_BAD_MISCSIZE, "invalid size (%d) for miscellaneous chunk", bytes);
9804
return -1;
9805
}
9806
9807
if (miscellaneous->buffer == NULL && miscellaneous->size != 0)
9808
{
9809
miscellaneous->buffer = _af_malloc(miscellaneous->size);
9810
if (miscellaneous->buffer == NULL)
9811
return -1;
9812
memset(miscellaneous->buffer, 0, miscellaneous->size);
9813
}
9814
9815
int localsize = std::min(bytes,
9816
miscellaneous->size - miscellaneous->position);
9817
memcpy((char *) miscellaneous->buffer + miscellaneous->position,
9818
buf, localsize);
9819
miscellaneous->position += localsize;
9820
return localsize;
9821
}
9822
9823
int afReadMisc (AFfilehandle file, int miscellaneousid, void *buf, int bytes)
9824
{
9825
if (!_af_filehandle_ok(file))
9826
return -1;
9827
9828
if (!file->checkCanRead())
9829
return -1;
9830
9831
Miscellaneous *miscellaneous = file->getMiscellaneous(miscellaneousid);
9832
if (!miscellaneous)
9833
return -1;
9834
9835
if (bytes <= 0)
9836
{
9837
_af_error(AF_BAD_MISCSIZE, "invalid size (%d) for miscellaneous chunk", bytes);
9838
return -1;
9839
}
9840
9841
int localsize = std::min(bytes,
9842
miscellaneous->size - miscellaneous->position);
9843
memcpy(buf, (char *) miscellaneous->buffer + miscellaneous->position,
9844
localsize);
9845
miscellaneous->position += localsize;
9846
return localsize;
9847
}
9848
9849
int afSeekMisc (AFfilehandle file, int miscellaneousid, int offset)
9850
{
9851
if (!_af_filehandle_ok(file))
9852
return -1;
9853
9854
Miscellaneous *miscellaneous = file->getMiscellaneous(miscellaneousid);
9855
if (!miscellaneous)
9856
return -1;
9857
9858
if (offset >= miscellaneous->size)
9859
{
9860
_af_error(AF_BAD_MISCSEEK,
9861
"offset %d too big for miscellaneous chunk %d "
9862
"(%d data bytes)",
9863
offset, miscellaneousid, miscellaneous->size);
9864
return -1;
9865
}
9866
9867
miscellaneous->position = offset;
9868
9869
return offset;
9870
}
9871
9872
// file: PacketTable.cpp
9873
/*
9874
Audio File Library
9875
Copyright (C) 2013 Michael Pruett <[email protected]>
9876
9877
This library is free software; you can redistribute it and/or
9878
modify it under the terms of the GNU Lesser General Public
9879
License as published by the Free Software Foundation; either
9880
version 2.1 of the License, or (at your option) any later version.
9881
9882
This library is distributed in the hope that it will be useful,
9883
but WITHOUT ANY WARRANTY; without even the implied warranty of
9884
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9885
Lesser General Public License for more details.
9886
9887
You should have received a copy of the GNU Lesser General Public
9888
License along with this library; if not, write to the
9889
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
9890
Boston, MA 02110-1301 USA
9891
*/
9892
9893
9894
PacketTable::PacketTable(int64_t numValidFrames, int32_t primingFrames,
9895
int32_t remainderFrames) :
9896
m_numValidFrames(numValidFrames),
9897
m_primingFrames(primingFrames),
9898
m_remainderFrames(remainderFrames)
9899
{
9900
}
9901
9902
PacketTable::PacketTable()
9903
{
9904
m_numValidFrames = 0;
9905
m_primingFrames = 0;
9906
m_remainderFrames = 0;
9907
}
9908
9909
PacketTable::~PacketTable()
9910
{
9911
}
9912
9913
void PacketTable::setNumValidFrames(int64_t numValidFrames)
9914
{
9915
m_numValidFrames = numValidFrames;
9916
}
9917
9918
void PacketTable::setPrimingFrames(int32_t primingFrames)
9919
{
9920
m_primingFrames = primingFrames;
9921
}
9922
9923
void PacketTable::setRemainderFrames(int32_t remainderFrames)
9924
{
9925
m_remainderFrames = remainderFrames;
9926
}
9927
9928
void PacketTable::append(size_t bytesPerPacket)
9929
{
9930
m_bytesPerPacket.push_back(bytesPerPacket);
9931
}
9932
9933
AFfileoffset PacketTable::startOfPacket(size_t packet) const
9934
{
9935
AFfileoffset offset = 0;
9936
for (size_t i=0; i<packet; i++)
9937
offset += m_bytesPerPacket[i];
9938
return offset;
9939
}
9940
9941
// file: Raw.cpp
9942
/*
9943
Audio File Library
9944
Copyright (C) 2000, Silicon Graphics, Inc.
9945
9946
This library is free software; you can redistribute it and/or
9947
modify it under the terms of the GNU Lesser General Public
9948
License as published by the Free Software Foundation; either
9949
version 2.1 of the License, or (at your option) any later version.
9950
9951
This library is distributed in the hope that it will be useful,
9952
but WITHOUT ANY WARRANTY; without even the implied warranty of
9953
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9954
Lesser General Public License for more details.
9955
9956
You should have received a copy of the GNU Lesser General Public
9957
License along with this library; if not, write to the
9958
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
9959
Boston, MA 02110-1301 USA
9960
*/
9961
9962
/*
9963
Raw.cpp
9964
9965
This file contains code for reading and writing raw audio
9966
data files.
9967
*/
9968
9969
9970
9971
static const _AFfilesetup rawDefaultFileSetup =
9972
{
9973
_AF_VALID_FILESETUP, // valid
9974
AF_FILE_RAWDATA, // fileFormat
9975
true, // trackSet
9976
true, // instrumentSet
9977
true, // miscellaneousSet
9978
1, // trackCount
9979
NULL, // tracks
9980
0, // instrumentCount
9981
NULL, // instruments
9982
0, // miscellaneousCount
9983
NULL // miscellaneous
9984
};
9985
9986
const int _af_raw_compression_types[_AF_RAW_NUM_COMPTYPES] =
9987
{
9988
AF_COMPRESSION_G711_ULAW,
9989
AF_COMPRESSION_G711_ALAW
9990
};
9991
9992
bool RawFile::recognize(File *fh)
9993
{
9994
return false;
9995
}
9996
9997
status RawFile::readInit(AFfilesetup fileSetup)
9998
{
9999
if (!fileSetup)
10000
{
10001
_af_error(AF_BAD_FILESETUP, "a valid AFfilesetup is required for reading raw data");
10002
return AF_FAIL;
10003
}
10004
10005
if (initFromSetup(fileSetup) == AF_FAIL)
10006
return AF_FAIL;
10007
10008
TrackSetup *trackSetup = fileSetup->getTrack();
10009
if (!trackSetup)
10010
return AF_FAIL;
10011
10012
Track *track = getTrack();
10013
10014
/* Set the track's data offset. */
10015
if (trackSetup->dataOffsetSet)
10016
track->fpos_first_frame = trackSetup->dataOffset;
10017
else
10018
track->fpos_first_frame = 0;
10019
10020
/* Set the track's frame count. */
10021
if (trackSetup->frameCountSet)
10022
{
10023
track->totalfframes = trackSetup->frameCount;
10024
}
10025
else
10026
{
10027
AFfileoffset filesize = m_fh->length();
10028
if (filesize == -1)
10029
track->totalfframes = -1;
10030
else
10031
{
10032
/* Ensure that the data offset is valid. */
10033
if (track->fpos_first_frame > filesize)
10034
{
10035
_af_error(AF_BAD_FILESETUP, "data offset is larger than file size");
10036
return AF_FAIL;
10037
}
10038
10039
filesize -= track->fpos_first_frame;
10040
track->totalfframes = filesize / (int) _af_format_frame_size(&track->f, false);
10041
}
10042
track->data_size = filesize;
10043
}
10044
10045
return AF_SUCCEED;
10046
}
10047
10048
status RawFile::writeInit(AFfilesetup setup)
10049
{
10050
if (initFromSetup(setup) == AF_FAIL)
10051
return AF_FAIL;
10052
10053
TrackSetup *trackSetup = setup->getTrack();
10054
if (!trackSetup)
10055
return AF_FAIL;
10056
10057
Track *track = getTrack();
10058
10059
if (trackSetup->dataOffsetSet)
10060
track->fpos_first_frame = trackSetup->dataOffset;
10061
else
10062
track->fpos_first_frame = 0;
10063
10064
return AF_SUCCEED;
10065
}
10066
10067
status RawFile::update()
10068
{
10069
return AF_SUCCEED;
10070
}
10071
10072
AFfilesetup RawFile::completeSetup(AFfilesetup setup)
10073
{
10074
AFfilesetup newSetup;
10075
10076
if (setup->trackSet && setup->trackCount != 1)
10077
{
10078
_af_error(AF_BAD_FILESETUP, "raw file must have exactly one track");
10079
return AF_NULL_FILESETUP;
10080
}
10081
10082
TrackSetup *track = setup->getTrack();
10083
if (!track)
10084
{
10085
_af_error(AF_BAD_FILESETUP, "could not access track in file setup");
10086
return AF_NULL_FILESETUP;
10087
}
10088
10089
if (track->aesDataSet)
10090
{
10091
_af_error(AF_BAD_FILESETUP, "raw file cannot have AES data");
10092
return AF_NULL_FILESETUP;
10093
}
10094
10095
if (track->markersSet && track->markerCount != 0)
10096
{
10097
_af_error(AF_BAD_NUMMARKS, "raw file cannot have markers");
10098
return AF_NULL_FILESETUP;
10099
}
10100
10101
if (setup->instrumentSet && setup->instrumentCount != 0)
10102
{
10103
_af_error(AF_BAD_NUMINSTS, "raw file cannot have instruments");
10104
return AF_NULL_FILESETUP;
10105
}
10106
10107
if (setup->miscellaneousSet && setup->miscellaneousCount != 0)
10108
{
10109
_af_error(AF_BAD_NUMMISC, "raw file cannot have miscellaneous data");
10110
return AF_NULL_FILESETUP;
10111
}
10112
10113
newSetup = (_AFfilesetup *) _af_malloc(sizeof (_AFfilesetup));
10114
*newSetup = rawDefaultFileSetup;
10115
10116
newSetup->tracks = (TrackSetup *) _af_malloc(sizeof (TrackSetup));
10117
newSetup->tracks[0] = setup->tracks[0];
10118
newSetup->tracks[0].f.compressionParams = NULL;
10119
10120
newSetup->tracks[0].markerCount = 0;
10121
newSetup->tracks[0].markers = NULL;
10122
10123
return newSetup;
10124
}
10125
10126
// file: Setup.cpp
10127
/*
10128
Audio File Library
10129
Copyright (C) 2000, Silicon Graphics, Inc.
10130
10131
This library is free software; you can redistribute it and/or
10132
modify it under the terms of the GNU Lesser General Public
10133
License as published by the Free Software Foundation; either
10134
version 2.1 of the License, or (at your option) any later version.
10135
10136
This library is distributed in the hope that it will be useful,
10137
but WITHOUT ANY WARRANTY; without even the implied warranty of
10138
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10139
Lesser General Public License for more details.
10140
10141
You should have received a copy of the GNU Lesser General Public
10142
License along with this library; if not, write to the
10143
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
10144
Boston, MA 02110-1301 USA
10145
*/
10146
10147
/*
10148
Setup.cpp
10149
*/
10150
10151
10152
#include <stdlib.h>
10153
#include <string.h>
10154
10155
10156
static const _AFfilesetup _af_default_file_setup =
10157
{
10158
_AF_VALID_FILESETUP, /* valid */
10159
#if WORDS_BIGENDIAN
10160
AF_FILE_AIFFC, /* file format */
10161
#else
10162
AF_FILE_WAVE, /* file format */
10163
#endif
10164
false, /* trackSet */
10165
false, /* instrumentSet */
10166
false, /* miscellaneousSet */
10167
1, /* trackCount */
10168
NULL, /* tracks */
10169
1, /* instrumentCount */
10170
NULL, /* instruments */
10171
0, /* miscellaneousCount */
10172
NULL /* miscellaneous */
10173
};
10174
10175
static const InstrumentSetup _af_default_instrumentsetup =
10176
{
10177
0, /* id */
10178
2, /* loopCount */
10179
NULL, /* loops */
10180
false /* loopSet */
10181
};
10182
10183
static const TrackSetup _af_default_tracksetup =
10184
{
10185
0,
10186
{
10187
44100.0,
10188
AF_SAMPFMT_TWOSCOMP,
10189
16,
10190
_AF_BYTEORDER_NATIVE,
10191
{ SLOPE_INT16, 0, MIN_INT16, MAX_INT16 },
10192
2,
10193
AF_COMPRESSION_NONE,
10194
NULL
10195
},
10196
false, /* rateSet */
10197
false, /* sampleFormatSet */
10198
false, /* sampleWidthSet */
10199
false, /* byteOrderSet */
10200
false, /* channelCountSet */
10201
false, /* compressionSet */
10202
false, /* aesDataSet */
10203
false, /* markersSet */
10204
false, /* dataOffsetSet */
10205
false, /* frameCountSet */
10206
10207
4, /* markerCount */
10208
NULL, /* markers */
10209
0, /* dataOffset */
10210
0 /* frameCount */
10211
};
10212
10213
TrackSetup *_af_tracksetup_new (int trackCount)
10214
{
10215
TrackSetup *tracks;
10216
10217
if (trackCount == 0)
10218
return NULL;
10219
10220
tracks = (TrackSetup *) _af_calloc(trackCount, sizeof (TrackSetup));
10221
if (tracks == NULL)
10222
return NULL;
10223
10224
for (int i=0; i<trackCount; i++)
10225
{
10226
tracks[i] = _af_default_tracksetup;
10227
10228
tracks[i].id = AF_DEFAULT_TRACK + i;
10229
10230
/* XXXmpruett deal with compression */
10231
10232
_af_set_sample_format(&tracks[i].f, tracks[i].f.sampleFormat,
10233
tracks[i].f.sampleWidth);
10234
10235
if (tracks[i].markerCount == 0)
10236
tracks[i].markers = NULL;
10237
else
10238
{
10239
tracks[i].markers = (MarkerSetup *) _af_calloc(tracks[i].markerCount,
10240
sizeof (MarkerSetup));
10241
10242
if (tracks[i].markers == NULL)
10243
return NULL;
10244
10245
for (int j=0; j<tracks[i].markerCount; j++)
10246
{
10247
tracks[i].markers[j].id = j+1;
10248
10249
tracks[i].markers[j].name = _af_strdup("");
10250
if (tracks[i].markers[j].name == NULL)
10251
return NULL;
10252
10253
tracks[i].markers[j].comment = _af_strdup("");
10254
if (tracks[i].markers[j].comment == NULL)
10255
return NULL;
10256
}
10257
}
10258
}
10259
10260
return tracks;
10261
}
10262
10263
InstrumentSetup *_af_instsetup_new (int instrumentCount)
10264
{
10265
InstrumentSetup *instruments;
10266
10267
if (instrumentCount == 0)
10268
return NULL;
10269
instruments = (InstrumentSetup *) _af_calloc(instrumentCount, sizeof (InstrumentSetup));
10270
if (instruments == NULL)
10271
return NULL;
10272
10273
for (int i=0; i<instrumentCount; i++)
10274
{
10275
instruments[i] = _af_default_instrumentsetup;
10276
instruments[i].id = AF_DEFAULT_INST + i;
10277
if (instruments[i].loopCount == 0)
10278
instruments[i].loops = NULL;
10279
else
10280
{
10281
instruments[i].loops = (LoopSetup *) _af_calloc(instruments[i].loopCount, sizeof (LoopSetup));
10282
if (instruments[i].loops == NULL)
10283
return NULL;
10284
10285
for (int j=0; j<instruments[i].loopCount; j++)
10286
instruments[i].loops[j].id = j+1;
10287
}
10288
}
10289
10290
return instruments;
10291
}
10292
10293
AFfilesetup afNewFileSetup (void)
10294
{
10295
AFfilesetup setup;
10296
10297
setup = (_AFfilesetup *) _af_malloc(sizeof (_AFfilesetup));
10298
if (setup == NULL) return AF_NULL_FILESETUP;
10299
10300
*setup = _af_default_file_setup;
10301
10302
setup->tracks = _af_tracksetup_new(setup->trackCount);
10303
10304
setup->instruments = _af_instsetup_new(setup->instrumentCount);
10305
10306
if (setup->miscellaneousCount == 0)
10307
setup->miscellaneous = NULL;
10308
else
10309
{
10310
setup->miscellaneous = (MiscellaneousSetup *) _af_calloc(setup->miscellaneousCount,
10311
sizeof (MiscellaneousSetup));
10312
for (int i=0; i<setup->miscellaneousCount; i++)
10313
{
10314
setup->miscellaneous[i].id = i+1;
10315
setup->miscellaneous[i].type = 0;
10316
setup->miscellaneous[i].size = 0;
10317
}
10318
}
10319
10320
return setup;
10321
}
10322
10323
/*
10324
Free the specified track's markers and their subfields.
10325
*/
10326
void _af_setup_free_markers (AFfilesetup setup, int trackno)
10327
{
10328
if (setup->tracks[trackno].markerCount != 0)
10329
{
10330
for (int i=0; i<setup->tracks[trackno].markerCount; i++)
10331
{
10332
free(setup->tracks[trackno].markers[i].name);
10333
free(setup->tracks[trackno].markers[i].comment);
10334
}
10335
10336
free(setup->tracks[trackno].markers);
10337
}
10338
10339
setup->tracks[trackno].markers = NULL;
10340
setup->tracks[trackno].markerCount = 0;
10341
}
10342
10343
/*
10344
Free the specified setup's tracks and their subfields.
10345
*/
10346
void _af_setup_free_tracks (AFfilesetup setup)
10347
{
10348
if (setup->tracks)
10349
{
10350
for (int i=0; i<setup->trackCount; i++)
10351
{
10352
_af_setup_free_markers(setup, i);
10353
}
10354
10355
free(setup->tracks);
10356
}
10357
10358
setup->tracks = NULL;
10359
setup->trackCount = 0;
10360
}
10361
10362
/*
10363
Free the specified setup's instruments and their subfields.
10364
*/
10365
void _af_setup_free_instruments (AFfilesetup setup)
10366
{
10367
if (setup->instruments)
10368
{
10369
for (int i=0; i < setup->instrumentCount; i++)
10370
setup->instruments[i].freeLoops();
10371
10372
free(setup->instruments);
10373
}
10374
10375
setup->instruments = NULL;
10376
setup->instrumentCount = 0;
10377
}
10378
10379
void afFreeFileSetup (AFfilesetup setup)
10380
{
10381
if (!_af_filesetup_ok(setup))
10382
return;
10383
10384
_af_setup_free_tracks(setup);
10385
10386
_af_setup_free_instruments(setup);
10387
10388
if (setup->miscellaneousCount)
10389
{
10390
free(setup->miscellaneous);
10391
setup->miscellaneous = NULL;
10392
setup->miscellaneousCount = 0;
10393
}
10394
10395
memset(setup, 0, sizeof (_AFfilesetup));
10396
free(setup);
10397
}
10398
10399
void afInitFileFormat (AFfilesetup setup, int filefmt)
10400
{
10401
if (!_af_filesetup_ok(setup))
10402
return;
10403
10404
if (filefmt < 0 || filefmt >= _AF_NUM_UNITS)
10405
{
10406
_af_error(AF_BAD_FILEFMT, "unrecognized file format %d",
10407
filefmt);
10408
return;
10409
}
10410
10411
if (!_af_units[filefmt].implemented)
10412
{
10413
_af_error(AF_BAD_NOT_IMPLEMENTED,
10414
"%s format not currently supported",
10415
_af_units[filefmt].name);
10416
return;
10417
}
10418
10419
setup->fileFormat = filefmt;
10420
}
10421
10422
void afInitChannels (AFfilesetup setup, int trackid, int channels)
10423
{
10424
if (!_af_filesetup_ok(setup))
10425
return;
10426
10427
TrackSetup *track = setup->getTrack(trackid);
10428
if (!track)
10429
return;
10430
10431
if (channels < 1)
10432
{
10433
_af_error(AF_BAD_CHANNELS, "invalid number of channels %d",
10434
channels);
10435
return;
10436
}
10437
10438
track->f.channelCount = channels;
10439
track->channelCountSet = true;
10440
}
10441
10442
void afInitSampleFormat (AFfilesetup setup, int trackid, int sampfmt, int sampwidth)
10443
{
10444
if (!_af_filesetup_ok(setup))
10445
return;
10446
10447
TrackSetup *track = setup->getTrack(trackid);
10448
if (!track)
10449
return;
10450
10451
_af_set_sample_format(&track->f, sampfmt, sampwidth);
10452
10453
track->sampleFormatSet = true;
10454
track->sampleWidthSet = true;
10455
}
10456
10457
void afInitByteOrder (AFfilesetup setup, int trackid, int byteorder)
10458
{
10459
if (!_af_filesetup_ok(setup))
10460
return;
10461
10462
TrackSetup *track = setup->getTrack(trackid);
10463
if (!track)
10464
return;
10465
10466
if (byteorder != AF_BYTEORDER_BIGENDIAN &&
10467
byteorder != AF_BYTEORDER_LITTLEENDIAN)
10468
{
10469
_af_error(AF_BAD_BYTEORDER, "invalid byte order %d", byteorder);
10470
return;
10471
}
10472
10473
track->f.byteOrder = byteorder;
10474
track->byteOrderSet = true;
10475
}
10476
10477
void afInitRate (AFfilesetup setup, int trackid, double rate)
10478
{
10479
if (!_af_filesetup_ok(setup))
10480
return;
10481
10482
TrackSetup *track = setup->getTrack(trackid);
10483
if (!track)
10484
return;
10485
10486
if (rate <= 0.0)
10487
{
10488
_af_error(AF_BAD_RATE, "invalid sample rate %.30g", rate);
10489
return;
10490
}
10491
10492
track->f.sampleRate = rate;
10493
track->rateSet = true;
10494
}
10495
10496
/*
10497
track data: data offset within the file (initialized for raw reading only)
10498
*/
10499
void afInitDataOffset (AFfilesetup setup, int trackid, AFfileoffset offset)
10500
{
10501
if (!_af_filesetup_ok(setup))
10502
return;
10503
10504
TrackSetup *track = setup->getTrack(trackid);
10505
if (!track)
10506
return;
10507
10508
if (offset < 0)
10509
{
10510
_af_error(AF_BAD_DATAOFFSET, "invalid data offset %jd",
10511
static_cast<intmax_t>(offset));
10512
return;
10513
}
10514
10515
track->dataOffset = offset;
10516
track->dataOffsetSet = true;
10517
}
10518
10519
/*
10520
track data: data offset within the file (initialized for raw reading only)
10521
*/
10522
void afInitFrameCount (AFfilesetup setup, int trackid, AFfileoffset count)
10523
{
10524
if (!_af_filesetup_ok(setup))
10525
return;
10526
10527
TrackSetup *track = setup->getTrack(trackid);
10528
if (!track)
10529
return;
10530
10531
if (count < 0)
10532
{
10533
_af_error(AF_BAD_FRAMECNT, "invalid frame count %jd",
10534
static_cast<intmax_t>(count));
10535
return;
10536
}
10537
10538
track->frameCount = count;
10539
track->frameCountSet = true;
10540
}
10541
10542
#define alloccopy(type, n, var, copyfrom) \
10543
{ \
10544
if (n == 0) \
10545
var = NULL; \
10546
else \
10547
{ \
10548
if ((var = (type *) _af_calloc(n, sizeof (type))) == NULL) \
10549
goto fail; \
10550
memcpy((var), (copyfrom), (n) * sizeof (type)); \
10551
} \
10552
}
10553
10554
AFfilesetup _af_filesetup_copy (const _AFfilesetup *setup,
10555
const _AFfilesetup *defaultSetup, bool copyMarks)
10556
{
10557
AFfilesetup newsetup;
10558
int instrumentCount, miscellaneousCount, trackCount;
10559
10560
newsetup = (_AFfilesetup *) _af_malloc(sizeof (_AFfilesetup));
10561
if (newsetup == AF_NULL_FILESETUP)
10562
return AF_NULL_FILESETUP;
10563
10564
*newsetup = *defaultSetup;
10565
10566
newsetup->tracks = NULL;
10567
newsetup->instruments = NULL;
10568
newsetup->miscellaneous = NULL;
10569
10570
/* Copy tracks. */
10571
trackCount = setup->trackSet ? setup->trackCount :
10572
newsetup->trackSet ? newsetup->trackCount : 0;
10573
alloccopy(TrackSetup, trackCount, newsetup->tracks, setup->tracks);
10574
newsetup->trackCount = trackCount;
10575
10576
/* Copy instruments. */
10577
instrumentCount = setup->instrumentSet ? setup->instrumentCount :
10578
newsetup->instrumentSet ? newsetup->instrumentCount : 0;
10579
alloccopy(InstrumentSetup, instrumentCount, newsetup->instruments, setup->instruments);
10580
newsetup->instrumentCount = instrumentCount;
10581
10582
/* Copy miscellaneous information. */
10583
miscellaneousCount = setup->miscellaneousSet ? setup->miscellaneousCount :
10584
newsetup->miscellaneousSet ? newsetup->miscellaneousCount : 0;
10585
alloccopy(MiscellaneousSetup, miscellaneousCount, newsetup->miscellaneous, setup->miscellaneous);
10586
newsetup->miscellaneousCount = miscellaneousCount;
10587
10588
for (int i=0; i<setup->trackCount; i++)
10589
{
10590
TrackSetup *track = &newsetup->tracks[i];
10591
10592
/* XXXmpruett set compression information */
10593
10594
if (!setup->tracks[i].markersSet && !copyMarks)
10595
{
10596
track->markers = NULL;
10597
track->markerCount = 0;
10598
continue;
10599
}
10600
10601
alloccopy(MarkerSetup, setup->tracks[i].markerCount,
10602
track->markers, setup->tracks[i].markers);
10603
track->markerCount = setup->tracks[i].markerCount;
10604
10605
for (int j=0; j<setup->tracks[i].markerCount; j++)
10606
{
10607
track->markers[j].name =
10608
_af_strdup(setup->tracks[i].markers[j].name);
10609
if (track->markers[j].name == NULL)
10610
goto fail;
10611
10612
track->markers[j].comment =
10613
_af_strdup(setup->tracks[i].markers[j].comment);
10614
if (track->markers[j].comment == NULL)
10615
goto fail;
10616
}
10617
}
10618
10619
for (int i=0; i<newsetup->instrumentCount; i++)
10620
{
10621
InstrumentSetup *instrument = &newsetup->instruments[i];
10622
alloccopy(LoopSetup, setup->instruments[i].loopCount,
10623
instrument->loops, setup->instruments[i].loops);
10624
}
10625
10626
return newsetup;
10627
10628
fail:
10629
if (newsetup->miscellaneous)
10630
free(newsetup->miscellaneous);
10631
if (newsetup->instruments)
10632
free(newsetup->instruments);
10633
if (newsetup->tracks)
10634
free(newsetup->tracks);
10635
if (newsetup)
10636
free(newsetup);
10637
10638
return AF_NULL_FILESETUP;
10639
}
10640
10641
TrackSetup *_AFfilesetup::getTrack(int trackID)
10642
{
10643
for (int i=0; i<trackCount; i++)
10644
{
10645
if (tracks[i].id == trackID)
10646
return &tracks[i];
10647
}
10648
10649
_af_error(AF_BAD_TRACKID, "bad track id %d", trackID);
10650
return NULL;
10651
}
10652
10653
InstrumentSetup *_AFfilesetup::getInstrument(int instrumentID)
10654
{
10655
for (int i=0; i < instrumentCount; i++)
10656
if (instruments[i].id == instrumentID)
10657
return &instruments[i];
10658
10659
_af_error(AF_BAD_INSTID, "invalid instrument id %d", instrumentID);
10660
return NULL;
10661
}
10662
10663
MiscellaneousSetup *_AFfilesetup::getMiscellaneous(int miscellaneousID)
10664
{
10665
for (int i=0; i<miscellaneousCount; i++)
10666
{
10667
if (miscellaneous[i].id == miscellaneousID)
10668
return &miscellaneous[i];
10669
}
10670
10671
_af_error(AF_BAD_MISCID, "bad miscellaneous id %d", miscellaneousID);
10672
10673
return NULL;
10674
}
10675
10676
// file: Track.cpp
10677
/*
10678
Audio File Library
10679
Copyright (C) 1998, Michael Pruett <[email protected]>
10680
10681
This library is free software; you can redistribute it and/or
10682
modify it under the terms of the GNU Lesser General Public
10683
License as published by the Free Software Foundation; either
10684
version 2.1 of the License, or (at your option) any later version.
10685
10686
This library is distributed in the hope that it will be useful,
10687
but WITHOUT ANY WARRANTY; without even the implied warranty of
10688
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10689
Lesser General Public License for more details.
10690
10691
You should have received a copy of the GNU Lesser General Public
10692
License along with this library; if not, write to the
10693
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
10694
Boston, MA 02110-1301 USA
10695
*/
10696
10697
/*
10698
track.c
10699
10700
This file contains functions for dealing with tracks within an
10701
audio file.
10702
*/
10703
10704
10705
#include <assert.h>
10706
#include <stddef.h>
10707
#include <stdio.h>
10708
#include <string.h>
10709
10710
10711
void afInitTrackIDs (AFfilesetup file, const int *trackids, int trackCount)
10712
{
10713
assert(file);
10714
assert(trackids);
10715
assert(trackCount == 1);
10716
assert(trackids[0] == AF_DEFAULT_TRACK);
10717
}
10718
10719
int afGetTrackIDs (AFfilehandle file, int *trackids)
10720
{
10721
assert(file);
10722
10723
if (trackids != NULL)
10724
trackids[0] = AF_DEFAULT_TRACK;
10725
10726
return 1;
10727
}
10728
10729
Track::Track()
10730
{
10731
id = AF_DEFAULT_TRACK;
10732
10733
f.compressionParams = NULL;
10734
v.compressionParams = NULL;
10735
10736
channelMatrix = NULL;
10737
10738
markerCount = 0;
10739
markers = NULL;
10740
10741
hasAESData = false;
10742
memset(aesData, 0, 24);
10743
10744
totalfframes = 0;
10745
nextfframe = 0;
10746
frames2ignore = 0;
10747
fpos_first_frame = 0;
10748
fpos_next_frame = 0;
10749
fpos_after_data = 0;
10750
totalvframes = 0;
10751
nextvframe = 0;
10752
data_size = 0;
10753
}
10754
10755
Track::~Track()
10756
{
10757
if (f.compressionParams)
10758
{
10759
AUpvfree(f.compressionParams);
10760
f.compressionParams = NULL;
10761
}
10762
10763
if (v.compressionParams)
10764
{
10765
AUpvfree(v.compressionParams);
10766
v.compressionParams = NULL;
10767
}
10768
10769
free(channelMatrix);
10770
channelMatrix = NULL;
10771
10772
if (markers)
10773
{
10774
for (int j=0; j<markerCount; j++)
10775
{
10776
free(markers[j].name);
10777
markers[j].name = NULL;
10778
free(markers[j].comment);
10779
markers[j].comment = NULL;
10780
}
10781
10782
free(markers);
10783
markers = NULL;
10784
}
10785
}
10786
10787
void Track::print()
10788
{
10789
fprintf(stderr, "totalfframes %jd\n", (intmax_t) totalfframes);
10790
fprintf(stderr, "nextfframe %jd\n", (intmax_t) nextfframe);
10791
fprintf(stderr, "frames2ignore %jd\n", (intmax_t) frames2ignore);
10792
fprintf(stderr, "fpos_first_frame %jd\n", (intmax_t) fpos_first_frame);
10793
fprintf(stderr, "fpos_next_frame %jd\n", (intmax_t) fpos_next_frame);
10794
fprintf(stderr, "fpos_after_data %jd\n", (intmax_t) fpos_after_data);
10795
fprintf(stderr, "totalvframes %jd\n", (intmax_t) totalvframes);
10796
fprintf(stderr, "nextvframe %jd\n", (intmax_t) nextvframe);
10797
fprintf(stderr, "data_size %jd\n", (intmax_t) data_size);
10798
}
10799
10800
Marker *Track::getMarker(int markerID)
10801
{
10802
for (int i=0; i<markerCount; i++)
10803
if (markers[i].id == markerID)
10804
return &markers[i];
10805
10806
_af_error(AF_BAD_MARKID, "no marker with id %d found in track %d",
10807
markerID, id);
10808
10809
return NULL;
10810
}
10811
10812
status Track::copyMarkers(TrackSetup *setup)
10813
{
10814
if ((markerCount = setup->markerCount) == 0)
10815
{
10816
markers = NULL;
10817
return AF_SUCCEED;
10818
}
10819
10820
markers = _af_marker_new(markerCount);
10821
if (!markers)
10822
return AF_FAIL;
10823
10824
for (int i=0; i<markerCount; i++)
10825
{
10826
markers[i].id = setup->markers[i].id;
10827
markers[i].name = _af_strdup(setup->markers[i].name);
10828
if (!markers[i].name)
10829
return AF_FAIL;
10830
10831
markers[i].comment = _af_strdup(setup->markers[i].comment);
10832
if (!markers[i].comment)
10833
return AF_FAIL;
10834
markers[i].position = 0;
10835
}
10836
10837
return AF_SUCCEED;
10838
}
10839
10840
void Track::computeTotalFileFrames()
10841
{
10842
if (f.bytesPerPacket && f.framesPerPacket)
10843
totalfframes = (data_size / f.bytesPerPacket) * f.framesPerPacket;
10844
}
10845
10846
// file: UUID.cpp
10847
/*
10848
Copyright (C) 2011, Michael Pruett. All rights reserved.
10849
10850
Redistribution and use in source and binary forms, with or without
10851
modification, are permitted provided that the following conditions
10852
are met:
10853
10854
1. Redistributions of source code must retain the above copyright
10855
notice, this list of conditions and the following disclaimer.
10856
10857
2. Redistributions in binary form must reproduce the above copyright
10858
notice, this list of conditions and the following disclaimer in the
10859
documentation and/or other materials provided with the distribution.
10860
10861
3. The name of the author may not be used to endorse or promote products
10862
derived from this software without specific prior written permission.
10863
10864
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
10865
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
10866
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
10867
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
10868
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10869
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10870
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
10871
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10872
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
10873
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10874
*/
10875
10876
10877
#include <stdio.h>
10878
#include <string.h>
10879
10880
bool UUID::operator==(const UUID &u) const
10881
{
10882
return !memcmp(data, u.data, 16);
10883
}
10884
10885
bool UUID::operator!=(const UUID &u) const
10886
{
10887
return memcmp(data, u.data, 16) != 0;
10888
}
10889
10890
std::string UUID::name() const
10891
{
10892
char s[37];
10893
uint32_t u1 =
10894
(data[0] << 24) |
10895
(data[1] << 16) |
10896
(data[2] << 8) |
10897
data[3];
10898
uint16_t u2 =
10899
(data[4] << 8) |
10900
data[5];
10901
uint16_t u3 =
10902
(data[6] << 8) |
10903
data[7];
10904
uint16_t u4 =
10905
(data[8] << 8) |
10906
data[9];
10907
snprintf(s, 37, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
10908
u1, u2, u3, u4,
10909
data[10], data[11], data[12], data[13], data[14], data[15]);
10910
return std::string(s);
10911
}
10912
10913
// file: WAVE.cpp
10914
/*
10915
Audio File Library
10916
Copyright (C) 1998-2000, 2003-2004, 2010-2013, Michael Pruett <[email protected]>
10917
Copyright (C) 2000-2002, Silicon Graphics, Inc.
10918
Copyright (C) 2002-2003, Davy Durham
10919
10920
This library is free software; you can redistribute it and/or
10921
modify it under the terms of the GNU Lesser General Public
10922
License as published by the Free Software Foundation; either
10923
version 2.1 of the License, or (at your option) any later version.
10924
10925
This library is distributed in the hope that it will be useful,
10926
but WITHOUT ANY WARRANTY; without even the implied warranty of
10927
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10928
Lesser General Public License for more details.
10929
10930
You should have received a copy of the GNU Lesser General Public
10931
License along with this library; if not, write to the
10932
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
10933
Boston, MA 02110-1301 USA
10934
*/
10935
10936
/*
10937
WAVE.cpp
10938
10939
This file contains code for reading and writing RIFF WAVE format
10940
sound files.
10941
*/
10942
10943
10944
#include <assert.h>
10945
#include <math.h>
10946
#include <stdint.h>
10947
#include <stdlib.h>
10948
#include <string.h>
10949
10950
10951
/* These constants are from RFC 2361. */
10952
enum
10953
{
10954
WAVE_FORMAT_UNKNOWN = 0x0000, /* Microsoft Unknown Wave Format */
10955
WAVE_FORMAT_PCM = 0x0001, /* Microsoft PCM Format */
10956
WAVE_FORMAT_ADPCM = 0x0002, /* Microsoft ADPCM Format */
10957
WAVE_FORMAT_IEEE_FLOAT = 0x0003, /* IEEE Float */
10958
WAVE_FORMAT_VSELP = 0x0004, /* Compaq Computer's VSELP */
10959
WAVE_FORMAT_IBM_CVSD = 0x0005, /* IBM CVSD */
10960
WAVE_FORMAT_ALAW = 0x0006, /* Microsoft ALAW */
10961
WAVE_FORMAT_MULAW = 0x0007, /* Microsoft MULAW */
10962
WAVE_FORMAT_OKI_ADPCM = 0x0010, /* OKI ADPCM */
10963
WAVE_FORMAT_DVI_ADPCM = 0x0011, /* Intel's DVI ADPCM */
10964
WAVE_FORMAT_MEDIASPACE_ADPCM = 0x0012, /* Videologic's MediaSpace ADPCM */
10965
WAVE_FORMAT_SIERRA_ADPCM = 0x0013, /* Sierra ADPCM */
10966
WAVE_FORMAT_G723_ADPCM = 0x0014, /* G.723 ADPCM */
10967
WAVE_FORMAT_DIGISTD = 0x0015, /* DSP Solutions' DIGISTD */
10968
WAVE_FORMAT_DIGIFIX = 0x0016, /* DSP Solutions' DIGIFIX */
10969
WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 0x0017, /* Dialogic OKI ADPCM */
10970
WAVE_FORMAT_MEDIAVISION_ADPCM = 0x0018, /* MediaVision ADPCM */
10971
WAVE_FORMAT_CU_CODEC = 0x0019, /* HP CU */
10972
WAVE_FORMAT_YAMAHA_ADPCM = 0x0020, /* Yamaha ADPCM */
10973
WAVE_FORMAT_SONARC = 0x0021, /* Speech Compression's Sonarc */
10974
WAVE_FORMAT_DSP_TRUESPEECH = 0x0022, /* DSP Group's True Speech */
10975
WAVE_FORMAT_ECHOSC1 = 0x0023, /* Echo Speech's EchoSC1 */
10976
WAVE_FORMAT_AUDIOFILE_AF36 = 0x0024, /* Audiofile AF36 */
10977
WAVE_FORMAT_APTX = 0x0025, /* APTX */
10978
WAVE_FORMAT_DOLBY_AC2 = 0x0030, /* Dolby AC2 */
10979
WAVE_FORMAT_GSM610 = 0x0031, /* GSM610 */
10980
WAVE_FORMAT_MSNAUDIO = 0x0032, /* MSNAudio */
10981
WAVE_FORMAT_ANTEX_ADPCME = 0x0033, /* Antex ADPCME */
10982
10983
WAVE_FORMAT_MPEG = 0x0050, /* MPEG */
10984
WAVE_FORMAT_MPEGLAYER3 = 0x0055, /* MPEG layer 3 */
10985
WAVE_FORMAT_LUCENT_G723 = 0x0059, /* Lucent G.723 */
10986
WAVE_FORMAT_G726_ADPCM = 0x0064, /* G.726 ADPCM */
10987
WAVE_FORMAT_G722_ADPCM = 0x0065, /* G.722 ADPCM */
10988
10989
IBM_FORMAT_MULAW = 0x0101,
10990
IBM_FORMAT_ALAW = 0x0102,
10991
IBM_FORMAT_ADPCM = 0x0103,
10992
10993
WAVE_FORMAT_CREATIVE_ADPCM = 0x0200,
10994
10995
WAVE_FORMAT_EXTENSIBLE = 0xfffe
10996
};
10997
10998
const int _af_wave_compression_types[_AF_WAVE_NUM_COMPTYPES] =
10999
{
11000
AF_COMPRESSION_G711_ULAW,
11001
AF_COMPRESSION_G711_ALAW,
11002
AF_COMPRESSION_IMA,
11003
AF_COMPRESSION_MS_ADPCM
11004
};
11005
11006
const InstParamInfo _af_wave_inst_params[_AF_WAVE_NUM_INSTPARAMS] =
11007
{
11008
{ AF_INST_MIDI_BASENOTE, AU_PVTYPE_LONG, "MIDI base note", {60} },
11009
{ AF_INST_NUMCENTS_DETUNE, AU_PVTYPE_LONG, "Detune in cents", {0} },
11010
{ AF_INST_MIDI_LOVELOCITY, AU_PVTYPE_LONG, "Low velocity", {1} },
11011
{ AF_INST_MIDI_HIVELOCITY, AU_PVTYPE_LONG, "High velocity", {127} },
11012
{ AF_INST_MIDI_LONOTE, AU_PVTYPE_LONG, "Low note", {0} },
11013
{ AF_INST_MIDI_HINOTE, AU_PVTYPE_LONG, "High note", {127} },
11014
{ AF_INST_NUMDBS_GAIN, AU_PVTYPE_LONG, "Gain in dB", {0} }
11015
};
11016
11017
static const _AFfilesetup waveDefaultFileSetup =
11018
{
11019
_AF_VALID_FILESETUP, /* valid */
11020
AF_FILE_WAVE, /* fileFormat */
11021
true, /* trackSet */
11022
true, /* instrumentSet */
11023
true, /* miscellaneousSet */
11024
1, /* trackCount */
11025
NULL, /* tracks */
11026
0, /* instrumentCount */
11027
NULL, /* instruments */
11028
0, /* miscellaneousCount */
11029
NULL /* miscellaneous */
11030
};
11031
11032
static const UUID _af_wave_guid_pcm =
11033
{{
11034
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
11035
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
11036
}};
11037
static const UUID _af_wave_guid_ieee_float =
11038
{{
11039
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
11040
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
11041
}};
11042
static const UUID _af_wave_guid_ulaw =
11043
{{
11044
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
11045
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
11046
}};
11047
static const UUID _af_wave_guid_alaw =
11048
{{
11049
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
11050
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
11051
}};
11052
11053
WAVEFile::WAVEFile()
11054
{
11055
setFormatByteOrder(AF_BYTEORDER_LITTLEENDIAN);
11056
11057
m_factOffset = 0;
11058
m_miscellaneousOffset = 0;
11059
m_markOffset = 0;
11060
m_dataSizeOffset = 0;
11061
11062
m_msadpcmNumCoefficients = 0;
11063
}
11064
11065
status WAVEFile::parseFrameCount(const Tag &id, uint32_t size)
11066
{
11067
Track *track = getTrack();
11068
11069
uint32_t totalFrames;
11070
readU32(&totalFrames);
11071
11072
track->totalfframes = totalFrames;
11073
11074
return AF_SUCCEED;
11075
}
11076
11077
status WAVEFile::parseFormat(const Tag &id, uint32_t size)
11078
{
11079
Track *track = getTrack();
11080
11081
uint16_t formatTag;
11082
readU16(&formatTag);
11083
uint16_t channelCount;
11084
readU16(&channelCount);
11085
uint32_t sampleRate;
11086
readU32(&sampleRate);
11087
uint32_t averageBytesPerSecond;
11088
readU32(&averageBytesPerSecond);
11089
uint16_t blockAlign;
11090
readU16(&blockAlign);
11091
11092
if (!channelCount)
11093
{
11094
_af_error(AF_BAD_CHANNELS, "invalid file with 0 channels");
11095
return AF_FAIL;
11096
}
11097
11098
track->f.channelCount = channelCount;
11099
track->f.sampleRate = sampleRate;
11100
track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
11101
11102
/* Default to uncompressed audio data. */
11103
track->f.compressionType = AF_COMPRESSION_NONE;
11104
track->f.framesPerPacket = 1;
11105
11106
switch (formatTag)
11107
{
11108
case WAVE_FORMAT_PCM:
11109
{
11110
uint16_t bitsPerSample;
11111
readU16(&bitsPerSample);
11112
11113
track->f.sampleWidth = bitsPerSample;
11114
11115
if (bitsPerSample == 0 || bitsPerSample > 32)
11116
{
11117
_af_error(AF_BAD_WIDTH,
11118
"bad sample width of %d bits",
11119
bitsPerSample);
11120
return AF_FAIL;
11121
}
11122
11123
if (bitsPerSample <= 8)
11124
track->f.sampleFormat = AF_SAMPFMT_UNSIGNED;
11125
else
11126
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11127
}
11128
break;
11129
11130
case WAVE_FORMAT_MULAW:
11131
case IBM_FORMAT_MULAW:
11132
track->f.sampleWidth = 16;
11133
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11134
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
11135
track->f.compressionType = AF_COMPRESSION_G711_ULAW;
11136
track->f.bytesPerPacket = track->f.channelCount;
11137
break;
11138
11139
case WAVE_FORMAT_ALAW:
11140
case IBM_FORMAT_ALAW:
11141
track->f.sampleWidth = 16;
11142
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11143
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
11144
track->f.compressionType = AF_COMPRESSION_G711_ALAW;
11145
track->f.bytesPerPacket = track->f.channelCount;
11146
break;
11147
11148
case WAVE_FORMAT_IEEE_FLOAT:
11149
{
11150
uint16_t bitsPerSample;
11151
readU16(&bitsPerSample);
11152
11153
if (bitsPerSample == 64)
11154
{
11155
track->f.sampleWidth = 64;
11156
track->f.sampleFormat = AF_SAMPFMT_DOUBLE;
11157
}
11158
else
11159
{
11160
track->f.sampleWidth = 32;
11161
track->f.sampleFormat = AF_SAMPFMT_FLOAT;
11162
}
11163
}
11164
break;
11165
11166
case WAVE_FORMAT_ADPCM:
11167
{
11168
uint16_t bitsPerSample, extraByteCount,
11169
samplesPerBlock, numCoefficients;
11170
11171
if (track->f.channelCount != 1 &&
11172
track->f.channelCount != 2)
11173
{
11174
_af_error(AF_BAD_CHANNELS,
11175
"WAVE file with MS ADPCM compression "
11176
"must have 1 or 2 channels");
11177
}
11178
11179
readU16(&bitsPerSample);
11180
readU16(&extraByteCount);
11181
readU16(&samplesPerBlock);
11182
readU16(&numCoefficients);
11183
11184
/* numCoefficients should be at least 7. */
11185
assert(numCoefficients >= 7 && numCoefficients <= 255);
11186
11187
m_msadpcmNumCoefficients = numCoefficients;
11188
11189
for (int i=0; i<m_msadpcmNumCoefficients; i++)
11190
{
11191
readS16(&m_msadpcmCoefficients[i][0]);
11192
readS16(&m_msadpcmCoefficients[i][1]);
11193
}
11194
11195
track->f.sampleWidth = 16;
11196
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11197
track->f.compressionType = AF_COMPRESSION_MS_ADPCM;
11198
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
11199
11200
track->f.framesPerPacket = samplesPerBlock;
11201
track->f.bytesPerPacket = blockAlign;
11202
11203
// Create the parameter list.
11204
AUpvlist pv = AUpvnew(2);
11205
AUpvsetparam(pv, 0, _AF_MS_ADPCM_NUM_COEFFICIENTS);
11206
AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG);
11207
long l = m_msadpcmNumCoefficients;
11208
AUpvsetval(pv, 0, &l);
11209
11210
AUpvsetparam(pv, 1, _AF_MS_ADPCM_COEFFICIENTS);
11211
AUpvsetvaltype(pv, 1, AU_PVTYPE_PTR);
11212
void *v = m_msadpcmCoefficients;
11213
AUpvsetval(pv, 1, &v);
11214
11215
track->f.compressionParams = pv;
11216
}
11217
break;
11218
11219
case WAVE_FORMAT_DVI_ADPCM:
11220
{
11221
uint16_t bitsPerSample, extraByteCount, samplesPerBlock;
11222
11223
readU16(&bitsPerSample);
11224
readU16(&extraByteCount);
11225
readU16(&samplesPerBlock);
11226
11227
if (bitsPerSample != 4)
11228
{
11229
_af_error(AF_BAD_NOT_IMPLEMENTED,
11230
"IMA ADPCM compression supports only 4 bits per sample");
11231
}
11232
11233
int bytesPerBlock = (samplesPerBlock + 14) / 8 * 4 * channelCount;
11234
if (bytesPerBlock > blockAlign || (samplesPerBlock % 8) != 1)
11235
{
11236
_af_error(AF_BAD_CODEC_CONFIG,
11237
"Invalid samples per block for IMA ADPCM compression");
11238
}
11239
11240
track->f.sampleWidth = 16;
11241
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11242
track->f.compressionType = AF_COMPRESSION_IMA;
11243
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
11244
11245
initIMACompressionParams();
11246
11247
track->f.framesPerPacket = samplesPerBlock;
11248
track->f.bytesPerPacket = blockAlign;
11249
}
11250
break;
11251
11252
case WAVE_FORMAT_EXTENSIBLE:
11253
{
11254
uint16_t bitsPerSample;
11255
readU16(&bitsPerSample);
11256
uint16_t extraByteCount;
11257
readU16(&extraByteCount);
11258
uint16_t reserved;
11259
readU16(&reserved);
11260
uint32_t channelMask;
11261
readU32(&channelMask);
11262
UUID subformat;
11263
readUUID(&subformat);
11264
if (subformat == _af_wave_guid_pcm)
11265
{
11266
track->f.sampleWidth = bitsPerSample;
11267
11268
if (bitsPerSample == 0 || bitsPerSample > 32)
11269
{
11270
_af_error(AF_BAD_WIDTH,
11271
"bad sample width of %d bits",
11272
bitsPerSample);
11273
return AF_FAIL;
11274
}
11275
11276
// Use valid bits per sample if bytes per sample is the same.
11277
if (reserved <= bitsPerSample &&
11278
(reserved + 7) / 8 == (bitsPerSample + 7) / 8)
11279
track->f.sampleWidth = reserved;
11280
11281
if (bitsPerSample <= 8)
11282
track->f.sampleFormat = AF_SAMPFMT_UNSIGNED;
11283
else
11284
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11285
}
11286
else if (subformat == _af_wave_guid_ieee_float)
11287
{
11288
if (bitsPerSample == 64)
11289
{
11290
track->f.sampleWidth = 64;
11291
track->f.sampleFormat = AF_SAMPFMT_DOUBLE;
11292
}
11293
else
11294
{
11295
track->f.sampleWidth = 32;
11296
track->f.sampleFormat = AF_SAMPFMT_FLOAT;
11297
}
11298
}
11299
else if (subformat == _af_wave_guid_alaw ||
11300
subformat == _af_wave_guid_ulaw)
11301
{
11302
track->f.compressionType = subformat == _af_wave_guid_alaw ?
11303
AF_COMPRESSION_G711_ALAW : AF_COMPRESSION_G711_ULAW;
11304
track->f.sampleWidth = 16;
11305
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11306
track->f.byteOrder = _AF_BYTEORDER_NATIVE;
11307
track->f.bytesPerPacket = channelCount;
11308
}
11309
else
11310
{
11311
_af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE extensible data format %s is not currently supported", subformat.name().c_str());
11312
return AF_FAIL;
11313
}
11314
}
11315
break;
11316
11317
case WAVE_FORMAT_YAMAHA_ADPCM:
11318
case WAVE_FORMAT_OKI_ADPCM:
11319
case WAVE_FORMAT_CREATIVE_ADPCM:
11320
case IBM_FORMAT_ADPCM:
11321
_af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE ADPCM data format 0x%x is not currently supported", formatTag);
11322
return AF_FAIL;
11323
break;
11324
11325
case WAVE_FORMAT_MPEG:
11326
_af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE MPEG data format is not supported");
11327
return AF_FAIL;
11328
break;
11329
11330
case WAVE_FORMAT_MPEGLAYER3:
11331
_af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE MPEG layer 3 data format is not supported");
11332
return AF_FAIL;
11333
break;
11334
11335
default:
11336
_af_error(AF_BAD_NOT_IMPLEMENTED, "WAVE file data format 0x%x not currently supported != 0xfffe ? %d, != EXTENSIBLE? %d", formatTag, formatTag != 0xfffe, formatTag != WAVE_FORMAT_EXTENSIBLE);
11337
return AF_FAIL;
11338
break;
11339
}
11340
11341
if (track->f.isUncompressed())
11342
track->f.computeBytesPerPacketPCM();
11343
11344
_af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth);
11345
11346
return AF_SUCCEED;
11347
}
11348
11349
status WAVEFile::parseData(const Tag &id, uint32_t size)
11350
{
11351
Track *track = getTrack();
11352
11353
track->fpos_first_frame = m_fh->tell();
11354
track->data_size = size;
11355
11356
return AF_SUCCEED;
11357
}
11358
11359
status WAVEFile::parsePlayList(const Tag &id, uint32_t size)
11360
{
11361
uint32_t segmentCount;
11362
readU32(&segmentCount);
11363
11364
if (segmentCount == 0)
11365
{
11366
m_instrumentCount = 0;
11367
m_instruments = NULL;
11368
return AF_SUCCEED;
11369
}
11370
11371
for (unsigned segment=0; segment<segmentCount; segment++)
11372
{
11373
uint32_t startMarkID, loopLength, loopCount;
11374
11375
readU32(&startMarkID);
11376
readU32(&loopLength);
11377
readU32(&loopCount);
11378
}
11379
11380
return AF_SUCCEED;
11381
}
11382
11383
status WAVEFile::parseCues(const Tag &id, uint32_t size)
11384
{
11385
Track *track = getTrack();
11386
11387
uint32_t markerCount;
11388
readU32(&markerCount);
11389
track->markerCount = markerCount;
11390
11391
if (markerCount == 0)
11392
{
11393
track->markers = NULL;
11394
return AF_SUCCEED;
11395
}
11396
11397
if ((track->markers = _af_marker_new(markerCount)) == NULL)
11398
return AF_FAIL;
11399
11400
for (unsigned i=0; i<markerCount; i++)
11401
{
11402
uint32_t id, position, chunkid;
11403
uint32_t chunkByteOffset, blockByteOffset;
11404
uint32_t sampleFrameOffset;
11405
Marker *marker = &track->markers[i];
11406
11407
readU32(&id);
11408
readU32(&position);
11409
readU32(&chunkid);
11410
readU32(&chunkByteOffset);
11411
readU32(&blockByteOffset);
11412
11413
/*
11414
sampleFrameOffset represents the position of
11415
the mark in units of frames.
11416
*/
11417
readU32(&sampleFrameOffset);
11418
11419
marker->id = id;
11420
marker->position = sampleFrameOffset;
11421
marker->name = _af_strdup("");
11422
marker->comment = _af_strdup("");
11423
}
11424
11425
return AF_SUCCEED;
11426
}
11427
11428
/* Parse an adtl sub-chunk within a LIST chunk. */
11429
status WAVEFile::parseADTLSubChunk(const Tag &id, uint32_t size)
11430
{
11431
Track *track = getTrack();
11432
11433
AFfileoffset endPos = m_fh->tell() + size;
11434
11435
while (m_fh->tell() < endPos)
11436
{
11437
Tag chunkID;
11438
uint32_t chunkSize;
11439
11440
readTag(&chunkID);
11441
readU32(&chunkSize);
11442
11443
if (chunkID == "labl" || chunkID == "note")
11444
{
11445
uint32_t id;
11446
long length=chunkSize-4;
11447
char *p = (char *) _af_malloc(length);
11448
11449
readU32(&id);
11450
m_fh->read(p, length);
11451
11452
Marker *marker = track->getMarker(id);
11453
11454
if (marker)
11455
{
11456
if (chunkID == "labl")
11457
{
11458
free(marker->name);
11459
marker->name = p;
11460
}
11461
else if (chunkID == "note")
11462
{
11463
free(marker->comment);
11464
marker->comment = p;
11465
}
11466
else
11467
free(p);
11468
}
11469
else
11470
free(p);
11471
11472
/*
11473
If chunkSize is odd, skip an extra byte
11474
at the end of the chunk.
11475
*/
11476
if ((chunkSize % 2) != 0)
11477
m_fh->seek(1, File::SeekFromCurrent);
11478
}
11479
else
11480
{
11481
/* If chunkSize is odd, skip an extra byte. */
11482
m_fh->seek(chunkSize + (chunkSize % 2), File::SeekFromCurrent);
11483
}
11484
}
11485
return AF_SUCCEED;
11486
}
11487
11488
/* Parse an INFO sub-chunk within a LIST chunk. */
11489
status WAVEFile::parseINFOSubChunk(const Tag &id, uint32_t size)
11490
{
11491
AFfileoffset endPos = m_fh->tell() + size;
11492
11493
while (m_fh->tell() < endPos)
11494
{
11495
int misctype = AF_MISC_UNRECOGNIZED;
11496
Tag miscid;
11497
uint32_t miscsize;
11498
11499
readTag(&miscid);
11500
readU32(&miscsize);
11501
11502
if (miscid == "IART")
11503
misctype = AF_MISC_AUTH;
11504
else if (miscid == "INAM")
11505
misctype = AF_MISC_NAME;
11506
else if (miscid == "ICOP")
11507
misctype = AF_MISC_COPY;
11508
else if (miscid == "ICMT")
11509
misctype = AF_MISC_ICMT;
11510
else if (miscid == "ICRD")
11511
misctype = AF_MISC_ICRD;
11512
else if (miscid == "ISFT")
11513
misctype = AF_MISC_ISFT;
11514
11515
if (misctype != AF_MISC_UNRECOGNIZED)
11516
{
11517
char *string = (char *) _af_malloc(miscsize);
11518
11519
m_fh->read(string, miscsize);
11520
11521
m_miscellaneousCount++;
11522
m_miscellaneous = (Miscellaneous *) _af_realloc(m_miscellaneous, sizeof (Miscellaneous) * m_miscellaneousCount);
11523
11524
m_miscellaneous[m_miscellaneousCount-1].id = m_miscellaneousCount;
11525
m_miscellaneous[m_miscellaneousCount-1].type = misctype;
11526
m_miscellaneous[m_miscellaneousCount-1].size = miscsize;
11527
m_miscellaneous[m_miscellaneousCount-1].position = 0;
11528
m_miscellaneous[m_miscellaneousCount-1].buffer = string;
11529
}
11530
else
11531
{
11532
m_fh->seek(miscsize, File::SeekFromCurrent);
11533
}
11534
11535
/* Make the current position an even number of bytes. */
11536
if (miscsize % 2 != 0)
11537
m_fh->seek(1, File::SeekFromCurrent);
11538
}
11539
return AF_SUCCEED;
11540
}
11541
11542
status WAVEFile::parseList(const Tag &id, uint32_t size)
11543
{
11544
Tag typeID;
11545
readTag(&typeID);
11546
size-=4;
11547
11548
if (typeID == "adtl")
11549
{
11550
/* Handle adtl sub-chunks. */
11551
return parseADTLSubChunk(typeID, size);
11552
}
11553
else if (typeID == "INFO")
11554
{
11555
/* Handle INFO sub-chunks. */
11556
return parseINFOSubChunk(typeID, size);
11557
}
11558
else
11559
{
11560
/* Skip unhandled sub-chunks. */
11561
m_fh->seek(size, File::SeekFromCurrent);
11562
return AF_SUCCEED;
11563
}
11564
return AF_SUCCEED;
11565
}
11566
11567
status WAVEFile::parseInstrument(const Tag &id, uint32_t size)
11568
{
11569
uint8_t baseNote;
11570
int8_t detune, gain;
11571
uint8_t lowNote, highNote, lowVelocity, highVelocity;
11572
uint8_t padByte;
11573
11574
readU8(&baseNote);
11575
readS8(&detune);
11576
readS8(&gain);
11577
readU8(&lowNote);
11578
readU8(&highNote);
11579
readU8(&lowVelocity);
11580
readU8(&highVelocity);
11581
readU8(&padByte);
11582
11583
return AF_SUCCEED;
11584
}
11585
11586
bool WAVEFile::recognize(File *fh)
11587
{
11588
uint8_t buffer[8];
11589
11590
fh->seek(0, File::SeekFromBeginning);
11591
11592
if (fh->read(buffer, 8) != 8 || memcmp(buffer, "RIFF", 4) != 0)
11593
return false;
11594
if (fh->read(buffer, 4) != 4 || memcmp(buffer, "WAVE", 4) != 0)
11595
return false;
11596
11597
return true;
11598
}
11599
11600
status WAVEFile::readInit(AFfilesetup setup)
11601
{
11602
Tag type, formtype;
11603
uint32_t size;
11604
uint32_t index = 0;
11605
11606
bool hasFormat = false;
11607
bool hasData = false;
11608
bool hasFrameCount = false;
11609
11610
Track *track = allocateTrack();
11611
11612
m_fh->seek(0, File::SeekFromBeginning);
11613
11614
readTag(&type);
11615
readU32(&size);
11616
readTag(&formtype);
11617
11618
assert(type == "RIFF");
11619
assert(formtype == "WAVE");
11620
11621
/* Include the offset of the form type. */
11622
index += 4;
11623
11624
while (index < size)
11625
{
11626
Tag chunkid;
11627
uint32_t chunksize = 0;
11628
status result;
11629
11630
readTag(&chunkid);
11631
readU32(&chunksize);
11632
11633
if (chunkid == "fmt ")
11634
{
11635
result = parseFormat(chunkid, chunksize);
11636
if (result == AF_FAIL)
11637
return AF_FAIL;
11638
11639
hasFormat = true;
11640
}
11641
else if (chunkid == "data")
11642
{
11643
/* The format chunk must precede the data chunk. */
11644
if (!hasFormat)
11645
{
11646
_af_error(AF_BAD_HEADER, "missing format chunk in WAVE file");
11647
return AF_FAIL;
11648
}
11649
11650
result = parseData(chunkid, chunksize);
11651
if (result == AF_FAIL)
11652
return AF_FAIL;
11653
11654
hasData = true;
11655
}
11656
else if (chunkid == "inst")
11657
{
11658
result = parseInstrument(chunkid, chunksize);
11659
if (result == AF_FAIL)
11660
return AF_FAIL;
11661
}
11662
else if (chunkid == "fact")
11663
{
11664
hasFrameCount = true;
11665
result = parseFrameCount(chunkid, chunksize);
11666
if (result == AF_FAIL)
11667
return AF_FAIL;
11668
}
11669
else if (chunkid == "cue ")
11670
{
11671
result = parseCues(chunkid, chunksize);
11672
if (result == AF_FAIL)
11673
return AF_FAIL;
11674
}
11675
else if (chunkid == "LIST" || chunkid == "list")
11676
{
11677
result = parseList(chunkid, chunksize);
11678
if (result == AF_FAIL)
11679
return AF_FAIL;
11680
}
11681
else if (chunkid == "INST")
11682
{
11683
result = parseInstrument(chunkid, chunksize);
11684
if (result == AF_FAIL)
11685
return AF_FAIL;
11686
}
11687
else if (chunkid == "plst")
11688
{
11689
result = parsePlayList(chunkid, chunksize);
11690
if (result == AF_FAIL)
11691
return AF_FAIL;
11692
}
11693
11694
index += chunksize + 8;
11695
11696
/* All chunks must be aligned on an even number of bytes */
11697
if ((index % 2) != 0)
11698
index++;
11699
11700
m_fh->seek(index + 8, File::SeekFromBeginning);
11701
}
11702
11703
/* The format chunk and the data chunk are required. */
11704
if (!hasFormat || !hasData)
11705
{
11706
return AF_FAIL;
11707
}
11708
11709
/*
11710
At this point we know that the file has a format chunk and a
11711
data chunk, so we can assume that track->f and track->data_size
11712
have been initialized.
11713
*/
11714
if (!hasFrameCount)
11715
{
11716
if (track->f.bytesPerPacket && track->f.framesPerPacket)
11717
{
11718
track->computeTotalFileFrames();
11719
}
11720
else
11721
{
11722
_af_error(AF_BAD_HEADER, "Frame count required but not found");
11723
return AF_FAIL;
11724
}
11725
}
11726
11727
return AF_SUCCEED;
11728
}
11729
11730
AFfilesetup WAVEFile::completeSetup(AFfilesetup setup)
11731
{
11732
if (setup->trackSet && setup->trackCount != 1)
11733
{
11734
_af_error(AF_BAD_NUMTRACKS, "WAVE file must have 1 track");
11735
return AF_NULL_FILESETUP;
11736
}
11737
11738
TrackSetup *track = setup->getTrack();
11739
if (!track)
11740
return AF_NULL_FILESETUP;
11741
11742
if (track->f.isCompressed())
11743
{
11744
if (!track->sampleFormatSet)
11745
_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, 16);
11746
else
11747
_af_set_sample_format(&track->f, track->f.sampleFormat, track->f.sampleWidth);
11748
}
11749
else if (track->sampleFormatSet)
11750
{
11751
switch (track->f.sampleFormat)
11752
{
11753
case AF_SAMPFMT_FLOAT:
11754
if (track->sampleWidthSet &&
11755
track->f.sampleWidth != 32)
11756
{
11757
_af_error(AF_BAD_WIDTH,
11758
"Warning: invalid sample width for floating-point WAVE file: %d (must be 32 bits)\n",
11759
track->f.sampleWidth);
11760
_af_set_sample_format(&track->f, AF_SAMPFMT_FLOAT, 32);
11761
}
11762
break;
11763
11764
case AF_SAMPFMT_DOUBLE:
11765
if (track->sampleWidthSet &&
11766
track->f.sampleWidth != 64)
11767
{
11768
_af_error(AF_BAD_WIDTH,
11769
"Warning: invalid sample width for double-precision floating-point WAVE file: %d (must be 64 bits)\n",
11770
track->f.sampleWidth);
11771
_af_set_sample_format(&track->f, AF_SAMPFMT_DOUBLE, 64);
11772
}
11773
break;
11774
11775
case AF_SAMPFMT_UNSIGNED:
11776
if (track->sampleWidthSet)
11777
{
11778
if (track->f.sampleWidth < 1 || track->f.sampleWidth > 32)
11779
{
11780
_af_error(AF_BAD_WIDTH, "invalid sample width for WAVE file: %d (must be 1-32 bits)\n", track->f.sampleWidth);
11781
return AF_NULL_FILESETUP;
11782
}
11783
if (track->f.sampleWidth > 8)
11784
{
11785
_af_error(AF_BAD_SAMPFMT, "WAVE integer data of more than 8 bits must be two's complement signed");
11786
_af_set_sample_format(&track->f, AF_SAMPFMT_TWOSCOMP, track->f.sampleWidth);
11787
}
11788
}
11789
else
11790
/*
11791
If the sample width is not set but the user requests
11792
unsigned data, set the width to 8 bits.
11793
*/
11794
_af_set_sample_format(&track->f, track->f.sampleFormat, 8);
11795
break;
11796
11797
case AF_SAMPFMT_TWOSCOMP:
11798
if (track->sampleWidthSet)
11799
{
11800
if (track->f.sampleWidth < 1 || track->f.sampleWidth > 32)
11801
{
11802
_af_error(AF_BAD_WIDTH, "invalid sample width %d for WAVE file (must be 1-32)", track->f.sampleWidth);
11803
return AF_NULL_FILESETUP;
11804
}
11805
else if (track->f.sampleWidth <= 8)
11806
{
11807
_af_error(AF_BAD_SAMPFMT, "Warning: WAVE format integer data of 1-8 bits must be unsigned; setting sample format to unsigned");
11808
_af_set_sample_format(&track->f, AF_SAMPFMT_UNSIGNED, track->f.sampleWidth);
11809
}
11810
}
11811
else
11812
/*
11813
If no sample width was specified, we default to 16 bits
11814
for signed integer data.
11815
*/
11816
_af_set_sample_format(&track->f, track->f.sampleFormat, 16);
11817
break;
11818
}
11819
}
11820
/*
11821
Otherwise set the sample format depending on the sample
11822
width or set completely to default.
11823
*/
11824
else
11825
{
11826
if (!track->sampleWidthSet)
11827
{
11828
track->f.sampleWidth = 16;
11829
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11830
}
11831
else
11832
{
11833
if (track->f.sampleWidth < 1 || track->f.sampleWidth > 32)
11834
{
11835
_af_error(AF_BAD_WIDTH, "invalid sample width %d for WAVE file (must be 1-32)", track->f.sampleWidth);
11836
return AF_NULL_FILESETUP;
11837
}
11838
else if (track->f.sampleWidth > 8)
11839
/* Here track->f.sampleWidth is in {1..32}. */
11840
track->f.sampleFormat = AF_SAMPFMT_TWOSCOMP;
11841
else
11842
/* Here track->f.sampleWidth is in {1..8}. */
11843
track->f.sampleFormat = AF_SAMPFMT_UNSIGNED;
11844
}
11845
}
11846
11847
if (track->f.compressionType != AF_COMPRESSION_NONE &&
11848
track->f.compressionType != AF_COMPRESSION_G711_ULAW &&
11849
track->f.compressionType != AF_COMPRESSION_G711_ALAW &&
11850
track->f.compressionType != AF_COMPRESSION_IMA &&
11851
track->f.compressionType != AF_COMPRESSION_MS_ADPCM)
11852
{
11853
_af_error(AF_BAD_NOT_IMPLEMENTED, "compression format not supported in WAVE format");
11854
return AF_NULL_FILESETUP;
11855
}
11856
11857
if (track->f.isUncompressed() &&
11858
track->byteOrderSet &&
11859
track->f.byteOrder != AF_BYTEORDER_LITTLEENDIAN &&
11860
track->f.isByteOrderSignificant())
11861
{
11862
_af_error(AF_BAD_BYTEORDER, "WAVE format only supports little-endian data");
11863
return AF_NULL_FILESETUP;
11864
}
11865
11866
if (track->f.isUncompressed())
11867
track->f.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
11868
11869
if (track->aesDataSet)
11870
{
11871
_af_error(AF_BAD_FILESETUP, "WAVE files cannot have AES data");
11872
return AF_NULL_FILESETUP;
11873
}
11874
11875
if (setup->instrumentSet)
11876
{
11877
if (setup->instrumentCount > 1)
11878
{
11879
_af_error(AF_BAD_NUMINSTS, "WAVE files can have 0 or 1 instrument");
11880
return AF_NULL_FILESETUP;
11881
}
11882
else if (setup->instrumentCount == 1)
11883
{
11884
if (setup->instruments[0].loopSet &&
11885
setup->instruments[0].loopCount > 0 &&
11886
(!track->markersSet || track->markerCount == 0))
11887
{
11888
_af_error(AF_BAD_NUMMARKS, "WAVE files with loops must contain at least 1 marker");
11889
return AF_NULL_FILESETUP;
11890
}
11891
}
11892
}
11893
11894
/* Make sure the miscellaneous data is of an acceptable type. */
11895
if (setup->miscellaneousSet)
11896
{
11897
for (int i=0; i<setup->miscellaneousCount; i++)
11898
{
11899
switch (setup->miscellaneous[i].type)
11900
{
11901
case AF_MISC_COPY:
11902
case AF_MISC_AUTH:
11903
case AF_MISC_NAME:
11904
case AF_MISC_ICRD:
11905
case AF_MISC_ISFT:
11906
case AF_MISC_ICMT:
11907
break;
11908
default:
11909
_af_error(AF_BAD_MISCTYPE, "illegal miscellaneous type [%d] for WAVE file", setup->miscellaneous[i].type);
11910
return AF_NULL_FILESETUP;
11911
}
11912
}
11913
}
11914
11915
/*
11916
Allocate an AFfilesetup and make all the unset fields correct.
11917
*/
11918
AFfilesetup newsetup = _af_filesetup_copy(setup, &waveDefaultFileSetup, false);
11919
11920
/* Make sure we do not copy loops if they are not specified in setup. */
11921
if (setup->instrumentSet && setup->instrumentCount > 0 &&
11922
setup->instruments[0].loopSet)
11923
{
11924
free(newsetup->instruments[0].loops);
11925
newsetup->instruments[0].loopCount = 0;
11926
}
11927
11928
return newsetup;
11929
}
11930
11931
bool WAVEFile::isInstrumentParameterValid(AUpvlist list, int i)
11932
{
11933
int param, type;
11934
11935
AUpvgetparam(list, i, &param);
11936
AUpvgetvaltype(list, i, &type);
11937
if (type != AU_PVTYPE_LONG)
11938
return false;
11939
11940
long lval;
11941
AUpvgetval(list, i, &lval);
11942
11943
switch (param)
11944
{
11945
case AF_INST_MIDI_BASENOTE:
11946
return ((lval >= 0) && (lval <= 127));
11947
11948
case AF_INST_NUMCENTS_DETUNE:
11949
return ((lval >= -50) && (lval <= 50));
11950
11951
case AF_INST_MIDI_LOVELOCITY:
11952
return ((lval >= 1) && (lval <= 127));
11953
11954
case AF_INST_MIDI_HIVELOCITY:
11955
return ((lval >= 1) && (lval <= 127));
11956
11957
case AF_INST_MIDI_LONOTE:
11958
return ((lval >= 0) && (lval <= 127));
11959
11960
case AF_INST_MIDI_HINOTE:
11961
return ((lval >= 0) && (lval <= 127));
11962
11963
case AF_INST_NUMDBS_GAIN:
11964
return true;
11965
11966
default:
11967
return false;
11968
}
11969
11970
return true;
11971
}
11972
11973
status WAVEFile::writeFormat()
11974
{
11975
uint16_t formatTag, channelCount;
11976
uint32_t sampleRate, averageBytesPerSecond;
11977
uint16_t blockAlign;
11978
uint32_t chunkSize;
11979
uint16_t bitsPerSample;
11980
11981
Track *track = getTrack();
11982
11983
m_fh->write("fmt ", 4);
11984
11985
switch (track->f.compressionType)
11986
{
11987
case AF_COMPRESSION_NONE:
11988
chunkSize = 16;
11989
if (track->f.sampleFormat == AF_SAMPFMT_FLOAT ||
11990
track->f.sampleFormat == AF_SAMPFMT_DOUBLE)
11991
{
11992
formatTag = WAVE_FORMAT_IEEE_FLOAT;
11993
}
11994
else if (track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP ||
11995
track->f.sampleFormat == AF_SAMPFMT_UNSIGNED)
11996
{
11997
formatTag = WAVE_FORMAT_PCM;
11998
}
11999
else
12000
{
12001
_af_error(AF_BAD_COMPTYPE, "bad sample format");
12002
return AF_FAIL;
12003
}
12004
12005
blockAlign = _af_format_frame_size(&track->f, false);
12006
bitsPerSample = 8 * _af_format_sample_size(&track->f, false);
12007
break;
12008
12009
/*
12010
G.711 compression uses eight bits per sample.
12011
*/
12012
case AF_COMPRESSION_G711_ULAW:
12013
chunkSize = 18;
12014
formatTag = IBM_FORMAT_MULAW;
12015
blockAlign = track->f.channelCount;
12016
bitsPerSample = 8;
12017
break;
12018
12019
case AF_COMPRESSION_G711_ALAW:
12020
chunkSize = 18;
12021
formatTag = IBM_FORMAT_ALAW;
12022
blockAlign = track->f.channelCount;
12023
bitsPerSample = 8;
12024
break;
12025
12026
case AF_COMPRESSION_IMA:
12027
chunkSize = 20;
12028
formatTag = WAVE_FORMAT_DVI_ADPCM;
12029
blockAlign = track->f.bytesPerPacket;
12030
bitsPerSample = 4;
12031
break;
12032
12033
case AF_COMPRESSION_MS_ADPCM:
12034
chunkSize = 50;
12035
formatTag = WAVE_FORMAT_ADPCM;
12036
blockAlign = track->f.bytesPerPacket;
12037
bitsPerSample = 4;
12038
break;
12039
12040
default:
12041
_af_error(AF_BAD_COMPTYPE, "bad compression type");
12042
return AF_FAIL;
12043
}
12044
12045
writeU32(&chunkSize);
12046
writeU16(&formatTag);
12047
12048
channelCount = track->f.channelCount;
12049
writeU16(&channelCount);
12050
12051
sampleRate = track->f.sampleRate;
12052
writeU32(&sampleRate);
12053
12054
averageBytesPerSecond =
12055
track->f.sampleRate * _af_format_frame_size(&track->f, false);
12056
if (track->f.compressionType == AF_COMPRESSION_IMA ||
12057
track->f.compressionType == AF_COMPRESSION_MS_ADPCM)
12058
averageBytesPerSecond = track->f.sampleRate * track->f.bytesPerPacket /
12059
track->f.framesPerPacket;
12060
writeU32(&averageBytesPerSecond);
12061
12062
writeU16(&blockAlign);
12063
12064
writeU16(&bitsPerSample);
12065
12066
if (track->f.compressionType == AF_COMPRESSION_G711_ULAW ||
12067
track->f.compressionType == AF_COMPRESSION_G711_ALAW)
12068
{
12069
uint16_t zero = 0;
12070
writeU16(&zero);
12071
}
12072
else if (track->f.compressionType == AF_COMPRESSION_IMA)
12073
{
12074
uint16_t extraByteCount = 2;
12075
writeU16(&extraByteCount);
12076
uint16_t samplesPerBlock = track->f.framesPerPacket;
12077
writeU16(&samplesPerBlock);
12078
}
12079
else if (track->f.compressionType == AF_COMPRESSION_MS_ADPCM)
12080
{
12081
uint16_t extraByteCount = 2 + 2 + m_msadpcmNumCoefficients * 4;
12082
writeU16(&extraByteCount);
12083
uint16_t samplesPerBlock = track->f.framesPerPacket;
12084
writeU16(&samplesPerBlock);
12085
12086
uint16_t numCoefficients = m_msadpcmNumCoefficients;
12087
writeU16(&numCoefficients);
12088
12089
for (int i=0; i<m_msadpcmNumCoefficients; i++)
12090
{
12091
writeS16(&m_msadpcmCoefficients[i][0]);
12092
writeS16(&m_msadpcmCoefficients[i][1]);
12093
}
12094
}
12095
12096
return AF_SUCCEED;
12097
}
12098
12099
status WAVEFile::writeFrameCount()
12100
{
12101
uint32_t factSize = 4;
12102
uint32_t totalFrameCount;
12103
12104
Track *track = getTrack();
12105
12106
/* Omit the fact chunk only for uncompressed integer audio formats. */
12107
if (track->f.compressionType == AF_COMPRESSION_NONE &&
12108
(track->f.sampleFormat == AF_SAMPFMT_TWOSCOMP ||
12109
track->f.sampleFormat == AF_SAMPFMT_UNSIGNED))
12110
return AF_SUCCEED;
12111
12112
/*
12113
If the offset for the fact chunk hasn't been set yet,
12114
set it to the file's current position.
12115
*/
12116
if (m_factOffset == 0)
12117
m_factOffset = m_fh->tell();
12118
else
12119
m_fh->seek(m_factOffset, File::SeekFromBeginning);
12120
12121
m_fh->write("fact", 4);
12122
writeU32(&factSize);
12123
12124
totalFrameCount = track->totalfframes;
12125
writeU32(&totalFrameCount);
12126
12127
return AF_SUCCEED;
12128
}
12129
12130
status WAVEFile::writeData()
12131
{
12132
Track *track = getTrack();
12133
12134
m_fh->write("data", 4);
12135
m_dataSizeOffset = m_fh->tell();
12136
12137
uint32_t chunkSize = track->data_size;
12138
12139
writeU32(&chunkSize);
12140
track->fpos_first_frame = m_fh->tell();
12141
12142
return AF_SUCCEED;
12143
}
12144
12145
status WAVEFile::update()
12146
{
12147
Track *track = getTrack();
12148
12149
if (track->fpos_first_frame != 0)
12150
{
12151
uint32_t dataLength, fileLength;
12152
12153
// Update the frame count chunk if present.
12154
writeFrameCount();
12155
12156
// Update the length of the data chunk.
12157
m_fh->seek(m_dataSizeOffset, File::SeekFromBeginning);
12158
dataLength = (uint32_t) track->data_size;
12159
writeU32(&dataLength);
12160
12161
// Update the length of the RIFF chunk.
12162
fileLength = (uint32_t) m_fh->length();
12163
fileLength -= 8;
12164
12165
m_fh->seek(4, File::SeekFromBeginning);
12166
writeU32(&fileLength);
12167
}
12168
12169
/*
12170
Write the actual data that was set after initializing
12171
the miscellaneous IDs. The size of the data will be
12172
unchanged.
12173
*/
12174
writeMiscellaneous();
12175
12176
// Write the new positions; the size of the data will be unchanged.
12177
writeCues();
12178
12179
return AF_SUCCEED;
12180
}
12181
12182
/* Convert an Audio File Library miscellaneous type to a WAVE type. */
12183
static bool misc_type_to_wave (int misctype, Tag *miscid)
12184
{
12185
if (misctype == AF_MISC_AUTH)
12186
*miscid = "IART";
12187
else if (misctype == AF_MISC_NAME)
12188
*miscid = "INAM";
12189
else if (misctype == AF_MISC_COPY)
12190
*miscid = "ICOP";
12191
else if (misctype == AF_MISC_ICMT)
12192
*miscid = "ICMT";
12193
else if (misctype == AF_MISC_ICRD)
12194
*miscid = "ICRD";
12195
else if (misctype == AF_MISC_ISFT)
12196
*miscid = "ISFT";
12197
else
12198
return false;
12199
12200
return true;
12201
}
12202
12203
status WAVEFile::writeMiscellaneous()
12204
{
12205
if (m_miscellaneousCount != 0)
12206
{
12207
uint32_t miscellaneousBytes;
12208
uint32_t chunkSize;
12209
12210
/* Start at 12 to account for 'LIST', size, and 'INFO'. */
12211
miscellaneousBytes = 12;
12212
12213
/* Then calculate the size of the whole INFO chunk. */
12214
for (int i=0; i<m_miscellaneousCount; i++)
12215
{
12216
Tag miscid;
12217
12218
// Skip miscellaneous data of an unsupported type.
12219
if (!misc_type_to_wave(m_miscellaneous[i].type, &miscid))
12220
continue;
12221
12222
// Account for miscellaneous type and size.
12223
miscellaneousBytes += 8;
12224
miscellaneousBytes += m_miscellaneous[i].size;
12225
12226
// Add a pad byte if necessary.
12227
if (m_miscellaneous[i].size % 2 != 0)
12228
miscellaneousBytes++;
12229
12230
assert(miscellaneousBytes % 2 == 0);
12231
}
12232
12233
if (m_miscellaneousOffset == 0)
12234
m_miscellaneousOffset = m_fh->tell();
12235
else
12236
m_fh->seek(m_miscellaneousOffset, File::SeekFromBeginning);
12237
12238
/*
12239
Write the data. On the first call to this
12240
function (from _af_wave_write_init), the
12241
data won't be available, fh->seek is used to
12242
reserve space until the data has been provided.
12243
On subseuent calls to this function (from
12244
_af_wave_update), the data will really be written.
12245
*/
12246
12247
/* Write 'LIST'. */
12248
m_fh->write("LIST", 4);
12249
12250
/* Write the size of the following chunk. */
12251
chunkSize = miscellaneousBytes-8;
12252
writeU32(&chunkSize);
12253
12254
/* Write 'INFO'. */
12255
m_fh->write("INFO", 4);
12256
12257
/* Write each miscellaneous chunk. */
12258
for (int i=0; i<m_miscellaneousCount; i++)
12259
{
12260
uint32_t miscsize = m_miscellaneous[i].size;
12261
Tag miscid;
12262
12263
// Skip miscellaneous data of an unsupported type.
12264
if (!misc_type_to_wave(m_miscellaneous[i].type, &miscid))
12265
continue;
12266
12267
writeTag(&miscid);
12268
writeU32(&miscsize);
12269
if (m_miscellaneous[i].buffer != NULL)
12270
{
12271
uint8_t zero = 0;
12272
12273
m_fh->write(m_miscellaneous[i].buffer, m_miscellaneous[i].size);
12274
12275
// Pad if necessary.
12276
if ((m_miscellaneous[i].size%2) != 0)
12277
writeU8(&zero);
12278
}
12279
else
12280
{
12281
int size;
12282
size = m_miscellaneous[i].size;
12283
12284
// Pad if necessary.
12285
if ((size % 2) != 0)
12286
size++;
12287
m_fh->seek(size, File::SeekFromCurrent);
12288
}
12289
}
12290
}
12291
12292
return AF_SUCCEED;
12293
}
12294
12295
status WAVEFile::writeCues()
12296
{
12297
Track *track = getTrack();
12298
12299
if (!track->markerCount)
12300
return AF_SUCCEED;
12301
12302
if (m_markOffset == 0)
12303
m_markOffset = m_fh->tell();
12304
else
12305
m_fh->seek(m_markOffset, File::SeekFromBeginning);
12306
12307
Tag cue("cue ");
12308
writeTag(&cue);
12309
12310
/*
12311
The cue chunk consists of 4 bytes for the number of cue points
12312
followed by 24 bytes for each cue point record.
12313
*/
12314
uint32_t cueChunkSize = 4 + track->markerCount * 24;
12315
writeU32(&cueChunkSize);
12316
uint32_t numCues = track->markerCount;
12317
writeU32(&numCues);
12318
12319
// Write each marker to the file.
12320
for (int i=0; i<track->markerCount; i++)
12321
{
12322
uint32_t identifier = track->markers[i].id;
12323
writeU32(&identifier);
12324
12325
uint32_t position = i;
12326
writeU32(&position);
12327
12328
Tag data("data");
12329
writeTag(&data);
12330
12331
/*
12332
For an uncompressed WAVE file which contains only one data chunk,
12333
chunkStart and blockStart are zero.
12334
*/
12335
uint32_t chunkStart = 0;
12336
writeU32(&chunkStart);
12337
12338
uint32_t blockStart = 0;
12339
writeU32(&blockStart);
12340
12341
AFframecount markPosition = track->markers[i].position;
12342
uint32_t sampleOffset = markPosition;
12343
writeU32(&sampleOffset);
12344
}
12345
12346
// Now write the cue names and comments within a master list chunk.
12347
uint32_t listChunkSize = 4;
12348
for (int i=0; i<track->markerCount; i++)
12349
{
12350
const char *name = track->markers[i].name;
12351
const char *comment = track->markers[i].comment;
12352
12353
/*
12354
Each 'labl' or 'note' chunk consists of 4 bytes for the chunk ID,
12355
4 bytes for the chunk data size, 4 bytes for the cue point ID,
12356
and then the length of the label as a null-terminated string.
12357
12358
In all, this is 12 bytes plus the length of the string, its null
12359
termination byte, and a trailing pad byte if the length of the
12360
chunk is otherwise odd.
12361
*/
12362
listChunkSize += 12 + zStringLength(name);
12363
listChunkSize += 12 + zStringLength(comment);
12364
}
12365
12366
Tag list("LIST");
12367
writeTag(&list);
12368
writeU32(&listChunkSize);
12369
Tag adtl("adtl");
12370
writeTag(&adtl);
12371
12372
for (int i=0; i<track->markerCount; i++)
12373
{
12374
uint32_t cuePointID = track->markers[i].id;
12375
12376
const char *name = track->markers[i].name;
12377
uint32_t labelSize = 4 + zStringLength(name);
12378
Tag lablTag("labl");
12379
writeTag(&lablTag);
12380
writeU32(&labelSize);
12381
writeU32(&cuePointID);
12382
writeZString(name);
12383
12384
const char *comment = track->markers[i].comment;
12385
uint32_t noteSize = 4 + zStringLength(comment);
12386
Tag noteTag("note");
12387
writeTag(&noteTag);
12388
writeU32(&noteSize);
12389
writeU32(&cuePointID);
12390
writeZString(comment);
12391
}
12392
12393
return AF_SUCCEED;
12394
}
12395
12396
bool WAVEFile::writeZString(const char *s)
12397
{
12398
ssize_t lengthPlusNull = strlen(s) + 1;
12399
if (m_fh->write(s, lengthPlusNull) != lengthPlusNull)
12400
return false;
12401
if (lengthPlusNull & 1)
12402
{
12403
uint8_t zero = 0;
12404
if (!writeU8(&zero))
12405
return false;
12406
}
12407
return true;
12408
}
12409
12410
size_t WAVEFile::zStringLength(const char *s)
12411
{
12412
size_t lengthPlusNull = strlen(s) + 1;
12413
return lengthPlusNull + (lengthPlusNull & 1);
12414
}
12415
12416
status WAVEFile::writeInit(AFfilesetup setup)
12417
{
12418
if (initFromSetup(setup) == AF_FAIL)
12419
return AF_FAIL;
12420
12421
initCompressionParams();
12422
12423
uint32_t zero = 0;
12424
12425
m_fh->seek(0, File::SeekFromBeginning);
12426
m_fh->write("RIFF", 4);
12427
m_fh->write(&zero, 4);
12428
m_fh->write("WAVE", 4);
12429
12430
writeMiscellaneous();
12431
writeCues();
12432
writeFormat();
12433
writeFrameCount();
12434
writeData();
12435
12436
return AF_SUCCEED;
12437
}
12438
12439
bool WAVEFile::readUUID(UUID *u)
12440
{
12441
return m_fh->read(u->data, 16) == 16;
12442
}
12443
12444
bool WAVEFile::writeUUID(const UUID *u)
12445
{
12446
return m_fh->write(u->data, 16) == 16;
12447
}
12448
12449
void WAVEFile::initCompressionParams()
12450
{
12451
Track *track = getTrack();
12452
if (track->f.compressionType == AF_COMPRESSION_IMA)
12453
initIMACompressionParams();
12454
else if (track->f.compressionType == AF_COMPRESSION_MS_ADPCM)
12455
initMSADPCMCompressionParams();
12456
}
12457
12458
void WAVEFile::initIMACompressionParams()
12459
{
12460
Track *track = getTrack();
12461
12462
track->f.framesPerPacket = 505;
12463
track->f.bytesPerPacket = 256 * track->f.channelCount;
12464
12465
AUpvlist pv = AUpvnew(1);
12466
AUpvsetparam(pv, 0, _AF_IMA_ADPCM_TYPE);
12467
AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG);
12468
long l = _AF_IMA_ADPCM_TYPE_WAVE;
12469
AUpvsetval(pv, 0, &l);
12470
12471
track->f.compressionParams = pv;
12472
}
12473
12474
void WAVEFile::initMSADPCMCompressionParams()
12475
{
12476
const int16_t coefficients[7][2] =
12477
{
12478
{ 256, 0 },
12479
{ 512, -256 },
12480
{ 0, 0 },
12481
{ 192, 64 },
12482
{ 240, 0 },
12483
{ 460, -208 },
12484
{ 392, -232 }
12485
};
12486
memcpy(m_msadpcmCoefficients, coefficients, sizeof (int16_t) * 7 * 2);
12487
m_msadpcmNumCoefficients = 7;
12488
12489
Track *track = getTrack();
12490
12491
track->f.framesPerPacket = 500;
12492
track->f.bytesPerPacket = 256 * track->f.channelCount;
12493
12494
AUpvlist pv = AUpvnew(2);
12495
AUpvsetparam(pv, 0, _AF_MS_ADPCM_NUM_COEFFICIENTS);
12496
AUpvsetvaltype(pv, 0, AU_PVTYPE_LONG);
12497
long l = m_msadpcmNumCoefficients;
12498
AUpvsetval(pv, 0, &l);
12499
12500
AUpvsetparam(pv, 1, _AF_MS_ADPCM_COEFFICIENTS);
12501
AUpvsetvaltype(pv, 1, AU_PVTYPE_PTR);
12502
void *v = m_msadpcmCoefficients;
12503
AUpvsetval(pv, 1, &v);
12504
12505
track->f.compressionParams = pv;
12506
}
12507
12508
// file: aes.cpp
12509
/*
12510
Audio File Library
12511
Copyright (C) 1998-1999, Michael Pruett <[email protected]>
12512
Copyright (C) 2000, Silicon Graphics, Inc.
12513
12514
This library is free software; you can redistribute it and/or
12515
modify it under the terms of the GNU Lesser General Public
12516
License as published by the Free Software Foundation; either
12517
version 2.1 of the License, or (at your option) any later version.
12518
12519
This library is distributed in the hope that it will be useful,
12520
but WITHOUT ANY WARRANTY; without even the implied warranty of
12521
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12522
Lesser General Public License for more details.
12523
12524
You should have received a copy of the GNU Lesser General Public
12525
License along with this library; if not, write to the
12526
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12527
Boston, MA 02110-1301 USA
12528
*/
12529
12530
/*
12531
aes.c
12532
12533
This file contains routines for dealing with AES recording data.
12534
*/
12535
12536
12537
#include <string.h>
12538
#include <assert.h>
12539
12540
12541
void afInitAESChannelData (AFfilesetup setup, int trackid)
12542
{
12543
if (!_af_filesetup_ok(setup))
12544
return;
12545
12546
TrackSetup *track = setup->getTrack(trackid);
12547
if (!track)
12548
return;
12549
12550
track->aesDataSet = true;
12551
}
12552
12553
void afInitAESChannelDataTo (AFfilesetup setup, int trackid, int willBeData)
12554
{
12555
if (!_af_filesetup_ok(setup))
12556
return;
12557
12558
TrackSetup *track = setup->getTrack(trackid);
12559
if (!track)
12560
return;
12561
12562
track->aesDataSet = willBeData;
12563
}
12564
12565
int afGetAESChannelData (AFfilehandle file, int trackid, unsigned char buf[24])
12566
{
12567
if (!_af_filehandle_ok(file))
12568
return -1;
12569
12570
Track *track = file->getTrack(trackid);
12571
if (!track)
12572
return -1;
12573
12574
if (!track->hasAESData)
12575
{
12576
if (buf)
12577
memset(buf, 0, 24);
12578
return 0;
12579
}
12580
12581
if (buf)
12582
memcpy(buf, track->aesData, 24);
12583
12584
return 1;
12585
}
12586
12587
void afSetAESChannelData (AFfilehandle file, int trackid, unsigned char buf[24])
12588
{
12589
if (!_af_filehandle_ok(file))
12590
return;
12591
12592
Track *track = file->getTrack(trackid);
12593
if (!track)
12594
return;
12595
12596
if (!file->checkCanWrite())
12597
return;
12598
12599
if (track->hasAESData)
12600
{
12601
memcpy(track->aesData, buf, 24);
12602
}
12603
else
12604
{
12605
_af_error(AF_BAD_NOAESDATA,
12606
"unable to store AES channel status data for track %d",
12607
trackid);
12608
}
12609
}
12610
12611
// file: af_vfs.cpp
12612
/*
12613
Audio File Library
12614
Copyright (C) 1999, Elliot Lee <[email protected]>
12615
12616
This library is free software; you can redistribute it and/or
12617
modify it under the terms of the GNU Lesser General Public
12618
License as published by the Free Software Foundation; either
12619
version 2.1 of the License, or (at your option) any later version.
12620
12621
This library is distributed in the hope that it will be useful,
12622
but WITHOUT ANY WARRANTY; without even the implied warranty of
12623
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12624
Lesser General Public License for more details.
12625
12626
You should have received a copy of the GNU Lesser General Public
12627
License along with this library; if not, write to the
12628
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12629
Boston, MA 02110-1301 USA
12630
*/
12631
12632
/*
12633
af_vfs.cpp
12634
12635
Virtual file operations for the Audio File Library.
12636
*/
12637
12638
12639
12640
#include <stdlib.h>
12641
12642
AFvirtualfile *af_virtual_file_new()
12643
{
12644
return (AFvirtualfile *) calloc(sizeof (AFvirtualfile), 1);
12645
}
12646
12647
void af_virtual_file_destroy(AFvirtualfile *vfile)
12648
{
12649
vfile->destroy(vfile);
12650
12651
free(vfile);
12652
}
12653
12654
// file: aupv.c
12655
/*
12656
Audio File Library
12657
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
12658
12659
This library is free software; you can redistribute it and/or
12660
modify it under the terms of the GNU Lesser General Public
12661
License as published by the Free Software Foundation; either
12662
version 2.1 of the License, or (at your option) any later version.
12663
12664
This library is distributed in the hope that it will be useful,
12665
but WITHOUT ANY WARRANTY; without even the implied warranty of
12666
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12667
Lesser General Public License for more details.
12668
12669
You should have received a copy of the GNU Lesser General Public
12670
License along with this library; if not, write to the
12671
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12672
Boston, MA 02110-1301 USA
12673
*/
12674
12675
/*
12676
aupv.c
12677
12678
This file contains an implementation of SGI's Audio Library parameter
12679
value list functions.
12680
*/
12681
12682
12683
#include <stdlib.h>
12684
#include <string.h>
12685
#include <assert.h>
12686
12687
12688
AUpvlist AUpvnew (int maxitems)
12689
{
12690
AUpvlist aupvlist;
12691
int i;
12692
12693
if (maxitems <= 0)
12694
return AU_NULL_PVLIST;
12695
12696
aupvlist = (AUpvlist) malloc(sizeof (struct _AUpvlist));
12697
assert(aupvlist);
12698
if (aupvlist == NULL)
12699
return AU_NULL_PVLIST;
12700
12701
aupvlist->items = (struct _AUpvitem *)calloc(maxitems, sizeof (struct _AUpvitem));
12702
12703
assert(aupvlist->items);
12704
if (aupvlist->items == NULL)
12705
{
12706
free(aupvlist);
12707
return AU_NULL_PVLIST;
12708
}
12709
12710
/* Initialize the items in the list. */
12711
for (i=0; i<maxitems; i++)
12712
{
12713
aupvlist->items[i].valid = _AU_VALID_PVITEM;
12714
aupvlist->items[i].type = AU_PVTYPE_LONG;
12715
aupvlist->items[i].parameter = 0;
12716
memset(&aupvlist->items[i].value, 0, sizeof (aupvlist->items[i].value));
12717
}
12718
12719
aupvlist->valid = _AU_VALID_PVLIST;
12720
aupvlist->count = maxitems;
12721
12722
return aupvlist;
12723
}
12724
12725
int AUpvgetmaxitems (AUpvlist list)
12726
{
12727
assert(list);
12728
12729
if (list == AU_NULL_PVLIST)
12730
return AU_BAD_PVLIST;
12731
if (list->valid != _AU_VALID_PVLIST)
12732
return AU_BAD_PVLIST;
12733
12734
return list->count;
12735
}
12736
12737
int AUpvfree (AUpvlist list)
12738
{
12739
assert(list);
12740
assert(list->items);
12741
12742
if (list == AU_NULL_PVLIST)
12743
return AU_BAD_PVLIST;
12744
if (list->valid != _AU_VALID_PVLIST)
12745
return AU_BAD_PVLIST;
12746
12747
if ((list->items != _AU_NULL_PVITEM) &&
12748
(list->items[0].valid == _AU_VALID_PVITEM))
12749
{
12750
free(list->items);
12751
}
12752
12753
free(list);
12754
12755
return _AU_SUCCESS;
12756
}
12757
12758
int AUpvsetparam (AUpvlist list, int item, int param)
12759
{
12760
assert(list);
12761
assert(list->items);
12762
assert(item >= 0);
12763
assert(item < list->count);
12764
12765
if (list == AU_NULL_PVLIST)
12766
return AU_BAD_PVLIST;
12767
if (list->valid != _AU_VALID_PVLIST)
12768
return AU_BAD_PVLIST;
12769
if ((item < 0) || (item > list->count - 1))
12770
return AU_BAD_PVITEM;
12771
if (list->items[item].valid != _AU_VALID_PVITEM)
12772
return AU_BAD_PVLIST;
12773
12774
list->items[item].parameter = param;
12775
return _AU_SUCCESS;
12776
}
12777
12778
int AUpvsetvaltype (AUpvlist list, int item, int type)
12779
{
12780
assert(list);
12781
assert(list->items);
12782
assert(item >= 0);
12783
assert(item < list->count);
12784
12785
if (list == AU_NULL_PVLIST)
12786
return AU_BAD_PVLIST;
12787
if (list->valid != _AU_VALID_PVLIST)
12788
return AU_BAD_PVLIST;
12789
if ((item < 0) || (item > list->count - 1))
12790
return AU_BAD_PVITEM;
12791
if (list->items[item].valid != _AU_VALID_PVITEM)
12792
return AU_BAD_PVLIST;
12793
12794
list->items[item].type = type;
12795
return _AU_SUCCESS;
12796
}
12797
12798
int AUpvsetval (AUpvlist list, int item, void *val)
12799
{
12800
assert(list);
12801
assert(list->items);
12802
assert(item >= 0);
12803
assert(item < list->count);
12804
12805
if (list == AU_NULL_PVLIST)
12806
return AU_BAD_PVLIST;
12807
if (list->valid != _AU_VALID_PVLIST)
12808
return AU_BAD_PVLIST;
12809
if ((item < 0) || (item > list->count - 1))
12810
return AU_BAD_PVITEM;
12811
if (list->items[item].valid != _AU_VALID_PVITEM)
12812
return AU_BAD_PVLIST;
12813
12814
switch (list->items[item].type)
12815
{
12816
case AU_PVTYPE_LONG:
12817
list->items[item].value.l = *((long *) val);
12818
break;
12819
case AU_PVTYPE_DOUBLE:
12820
list->items[item].value.d = *((double *) val);
12821
break;
12822
case AU_PVTYPE_PTR:
12823
list->items[item].value.v = *((void **) val);
12824
break;
12825
default:
12826
assert(0);
12827
return AU_BAD_PVLIST;
12828
}
12829
12830
return _AU_SUCCESS;
12831
}
12832
12833
int AUpvgetparam (AUpvlist list, int item, int *param)
12834
{
12835
assert(list);
12836
assert(list->items);
12837
assert(item >= 0);
12838
assert(item < list->count);
12839
12840
if (list == AU_NULL_PVLIST)
12841
return AU_BAD_PVLIST;
12842
if (list->valid != _AU_VALID_PVLIST)
12843
return AU_BAD_PVLIST;
12844
if ((item < 0) || (item > list->count - 1))
12845
return AU_BAD_PVITEM;
12846
if (list->items[item].valid != _AU_VALID_PVITEM)
12847
return AU_BAD_PVLIST;
12848
12849
*param = list->items[item].parameter;
12850
return _AU_SUCCESS;
12851
}
12852
12853
int AUpvgetvaltype (AUpvlist list, int item, int *type)
12854
{
12855
assert(list);
12856
assert(list->items);
12857
assert(item >= 0);
12858
assert(item < list->count);
12859
12860
if (list == AU_NULL_PVLIST)
12861
return AU_BAD_PVLIST;
12862
if (list->valid != _AU_VALID_PVLIST)
12863
return AU_BAD_PVLIST;
12864
if ((item < 0) || (item > list->count - 1))
12865
return AU_BAD_PVITEM;
12866
if (list->items[item].valid != _AU_VALID_PVITEM)
12867
return AU_BAD_PVLIST;
12868
12869
*type = list->items[item].type;
12870
return _AU_SUCCESS;
12871
}
12872
12873
int AUpvgetval (AUpvlist list, int item, void *val)
12874
{
12875
assert(list);
12876
assert(list->items);
12877
assert(item >= 0);
12878
assert(item < list->count);
12879
12880
if (list == AU_NULL_PVLIST)
12881
return AU_BAD_PVLIST;
12882
if (list->valid != _AU_VALID_PVLIST)
12883
return AU_BAD_PVLIST;
12884
if ((item < 0) || (item > list->count - 1))
12885
return AU_BAD_PVITEM;
12886
if (list->items[item].valid != _AU_VALID_PVITEM)
12887
return AU_BAD_PVLIST;
12888
12889
switch (list->items[item].type)
12890
{
12891
case AU_PVTYPE_LONG:
12892
*((long *) val) = list->items[item].value.l;
12893
break;
12894
case AU_PVTYPE_DOUBLE:
12895
*((double *) val) = list->items[item].value.d;
12896
break;
12897
case AU_PVTYPE_PTR:
12898
*((void **) val) = list->items[item].value.v;
12899
break;
12900
}
12901
12902
return _AU_SUCCESS;
12903
}
12904
12905
// file: compression.cpp
12906
/*
12907
Audio File Library
12908
Copyright (C) 1999-2000, Michael Pruett <[email protected]>
12909
Copyright (C) 2000, Silicon Graphics, Inc.
12910
12911
This library is free software; you can redistribute it and/or
12912
modify it under the terms of the GNU Lesser General Public
12913
License as published by the Free Software Foundation; either
12914
version 2.1 of the License, or (at your option) any later version.
12915
12916
This library is distributed in the hope that it will be useful,
12917
but WITHOUT ANY WARRANTY; without even the implied warranty of
12918
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12919
Lesser General Public License for more details.
12920
12921
You should have received a copy of the GNU Lesser General Public
12922
License along with this library; if not, write to the
12923
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12924
Boston, MA 02110-1301 USA
12925
*/
12926
12927
/*
12928
compression.cpp
12929
12930
This file contains routines for configuring compressed audio.
12931
*/
12932
12933
12934
#include <assert.h>
12935
12936
12937
const CompressionUnit *_af_compression_unit_from_id (int compressionid)
12938
{
12939
for (int i=0; i<_AF_NUM_COMPRESSION; i++)
12940
if (_af_compression[i].compressionID == compressionid)
12941
return &_af_compression[i];
12942
12943
_af_error(AF_BAD_COMPTYPE, "compression type %d not available", compressionid);
12944
return NULL;
12945
}
12946
12947
int afGetCompression (AFfilehandle file, int trackid)
12948
{
12949
if (!_af_filehandle_ok(file))
12950
return -1;
12951
12952
Track *track = file->getTrack(trackid);
12953
if (!track)
12954
return -1;
12955
12956
return track->f.compressionType;
12957
}
12958
12959
void afInitCompression (AFfilesetup setup, int trackid, int compression)
12960
{
12961
if (!_af_filesetup_ok(setup))
12962
return;
12963
12964
TrackSetup *track = setup->getTrack(trackid);
12965
if (!track)
12966
return;
12967
12968
if (!_af_compression_unit_from_id(compression))
12969
return;
12970
12971
track->compressionSet = true;
12972
track->f.compressionType = compression;
12973
}
12974
12975
#if 0
12976
int afGetCompressionParams (AFfilehandle file, int trackid,
12977
int *compression, AUpvlist pvlist, int numitems)
12978
{
12979
assert(file);
12980
assert(trackid == AF_DEFAULT_TRACK);
12981
}
12982
12983
void afInitCompressionParams (AFfilesetup setup, int trackid,
12984
int compression, AUpvlist pvlist, int numitems)
12985
{
12986
assert(setup);
12987
assert(trackid == AF_DEFAULT_TRACK);
12988
}
12989
#endif
12990
12991
// file: data.cpp
12992
/*
12993
Audio File Library
12994
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
12995
Copyright (C) 2000, Silicon Graphics, Inc.
12996
12997
This library is free software; you can redistribute it and/or
12998
modify it under the terms of the GNU Lesser General Public
12999
License as published by the Free Software Foundation; either
13000
version 2.1 of the License, or (at your option) any later version.
13001
13002
This library is distributed in the hope that it will be useful,
13003
but WITHOUT ANY WARRANTY; without even the implied warranty of
13004
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13005
Lesser General Public License for more details.
13006
13007
You should have received a copy of the GNU Lesser General Public
13008
License along with this library; if not, write to the
13009
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
13010
Boston, MA 02110-1301 USA
13011
*/
13012
13013
/*
13014
data.cpp
13015
*/
13016
13017
13018
#include <assert.h>
13019
#include <stdlib.h>
13020
#include <string.h>
13021
13022
13023
int afWriteFrames (AFfilehandle file, int trackid, const void *samples,
13024
int nvframes2write)
13025
{
13026
SharedPtr<Module> firstmod;
13027
SharedPtr<Chunk> userc;
13028
int bytes_per_vframe;
13029
AFframecount vframe;
13030
13031
if (!_af_filehandle_ok(file))
13032
return -1;
13033
13034
if (!file->checkCanWrite())
13035
return -1;
13036
13037
Track *track = file->getTrack(trackid);
13038
if (!track)
13039
return -1;
13040
13041
if (track->ms->isDirty() && track->ms->setup(file, track) == AF_FAIL)
13042
return -1;
13043
13044
if (!track->ms->fileModuleHandlesSeeking() &&
13045
file->m_seekok &&
13046
file->m_fh->seek(track->fpos_next_frame, File::SeekFromBeginning) !=
13047
track->fpos_next_frame)
13048
{
13049
_af_error(AF_BAD_LSEEK, "unable to position write pointer at next frame");
13050
return -1;
13051
}
13052
13053
bytes_per_vframe = _af_format_frame_size(&track->v, true);
13054
13055
firstmod = track->ms->modules().front();
13056
userc = track->ms->chunks().front();
13057
13058
track->filemodhappy = true;
13059
13060
vframe = 0;
13061
#ifdef UNLIMITED_CHUNK_NVFRAMES
13062
/*
13063
OPTIMIZATION: see the comment at the very end of
13064
arrangemodules() in modules.c for an explanation of this:
13065
*/
13066
if (!trk->ms->mustUseAtomicNVFrames())
13067
{
13068
userc->buffer = (char *) samples;
13069
userc->frameCount = nvframes2write;
13070
13071
firstmod->runPush();
13072
13073
/* Count this chunk if there was no i/o error. */
13074
if (trk->filemodhappy)
13075
vframe += userc->frameCount;
13076
}
13077
else
13078
#else
13079
/* Optimization must be off. */
13080
assert(track->ms->mustUseAtomicNVFrames());
13081
#endif
13082
{
13083
while (vframe < nvframes2write)
13084
{
13085
userc->buffer = (char *) samples + bytes_per_vframe * vframe;
13086
if (vframe <= nvframes2write - _AF_ATOMIC_NVFRAMES)
13087
userc->frameCount = _AF_ATOMIC_NVFRAMES;
13088
else
13089
userc->frameCount = nvframes2write - vframe;
13090
13091
firstmod->runPush();
13092
13093
if (!track->filemodhappy)
13094
break;
13095
13096
vframe += userc->frameCount;
13097
}
13098
}
13099
13100
track->nextvframe += vframe;
13101
track->totalvframes += vframe;
13102
13103
return vframe;
13104
}
13105
13106
int afReadFrames (AFfilehandle file, int trackid, void *samples,
13107
int nvframeswanted)
13108
{
13109
SharedPtr<Module> firstmod;
13110
SharedPtr<Chunk> userc;
13111
AFframecount nvframesleft, nvframes2read;
13112
int bytes_per_vframe;
13113
AFframecount vframe;
13114
13115
if (!_af_filehandle_ok(file))
13116
return -1;
13117
13118
if (!file->checkCanRead())
13119
return -1;
13120
13121
Track *track = file->getTrack(trackid);
13122
if (!track)
13123
return -1;
13124
13125
if (track->ms->isDirty() && track->ms->setup(file, track) == AF_FAIL)
13126
return -1;
13127
13128
if (!track->ms->fileModuleHandlesSeeking() &&
13129
file->m_seekok &&
13130
file->m_fh->seek(track->fpos_next_frame, File::SeekFromBeginning) !=
13131
track->fpos_next_frame)
13132
{
13133
_af_error(AF_BAD_LSEEK, "unable to position read pointer at next frame");
13134
return -1;
13135
}
13136
13137
if (track->totalvframes == -1)
13138
nvframes2read = nvframeswanted;
13139
else
13140
{
13141
nvframesleft = track->totalvframes - track->nextvframe;
13142
nvframes2read = (nvframeswanted > nvframesleft) ?
13143
nvframesleft : nvframeswanted;
13144
}
13145
bytes_per_vframe = _af_format_frame_size(&track->v, true);
13146
13147
firstmod = track->ms->modules().back();
13148
userc = track->ms->chunks().back();
13149
13150
track->filemodhappy = true;
13151
13152
vframe = 0;
13153
13154
if (!track->ms->mustUseAtomicNVFrames())
13155
{
13156
assert(track->frames2ignore == 0);
13157
userc->buffer = samples;
13158
userc->frameCount = nvframes2read;
13159
13160
firstmod->runPull();
13161
if (track->filemodhappy)
13162
vframe += userc->frameCount;
13163
}
13164
else
13165
{
13166
bool eof = false;
13167
13168
if (track->frames2ignore != 0)
13169
{
13170
userc->frameCount = track->frames2ignore;
13171
userc->allocate(track->frames2ignore * bytes_per_vframe);
13172
if (!userc->buffer)
13173
return 0;
13174
13175
firstmod->runPull();
13176
13177
/* Have we hit EOF? */
13178
if (static_cast<ssize_t>(userc->frameCount) < track->frames2ignore)
13179
eof = true;
13180
13181
track->frames2ignore = 0;
13182
13183
userc->deallocate();
13184
}
13185
13186
/*
13187
Now start reading useful frames, until EOF or
13188
premature EOF.
13189
*/
13190
13191
while (track->filemodhappy && !eof && vframe < nvframes2read)
13192
{
13193
AFframecount nvframes2pull;
13194
userc->buffer = (char *) samples + bytes_per_vframe * vframe;
13195
13196
if (vframe <= nvframes2read - _AF_ATOMIC_NVFRAMES)
13197
nvframes2pull = _AF_ATOMIC_NVFRAMES;
13198
else
13199
nvframes2pull = nvframes2read - vframe;
13200
13201
userc->frameCount = nvframes2pull;
13202
13203
firstmod->runPull();
13204
13205
if (track->filemodhappy)
13206
{
13207
vframe += userc->frameCount;
13208
if (static_cast<ssize_t>(userc->frameCount) < nvframes2pull)
13209
eof = true;
13210
}
13211
}
13212
}
13213
13214
track->nextvframe += vframe;
13215
13216
return vframe;
13217
}
13218
13219
// file: debug.cpp
13220
/*
13221
Audio File Library
13222
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
13223
Copyright (C) 2000, Silicon Graphics, Inc.
13224
13225
This library is free software; you can redistribute it and/or
13226
modify it under the terms of the GNU Lesser General Public
13227
License as published by the Free Software Foundation; either
13228
version 2.1 of the License, or (at your option) any later version.
13229
13230
This library is distributed in the hope that it will be useful,
13231
but WITHOUT ANY WARRANTY; without even the implied warranty of
13232
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13233
Lesser General Public License for more details.
13234
13235
You should have received a copy of the GNU Lesser General Public
13236
License along with this library; if not, write to the
13237
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
13238
Boston, MA 02110-1301 USA
13239
*/
13240
13241
/*
13242
debug.cpp
13243
13244
This file contains debugging routines for the Audio File
13245
Library.
13246
*/
13247
13248
13249
#include <stdio.h>
13250
#include <stdlib.h>
13251
#include <math.h>
13252
#include <string.h>
13253
#include <assert.h>
13254
13255
13256
13257
void _af_print_pvlist (AUpvlist list)
13258
{
13259
assert(list);
13260
13261
printf("list.valid: %d\n", list->valid);
13262
printf("list.count: %zu\n", list->count);
13263
13264
for (unsigned i=0; i<list->count; i++)
13265
{
13266
printf("item %u valid %d, should be %d\n",
13267
i, list->items[i].valid, _AU_VALID_PVITEM);
13268
13269
switch (list->items[i].type)
13270
{
13271
case AU_PVTYPE_LONG:
13272
printf("item #%u, parameter %d, long: %ld\n",
13273
i, list->items[i].parameter,
13274
list->items[i].value.l);
13275
break;
13276
case AU_PVTYPE_DOUBLE:
13277
printf("item #%u, parameter %d, double: %f\n",
13278
i, list->items[i].parameter,
13279
list->items[i].value.d);
13280
break;
13281
case AU_PVTYPE_PTR:
13282
printf("item #%u, parameter %d, pointer: %p\n",
13283
i, list->items[i].parameter,
13284
list->items[i].value.v);
13285
break;
13286
13287
default:
13288
printf("item #%u, invalid type %d\n", i,
13289
list->items[i].type);
13290
assert(false);
13291
break;
13292
}
13293
}
13294
}
13295
13296
void _af_print_audioformat (AudioFormat *fmt)
13297
{
13298
/* sampleRate, channelCount */
13299
printf("{ %7.2f Hz %d ch ", fmt->sampleRate, fmt->channelCount);
13300
13301
/* sampleFormat, sampleWidth */
13302
switch (fmt->sampleFormat)
13303
{
13304
case AF_SAMPFMT_TWOSCOMP:
13305
printf("%db 2 ", fmt->sampleWidth);
13306
break;
13307
case AF_SAMPFMT_UNSIGNED:
13308
printf("%db u ", fmt->sampleWidth);
13309
break;
13310
case AF_SAMPFMT_FLOAT:
13311
printf("flt ");
13312
break;
13313
case AF_SAMPFMT_DOUBLE:
13314
printf("dbl ");
13315
break;
13316
default:
13317
printf("%dsampfmt? ", fmt->sampleFormat);
13318
}
13319
13320
/* pcm */
13321
printf("(%.30g+-%.30g [%.30g,%.30g]) ",
13322
fmt->pcm.intercept, fmt->pcm.slope,
13323
fmt->pcm.minClip, fmt->pcm.maxClip);
13324
13325
/* byteOrder */
13326
switch (fmt->byteOrder)
13327
{
13328
case AF_BYTEORDER_BIGENDIAN:
13329
printf("big ");
13330
break;
13331
case AF_BYTEORDER_LITTLEENDIAN:
13332
printf("little ");
13333
break;
13334
default:
13335
printf("%dbyteorder? ", fmt->byteOrder);
13336
break;
13337
}
13338
13339
/* compression */
13340
{
13341
const CompressionUnit *unit = _af_compression_unit_from_id(fmt->compressionType);
13342
if (!unit)
13343
printf("%dcompression?", fmt->compressionType);
13344
else if (fmt->compressionType == AF_COMPRESSION_NONE)
13345
printf("pcm");
13346
else
13347
printf("%s", unit->label);
13348
}
13349
13350
printf(" }");
13351
}
13352
13353
void _af_print_tracks (AFfilehandle filehandle)
13354
{
13355
for (int i=0; i<filehandle->m_trackCount; i++)
13356
{
13357
Track *track = &filehandle->m_tracks[i];
13358
printf("track %d\n", i);
13359
printf(" id %d\n", track->id);
13360
printf(" sample format\n");
13361
_af_print_audioformat(&track->f);
13362
printf(" virtual format\n");
13363
_af_print_audioformat(&track->v);
13364
printf(" total file frames: %jd\n",
13365
(intmax_t) track->totalfframes);
13366
printf(" total virtual frames: %jd\n",
13367
(intmax_t) track->totalvframes);
13368
printf(" next file frame: %jd\n",
13369
(intmax_t) track->nextfframe);
13370
printf(" next virtual frame: %jd\n",
13371
(intmax_t) track->nextvframe);
13372
printf(" frames to ignore: %jd\n",
13373
(intmax_t) track->frames2ignore);
13374
13375
printf(" data_size: %jd\n",
13376
(intmax_t) track->data_size);
13377
printf(" fpos_first_frame: %jd\n",
13378
(intmax_t) track->fpos_first_frame);
13379
printf(" fpos_next_frame: %jd\n",
13380
(intmax_t) track->fpos_next_frame);
13381
printf(" fpos_after_data: %jd\n",
13382
(intmax_t) track->fpos_after_data);
13383
13384
printf(" channel matrix:");
13385
_af_print_channel_matrix(track->channelMatrix,
13386
track->f.channelCount, track->v.channelCount);
13387
printf("\n");
13388
13389
printf(" marker count: %d\n", track->markerCount);
13390
}
13391
}
13392
13393
void _af_print_filehandle (AFfilehandle filehandle)
13394
{
13395
printf("file handle: 0x%p\n", filehandle);
13396
13397
if (filehandle->m_valid == _AF_VALID_FILEHANDLE)
13398
printf("valid\n");
13399
else
13400
printf("invalid!\n");
13401
13402
printf(" access: ");
13403
if (filehandle->m_access == _AF_READ_ACCESS)
13404
putchar('r');
13405
else
13406
putchar('w');
13407
13408
printf(" fileFormat: %d\n", filehandle->m_fileFormat);
13409
13410
printf(" instrument count: %d\n", filehandle->m_instrumentCount);
13411
printf(" instruments: 0x%p\n", filehandle->m_instruments);
13412
13413
printf(" miscellaneous count: %d\n", filehandle->m_miscellaneousCount);
13414
printf(" miscellaneous: 0x%p\n", filehandle->m_miscellaneous);
13415
13416
printf(" trackCount: %d\n", filehandle->m_trackCount);
13417
printf(" tracks: 0x%p\n", filehandle->m_tracks);
13418
_af_print_tracks(filehandle);
13419
}
13420
13421
void _af_print_channel_matrix (double *matrix, int fchans, int vchans)
13422
{
13423
int v, f;
13424
13425
if (!matrix)
13426
{
13427
printf("NULL");
13428
return;
13429
}
13430
13431
printf("{");
13432
for (v=0; v < vchans; v++)
13433
{
13434
if (v) printf(" ");
13435
printf("{");
13436
for (f=0; f < fchans; f++)
13437
{
13438
if (f) printf(" ");
13439
printf("%5.2f", *(matrix + v*fchans + f));
13440
}
13441
printf("}");
13442
}
13443
printf("}");
13444
}
13445
13446
void _af_print_frame (AFframecount frameno, double *frame, int nchannels,
13447
char *formatstring, int numberwidth,
13448
double slope, double intercept, double minclip, double maxclip)
13449
{
13450
char linebuf[81];
13451
int wavewidth = 78 - numberwidth*nchannels - 6;
13452
int c;
13453
13454
memset(linebuf, ' ', 80);
13455
linebuf[0] = '|';
13456
linebuf[wavewidth-1] = '|';
13457
linebuf[wavewidth] = 0;
13458
13459
printf("%05jd ", (intmax_t) frameno);
13460
13461
for (c=0; c < nchannels; c++)
13462
{
13463
double pcm = frame[c];
13464
printf(formatstring, pcm);
13465
}
13466
for (c=0; c < nchannels; c++)
13467
{
13468
double pcm = frame[c], volts;
13469
if (maxclip > minclip)
13470
{
13471
if (pcm < minclip) pcm = minclip;
13472
if (pcm > maxclip) pcm = maxclip;
13473
}
13474
volts = (pcm - intercept) / slope;
13475
linebuf[(int)((volts/2 + 0.5)*(wavewidth-3)) + 1] = '0' + c;
13476
}
13477
printf("%s\n", linebuf);
13478
}
13479
13480
// file: error.c
13481
/*
13482
Audio File Library
13483
Copyright (C) 1998, Michael Pruett <[email protected]>
13484
13485
This library is free software; you can redistribute it and/or
13486
modify it under the terms of the GNU Lesser General Public
13487
License as published by the Free Software Foundation; either
13488
version 2.1 of the License, or (at your option) any later version.
13489
13490
This library is distributed in the hope that it will be useful,
13491
but WITHOUT ANY WARRANTY; without even the implied warranty of
13492
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13493
Lesser General Public License for more details.
13494
13495
You should have received a copy of the GNU Lesser General Public
13496
License along with this library; if not, write to the
13497
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
13498
Boston, MA 02110-1301 USA
13499
*/
13500
13501
/*
13502
error.c
13503
13504
This file contains the routines used in the Audio File Library's
13505
error handling.
13506
*/
13507
13508
13509
#include <stdio.h>
13510
#include <stdarg.h>
13511
#include <assert.h>
13512
13513
static void defaultErrorFunction (long error, const char *str);
13514
13515
static AFerrfunc errorFunction = defaultErrorFunction;
13516
13517
AFerrfunc afSetErrorHandler (AFerrfunc efunc)
13518
{
13519
AFerrfunc old;
13520
13521
old = errorFunction;
13522
errorFunction = efunc;
13523
13524
return old;
13525
}
13526
13527
static void defaultErrorFunction (long error, const char *str)
13528
{
13529
fprintf(stderr, "Audio File Library: ");
13530
fprintf(stderr, "%s", str);
13531
fprintf(stderr, " [error %ld]\n", error);
13532
}
13533
13534
void _af_error (int errorCode, const char *fmt, ...)
13535
{
13536
char buf[1024];
13537
va_list ap;
13538
13539
va_start(ap, fmt);
13540
13541
vsnprintf(buf, 1024, fmt, ap);
13542
13543
va_end(ap);
13544
13545
if (errorFunction != NULL)
13546
errorFunction(errorCode, buf);
13547
}
13548
13549
// file: extended.c
13550
/* Copyright (C) 1989-1991 Apple Computer, Inc.
13551
*
13552
* All rights reserved.
13553
*
13554
* Warranty Information
13555
* Even though Apple has reviewed this software, Apple makes no warranty
13556
* or representation, either express or implied, with respect to this
13557
* software, its quality, accuracy, merchantability, or fitness for a
13558
* particular purpose. As a result, this software is provided "as is,"
13559
* and you, its user, are assuming the entire risk as to its quality
13560
* and accuracy.
13561
*
13562
* This code may be used and freely distributed as long as it includes
13563
* this copyright notice and the above warranty information.
13564
*
13565
* Machine-independent I/O routines for IEEE floating-point numbers.
13566
*
13567
* NaN's and infinities are converted to HUGE_VAL or HUGE, which
13568
* happens to be infinity on IEEE machines. Unfortunately, it is
13569
* impossible to preserve NaN's in a machine-independent way.
13570
* Infinities are, however, preserved on IEEE machines.
13571
*
13572
* These routines have been tested on the following machines:
13573
* Apple Macintosh, MPW 3.1 C compiler
13574
* Apple Macintosh, THINK C compiler
13575
* Silicon Graphics IRIS, MIPS compiler
13576
* Cray X/MP and Y/MP
13577
* Digital Equipment VAX
13578
* Sequent Balance (Multiprocesor 386)
13579
* NeXT
13580
*
13581
*
13582
* Implemented by Malcolm Slaney and Ken Turkowski.
13583
*
13584
* Malcolm Slaney contributions during 1988-1990 include big- and little-
13585
* endian file I/O, conversion to and from Motorola's extended 80-bit
13586
* floating-point format, and conversions to and from IEEE single-
13587
* precision floating-point format.
13588
*
13589
* In 1991, Ken Turkowski implemented the conversions to and from
13590
* IEEE double-precision format, added more precision to the extended
13591
* conversions, and accommodated conversions involving +/- infinity,
13592
* NaN's, and denormalized numbers.
13593
*/
13594
13595
/****************************************************************
13596
* Extended precision IEEE floating-point conversion routines.
13597
* Extended is an 80-bit number as defined by Motorola,
13598
* with a sign bit, 15 bits of exponent (offset 16383?),
13599
* and a 64-bit mantissa, with no hidden bit.
13600
****************************************************************/
13601
13602
13603
#include <math.h>
13604
13605
#ifndef HUGE_VAL
13606
#define HUGE_VAL HUGE
13607
#endif
13608
13609
#define FloatToUnsigned(f) ((unsigned long) (((long) (f - 2147483648.0)) + 2147483647L) + 1)
13610
13611
void _af_convert_to_ieee_extended (double num, unsigned char *bytes)
13612
{
13613
int sign;
13614
int expon;
13615
double fMant, fsMant;
13616
unsigned long hiMant, loMant;
13617
13618
if (num < 0) {
13619
sign = 0x8000;
13620
num *= -1;
13621
} else {
13622
sign = 0;
13623
}
13624
13625
if (num == 0) {
13626
expon = 0; hiMant = 0; loMant = 0;
13627
}
13628
else {
13629
fMant = frexp(num, &expon);
13630
if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */
13631
expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
13632
}
13633
else { /* Finite */
13634
expon += 16382;
13635
if (expon < 0) { /* denormalized */
13636
fMant = ldexp(fMant, expon);
13637
expon = 0;
13638
}
13639
expon |= sign;
13640
fMant = ldexp(fMant, 32);
13641
fsMant = floor(fMant);
13642
hiMant = FloatToUnsigned(fsMant);
13643
fMant = ldexp(fMant - fsMant, 32);
13644
fsMant = floor(fMant);
13645
loMant = FloatToUnsigned(fsMant);
13646
}
13647
}
13648
13649
bytes[0] = expon >> 8;
13650
bytes[1] = expon;
13651
bytes[2] = hiMant >> 24;
13652
bytes[3] = hiMant >> 16;
13653
bytes[4] = hiMant >> 8;
13654
bytes[5] = hiMant;
13655
bytes[6] = loMant >> 24;
13656
bytes[7] = loMant >> 16;
13657
bytes[8] = loMant >> 8;
13658
bytes[9] = loMant;
13659
}
13660
13661
#define UnsignedToFloat(u) (((double) ((long) (u - 2147483647L - 1))) + 2147483648.0)
13662
13663
double _af_convert_from_ieee_extended (const unsigned char *bytes)
13664
{
13665
double f;
13666
int expon;
13667
unsigned long hiMant, loMant;
13668
13669
expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
13670
hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24)
13671
| ((unsigned long) (bytes[3] & 0xFF) << 16)
13672
| ((unsigned long) (bytes[4] & 0xFF) << 8)
13673
| ((unsigned long) (bytes[5] & 0xFF));
13674
loMant = ((unsigned long) (bytes[6] & 0xFF) << 24)
13675
| ((unsigned long) (bytes[7] & 0xFF) << 16)
13676
| ((unsigned long) (bytes[8] & 0xFF) << 8)
13677
| ((unsigned long) (bytes[9] & 0xFF));
13678
13679
if (expon == 0 && hiMant == 0 && loMant == 0) {
13680
f = 0;
13681
}
13682
else {
13683
if (expon == 0x7FFF) { /* Infinity or NaN */
13684
f = HUGE_VAL;
13685
}
13686
else {
13687
expon -= 16383;
13688
f = ldexp(UnsignedToFloat(hiMant), expon-=31);
13689
f += ldexp(UnsignedToFloat(loMant), expon-=32);
13690
}
13691
}
13692
13693
if (bytes[0] & 0x80)
13694
return -f;
13695
else
13696
return f;
13697
}
13698
13699
// file: format.cpp
13700
/*
13701
Audio File Library
13702
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
13703
Copyright (C) 2000, Silicon Graphics, Inc.
13704
13705
This library is free software; you can redistribute it and/or
13706
modify it under the terms of the GNU Lesser General Public
13707
License as published by the Free Software Foundation; either
13708
version 2.1 of the License, or (at your option) any later version.
13709
13710
This library is distributed in the hope that it will be useful,
13711
but WITHOUT ANY WARRANTY; without even the implied warranty of
13712
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13713
Lesser General Public License for more details.
13714
13715
You should have received a copy of the GNU Lesser General Public
13716
License along with this library; if not, write to the
13717
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
13718
Boston, MA 02110-1301 USA
13719
*/
13720
13721
/*
13722
audiofile.c
13723
13724
This file implements many of the main interface routines of the
13725
Audio File Library.
13726
*/
13727
13728
13729
#include <assert.h>
13730
#include <stdint.h>
13731
#include <stdlib.h>
13732
#include <string.h>
13733
13734
13735
AFfileoffset afGetDataOffset (AFfilehandle file, int trackid)
13736
{
13737
if (!_af_filehandle_ok(file))
13738
return -1;
13739
13740
Track *track = file->getTrack(trackid);
13741
if (!track)
13742
return -1;
13743
13744
return track->fpos_first_frame;
13745
}
13746
13747
AFfileoffset afGetTrackBytes (AFfilehandle file, int trackid)
13748
{
13749
if (!_af_filehandle_ok(file))
13750
return -1;
13751
13752
Track *track = file->getTrack(trackid);
13753
if (!track)
13754
return -1;
13755
13756
return track->data_size;
13757
}
13758
13759
/*
13760
afGetFrameSize returns the size (in bytes) of a sample frame from
13761
the specified track of an audio file.
13762
13763
stretch3to4 == true: size which user sees
13764
stretch3to4 == false: size used in file
13765
*/
13766
float afGetFrameSize (AFfilehandle file, int trackid, int stretch3to4)
13767
{
13768
if (!_af_filehandle_ok(file))
13769
return -1;
13770
13771
Track *track = file->getTrack(trackid);
13772
if (!track)
13773
return -1;
13774
13775
return _af_format_frame_size(&track->f, stretch3to4);
13776
}
13777
13778
float afGetVirtualFrameSize (AFfilehandle file, int trackid, int stretch3to4)
13779
{
13780
if (!_af_filehandle_ok(file))
13781
return -1;
13782
13783
Track *track = file->getTrack(trackid);
13784
if (!track)
13785
return -1;
13786
13787
return _af_format_frame_size(&track->v, stretch3to4);
13788
}
13789
13790
AFframecount afSeekFrame (AFfilehandle file, int trackid, AFframecount frame)
13791
{
13792
if (!_af_filehandle_ok(file))
13793
return -1;
13794
13795
if (!file->checkCanRead())
13796
return -1;
13797
13798
Track *track = file->getTrack(trackid);
13799
if (!track)
13800
return -1;
13801
13802
if (track->ms->isDirty() && track->ms->setup(file, track) == AF_FAIL)
13803
return -1;
13804
13805
if (frame < 0)
13806
return track->nextvframe;
13807
13808
/* Optimize the case of seeking to the current position. */
13809
if (frame == track->nextvframe)
13810
return track->nextvframe;
13811
13812
/* Limit request to the number of frames in the file. */
13813
if (track->totalvframes != -1)
13814
if (frame > track->totalvframes)
13815
frame = track->totalvframes - 1;
13816
13817
/*
13818
Now that the modules are not dirty and frame
13819
represents a valid virtual frame, we call
13820
_AFsetupmodules again after setting track->nextvframe.
13821
13822
_AFsetupmodules will look at track->nextvframe and
13823
compute track->nextfframe in clever and mysterious
13824
ways.
13825
*/
13826
track->nextvframe = frame;
13827
13828
if (track->ms->setup(file, track) == AF_FAIL)
13829
return -1;
13830
13831
return track->nextvframe;
13832
}
13833
13834
AFfileoffset afTellFrame (AFfilehandle file, int trackid)
13835
{
13836
return afSeekFrame(file, trackid, -1);
13837
}
13838
13839
int afSetVirtualByteOrder (AFfilehandle file, int trackid, int byteorder)
13840
{
13841
if (!_af_filehandle_ok(file))
13842
return AF_FAIL;
13843
13844
Track *track = file->getTrack(trackid);
13845
if (!track)
13846
return AF_FAIL;
13847
13848
if (byteorder != AF_BYTEORDER_BIGENDIAN &&
13849
byteorder != AF_BYTEORDER_LITTLEENDIAN)
13850
{
13851
_af_error(AF_BAD_BYTEORDER, "invalid byte order %d", byteorder);
13852
return AF_FAIL;
13853
}
13854
13855
track->v.byteOrder = byteorder;
13856
track->ms->setDirty();
13857
13858
return AF_SUCCEED;
13859
}
13860
13861
int afGetByteOrder (AFfilehandle file, int trackid)
13862
{
13863
if (!_af_filehandle_ok(file))
13864
return -1;
13865
13866
Track *track = file->getTrack(trackid);
13867
if (!track)
13868
return -1;
13869
13870
return track->f.byteOrder;
13871
}
13872
13873
int afGetVirtualByteOrder (AFfilehandle file, int trackid)
13874
{
13875
if (!_af_filehandle_ok(file))
13876
return -1;
13877
13878
Track *track = file->getTrack(trackid);
13879
if (!track)
13880
return -1;
13881
13882
return track->v.byteOrder;
13883
}
13884
13885
AFframecount afGetFrameCount (AFfilehandle file, int trackid)
13886
{
13887
if (!_af_filehandle_ok(file))
13888
return -1;
13889
13890
Track *track = file->getTrack(trackid);
13891
if (!track)
13892
return -1;
13893
13894
if (track->ms->isDirty() && track->ms->setup(file, track) == AF_FAIL)
13895
return -1;
13896
13897
return track->totalvframes;
13898
}
13899
13900
double afGetRate (AFfilehandle file, int trackid)
13901
{
13902
if (!_af_filehandle_ok(file))
13903
return -1;
13904
13905
Track *track = file->getTrack(trackid);
13906
if (!track)
13907
return -1;
13908
13909
return track->f.sampleRate;
13910
}
13911
13912
int afGetChannels (AFfilehandle file, int trackid)
13913
{
13914
if (!_af_filehandle_ok(file))
13915
return -1;
13916
13917
Track *track = file->getTrack(trackid);
13918
if (!track)
13919
return -1;
13920
13921
return track->f.channelCount;
13922
}
13923
13924
void afGetSampleFormat (AFfilehandle file, int trackid, int *sampleFormat, int *sampleWidth)
13925
{
13926
if (!_af_filehandle_ok(file))
13927
return;
13928
13929
Track *track = file->getTrack(trackid);
13930
if (!track)
13931
return;
13932
13933
if (sampleFormat)
13934
*sampleFormat = track->f.sampleFormat;
13935
13936
if (sampleWidth)
13937
*sampleWidth = track->f.sampleWidth;
13938
}
13939
13940
void afGetVirtualSampleFormat (AFfilehandle file, int trackid, int *sampleFormat, int *sampleWidth)
13941
{
13942
if (!_af_filehandle_ok(file))
13943
return;
13944
13945
Track *track = file->getTrack(trackid);
13946
if (!track)
13947
return;
13948
13949
if (sampleFormat)
13950
*sampleFormat = track->v.sampleFormat;
13951
13952
if (sampleWidth)
13953
*sampleWidth = track->v.sampleWidth;
13954
}
13955
13956
int afSetVirtualSampleFormat (AFfilehandle file, int trackid,
13957
int sampleFormat, int sampleWidth)
13958
{
13959
if (!_af_filehandle_ok(file))
13960
return -1;
13961
13962
Track *track = file->getTrack(trackid);
13963
if (!track)
13964
return -1;
13965
13966
if (_af_set_sample_format(&track->v, sampleFormat, sampleWidth) == AF_FAIL)
13967
return -1;
13968
13969
track->ms->setDirty();
13970
13971
return 0;
13972
}
13973
13974
/* XXXmpruett fix the version */
13975
int afGetFileFormat (AFfilehandle file, int *version)
13976
{
13977
if (!_af_filehandle_ok(file))
13978
return -1;
13979
13980
if (version != NULL)
13981
*version = file->getVersion();
13982
13983
return file->m_fileFormat;
13984
}
13985
13986
int afSetVirtualChannels (AFfilehandle file, int trackid, int channelCount)
13987
{
13988
if (!_af_filehandle_ok(file))
13989
return -1;
13990
13991
Track *track = file->getTrack(trackid);
13992
if (!track)
13993
return -1;
13994
13995
track->v.channelCount = channelCount;
13996
track->ms->setDirty();
13997
13998
if (track->channelMatrix)
13999
free(track->channelMatrix);
14000
track->channelMatrix = NULL;
14001
14002
return 0;
14003
}
14004
14005
double afGetVirtualRate (AFfilehandle file, int trackid)
14006
{
14007
if (!_af_filehandle_ok(file))
14008
return -1;
14009
14010
Track *track = file->getTrack(trackid);
14011
if (!track)
14012
return -1;
14013
14014
return track->v.sampleRate;
14015
}
14016
14017
int afSetVirtualRate (AFfilehandle file, int trackid, double rate)
14018
{
14019
if (!_af_filehandle_ok(file))
14020
return -1;
14021
14022
Track *track = file->getTrack(trackid);
14023
if (!track)
14024
return -1;
14025
14026
if (rate < 0)
14027
{
14028
_af_error(AF_BAD_RATE, "invalid sampling rate %.30g", rate);
14029
return -1;
14030
}
14031
14032
track->v.sampleRate = rate;
14033
track->ms->setDirty();
14034
14035
return 0;
14036
}
14037
14038
void afSetChannelMatrix (AFfilehandle file, int trackid, double* matrix)
14039
{
14040
if (!_af_filehandle_ok(file))
14041
return;
14042
14043
Track *track = file->getTrack(trackid);
14044
if (!track)
14045
return;
14046
14047
if (track->channelMatrix != NULL)
14048
free(track->channelMatrix);
14049
track->channelMatrix = NULL;
14050
14051
if (matrix != NULL)
14052
{
14053
int i, size;
14054
14055
size = track->v.channelCount * track->f.channelCount;
14056
14057
track->channelMatrix = (double *) malloc(size * sizeof (double));
14058
14059
for (i = 0; i < size; i++)
14060
track->channelMatrix[i] = matrix[i];
14061
}
14062
}
14063
14064
int afGetVirtualChannels (AFfilehandle file, int trackid)
14065
{
14066
if (!_af_filehandle_ok(file))
14067
return -1;
14068
14069
Track *track = file->getTrack(trackid);
14070
if (!track)
14071
return -1;
14072
14073
return track->v.channelCount;
14074
}
14075
14076
// file: g711.c
14077
/*
14078
* This source code is a product of Sun Microsystems, Inc. and is provided
14079
* for unrestricted use. Users may copy or modify this source code without
14080
* charge.
14081
*
14082
* SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
14083
* THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
14084
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14085
*
14086
* Sun source code is provided with no support and without any obligation on
14087
* the part of Sun Microsystems, Inc. to assist in its use, correction,
14088
* modification or enhancement.
14089
*
14090
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
14091
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
14092
* OR ANY PART THEREOF.
14093
*
14094
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
14095
* or profits or other special, indirect and consequential damages, even if
14096
* Sun has been advised of the possibility of such damages.
14097
*
14098
* Sun Microsystems, Inc.
14099
* 2550 Garcia Avenue
14100
* Mountain View, California 94043
14101
*/
14102
14103
#define SUPERCEDED
14104
14105
/*
14106
* g711.c
14107
*
14108
* u-law, A-law and linear PCM conversions.
14109
*/
14110
#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
14111
#define QUANT_MASK (0xf) /* Quantization field mask. */
14112
#define NSEGS (8) /* Number of A-law segments. */
14113
#define SEG_SHIFT (4) /* Left shift for segment number. */
14114
#define SEG_MASK (0x70) /* Segment field mask. */
14115
14116
/* see libst.h */
14117
#ifdef SUPERCEDED
14118
14119
static const short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,
14120
0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
14121
14122
static int search(int val, const short *table, int size)
14123
{
14124
int i;
14125
14126
for (i = 0; i < size; i++) {
14127
if (val <= *table++)
14128
return (i);
14129
}
14130
return (size);
14131
}
14132
14133
/*
14134
* linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
14135
*
14136
* linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
14137
*
14138
* Linear Input Code Compressed Code
14139
* ------------------------ ---------------
14140
* 0000000wxyza 000wxyz
14141
* 0000001wxyza 001wxyz
14142
* 000001wxyzab 010wxyz
14143
* 00001wxyzabc 011wxyz
14144
* 0001wxyzabcd 100wxyz
14145
* 001wxyzabcde 101wxyz
14146
* 01wxyzabcdef 110wxyz
14147
* 1wxyzabcdefg 111wxyz
14148
*
14149
* For further information see John C. Bellamy's Digital Telephony, 1982,
14150
* John Wiley & Sons, pps 98-111 and 472-476.
14151
*/
14152
unsigned char
14153
_af_linear2alaw(int pcm_val)
14154
{
14155
int mask;
14156
int seg;
14157
unsigned char aval;
14158
14159
if (pcm_val >= 0) {
14160
mask = 0xD5; /* sign (7th) bit = 1 */
14161
} else {
14162
mask = 0x55; /* sign bit = 0 */
14163
pcm_val = -pcm_val - 8;
14164
}
14165
14166
/* Convert the scaled magnitude to segment number. */
14167
seg = search(pcm_val, seg_end, 8);
14168
14169
/* Combine the sign, segment, and quantization bits. */
14170
14171
if (seg >= 8) /* out of range, return maximum value. */
14172
return (0x7F ^ mask);
14173
else {
14174
aval = seg << SEG_SHIFT;
14175
if (seg < 2)
14176
aval |= (pcm_val >> 4) & QUANT_MASK;
14177
else
14178
aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
14179
return (aval ^ mask);
14180
}
14181
}
14182
14183
/*
14184
* alaw2linear() - Convert an A-law value to 16-bit linear PCM
14185
*
14186
*/
14187
int
14188
_af_alaw2linear(unsigned char a_val)
14189
{
14190
int t;
14191
int seg;
14192
14193
a_val ^= 0x55;
14194
14195
t = (a_val & QUANT_MASK) << 4;
14196
seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
14197
switch (seg) {
14198
case 0:
14199
t += 8;
14200
break;
14201
case 1:
14202
t += 0x108;
14203
break;
14204
default:
14205
t += 0x108;
14206
t <<= seg - 1;
14207
}
14208
return ((a_val & SIGN_BIT) ? t : -t);
14209
}
14210
14211
#define BIAS (0x84) /* Bias for linear code. */
14212
14213
/*
14214
* linear2ulaw() - Convert a linear PCM value to u-law
14215
*
14216
* In order to simplify the encoding process, the original linear magnitude
14217
* is biased by adding 33 which shifts the encoding range from (0 - 8158) to
14218
* (33 - 8191). The result can be seen in the following encoding table:
14219
*
14220
* Biased Linear Input Code Compressed Code
14221
* ------------------------ ---------------
14222
* 00000001wxyza 000wxyz
14223
* 0000001wxyzab 001wxyz
14224
* 000001wxyzabc 010wxyz
14225
* 00001wxyzabcd 011wxyz
14226
* 0001wxyzabcde 100wxyz
14227
* 001wxyzabcdef 101wxyz
14228
* 01wxyzabcdefg 110wxyz
14229
* 1wxyzabcdefgh 111wxyz
14230
*
14231
* Each biased linear code has a leading 1 which identifies the segment
14232
* number. The value of the segment number is equal to 7 minus the number
14233
* of leading 0's. The quantization interval is directly available as the
14234
* four bits wxyz. * The trailing bits (a - h) are ignored.
14235
*
14236
* Ordinarily the complement of the resulting code word is used for
14237
* transmission, and so the code word is complemented before it is returned.
14238
*
14239
* For further information see John C. Bellamy's Digital Telephony, 1982,
14240
* John Wiley & Sons, pps 98-111 and 472-476.
14241
*/
14242
14243
/* 2's complement (16-bit range) */
14244
unsigned char _af_linear2ulaw (int pcm_val)
14245
{
14246
int mask;
14247
int seg;
14248
unsigned char uval;
14249
14250
/* Get the sign and the magnitude of the value. */
14251
if (pcm_val < 0) {
14252
pcm_val = BIAS - pcm_val;
14253
mask = 0x7F;
14254
} else {
14255
pcm_val += BIAS;
14256
mask = 0xFF;
14257
}
14258
14259
/* Convert the scaled magnitude to segment number. */
14260
seg = search(pcm_val, seg_end, 8);
14261
14262
/*
14263
* Combine the sign, segment, quantization bits;
14264
* and complement the code word.
14265
*/
14266
if (seg >= 8) /* out of range, return maximum value. */
14267
return (0x7F ^ mask);
14268
else {
14269
uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
14270
return (uval ^ mask);
14271
}
14272
14273
}
14274
14275
/*
14276
* ulaw2linear() - Convert a u-law value to 16-bit linear PCM
14277
*
14278
* First, a biased linear code is derived from the code word. An unbiased
14279
* output can then be obtained by subtracting 33 from the biased code.
14280
*
14281
* Note that this function expects to be passed the complement of the
14282
* original code word. This is in keeping with ISDN conventions.
14283
*/
14284
int _af_ulaw2linear (unsigned char u_val)
14285
{
14286
int t;
14287
14288
/* Complement to obtain normal u-law value. */
14289
u_val = ~u_val;
14290
14291
/*
14292
* Extract and bias the quantization bits. Then
14293
* shift up by the segment number and subtract out the bias.
14294
*/
14295
t = ((u_val & QUANT_MASK) << 3) + BIAS;
14296
t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
14297
14298
return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
14299
}
14300
14301
#endif
14302
14303
// file: openclose.cpp
14304
/*
14305
Audio File Library
14306
Copyright (C) 2000-2001, Silicon Graphics, Inc.
14307
14308
This library is free software; you can redistribute it and/or
14309
modify it under the terms of the GNU Lesser General Public
14310
License as published by the Free Software Foundation; either
14311
version 2.1 of the License, or (at your option) any later version.
14312
14313
This library is distributed in the hope that it will be useful,
14314
but WITHOUT ANY WARRANTY; without even the implied warranty of
14315
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14316
Lesser General Public License for more details.
14317
14318
You should have received a copy of the GNU Lesser General Public
14319
License along with this library; if not, write to the
14320
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
14321
Boston, MA 02110-1301 USA
14322
*/
14323
14324
14325
#include <stdlib.h>
14326
#include <assert.h>
14327
#include <string.h>
14328
14329
#ifdef HAVE_UNISTD_H
14330
#include <unistd.h>
14331
#endif
14332
14333
#include <audiofile.h>
14334
14335
14336
static status _afOpenFile (int access, File *f, const char *filename,
14337
AFfilehandle *file, AFfilesetup filesetup);
14338
14339
int _af_identify (File *f, int *implemented)
14340
{
14341
if (!f->canSeek())
14342
{
14343
_af_error(AF_BAD_LSEEK, "Cannot seek in file");
14344
return AF_FILE_UNKNOWN;
14345
}
14346
14347
AFfileoffset curpos = f->tell();
14348
14349
for (int i=0; i<_AF_NUM_UNITS; i++)
14350
{
14351
if (_af_units[i].recognize &&
14352
_af_units[i].recognize(f))
14353
{
14354
if (implemented != NULL)
14355
*implemented = _af_units[i].implemented;
14356
f->seek(curpos, File::SeekFromBeginning);
14357
return _af_units[i].fileFormat;
14358
}
14359
}
14360
14361
f->seek(curpos, File::SeekFromBeginning);
14362
14363
if (implemented != NULL)
14364
*implemented = false;
14365
14366
return AF_FILE_UNKNOWN;
14367
}
14368
14369
int afIdentifyFD (int fd)
14370
{
14371
/*
14372
Duplicate the file descriptor since otherwise the
14373
original file descriptor would get closed when we close
14374
the virtual file below.
14375
*/
14376
fd = dup(fd);
14377
File *f = File::create(fd, File::ReadAccess);
14378
14379
int result = _af_identify(f, NULL);
14380
14381
delete f;
14382
14383
return result;
14384
}
14385
14386
int afIdentifyNamedFD (int fd, const char *filename, int *implemented)
14387
{
14388
/*
14389
Duplicate the file descriptor since otherwise the
14390
original file descriptor would get closed when we close
14391
the virtual file below.
14392
*/
14393
fd = dup(fd);
14394
14395
File *f = File::create(fd, File::ReadAccess);
14396
if (!f)
14397
{
14398
_af_error(AF_BAD_OPEN, "could not open file '%s'", filename);
14399
return AF_FILE_UNKNOWN;
14400
}
14401
14402
int result = _af_identify(f, implemented);
14403
14404
delete f;
14405
14406
return result;
14407
}
14408
14409
AFfilehandle afOpenFD (int fd, const char *mode, AFfilesetup setup)
14410
{
14411
if (!mode)
14412
{
14413
_af_error(AF_BAD_ACCMODE, "null access mode");
14414
return AF_NULL_FILEHANDLE;
14415
}
14416
14417
int access;
14418
if (mode[0] == 'r')
14419
{
14420
access = _AF_READ_ACCESS;
14421
}
14422
else if (mode[0] == 'w')
14423
{
14424
access = _AF_WRITE_ACCESS;
14425
}
14426
else
14427
{
14428
_af_error(AF_BAD_ACCMODE, "unrecognized access mode '%s'", mode);
14429
return AF_NULL_FILEHANDLE;
14430
}
14431
14432
File *f = File::create(fd, access == _AF_READ_ACCESS ?
14433
File::ReadAccess : File::WriteAccess);
14434
14435
AFfilehandle filehandle = NULL;
14436
if (_afOpenFile(access, f, NULL, &filehandle, setup) != AF_SUCCEED)
14437
{
14438
delete f;
14439
}
14440
14441
return filehandle;
14442
}
14443
14444
AFfilehandle afOpenNamedFD (int fd, const char *mode, AFfilesetup setup,
14445
const char *filename)
14446
{
14447
if (!mode)
14448
{
14449
_af_error(AF_BAD_ACCMODE, "null access mode");
14450
return AF_NULL_FILEHANDLE;
14451
}
14452
14453
int access;
14454
if (mode[0] == 'r')
14455
access = _AF_READ_ACCESS;
14456
else if (mode[0] == 'w')
14457
access = _AF_WRITE_ACCESS;
14458
else
14459
{
14460
_af_error(AF_BAD_ACCMODE, "unrecognized access mode '%s'", mode);
14461
return AF_NULL_FILEHANDLE;
14462
}
14463
14464
File *f = File::create(fd, access == _AF_READ_ACCESS ?
14465
File::ReadAccess : File::WriteAccess);
14466
14467
AFfilehandle filehandle;
14468
if (_afOpenFile(access, f, filename, &filehandle, setup) != AF_SUCCEED)
14469
{
14470
delete f;
14471
}
14472
14473
return filehandle;
14474
}
14475
14476
AFfilehandle afOpenFile (const char *filename, const char *mode, AFfilesetup setup)
14477
{
14478
if (!mode)
14479
{
14480
_af_error(AF_BAD_ACCMODE, "null access mode");
14481
return AF_NULL_FILEHANDLE;
14482
}
14483
14484
int access;
14485
if (mode[0] == 'r')
14486
{
14487
access = _AF_READ_ACCESS;
14488
}
14489
else if (mode[0] == 'w')
14490
{
14491
access = _AF_WRITE_ACCESS;
14492
}
14493
else
14494
{
14495
_af_error(AF_BAD_ACCMODE, "unrecognized access mode '%s'", mode);
14496
return AF_NULL_FILEHANDLE;
14497
}
14498
14499
File *f = File::open(filename,
14500
access == _AF_READ_ACCESS ? File::ReadAccess : File::WriteAccess);
14501
if (!f)
14502
{
14503
_af_error(AF_BAD_OPEN, "could not open file '%s'", filename);
14504
return AF_NULL_FILEHANDLE;
14505
}
14506
14507
AFfilehandle filehandle;
14508
if (_afOpenFile(access, f, filename, &filehandle, setup) != AF_SUCCEED)
14509
{
14510
delete f;
14511
}
14512
14513
return filehandle;
14514
}
14515
14516
AFfilehandle afOpenVirtualFile (AFvirtualfile *vf, const char *mode,
14517
AFfilesetup setup)
14518
{
14519
if (!vf)
14520
{
14521
_af_error(AF_BAD_OPEN, "null virtual file");
14522
return AF_NULL_FILEHANDLE;
14523
}
14524
14525
if (!mode)
14526
{
14527
_af_error(AF_BAD_ACCMODE, "null access mode");
14528
return AF_NULL_FILEHANDLE;
14529
}
14530
14531
int access;
14532
if (mode[0] == 'r')
14533
{
14534
access = _AF_READ_ACCESS;
14535
}
14536
else if (mode[0] == 'w')
14537
{
14538
access = _AF_WRITE_ACCESS;
14539
}
14540
else
14541
{
14542
_af_error(AF_BAD_ACCMODE, "unrecognized access mode '%s'", mode);
14543
return AF_NULL_FILEHANDLE;
14544
}
14545
14546
File *f = File::create(vf,
14547
access == _AF_READ_ACCESS ? File::ReadAccess : File::WriteAccess);
14548
if (!f)
14549
{
14550
_af_error(AF_BAD_OPEN, "could not open virtual file");
14551
return AF_NULL_FILEHANDLE;
14552
}
14553
14554
AFfilehandle filehandle;
14555
if (_afOpenFile(access, f, NULL, &filehandle, setup) != AF_SUCCEED)
14556
{
14557
delete f;
14558
}
14559
14560
return filehandle;
14561
}
14562
14563
static status _afOpenFile (int access, File *f, const char *filename,
14564
AFfilehandle *file, AFfilesetup filesetup)
14565
{
14566
int fileFormat = AF_FILE_UNKNOWN;
14567
int implemented = true;
14568
14569
int userSampleFormat = 0;
14570
double userSampleRate = 0.0;
14571
PCMInfo userPCM = {0};
14572
bool userFormatSet = false;
14573
14574
AFfilehandle filehandle = AF_NULL_FILEHANDLE;
14575
AFfilesetup completesetup = AF_NULL_FILESETUP;
14576
14577
*file = AF_NULL_FILEHANDLE;
14578
14579
if (access == _AF_WRITE_ACCESS || filesetup != AF_NULL_FILESETUP)
14580
{
14581
if (!_af_filesetup_ok(filesetup))
14582
return AF_FAIL;
14583
14584
fileFormat = filesetup->fileFormat;
14585
if (access == _AF_READ_ACCESS && fileFormat != AF_FILE_RAWDATA)
14586
{
14587
_af_error(AF_BAD_FILESETUP,
14588
"warning: opening file for read access: "
14589
"ignoring file setup with non-raw file format");
14590
filesetup = AF_NULL_FILESETUP;
14591
fileFormat = _af_identify(f, &implemented);
14592
}
14593
}
14594
else if (filesetup == AF_NULL_FILESETUP)
14595
fileFormat = _af_identify(f, &implemented);
14596
14597
if (fileFormat == AF_FILE_UNKNOWN)
14598
{
14599
if (filename != NULL)
14600
_af_error(AF_BAD_NOT_IMPLEMENTED,
14601
"'%s': unrecognized audio file format",
14602
filename);
14603
else
14604
_af_error(AF_BAD_NOT_IMPLEMENTED,
14605
"unrecognized audio file format");
14606
return AF_FAIL;
14607
}
14608
14609
const char *formatName = _af_units[fileFormat].name;
14610
14611
if (!implemented)
14612
{
14613
_af_error(AF_BAD_NOT_IMPLEMENTED,
14614
"%s format not currently supported", formatName);
14615
}
14616
14617
completesetup = NULL;
14618
if (filesetup != AF_NULL_FILESETUP)
14619
{
14620
userSampleFormat = filesetup->tracks[0].f.sampleFormat;
14621
userPCM = filesetup->tracks[0].f.pcm;
14622
userSampleRate = filesetup->tracks[0].f.sampleRate;
14623
userFormatSet = true;
14624
if ((completesetup = _af_units[fileFormat].completesetup(filesetup)) == NULL)
14625
return AF_FAIL;
14626
}
14627
14628
filehandle = _AFfilehandle::create(fileFormat);
14629
if (!filehandle)
14630
{
14631
if (completesetup)
14632
afFreeFileSetup(completesetup);
14633
return AF_FAIL;
14634
}
14635
14636
filehandle->m_fh = f;
14637
filehandle->m_access = access;
14638
filehandle->m_seekok = f->canSeek();
14639
if (filename != NULL)
14640
filehandle->m_fileName = _af_strdup(filename);
14641
else
14642
filehandle->m_fileName = NULL;
14643
filehandle->m_fileFormat = fileFormat;
14644
14645
status result = access == _AF_READ_ACCESS ?
14646
filehandle->readInit(completesetup) :
14647
filehandle->writeInit(completesetup);
14648
14649
if (result != AF_SUCCEED)
14650
{
14651
delete filehandle;
14652
filehandle = AF_NULL_FILEHANDLE;
14653
if (completesetup)
14654
afFreeFileSetup(completesetup);
14655
return AF_FAIL;
14656
}
14657
14658
if (completesetup)
14659
afFreeFileSetup(completesetup);
14660
14661
/*
14662
Initialize virtual format.
14663
*/
14664
for (int t=0; t<filehandle->m_trackCount; t++)
14665
{
14666
Track *track = &filehandle->m_tracks[t];
14667
14668
track->v = track->f;
14669
14670
if (userFormatSet)
14671
{
14672
track->v.sampleFormat = userSampleFormat;
14673
track->v.pcm = userPCM;
14674
track->v.sampleRate = userSampleRate;
14675
}
14676
14677
track->v.compressionType = AF_COMPRESSION_NONE;
14678
track->v.compressionParams = NULL;
14679
14680
#if WORDS_BIGENDIAN
14681
track->v.byteOrder = AF_BYTEORDER_BIGENDIAN;
14682
#else
14683
track->v.byteOrder = AF_BYTEORDER_LITTLEENDIAN;
14684
#endif
14685
14686
track->ms = new ModuleState();
14687
if (track->ms->init(filehandle, track) == AF_FAIL)
14688
{
14689
delete filehandle;
14690
return AF_FAIL;
14691
}
14692
}
14693
14694
*file = filehandle;
14695
14696
return AF_SUCCEED;
14697
}
14698
14699
int afSyncFile (AFfilehandle handle)
14700
{
14701
if (!_af_filehandle_ok(handle))
14702
return -1;
14703
14704
if (handle->m_access == _AF_WRITE_ACCESS)
14705
{
14706
/* Finish writes on all tracks. */
14707
for (int trackno = 0; trackno < handle->m_trackCount; trackno++)
14708
{
14709
Track *track = &handle->m_tracks[trackno];
14710
14711
if (track->ms->isDirty() && track->ms->setup(handle, track) == AF_FAIL)
14712
return -1;
14713
14714
if (track->ms->sync(handle, track) != AF_SUCCEED)
14715
return -1;
14716
}
14717
14718
/* Update file headers. */
14719
if (handle->update() != AF_SUCCEED)
14720
return AF_FAIL;
14721
}
14722
else if (handle->m_access == _AF_READ_ACCESS)
14723
{
14724
/* Do nothing. */
14725
}
14726
else
14727
{
14728
_af_error(AF_BAD_ACCMODE, "unrecognized access mode %d",
14729
handle->m_access);
14730
return AF_FAIL;
14731
}
14732
14733
return AF_SUCCEED;
14734
}
14735
14736
int afCloseFile (AFfilehandle file)
14737
{
14738
int err;
14739
14740
if (!_af_filehandle_ok(file))
14741
return -1;
14742
14743
afSyncFile(file);
14744
14745
err = file->m_fh->close();
14746
if (err < 0)
14747
_af_error(AF_BAD_CLOSE, "close returned %d", err);
14748
14749
delete file->m_fh;
14750
delete file;
14751
14752
return 0;
14753
}
14754
14755
// file: pcm.cpp
14756
/*
14757
Audio File Library
14758
Copyright (C) 1999-2000, Michael Pruett <[email protected]>
14759
Copyright (C) 2000-2001, Silicon Graphics, Inc.
14760
14761
This library is free software; you can redistribute it and/or
14762
modify it under the terms of the GNU Lesser General Public
14763
License as published by the Free Software Foundation; either
14764
version 2.1 of the License, or (at your option) any later version.
14765
14766
This library is distributed in the hope that it will be useful,
14767
but WITHOUT ANY WARRANTY; without even the implied warranty of
14768
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14769
Lesser General Public License for more details.
14770
14771
You should have received a copy of the GNU Lesser General Public
14772
License along with this library; if not, write to the
14773
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
14774
Boston, MA 02110-1301 USA
14775
*/
14776
14777
/*
14778
pcm.cpp
14779
14780
This file declares default PCM mappings and defines routines
14781
for accessing and modifying PCM mappings in a track.
14782
*/
14783
14784
14785
14786
extern const PCMInfo _af_default_signed_integer_pcm_mappings[] =
14787
{
14788
{0, 0, 0, 0},
14789
{SLOPE_INT8, 0, MIN_INT8, MAX_INT8},
14790
{SLOPE_INT16, 0, MIN_INT16, MAX_INT16},
14791
{SLOPE_INT24, 0, MIN_INT24, MAX_INT24},
14792
{SLOPE_INT32, 0, MIN_INT32, MAX_INT32}
14793
};
14794
14795
extern const PCMInfo _af_default_unsigned_integer_pcm_mappings[] =
14796
{
14797
{0, 0, 0, 0},
14798
{SLOPE_INT8, INTERCEPT_U_INT8, 0, MAX_U_INT8},
14799
{SLOPE_INT16, INTERCEPT_U_INT16, 0, MAX_U_INT16},
14800
{SLOPE_INT24, INTERCEPT_U_INT24, 0, MAX_U_INT24},
14801
{SLOPE_INT32, INTERCEPT_U_INT32, 0, MAX_U_INT32}
14802
};
14803
14804
extern const PCMInfo _af_default_float_pcm_mapping =
14805
{1, 0, 0, 0};
14806
14807
extern const PCMInfo _af_default_double_pcm_mapping =
14808
{1, 0, 0, 0};
14809
14810
/*
14811
Initialize the PCM mapping for a given track.
14812
*/
14813
void afInitPCMMapping (AFfilesetup setup, int trackid,
14814
double slope, double intercept, double minClip, double maxClip)
14815
{
14816
if (!_af_filesetup_ok(setup))
14817
return;
14818
14819
TrackSetup *track = setup->getTrack(trackid);
14820
if (!track)
14821
return;
14822
14823
track->f.pcm.slope = slope;
14824
track->f.pcm.intercept = intercept;
14825
track->f.pcm.minClip = minClip;
14826
track->f.pcm.maxClip = maxClip;
14827
}
14828
14829
int afSetVirtualPCMMapping (AFfilehandle file, int trackid,
14830
double slope, double intercept, double minClip, double maxClip)
14831
{
14832
if (!_af_filehandle_ok(file))
14833
return -1;
14834
14835
Track *track = file->getTrack(trackid);
14836
if (!track)
14837
return -1;
14838
14839
track->v.pcm.slope = slope;
14840
track->v.pcm.intercept = intercept;
14841
track->v.pcm.minClip = minClip;
14842
track->v.pcm.maxClip = maxClip;
14843
14844
track->ms->setDirty();
14845
14846
return 0;
14847
}
14848
14849
int afSetTrackPCMMapping (AFfilehandle file, int trackid,
14850
double slope, double intercept, double minClip, double maxClip)
14851
{
14852
if (!_af_filehandle_ok(file))
14853
return -1;
14854
14855
Track *track = file->getTrack(trackid);
14856
if (!track)
14857
return -1;
14858
14859
/*
14860
NOTE: this is highly unusual: we don't ordinarily
14861
change track.f after the file is opened.
14862
14863
PCM mapping is the exception because this information
14864
is not encoded in sound files' headers using today's
14865
formats, so the user will probably want to set this
14866
information on a regular basis. The defaults may or
14867
may not be what the user wants.
14868
*/
14869
14870
track->f.pcm.slope = slope;
14871
track->f.pcm.intercept = intercept;
14872
track->f.pcm.minClip = minClip;
14873
track->f.pcm.maxClip = maxClip;
14874
14875
track->ms->setDirty();
14876
14877
return 0;
14878
}
14879
14880
void afGetPCMMapping (AFfilehandle file, int trackid,
14881
double *slope, double *intercept, double *minClip, double *maxClip)
14882
{
14883
if (!_af_filehandle_ok(file))
14884
return;
14885
14886
Track *track = file->getTrack(trackid);
14887
if (!track)
14888
return;
14889
14890
if (slope)
14891
*slope = track->f.pcm.slope;
14892
if (intercept)
14893
*intercept = track->f.pcm.intercept;
14894
if (minClip)
14895
*minClip = track->f.pcm.minClip;
14896
if (maxClip)
14897
*maxClip = track->f.pcm.maxClip;
14898
}
14899
14900
void afGetVirtualPCMMapping (AFfilehandle file, int trackid,
14901
double *slope, double *intercept, double *minClip, double *maxClip)
14902
{
14903
if (!_af_filehandle_ok(file))
14904
return;
14905
14906
Track *track = file->getTrack(trackid);
14907
if (!track)
14908
return;
14909
14910
if (slope)
14911
*slope = track->v.pcm.slope;
14912
if (intercept)
14913
*intercept = track->v.pcm.intercept;
14914
if (minClip)
14915
*minClip = track->v.pcm.minClip;
14916
if (maxClip)
14917
*maxClip = track->v.pcm.maxClip;
14918
}
14919
14920
// file: query.cpp
14921
/*
14922
Audio File Library
14923
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
14924
14925
This library is free software; you can redistribute it and/or
14926
modify it under the terms of the GNU Lesser General Public
14927
License as published by the Free Software Foundation; either
14928
version 2.1 of the License, or (at your option) any later version.
14929
14930
This library is distributed in the hope that it will be useful,
14931
but WITHOUT ANY WARRANTY; without even the implied warranty of
14932
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14933
Lesser General Public License for more details.
14934
14935
You should have received a copy of the GNU Lesser General Public
14936
License along with this library; if not, write to the
14937
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
14938
Boston, MA 02110-1301 USA
14939
*/
14940
14941
/*
14942
query.cpp
14943
14944
This file contains the implementation of the Audio File Library's
14945
query mechanism. Querying through the afQuery calls can allow the
14946
programmer to determine the capabilities and characteristics of
14947
the Audio File Library implementation and its supported formats.
14948
*/
14949
14950
14951
#include <assert.h>
14952
#include <stdlib.h>
14953
14954
14955
AUpvlist _afQueryFileFormat (int arg1, int arg2, int arg3, int arg4);
14956
AUpvlist _afQueryInstrument (int arg1, int arg2, int arg3, int arg4);
14957
AUpvlist _afQueryInstrumentParameter (int arg1, int arg2, int arg3, int arg4);
14958
AUpvlist _afQueryLoop (int arg1, int arg2, int arg3, int arg4);
14959
AUpvlist _afQueryMarker (int arg1, int arg2, int arg3, int arg4);
14960
AUpvlist _afQueryMiscellaneous (int arg1, int arg2, int arg3, int arg4);
14961
AUpvlist _afQueryCompression (int arg1, int arg2, int arg3, int arg4);
14962
AUpvlist _afQueryCompressionParameter (int arg1, int arg2, int arg3, int arg4);
14963
14964
AUpvlist afQuery (int querytype, int arg1, int arg2, int arg3, int arg4)
14965
{
14966
switch (querytype)
14967
{
14968
case AF_QUERYTYPE_INST:
14969
return _afQueryInstrument(arg1, arg2, arg3, arg4);
14970
case AF_QUERYTYPE_INSTPARAM:
14971
return _afQueryInstrumentParameter(arg1, arg2, arg3, arg4);
14972
case AF_QUERYTYPE_LOOP:
14973
return _afQueryLoop(arg1, arg2, arg3, arg4);
14974
case AF_QUERYTYPE_FILEFMT:
14975
return _afQueryFileFormat(arg1, arg2, arg3, arg4);
14976
case AF_QUERYTYPE_COMPRESSION:
14977
return _afQueryCompression(arg1, arg2, arg3, arg4);
14978
case AF_QUERYTYPE_COMPRESSIONPARAM:
14979
/* FIXME: This selector is not implemented. */
14980
return AU_NULL_PVLIST;
14981
case AF_QUERYTYPE_MISC:
14982
/* FIXME: This selector is not implemented. */
14983
return AU_NULL_PVLIST;
14984
case AF_QUERYTYPE_MARK:
14985
return _afQueryMarker(arg1, arg2, arg3, arg4);
14986
}
14987
14988
_af_error(AF_BAD_QUERYTYPE, "bad query type");
14989
return AU_NULL_PVLIST;
14990
}
14991
14992
/* ARGSUSED3 */
14993
AUpvlist _afQueryFileFormat (int arg1, int arg2, int arg3, int arg4)
14994
{
14995
switch (arg1)
14996
{
14997
/* The following select only on arg1. */
14998
case AF_QUERY_ID_COUNT:
14999
{
15000
int count = 0, idx;
15001
for (idx = 0; idx < _AF_NUM_UNITS; idx++)
15002
if (_af_units[idx].implemented)
15003
count++;
15004
return _af_pv_long(count);
15005
}
15006
/* NOTREACHED */
15007
break;
15008
15009
case AF_QUERY_IDS:
15010
{
15011
int count = 0, idx;
15012
int *buffer;
15013
15014
buffer = (int *) _af_calloc(_AF_NUM_UNITS, sizeof (int));
15015
if (buffer == NULL)
15016
return AU_NULL_PVLIST;
15017
15018
for (idx = 0; idx < _AF_NUM_UNITS; idx++)
15019
if (_af_units[idx].implemented)
15020
buffer[count++] = idx;
15021
15022
if (count == 0)
15023
{
15024
free(buffer);
15025
return AU_NULL_PVLIST;
15026
}
15027
15028
return _af_pv_pointer(buffer);
15029
}
15030
/* NOTREACHED */
15031
break;
15032
15033
/* The following select on arg2. */
15034
case AF_QUERY_LABEL:
15035
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15036
return AU_NULL_PVLIST;
15037
return _af_pv_pointer(const_cast<char *>(_af_units[arg2].label));
15038
15039
case AF_QUERY_NAME:
15040
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15041
return AU_NULL_PVLIST;
15042
return _af_pv_pointer(const_cast<char *>(_af_units[arg2].name));
15043
15044
case AF_QUERY_DESC:
15045
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15046
return AU_NULL_PVLIST;
15047
return _af_pv_pointer(const_cast<char *>(_af_units[arg2].description));
15048
15049
case AF_QUERY_IMPLEMENTED:
15050
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15051
return _af_pv_long(0);
15052
return _af_pv_long(_af_units[arg2].implemented);
15053
15054
/* The following select on arg3. */
15055
case AF_QUERY_SAMPLE_FORMATS:
15056
if (arg3 < 0 || arg3 >= _AF_NUM_UNITS)
15057
return AU_NULL_PVLIST;
15058
switch (arg2)
15059
{
15060
case AF_QUERY_DEFAULT:
15061
return _af_pv_long(_af_units[arg3].defaultSampleFormat);
15062
default:
15063
break;
15064
}
15065
/* NOTREACHED */
15066
break;
15067
15068
case AF_QUERY_SAMPLE_SIZES:
15069
if (arg3 < 0 || arg3 >= _AF_NUM_UNITS)
15070
return AU_NULL_PVLIST;
15071
15072
switch (arg2)
15073
{
15074
case AF_QUERY_DEFAULT:
15075
return _af_pv_long(_af_units[arg3].defaultSampleWidth);
15076
default:
15077
break;
15078
}
15079
/* NOTREACHED */
15080
break;
15081
15082
case AF_QUERY_COMPRESSION_TYPES:
15083
{
15084
int idx, count;
15085
int *buffer;
15086
15087
if (arg3 < 0 || arg3 >= _AF_NUM_UNITS)
15088
{
15089
_af_error(AF_BAD_QUERY,
15090
"unrecognized file format %d", arg3);
15091
return AU_NULL_PVLIST;
15092
}
15093
15094
switch (arg2)
15095
{
15096
case AF_QUERY_VALUE_COUNT:
15097
count = _af_units[arg3].compressionTypeCount;
15098
return _af_pv_long(count);
15099
15100
case AF_QUERY_VALUES:
15101
count = _af_units[arg3].compressionTypeCount;
15102
if (count == 0)
15103
return AU_NULL_PVLIST;
15104
15105
buffer = (int *) _af_calloc(count, sizeof (int));
15106
if (buffer == NULL)
15107
return AU_NULL_PVLIST;
15108
15109
for (idx = 0; idx < count; idx++)
15110
{
15111
buffer[idx] = _af_units[arg3].compressionTypes[idx];
15112
}
15113
15114
return _af_pv_pointer(buffer);
15115
}
15116
}
15117
break;
15118
}
15119
15120
_af_error(AF_BAD_QUERY, "bad query selector");
15121
return AU_NULL_PVLIST;
15122
}
15123
15124
long afQueryLong (int querytype, int arg1, int arg2, int arg3, int arg4)
15125
{
15126
AUpvlist list;
15127
int type;
15128
long value;
15129
15130
list = afQuery(querytype, arg1, arg2, arg3, arg4);
15131
if (list == AU_NULL_PVLIST)
15132
return -1;
15133
AUpvgetvaltype(list, 0, &type);
15134
if (type != AU_PVTYPE_LONG)
15135
return -1;
15136
AUpvgetval(list, 0, &value);
15137
AUpvfree(list);
15138
return value;
15139
}
15140
15141
double afQueryDouble (int querytype, int arg1, int arg2, int arg3, int arg4)
15142
{
15143
AUpvlist list;
15144
int type;
15145
double value;
15146
15147
list = afQuery(querytype, arg1, arg2, arg3, arg4);
15148
if (list == AU_NULL_PVLIST)
15149
return -1;
15150
AUpvgetvaltype(list, 0, &type);
15151
if (type != AU_PVTYPE_DOUBLE)
15152
return -1;
15153
AUpvgetval(list, 0, &value);
15154
AUpvfree(list);
15155
return value;
15156
}
15157
15158
void *afQueryPointer (int querytype, int arg1, int arg2, int arg3, int arg4)
15159
{
15160
AUpvlist list;
15161
int type;
15162
void *value;
15163
15164
list = afQuery(querytype, arg1, arg2, arg3, arg4);
15165
if (list == AU_NULL_PVLIST)
15166
return NULL;
15167
AUpvgetvaltype(list, 0, &type);
15168
if (type != AU_PVTYPE_PTR)
15169
return NULL;
15170
AUpvgetval(list, 0, &value);
15171
AUpvfree(list);
15172
return value;
15173
}
15174
15175
/* ARGSUSED3 */
15176
AUpvlist _afQueryInstrumentParameter (int arg1, int arg2, int arg3, int arg4)
15177
{
15178
switch (arg1)
15179
{
15180
/* For the following query types, arg2 is the file format. */
15181
case AF_QUERY_SUPPORTED:
15182
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15183
return AU_NULL_PVLIST;
15184
return _af_pv_long(_af_units[arg2].instrumentParameterCount != 0);
15185
15186
case AF_QUERY_ID_COUNT:
15187
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15188
return AU_NULL_PVLIST;
15189
return _af_pv_long(_af_units[arg2].instrumentParameterCount);
15190
15191
case AF_QUERY_IDS:
15192
{
15193
int count;
15194
int *buffer;
15195
15196
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15197
return AU_NULL_PVLIST;
15198
count = _af_units[arg2].instrumentParameterCount;
15199
if (count == 0)
15200
return AU_NULL_PVLIST;
15201
buffer = (int *) _af_calloc(count, sizeof (int));
15202
if (buffer == NULL)
15203
return AU_NULL_PVLIST;
15204
for (int i=0; i<count; i++)
15205
buffer[i] = _af_units[arg2].instrumentParameters[i].id;
15206
return _af_pv_pointer(buffer);
15207
}
15208
/* NOTREACHED */
15209
break;
15210
15211
/*
15212
For the next few query types, arg2 is the file
15213
format and arg3 is the instrument parameter id.
15214
*/
15215
case AF_QUERY_TYPE:
15216
{
15217
int idx;
15218
15219
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15220
return AU_NULL_PVLIST;
15221
15222
idx = _af_instparam_index_from_id(arg2, arg3);
15223
if (idx<0)
15224
return AU_NULL_PVLIST;
15225
return _af_pv_long(_af_units[arg2].instrumentParameters[idx].type);
15226
}
15227
15228
case AF_QUERY_NAME:
15229
{
15230
int idx;
15231
15232
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15233
return AU_NULL_PVLIST;
15234
idx = _af_instparam_index_from_id(arg2, arg3);
15235
if (idx < 0)
15236
return AU_NULL_PVLIST;
15237
return _af_pv_pointer(const_cast<char *>(_af_units[arg2].instrumentParameters[idx].name));
15238
}
15239
15240
case AF_QUERY_DEFAULT:
15241
{
15242
int idx;
15243
15244
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15245
return AU_NULL_PVLIST;
15246
idx = _af_instparam_index_from_id(arg2, arg3);
15247
if (idx >= 0)
15248
{
15249
AUpvlist ret = AUpvnew(1);
15250
AUpvsetparam(ret, 0, _af_units[arg2].instrumentParameters[idx].id);
15251
AUpvsetvaltype(ret, 0, _af_units[arg2].instrumentParameters[idx].type);
15252
AUpvsetval(ret, 0, const_cast<AFPVu *>(&_af_units[arg2].instrumentParameters[idx].defaultValue));
15253
return ret;
15254
}
15255
return AU_NULL_PVLIST;
15256
}
15257
}
15258
15259
_af_error(AF_BAD_QUERY, "bad query selector");
15260
return AU_NULL_PVLIST;
15261
}
15262
15263
/* ARGSUSED2 */
15264
AUpvlist _afQueryLoop (int arg1, int arg2, int arg3, int arg4)
15265
{
15266
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15267
return AU_NULL_PVLIST;
15268
15269
switch (arg1)
15270
{
15271
case AF_QUERY_SUPPORTED:
15272
return _af_pv_long(_af_units[arg2].loopPerInstrumentCount != 0);
15273
case AF_QUERY_MAX_NUMBER:
15274
return _af_pv_long(_af_units[arg2].loopPerInstrumentCount);
15275
}
15276
15277
_af_error(AF_BAD_QUERY, "bad query selector");
15278
return AU_NULL_PVLIST;
15279
}
15280
15281
/* ARGSUSED2 */
15282
AUpvlist _afQueryInstrument (int arg1, int arg2, int arg3, int arg4)
15283
{
15284
switch (arg1)
15285
{
15286
case AF_QUERY_SUPPORTED:
15287
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15288
return AU_NULL_PVLIST;
15289
return _af_pv_long(_af_units[arg2].instrumentCount != 0);
15290
15291
case AF_QUERY_MAX_NUMBER:
15292
if (arg2 < 0 || arg2 >= _AF_NUM_UNITS)
15293
return AU_NULL_PVLIST;
15294
return _af_pv_long(_af_units[arg2].instrumentCount);
15295
}
15296
15297
_af_error(AF_BAD_QUERY, "bad query selector");
15298
return AU_NULL_PVLIST;
15299
}
15300
15301
/* ARGSUSED0 */
15302
AUpvlist _afQueryMiscellaneous (int arg1, int arg2, int arg3, int arg4)
15303
{
15304
_af_error(AF_BAD_NOT_IMPLEMENTED, "not implemented yet");
15305
return AU_NULL_PVLIST;
15306
}
15307
15308
/* ARGSUSED2 */
15309
AUpvlist _afQueryMarker (int arg1, int arg2, int arg3, int arg4)
15310
{
15311
switch (arg1)
15312
{
15313
case AF_QUERY_SUPPORTED:
15314
return _af_pv_long(_af_units[arg2].markerCount != 0);
15315
case AF_QUERY_MAX_NUMBER:
15316
return _af_pv_long(_af_units[arg2].markerCount);
15317
}
15318
15319
_af_error(AF_BAD_QUERY, "bad query selector");
15320
return AU_NULL_PVLIST;
15321
}
15322
15323
/* ARGSUSED0 */
15324
AUpvlist _afQueryCompression (int arg1, int arg2, int arg3, int arg4)
15325
{
15326
const CompressionUnit *unit = NULL;
15327
15328
switch (arg1)
15329
{
15330
case AF_QUERY_ID_COUNT:
15331
{
15332
int count = 0;
15333
for (int i = 0; i < _AF_NUM_COMPRESSION; i++)
15334
if (_af_compression[i].implemented)
15335
count++;
15336
return _af_pv_long(count);
15337
}
15338
15339
case AF_QUERY_IDS:
15340
{
15341
int *buf = (int *) _af_calloc(_AF_NUM_COMPRESSION, sizeof (int));
15342
if (!buf)
15343
return AU_NULL_PVLIST;
15344
15345
int count = 0;
15346
for (int i = 0; i < _AF_NUM_COMPRESSION; i++)
15347
{
15348
if (_af_compression[i].implemented)
15349
buf[count++] = _af_compression[i].compressionID;
15350
}
15351
return _af_pv_pointer(buf);
15352
}
15353
15354
case AF_QUERY_IMPLEMENTED:
15355
unit = _af_compression_unit_from_id(arg2);
15356
if (!unit)
15357
return _af_pv_long(0);
15358
return _af_pv_long(unit->implemented);
15359
15360
case AF_QUERY_NATIVE_SAMPFMT:
15361
unit = _af_compression_unit_from_id(arg2);
15362
if (!unit)
15363
return AU_NULL_PVLIST;
15364
return _af_pv_long(unit->nativeSampleFormat);
15365
15366
case AF_QUERY_NATIVE_SAMPWIDTH:
15367
unit = _af_compression_unit_from_id(arg2);
15368
if (!unit)
15369
return AU_NULL_PVLIST;
15370
return _af_pv_long(unit->nativeSampleWidth);
15371
15372
case AF_QUERY_LABEL:
15373
unit = _af_compression_unit_from_id(arg2);
15374
if (!unit)
15375
return AU_NULL_PVLIST;
15376
return _af_pv_pointer(const_cast<char *>(unit->label));
15377
15378
case AF_QUERY_NAME:
15379
unit = _af_compression_unit_from_id(arg2);
15380
if (!unit)
15381
return AU_NULL_PVLIST;
15382
return _af_pv_pointer(const_cast<char *>(unit->shortname));
15383
15384
case AF_QUERY_DESC:
15385
unit = _af_compression_unit_from_id(arg2);
15386
if (!unit)
15387
return AU_NULL_PVLIST;
15388
return _af_pv_pointer(const_cast<char *>(unit->name));
15389
}
15390
15391
_af_error(AF_BAD_QUERY, "unrecognized query selector %d\n", arg1);
15392
return AU_NULL_PVLIST;
15393
}
15394
15395
// file: units.cpp
15396
/*
15397
Audio File Library
15398
Copyright (C) 2000-2001, Silicon Graphics, Inc.
15399
15400
This library is free software; you can redistribute it and/or
15401
modify it under the terms of the GNU Lesser General Public
15402
License as published by the Free Software Foundation; either
15403
version 2.1 of the License, or (at your option) any later version.
15404
15405
This library is distributed in the hope that it will be useful,
15406
but WITHOUT ANY WARRANTY; without even the implied warranty of
15407
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15408
Lesser General Public License for more details.
15409
15410
You should have received a copy of the GNU Lesser General Public
15411
License along with this library; if not, write to the
15412
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
15413
Boston, MA 02110-1301 USA
15414
*/
15415
15416
/*
15417
units.cpp
15418
15419
This file contains the file format units.
15420
*/
15421
15422
15423
15424
15425
15426
15427
const Unit _af_units[_AF_NUM_UNITS] =
15428
{
15429
{
15430
AF_FILE_RAWDATA,
15431
"Raw Data", "Raw Sound Data", "raw",
15432
true,
15433
&RawFile::completeSetup,
15434
&RawFile::recognize,
15435
AF_SAMPFMT_TWOSCOMP, 16,
15436
_AF_RAW_NUM_COMPTYPES,
15437
_af_raw_compression_types,
15438
0, /* maximum marker count */
15439
0, /* maximum instrument count */
15440
0, /* maxium number of loops per instrument */
15441
0, NULL,
15442
},
15443
{
15444
AF_FILE_AIFFC,
15445
"AIFF-C", "AIFF-C File Format", "aifc",
15446
true,
15447
AIFFFile::completeSetup,
15448
AIFFFile::recognizeAIFFC,
15449
AF_SAMPFMT_TWOSCOMP, 16,
15450
_AF_AIFFC_NUM_COMPTYPES,
15451
_af_aiffc_compression_types,
15452
65535, /* maximum marker count */
15453
1, /* maximum instrument count */
15454
2, /* maximum number of loops per instrument */
15455
_AF_AIFF_NUM_INSTPARAMS,
15456
_af_aiff_inst_params
15457
},
15458
{
15459
AF_FILE_AIFF,
15460
"AIFF", "Audio Interchange File Format", "aiff",
15461
true,
15462
AIFFFile::completeSetup,
15463
AIFFFile::recognizeAIFF,
15464
AF_SAMPFMT_TWOSCOMP, 16,
15465
0, /* supported compression types */
15466
NULL,
15467
65535, /* maximum marker count */
15468
1, /* maximum instrument count */
15469
2, /* maximum number of loops per instrument */
15470
_AF_AIFF_NUM_INSTPARAMS,
15471
_af_aiff_inst_params
15472
},
15473
{
15474
AF_FILE_WAVE,
15475
"MS RIFF WAVE", "Microsoft RIFF WAVE Format", "wave",
15476
true,
15477
WAVEFile::completeSetup,
15478
WAVEFile::recognize,
15479
AF_SAMPFMT_TWOSCOMP, 16,
15480
_AF_WAVE_NUM_COMPTYPES,
15481
_af_wave_compression_types,
15482
AF_NUM_UNLIMITED, /* maximum marker count */
15483
1, /* maximum instrument count */
15484
AF_NUM_UNLIMITED, /* maximum number of loops per instrument */
15485
_AF_WAVE_NUM_INSTPARAMS,
15486
_af_wave_inst_params
15487
},
15488
};
15489
15490
const CompressionUnit _af_compression[_AF_NUM_COMPRESSION] =
15491
{
15492
{
15493
AF_COMPRESSION_NONE,
15494
true,
15495
"none", /* label */
15496
"none", /* short name */
15497
"not compressed",
15498
1.0,
15499
AF_SAMPFMT_TWOSCOMP, 16,
15500
false, /* needsRebuffer */
15501
false, /* multiple_of */
15502
_af_pcm_format_ok,
15503
_AFpcminitcompress, _AFpcminitdecompress
15504
},
15505
{
15506
AF_COMPRESSION_G711_ULAW,
15507
true,
15508
"ulaw", /* label */
15509
"CCITT G.711 u-law", /* shortname */
15510
"CCITT G.711 u-law",
15511
2.0,
15512
AF_SAMPFMT_TWOSCOMP, 16,
15513
false, /* needsRebuffer */
15514
false, /* multiple_of */
15515
_af_g711_format_ok,
15516
_AFg711initcompress, _AFg711initdecompress
15517
},
15518
{
15519
AF_COMPRESSION_G711_ALAW,
15520
true,
15521
"alaw", /* label */
15522
"CCITT G.711 A-law", /* short name */
15523
"CCITT G.711 A-law",
15524
2.0,
15525
AF_SAMPFMT_TWOSCOMP, 16,
15526
false, /* needsRebuffer */
15527
false, /* multiple_of */
15528
_af_g711_format_ok,
15529
_AFg711initcompress, _AFg711initdecompress
15530
},
15531
{
15532
AF_COMPRESSION_MS_ADPCM,
15533
true,
15534
"msadpcm", /* label */
15535
"MS ADPCM", /* short name */
15536
"Microsoft ADPCM",
15537
4.0,
15538
AF_SAMPFMT_TWOSCOMP, 16,
15539
true, /* needsRebuffer */
15540
false, /* multiple_of */
15541
_af_ms_adpcm_format_ok,
15542
_af_ms_adpcm_init_compress, _af_ms_adpcm_init_decompress
15543
},
15544
};
15545
15546
// file: util.cpp
15547
/*
15548
Audio File Library
15549
Copyright (C) 1998-2000, Michael Pruett <[email protected]>
15550
Copyright (C) 2000, Silicon Graphics, Inc.
15551
15552
This library is free software; you can redistribute it and/or
15553
modify it under the terms of the GNU Lesser General Public
15554
License as published by the Free Software Foundation; either
15555
version 2.1 of the License, or (at your option) any later version.
15556
15557
This library is distributed in the hope that it will be useful,
15558
but WITHOUT ANY WARRANTY; without even the implied warranty of
15559
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15560
Lesser General Public License for more details.
15561
15562
You should have received a copy of the GNU Lesser General Public
15563
License along with this library; if not, write to the
15564
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
15565
Boston, MA 02110-1301 USA
15566
*/
15567
15568
/*
15569
util.c
15570
15571
This file contains general utility routines for the Audio File
15572
Library.
15573
*/
15574
15575
15576
#include <stdio.h>
15577
#include <stdlib.h>
15578
#include <string.h>
15579
#include <assert.h>
15580
15581
15582
15583
/*
15584
_af_filesetup_ok and _af_filehandle_ok are sanity check routines
15585
which are called at the beginning of every external subroutine.
15586
*/
15587
bool _af_filesetup_ok (AFfilesetup setup)
15588
{
15589
if (setup == AF_NULL_FILESETUP)
15590
{
15591
_af_error(AF_BAD_FILESETUP, "null file setup");
15592
return false;
15593
}
15594
if (setup->valid != _AF_VALID_FILESETUP)
15595
{
15596
_af_error(AF_BAD_FILESETUP, "invalid file setup");
15597
return false;
15598
}
15599
return true;
15600
}
15601
15602
bool _af_filehandle_ok (AFfilehandle file)
15603
{
15604
if (file == AF_NULL_FILEHANDLE)
15605
{
15606
_af_error(AF_BAD_FILEHANDLE, "null file handle");
15607
return false;
15608
}
15609
if (file->m_valid != _AF_VALID_FILEHANDLE)
15610
{
15611
_af_error(AF_BAD_FILEHANDLE, "invalid file handle");
15612
return false;
15613
}
15614
return true;
15615
}
15616
15617
void *_af_malloc (size_t size)
15618
{
15619
void *p;
15620
15621
if (size <= 0)
15622
{
15623
_af_error(AF_BAD_MALLOC, "bad memory allocation size request %zd", size);
15624
return NULL;
15625
}
15626
15627
p = malloc(size);
15628
15629
#ifdef AF_DEBUG
15630
if (p)
15631
memset(p, 0xff, size);
15632
#endif
15633
15634
if (p == NULL)
15635
{
15636
_af_error(AF_BAD_MALLOC, "allocation of %zd bytes failed", size);
15637
return NULL;
15638
}
15639
15640
return p;
15641
}
15642
15643
char *_af_strdup (const char *s)
15644
{
15645
char *p = (char *) malloc(strlen(s) + 1);
15646
15647
if (p)
15648
strcpy(p, s);
15649
15650
return p;
15651
}
15652
15653
void *_af_realloc (void *p, size_t size)
15654
{
15655
if (size <= 0)
15656
{
15657
_af_error(AF_BAD_MALLOC, "bad memory allocation size request %zd", size);
15658
return NULL;
15659
}
15660
15661
p = realloc(p, size);
15662
15663
if (p == NULL)
15664
{
15665
_af_error(AF_BAD_MALLOC, "allocation of %zd bytes failed", size);
15666
return NULL;
15667
}
15668
15669
return p;
15670
}
15671
15672
void *_af_calloc (size_t nmemb, size_t size)
15673
{
15674
void *p;
15675
15676
if (nmemb <= 0 || size <= 0)
15677
{
15678
_af_error(AF_BAD_MALLOC, "bad memory allocation size request "
15679
"%zd elements of %zd bytes each", nmemb, size);
15680
return NULL;
15681
}
15682
15683
p = calloc(nmemb, size);
15684
15685
if (p == NULL)
15686
{
15687
_af_error(AF_BAD_MALLOC, "allocation of %zd bytes failed",
15688
nmemb*size);
15689
return NULL;
15690
}
15691
15692
return p;
15693
}
15694
15695
AUpvlist _af_pv_long (long val)
15696
{
15697
AUpvlist ret = AUpvnew(1);
15698
AUpvsetparam(ret, 0, 0);
15699
AUpvsetvaltype(ret, 0, AU_PVTYPE_LONG);
15700
AUpvsetval(ret, 0, &val);
15701
return ret;
15702
}
15703
15704
AUpvlist _af_pv_double (double val)
15705
{
15706
AUpvlist ret = AUpvnew(1);
15707
AUpvsetparam(ret, 0, 0);
15708
AUpvsetvaltype(ret, 0, AU_PVTYPE_DOUBLE);
15709
AUpvsetval(ret, 0, &val);
15710
return ret;
15711
}
15712
15713
AUpvlist _af_pv_pointer (void *val)
15714
{
15715
AUpvlist ret = AUpvnew(1);
15716
AUpvsetparam(ret, 0, 0);
15717
AUpvsetvaltype(ret, 0, AU_PVTYPE_PTR);
15718
AUpvsetval(ret, 0, &val);
15719
return ret;
15720
}
15721
15722
bool _af_pv_getlong (AUpvlist pvlist, int param, long *l)
15723
{
15724
for (int i=0; i<AUpvgetmaxitems(pvlist); i++)
15725
{
15726
int p, t;
15727
15728
AUpvgetparam(pvlist, i, &p);
15729
15730
if (p != param)
15731
continue;
15732
15733
AUpvgetvaltype(pvlist, i, &t);
15734
15735
/* Ensure that this parameter is of type AU_PVTYPE_LONG. */
15736
if (t != AU_PVTYPE_LONG)
15737
return false;
15738
15739
AUpvgetval(pvlist, i, l);
15740
return true;
15741
}
15742
15743
return false;
15744
}
15745
15746
bool _af_pv_getdouble (AUpvlist pvlist, int param, double *d)
15747
{
15748
for (int i=0; i<AUpvgetmaxitems(pvlist); i++)
15749
{
15750
int p, t;
15751
15752
AUpvgetparam(pvlist, i, &p);
15753
15754
if (p != param)
15755
continue;
15756
15757
AUpvgetvaltype(pvlist, i, &t);
15758
15759
/* Ensure that this parameter is of type AU_PVTYPE_DOUBLE. */
15760
if (t != AU_PVTYPE_DOUBLE)
15761
return false;
15762
15763
AUpvgetval(pvlist, i, d);
15764
return true;
15765
}
15766
15767
return false;
15768
}
15769
15770
bool _af_pv_getptr (AUpvlist pvlist, int param, void **v)
15771
{
15772
for (int i=0; i<AUpvgetmaxitems(pvlist); i++)
15773
{
15774
int p, t;
15775
15776
AUpvgetparam(pvlist, i, &p);
15777
15778
if (p != param)
15779
continue;
15780
15781
AUpvgetvaltype(pvlist, i, &t);
15782
15783
/* Ensure that this parameter is of type AU_PVTYPE_PTR. */
15784
if (t != AU_PVTYPE_PTR)
15785
return false;
15786
15787
AUpvgetval(pvlist, i, v);
15788
return true;
15789
}
15790
15791
return false;
15792
}
15793
15794
int _af_format_sample_size_uncompressed (const AudioFormat *format, bool stretch3to4)
15795
{
15796
int size = 0;
15797
15798
switch (format->sampleFormat)
15799
{
15800
case AF_SAMPFMT_FLOAT:
15801
size = sizeof (float);
15802
break;
15803
case AF_SAMPFMT_DOUBLE:
15804
size = sizeof (double);
15805
break;
15806
default:
15807
size = (int) (format->sampleWidth + 7) / 8;
15808
if (format->compressionType == AF_COMPRESSION_NONE &&
15809
size == 3 && stretch3to4)
15810
size = 4;
15811
break;
15812
}
15813
15814
return size;
15815
}
15816
15817
float _af_format_sample_size (const AudioFormat *fmt, bool stretch3to4)
15818
{
15819
const CompressionUnit *unit = _af_compression_unit_from_id(fmt->compressionType);
15820
float squishFactor = unit->squishFactor;
15821
15822
return _af_format_sample_size_uncompressed(fmt, stretch3to4) /
15823
squishFactor;
15824
}
15825
15826
int _af_format_frame_size_uncompressed (const AudioFormat *fmt, bool stretch3to4)
15827
{
15828
return _af_format_sample_size_uncompressed(fmt, stretch3to4) *
15829
fmt->channelCount;
15830
}
15831
15832
float _af_format_frame_size (const AudioFormat *fmt, bool stretch3to4)
15833
{
15834
const CompressionUnit *unit = _af_compression_unit_from_id(fmt->compressionType);
15835
float squishFactor = unit->squishFactor;
15836
15837
return _af_format_frame_size_uncompressed(fmt, stretch3to4) /
15838
squishFactor;
15839
}
15840
15841
/*
15842
Set the sampleFormat and sampleWidth fields in f, and set the
15843
PCM info to the appropriate default values for the given sample
15844
format and sample width.
15845
*/
15846
status _af_set_sample_format (AudioFormat *f, int sampleFormat, int sampleWidth)
15847
{
15848
switch (sampleFormat)
15849
{
15850
case AF_SAMPFMT_UNSIGNED:
15851
case AF_SAMPFMT_TWOSCOMP:
15852
if (sampleWidth < 1 || sampleWidth > 32)
15853
{
15854
_af_error(AF_BAD_SAMPFMT,
15855
"illegal sample width %d for integer data",
15856
sampleWidth);
15857
return AF_FAIL;
15858
}
15859
else
15860
{
15861
int bytes;
15862
15863
f->sampleFormat = sampleFormat;
15864
f->sampleWidth = sampleWidth;
15865
15866
bytes = _af_format_sample_size_uncompressed(f, false);
15867
15868
if (sampleFormat == AF_SAMPFMT_TWOSCOMP)
15869
f->pcm = _af_default_signed_integer_pcm_mappings[bytes];
15870
else
15871
f->pcm = _af_default_unsigned_integer_pcm_mappings[bytes];
15872
}
15873
break;
15874
15875
case AF_SAMPFMT_FLOAT:
15876
f->sampleFormat = sampleFormat;
15877
f->sampleWidth = 32;
15878
f->pcm = _af_default_float_pcm_mapping;
15879
break;
15880
case AF_SAMPFMT_DOUBLE:
15881
f->sampleFormat = sampleFormat;
15882
f->sampleWidth = 64; /*for convenience */
15883
f->pcm = _af_default_double_pcm_mapping;
15884
break;
15885
default:
15886
_af_error(AF_BAD_SAMPFMT, "unknown sample format %d",
15887
sampleFormat);
15888
return AF_FAIL;
15889
}
15890
15891
return AF_SUCCEED;
15892
}
15893
15894
/*
15895
Verify the uniqueness of the nids ids given.
15896
15897
idname is the name of what the ids identify, as in "loop"
15898
iderr is an error as in AF_BAD_LOOPID
15899
*/
15900
bool _af_unique_ids (const int *ids, int nids, const char *idname, int iderr)
15901
{
15902
for (int i = 0; i < nids; i++)
15903
{
15904
for (int j = 0; j < i; j++)
15905
{
15906
if (ids[i] == ids[j])
15907
{
15908
_af_error(iderr, "nonunique %s id %d", idname, ids[i]);
15909
return false;
15910
}
15911
}
15912
}
15913
15914
return true;
15915
}
15916
15917