audiofile.cpp (410835B)
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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <sopwith@redhat.com> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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(×tamp); 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, ¶m); 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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, ¶m); 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, ¶m); 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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, ¶m); 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(¬eTag); 12388 writeU32(¬eSize); 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 <michael@68k.org> 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 <sopwith@redhat.com> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 <michael@68k.org> 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 }