From e27ad901c6975a97a9906050733a2dc1a2cfb2cc Mon Sep 17 00:00:00 2001 From: nobody Date: Fri, 19 May 2006 13:40:37 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create tag 'darkice-0_17_1'. --- darkice/tags/darkice-0_17_1/AUTHORS | 28 + darkice/tags/darkice-0_17_1/COPYING | 345 + darkice/tags/darkice-0_17_1/ChangeLog | 191 + darkice/tags/darkice-0_17_1/FAQ | 21 + darkice/tags/darkice-0_17_1/INSTALL | 52 + darkice/tags/darkice-0_17_1/INSTALL.lame | 52 + darkice/tags/darkice-0_17_1/INSTALL.vorbis | 39 + darkice/tags/darkice-0_17_1/Makefile.am | 19 + darkice/tags/darkice-0_17_1/NEWS | 115 + darkice/tags/darkice-0_17_1/README | 72 + darkice/tags/darkice-0_17_1/TODO | 11 + darkice/tags/darkice-0_17_1/acinclude.m4 | 299 + darkice/tags/darkice-0_17_1/autogen.sh | 69 + darkice/tags/darkice-0_17_1/configure.in | 293 + darkice/tags/darkice-0_17_1/darkice.cfg | 81 + .../tags/darkice-0_17_1/etc/doxygen.config | 1150 ++ .../etc/ebuild/darkice-0.15.ebuild | 42 + .../etc/ebuild/darkice-0.16.ebuild | 45 + .../etc/ebuild/darkice-0.17.1.ebuild | 43 + .../etc/ebuild/darkice-0.17.ebuild | 48 + .../etc/ebuild/twolame-0.3.6.ebuild | 21 + .../tags/darkice-0_17_1/etc/rpm/darkice.spec | 60 + darkice/tags/darkice-0_17_1/etc/rpm/lame.spec | 151 + darkice/tags/darkice-0_17_1/install-sh | 251 + darkice/tags/darkice-0_17_1/man/Makefile.am | 4 + darkice/tags/darkice-0_17_1/man/darkice.1 | 137 + darkice/tags/darkice-0_17_1/man/darkice.cfg.5 | 648 + darkice/tags/darkice-0_17_1/missing | 190 + darkice/tags/darkice-0_17_1/mkinstalldirs | 40 + .../tags/darkice-0_17_1/src/AlsaDspSource.cpp | 310 + .../tags/darkice-0_17_1/src/AlsaDspSource.h | 312 + .../tags/darkice-0_17_1/src/AudioEncoder.h | 488 + .../tags/darkice-0_17_1/src/AudioSource.cpp | 132 + darkice/tags/darkice-0_17_1/src/AudioSource.h | 340 + .../tags/darkice-0_17_1/src/BufferedSink.cpp | 395 + .../tags/darkice-0_17_1/src/BufferedSink.h | 421 + darkice/tags/darkice-0_17_1/src/CastSink.cpp | 179 + darkice/tags/darkice-0_17_1/src/CastSink.h | 500 + .../tags/darkice-0_17_1/src/ConfigSection.cpp | 216 + .../tags/darkice-0_17_1/src/ConfigSection.h | 212 + darkice/tags/darkice-0_17_1/src/Connector.cpp | 388 + darkice/tags/darkice-0_17_1/src/Connector.h | 286 + darkice/tags/darkice-0_17_1/src/DarkIce.cpp | 1307 ++ darkice/tags/darkice-0_17_1/src/DarkIce.h | 374 + .../tags/darkice-0_17_1/src/DarkIceConfig.cpp | 210 + .../tags/darkice-0_17_1/src/DarkIceConfig.h | 247 + darkice/tags/darkice-0_17_1/src/Exception.cpp | 228 + darkice/tags/darkice-0_17_1/src/Exception.h | 325 + .../tags/darkice-0_17_1/src/FaacEncoder.cpp | 207 + darkice/tags/darkice-0_17_1/src/FaacEncoder.h | 458 + darkice/tags/darkice-0_17_1/src/FileCast.cpp | 103 + darkice/tags/darkice-0_17_1/src/FileCast.h | 277 + darkice/tags/darkice-0_17_1/src/FileSink.cpp | 341 + darkice/tags/darkice-0_17_1/src/FileSink.h | 269 + darkice/tags/darkice-0_17_1/src/IceCast.cpp | 254 + darkice/tags/darkice-0_17_1/src/IceCast.h | 294 + darkice/tags/darkice-0_17_1/src/IceCast2.cpp | 306 + darkice/tags/darkice-0_17_1/src/IceCast2.h | 297 + .../tags/darkice-0_17_1/src/JackDspSource.cpp | 454 + .../tags/darkice-0_17_1/src/JackDspSource.h | 292 + .../darkice-0_17_1/src/LameLibEncoder.cpp | 467 + .../tags/darkice-0_17_1/src/LameLibEncoder.h | 505 + darkice/tags/darkice-0_17_1/src/Makefile.am | 70 + .../src/MultiThreadedConnector.cpp | 443 + .../src/MultiThreadedConnector.h | 370 + .../tags/darkice-0_17_1/src/OssDspSource.cpp | 353 + .../tags/darkice-0_17_1/src/OssDspSource.h | 286 + darkice/tags/darkice-0_17_1/src/Ref.h | 320 + darkice/tags/darkice-0_17_1/src/Referable.h | 185 + darkice/tags/darkice-0_17_1/src/Reporter.cpp | 77 + darkice/tags/darkice-0_17_1/src/Reporter.h | 350 + darkice/tags/darkice-0_17_1/src/ShoutCast.cpp | 238 + darkice/tags/darkice-0_17_1/src/ShoutCast.h | 276 + darkice/tags/darkice-0_17_1/src/Sink.h | 198 + .../darkice-0_17_1/src/SolarisDspSource.cpp | 281 + .../darkice-0_17_1/src/SolarisDspSource.h | 281 + darkice/tags/darkice-0_17_1/src/Source.h | 186 + darkice/tags/darkice-0_17_1/src/TcpSocket.cpp | 418 + darkice/tags/darkice-0_17_1/src/TcpSocket.h | 297 + .../darkice-0_17_1/src/TwoLameLibEncoder.cpp | 317 + .../darkice-0_17_1/src/TwoLameLibEncoder.h | 385 + darkice/tags/darkice-0_17_1/src/Util.cpp | 538 + darkice/tags/darkice-0_17_1/src/Util.h | 360 + .../darkice-0_17_1/src/VorbisLibEncoder.cpp | 494 + .../darkice-0_17_1/src/VorbisLibEncoder.h | 479 + .../tags/darkice-0_17_1/src/aflibConverter.cc | 797 + .../tags/darkice-0_17_1/src/aflibConverter.h | 236 + .../src/aflibConverterLargeFilter.h | 16432 ++++++++++++++++ .../src/aflibConverterSmallFilter.h | 4643 +++++ darkice/tags/darkice-0_17_1/src/aflibDebug.cc | 228 + darkice/tags/darkice-0_17_1/src/aflibDebug.h | 118 + darkice/tags/darkice-0_17_1/src/main.cpp | 227 + darkice/tags/darkice-0_17_1/stamp-h.in | 1 + 93 files changed, 45795 insertions(+) create mode 100644 darkice/tags/darkice-0_17_1/AUTHORS create mode 100644 darkice/tags/darkice-0_17_1/COPYING create mode 100644 darkice/tags/darkice-0_17_1/ChangeLog create mode 100644 darkice/tags/darkice-0_17_1/FAQ create mode 100644 darkice/tags/darkice-0_17_1/INSTALL create mode 100644 darkice/tags/darkice-0_17_1/INSTALL.lame create mode 100644 darkice/tags/darkice-0_17_1/INSTALL.vorbis create mode 100644 darkice/tags/darkice-0_17_1/Makefile.am create mode 100644 darkice/tags/darkice-0_17_1/NEWS create mode 100644 darkice/tags/darkice-0_17_1/README create mode 100644 darkice/tags/darkice-0_17_1/TODO create mode 100644 darkice/tags/darkice-0_17_1/acinclude.m4 create mode 100755 darkice/tags/darkice-0_17_1/autogen.sh create mode 100644 darkice/tags/darkice-0_17_1/configure.in create mode 100644 darkice/tags/darkice-0_17_1/darkice.cfg create mode 100644 darkice/tags/darkice-0_17_1/etc/doxygen.config create mode 100644 darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.15.ebuild create mode 100644 darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.16.ebuild create mode 100644 darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.1.ebuild create mode 100644 darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.ebuild create mode 100644 darkice/tags/darkice-0_17_1/etc/ebuild/twolame-0.3.6.ebuild create mode 100644 darkice/tags/darkice-0_17_1/etc/rpm/darkice.spec create mode 100644 darkice/tags/darkice-0_17_1/etc/rpm/lame.spec create mode 100755 darkice/tags/darkice-0_17_1/install-sh create mode 100644 darkice/tags/darkice-0_17_1/man/Makefile.am create mode 100644 darkice/tags/darkice-0_17_1/man/darkice.1 create mode 100644 darkice/tags/darkice-0_17_1/man/darkice.cfg.5 create mode 100755 darkice/tags/darkice-0_17_1/missing create mode 100755 darkice/tags/darkice-0_17_1/mkinstalldirs create mode 100644 darkice/tags/darkice-0_17_1/src/AlsaDspSource.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/AlsaDspSource.h create mode 100644 darkice/tags/darkice-0_17_1/src/AudioEncoder.h create mode 100644 darkice/tags/darkice-0_17_1/src/AudioSource.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/AudioSource.h create mode 100644 darkice/tags/darkice-0_17_1/src/BufferedSink.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/BufferedSink.h create mode 100644 darkice/tags/darkice-0_17_1/src/CastSink.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/CastSink.h create mode 100644 darkice/tags/darkice-0_17_1/src/ConfigSection.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/ConfigSection.h create mode 100644 darkice/tags/darkice-0_17_1/src/Connector.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/Connector.h create mode 100644 darkice/tags/darkice-0_17_1/src/DarkIce.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/DarkIce.h create mode 100644 darkice/tags/darkice-0_17_1/src/DarkIceConfig.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/DarkIceConfig.h create mode 100644 darkice/tags/darkice-0_17_1/src/Exception.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/Exception.h create mode 100644 darkice/tags/darkice-0_17_1/src/FaacEncoder.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/FaacEncoder.h create mode 100644 darkice/tags/darkice-0_17_1/src/FileCast.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/FileCast.h create mode 100644 darkice/tags/darkice-0_17_1/src/FileSink.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/FileSink.h create mode 100644 darkice/tags/darkice-0_17_1/src/IceCast.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/IceCast.h create mode 100644 darkice/tags/darkice-0_17_1/src/IceCast2.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/IceCast2.h create mode 100644 darkice/tags/darkice-0_17_1/src/JackDspSource.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/JackDspSource.h create mode 100644 darkice/tags/darkice-0_17_1/src/LameLibEncoder.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/LameLibEncoder.h create mode 100644 darkice/tags/darkice-0_17_1/src/Makefile.am create mode 100644 darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.h create mode 100644 darkice/tags/darkice-0_17_1/src/OssDspSource.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/OssDspSource.h create mode 100644 darkice/tags/darkice-0_17_1/src/Ref.h create mode 100644 darkice/tags/darkice-0_17_1/src/Referable.h create mode 100644 darkice/tags/darkice-0_17_1/src/Reporter.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/Reporter.h create mode 100644 darkice/tags/darkice-0_17_1/src/ShoutCast.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/ShoutCast.h create mode 100644 darkice/tags/darkice-0_17_1/src/Sink.h create mode 100644 darkice/tags/darkice-0_17_1/src/SolarisDspSource.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/SolarisDspSource.h create mode 100644 darkice/tags/darkice-0_17_1/src/Source.h create mode 100644 darkice/tags/darkice-0_17_1/src/TcpSocket.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/TcpSocket.h create mode 100644 darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.h create mode 100644 darkice/tags/darkice-0_17_1/src/Util.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/Util.h create mode 100644 darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.cpp create mode 100644 darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.h create mode 100644 darkice/tags/darkice-0_17_1/src/aflibConverter.cc create mode 100644 darkice/tags/darkice-0_17_1/src/aflibConverter.h create mode 100644 darkice/tags/darkice-0_17_1/src/aflibConverterLargeFilter.h create mode 100644 darkice/tags/darkice-0_17_1/src/aflibConverterSmallFilter.h create mode 100644 darkice/tags/darkice-0_17_1/src/aflibDebug.cc create mode 100644 darkice/tags/darkice-0_17_1/src/aflibDebug.h create mode 100644 darkice/tags/darkice-0_17_1/src/main.cpp create mode 100644 darkice/tags/darkice-0_17_1/stamp-h.in diff --git a/darkice/tags/darkice-0_17_1/AUTHORS b/darkice/tags/darkice-0_17_1/AUTHORS new file mode 100644 index 0000000..09cc55d --- /dev/null +++ b/darkice/tags/darkice-0_17_1/AUTHORS @@ -0,0 +1,28 @@ +DarkIce is being written by: + + Akos Maroy, + +with contributions by: + + Jim Crilly, + aNa|0Gue, + Robin P. Blanchard, + Tom Gray, + Michael Smith, + Julius O. Smith, + the OSALP team, http://osalp.sourceforge.net + Kristjan G. Bjarnason + Nicu Pavel + Kai Krakow + Atsuhiko Yamanaka + Ricardo Galli + John Hay + Christian Forster + John Deeny + Robert Lunnon + Enrico Ardizzoni + Deti Fliegl + Nicholas J. Humfrey + Joel Ebel + + diff --git a/darkice/tags/darkice-0_17_1/COPYING b/darkice/tags/darkice-0_17_1/COPYING new file mode 100644 index 0000000..598598b --- /dev/null +++ b/darkice/tags/darkice-0_17_1/COPYING @@ -0,0 +1,345 @@ +All source code in the src directory is covered under the +GNU General Public License (GNU GPL). + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/darkice/tags/darkice-0_17_1/ChangeLog b/darkice/tags/darkice-0_17_1/ChangeLog new file mode 100644 index 0000000..417d00e --- /dev/null +++ b/darkice/tags/darkice-0_17_1/ChangeLog @@ -0,0 +1,191 @@ +19-05-2006 DarkIce 0.17.1 released + + o bugfix: automatic reconnect works more reliably + +26-01-2006 DarkIce 0.17 released + + o added check for bufferSecs set to 0 + thanks to Toph + o added realtime parameter to the general section + o added MPEG2 support through the TwoLame library. + thanks to Nicholas J Humfrey + +22-10-2005 DarkIce 0.16 released + + o added AAC support through the faac codec, http://www.audiocoding.com + o bug fix: icecast2 sections didn't honor lowpass or highpass filters + when using the mp3 format + +14-04-2005 DarkIce 0.15 released + + o ported to OpenBSD and NetBSD, though real-time scheduling not supported, + since it is not implemented in OpenBSD / NetBSD + o added possibility to downsample from stereo to mono when encoding + to Ogg Vorbis, thanks to Deti Fliegl, + o added support for Jack inputs, enabling a lot of interesting usage, + including support for MacOS X. + Thanks to Nicholas J. Humfrey + o various improvements by Joel Ebel + o added option to turn off automatic reconnect feature + o added IPv6 support, thanks to + +15-02-2004: DarkIce 0.14 released + + o added ALSA support, thanks to Christian Forster + + o added fix to enable downsampling from stereo to mono of mp3 streams + when streaming to an icecast2 server. thanks to John Deeny + + o removed _X and _Y symbols from aflibConverter files, which caused + a naming collision on Solaris. thanks to Robert Lunnon, + + o bug fix: ogg vorbis recording to only a file caused a segfault. + now fixed, thanks to Enrico Ardizzoni + +07-01-2004: DarkIce 0.13.2 released + + o bug fix: two bugs fixed that caused core dump when encoding into + mp3 of FreeBSD. thanks to John Hay + o added configure option --with-debug to enable compilation for debug mode + +12-02-2003: Darkice 0.13.1 released + + o added cross-platform pthread detection, thanks to + Steven G. Johnson and + Alejandro Forero Cuervo + see http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html + o added proper detection of netural endiannes for 16 bit recording + o basically these changes allow compilation on FreeBSD + +09-02-2003: DarkIce 0.13 released + + o added feature for setting the TITLE comment field for vorbis + streams. thanks to Ricardo Galli + o bugfix: fixed minor bug in IcecCast2.cpp, which could have lead to + a buffer overflow. thanks to Atsuhiko Yamanaka + o bugfix: MultiThreadedConnector::sinkThread() was private, now public + o added fileAddDate configuration option + thanks to Nicu Pavel + o added support for big endian OSS devices (like Linux PowerPC) + +20-10-2002: DarkIce 0.12 released + + o ported to FreeBSD (removed reference to MSG_NOSIGNAL in TcpSocket.cpp) + o bug fix: maximum bitrate setting fixed for Ogg Vorbis streams + o changed internals so that now each encoding/server connection is + a separate thread + o when a connection is dropped, DarkIce tries to reconnect, indefinitely + +20-08-2002: DarkIce 0.11 released + + o added possibility to specify maximum bitrate for Ogg Vorbis streams + o added HTTP Basic authentication for icecast2 logins + o added mp3 streaming for icecast2 + o added possibility to stream in mono even when recording in stereo, + thus enabling mono and stereo streams with the same darkice instance. + only for mp3 streams at the moment + thanks to Kai Krakow + o bug fix: resampling audio for vorbis streams bugs fixed + +02-08-2002: DarkIce 0.10.1 released + + o bug fix: when the last server dropped connection, darkice crashed + thanks to Nicu Pavel + o bug fix for LameLibEncoder: the mp3 encoding buffer was deleted too + early, resulting in mp3 data corruption. + thanks to Nicu Pavel + +20-07-2002: DarkIce 0.10 released + + o added possibility to select constant, average and variable bit rate + encoding modes with specifying encoding quality as well. + thanks to Nicu Pavel + o added support for Ogg Vorbis 1.0 final, removed support for rc2 + o added fault tolerance: if one of several server connection drops, + DarkIce carries on with the rest of the servers still connected + +09-04-2002: DarkIce 0.9.1 released + + o bugfix: a memory leak was introduced in 0.9, which is fixed thanks to + Kristjan G. Bjarnason and Nicu Pavel + o minor documentation fix + +28-03-2002: DarkIce 0.9 released + + o added possibility to simply read from the soundcard, encode, and + save the encoded data into a local file (no streaming server needed) + o added variable bitrate support for vorbis streams + o support for both rc2 and rc3 versions of vorbis libraries + o added support for resampling when encoding to vorbis + thanks to the OSALP project for the resampling class, + http://osalp.sourceforge.net/ and + Julius O. Smith, for the original code + +20-02-2002: DarkIce 0.8 released + + o added possibility to disable lowpass and highpass filtering for lame + o fixed incorrect vorbis bitrate setting + o fix: DarkIce now reports public streams correctly + thanks to Tom Gray, + o made up-to-date with Ogg Vorbis rc3 libs + thanks to Michael Smith, + o made up-to-date with current IceCast2 cvs version + o added local stream dump possibility + +19-10-2001: DarkIce 0.7 released + + o added support for FreeBSD + thanks to Robin P. Blanchard, + o added support for resampling mp3 streams + o DarkIce config file now may contain spaces and tabs as white space + o configure script enables build with or without lame / Ogg Vorbis + also possibility to specify alternate locations for these + +18-09-2001: DarkIce 0.6 released + + o added support for IceCast2 server with Ogg Vorbis streaming + Ogg Vorbis support thanks to aNa|0Gue + o added support for SUN Solaris + o removed long command line options (as these are extensions to UNIX) + o removed configure option to specify location of lame library + o removed configure option to compile static executable + +09-09-2001: DarkIce 0.5 released + + o added support for ShoutCast servers + o removed local copy of SGI STL, uses STL of the C++ compiler + o compiles with gcc3-c++ + o added man page darkice.cfg.5 + o bugfix: config files can have comments before the first section + +02-09-2001: DarkIce 0.4 released + + o support for external command line encoder removed, replaced + with using lame as a shared object or statically linked library + o added darkice man page + o created RPM packages + o DarkIce no longer reports an error if the sound card recording + sample rate could not be set to the exact specified amount + (e.g. the sound card reports 44101 Hz instead of 44100 Hz) + + +26-08-2001: DarkIce 0.3.1 released + + o support for unlimited time encoding + thanks to Jim Crilly, + + +20-12-2000: DarkIce 0.3 released + + o added POSIX real-time scheduling + + +18-11-2000: DarkIce 0.2 released + + o code cleanup + o first real tests made + o added verbosity command line option + + +13-11-2000: DarkIce 0.1 released + diff --git a/darkice/tags/darkice-0_17_1/FAQ b/darkice/tags/darkice-0_17_1/FAQ new file mode 100644 index 0000000..d19c4e6 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/FAQ @@ -0,0 +1,21 @@ +DarkIce Frequenty Asked Questions + + +Q: I get the following error: + +DarkIce: LameLibEncoder.cpp:75: lame lib opening underlying sink error [0] + +What am I doing wrong? + + +A: This error means (quite anti-intuitively), that darkice coulnd't connect + to the streaming server. Please double-check the following values in + your config file: + - server + - port + - password + + If you're streaming to a shoutcast server, make sure that the port + you use is the _source_ port, which is usually 1 above the _client_ + port for shoutcast (the defaults are 8000 for client, 8001 for source). + diff --git a/darkice/tags/darkice-0_17_1/INSTALL b/darkice/tags/darkice-0_17_1/INSTALL new file mode 100644 index 0000000..9c330dc --- /dev/null +++ b/darkice/tags/darkice-0_17_1/INSTALL @@ -0,0 +1,52 @@ +DarkIce installation notes +========================== + +DarkIce uses the following libraries (and associated header files): + +for capability to stream mp3 to IceCast 1.x and Shoutcast: +- libmp3lame + +for capability to stream Ogg Vorbis to IceCast 2: +- libogg +- libvoribs +- libvorbisenc + +To install libmp3lame, please refer to INSTALL.lame. +To install libogg, libvoribs and libvorbisenc, please look at INSTALL.vorbis. + + +Installing DarkIce +------------------ + +If you're reading this, you probably have downloaded and extracted the +DarkIce tarball. Go to the directory you extracted it, and try: + +./configure --help + +This will give you all the compile configuration options. + +On Solaris systems, for some reason the configure script does not +find the include file lame/lame.h if it uses the SUN Workshop C compiler +as a preprocessor for testing. Therefore you might consider setting: + +export CPP="gcc -E" + +This hack is not needed on other systems. + +If chosing the default compile options, issue the following commands: + +./configure +make +make install + +For the last step, you need to be root or have write permissions in the +target directories, usually directories under /usr/local. + +Now you should have DarkIce installed. For documentation, try + +man darkice + +To try out the program, try + +darkice -h + diff --git a/darkice/tags/darkice-0_17_1/INSTALL.lame b/darkice/tags/darkice-0_17_1/INSTALL.lame new file mode 100644 index 0000000..f49d27c --- /dev/null +++ b/darkice/tags/darkice-0_17_1/INSTALL.lame @@ -0,0 +1,52 @@ +Installing Lame +--------------- + +To install DarkIce, you need the Lame 3.89 or later libraries and +related header files already installed on your system. + +It is recommended that use install Lame to the usual system locations, +/usr/lib, /usr/include, so that DarkIce will find the header files and +libraries. Thus when configuring, add --prefix=/usr to the configure +options. + +Grab the latest lame source tarball from a download site found at +http://www.mp3dev.org/mp3/download/download.html +or from the DarkIce SourceForge project download area +http://sourceforge.net/project/showfiles.php?group_id=14111 + +I took lame lame-3.91.tar.gz. Go to the directory where you saved it, +and issue the following commands: + +tar xfz lame-3.91.tar.gz +cd lame-3.91 +./configure --with-fileio=lame --without-vorbis --disable-gtktest --enable-expopt=full --prefix=/usr +make +make install + +For the last step, you need to be root or have write permissions in the +target directories. + +You might consider using nasm if you're on a i386 system, with the +configure option --enable-nasmm, for maximum performance. + + +On RedHat Linux +--------------- + +Compiling Lame on RedHat Linux is a tricky issue, because of gcc 2.96 +packaged with the distributions 7.0 and 7.1. You either have to use +the comaptibility compiler package (compat-egcs and related packages, +providing gcc 2.91), or even better, gcc 3.0. + +It is recommended that you compile lame with gcc 3. For maximum performance, +use the nasm assembler to compile assembly optimizations into lame. +Try the following commands: + +tar xfz lame-3.91.tar.gz +cd lame-3.91 +export CC=gcc3 +./configure --with-fileio=lame --without-vorbis --disable-gtktest --enable-nasm --enable-expopt=full --prefix=/usr +make +make install + + diff --git a/darkice/tags/darkice-0_17_1/INSTALL.vorbis b/darkice/tags/darkice-0_17_1/INSTALL.vorbis new file mode 100644 index 0000000..44d135f --- /dev/null +++ b/darkice/tags/darkice-0_17_1/INSTALL.vorbis @@ -0,0 +1,39 @@ +Installing Ogg Vorbis +--------------------- + +To install DarkIce, you need the following Ogg Vorbis 1.0 or later +libraries (and related header files): + +- libogg +- libvoribs +- libvorbisenc + +installed on your system. + +It is recommended that use install these to the usual system locations, +/usr/lib, /usr/include, so that DarkIce will find the header files and +libraries. Thus when configuring, add --prefix=/usr to the configure +options. + +Grab the latest Ogg Vorbis tarballs from +http://www.xiph.org/ogg/vorbis/download.html + +I took libogg-1.0.tar.gz and libvorbis-1.0.tar.gz. Go to the +directory where you saved them, and issue the following commands: + +tar xfz libogg-1.0.tar.gz +cd libogg-1.0 +./configure --prefix=/usr +make +make install +cd .. + +tar xfz libvorbis-1.0.tar.gz +cd libvorbis-1.0 +./configure --prefix=/usr +make +make install + +For the install steps, you need to be root or have write permissions in the +target directories. + diff --git a/darkice/tags/darkice-0_17_1/Makefile.am b/darkice/tags/darkice-0_17_1/Makefile.am new file mode 100644 index 0000000..64ad01e --- /dev/null +++ b/darkice/tags/darkice-0_17_1/Makefile.am @@ -0,0 +1,19 @@ +DOC_DIR = doc +DOXYGEN_DIR = doc/doxygen +DOXYGEN_CONFIG = etc/doxygen.config + +SUBDIRS = src man + +sysconf_DATA = darkice.cfg + +EXTRA_DIST = $(DOC_DIR) darkice.cfg INSTALL.lame INSTALL.vorbis FAQ + +.PHONY: doc + +doc: src + mkdir -p $(DOXYGEN_DIR) + doxygen etc/doxygen.config + +doxygen_clean: + rm -rf $(DOXYGEN_DIR) + diff --git a/darkice/tags/darkice-0_17_1/NEWS b/darkice/tags/darkice-0_17_1/NEWS new file mode 100644 index 0000000..9676490 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/NEWS @@ -0,0 +1,115 @@ +19-05-2006, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.17.1. See ChangeLog for changes. + + +26-01-2006, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.17. See ChangeLog for changes. + + +22-10-2005, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.16. See ChangeLog for changes. + + +14-04-2005, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.15. See ChangeLog for changes. + + +15-02-2004, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.14. See ChangeLog for changes. + + +07-01-2004, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.13.2. See ChangeLog for changes. + + +12-02-2003, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.13.1. See ChangeLog for changes. + + +09-02-2003, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.13. See ChangeLog for changes. + + +20-10-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.12. See ChangeLog for changes. + + +20-08-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.11. See ChangeLog for changes. + + +02-08-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.10.1. See ChangeLog for changes. + + +20-07-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.10. See ChangeLog for changes. + + +09-04-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.9.1. See ChangeLog for changes. + + +28-03-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.9. See ChangeLog for changes. + + +20-02-2002, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.8. See ChangeLog for changes. + + +19-10-2001, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.7. See ChangeLog for changes. + + +18-09-2001, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.6. See ChangeLog for changes. + + +09-09-2001, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.5. See ChangeLog for changes. + + +02-09-2001, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.4. See ChangeLog for changes. + + +26-08-2001, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.3.1. See ChangeLog for changes. + + +20-12-2000, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.3. See ChangeLog for changes. + + +18-11-2000, Akos Maroy, darkeye@users.sourceforge.net + + Released version 0.2. See ChangeLog for changes. + + +13-11-2000, Akos Maroy, darkeye@users.sourceforge.net + + Initial release. Supports the lame encoder. + + diff --git a/darkice/tags/darkice-0_17_1/README b/darkice/tags/darkice-0_17_1/README new file mode 100644 index 0000000..9e7c042 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/README @@ -0,0 +1,72 @@ +DarkIce live audio streamer, http://darkice.sourceforge.net +Copyright (c) 2000-2006, Tyrell Hungary, http://tyrell.hu + + +Contents +-------- + +1. What is DarkIce? +2. Compiling and installing +3. Reporting crashes + + +1. What is DarkIce? +------------------- + +DarkIce is an IceCast, IceCast2 and ShoutCast live audio streamer. It +takes audio input from a sound card, encodes it into mp3 and/or Ogg Vorbis, +and sends the mp3 stream to one or more IceCast and/or ShoutCast servers, +the Ogg Vorbis stream to one or more IceCast2 servers. + +DarkIce is hosted on SourceForge, at http://darkice.sourceforge.net/ + + +2. Compiling and installing +--------------------------- + +On how to compile and install, please read the file INSTALL. If you're +impatient, try: + +./configure +make + +The executable built is src/darkice. +To install, try as root: + +make install + + +For documentation, try: + +man darkice + + +3. Reporting crashes +-------------------- + +When DarkIce core dumps, please send the backtrace along with your error +report to the darkice mailing list: darkice-list@lists.sourceforge.net +To get the backtrace information, you need gdb, the GNU debugger: + +1. configure and compile using the --with-debug option: + +./configure --with-debug=yes +make clean all + +2. run darkice from within gdb: + +gdb src/darkice + +3. set parameters within gdb: + +(gdb) set args -c darkice.cfg + +4. run: + +(gdb) run + +5. after coredump, print the backtrace: + +(gdb) bt + + diff --git a/darkice/tags/darkice-0_17_1/TODO b/darkice/tags/darkice-0_17_1/TODO new file mode 100644 index 0000000..37c46a2 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/TODO @@ -0,0 +1,11 @@ +o change Ref to follow inheritance +o make a master config file, and a small one ? +o add support for multiple servers for one stream ? +o revisit real-time scheduling +o look into performance +o create proper error-reporting module +o set comment fields for Ogg Vorbis streams as in + http://www.xiph.org/ogg/vorbis/doc/v-comment.html +o change config file to separate descriptions of input, streams and + stream targets (servers, files, etc.) +o add support for 24 and 32 bit input and higher sample rates (up to 96kHz) diff --git a/darkice/tags/darkice-0_17_1/acinclude.m4 b/darkice/tags/darkice-0_17_1/acinclude.m4 new file mode 100644 index 0000000..db466d9 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/acinclude.m4 @@ -0,0 +1,299 @@ +dnl acinclude.m4. Change *this* file to add new or change macros. +dnl When changes have been made, delete aclocal.m4 and run +dnl "aclocal". +dnl +dnl DO NOT change aclocal.m4 ! +dnl + +dnl----------------------------------------------------------------------------- +dnl LA_SEARCH_FILE(variable, filename, PATH) +dnl Search "filename" in the specified "PATH", "variable" will +dnl contain the full pathname or the empty string +dnl PATH is space-separated list of directories. +dnl by Florian Bomers +dnl----------------------------------------------------------------------------- +AC_DEFUN(LA_SEARCH_FILE,[ + $1= + dnl hack: eliminate line feeds in $2 + for FILE in $2; do + for DIR in $3; do + dnl use PATH in order + if test ".$1"="." && test -f "$DIR/$FILE"; then + $1=$DIR + fi + done + done +]) + +dnl----------------------------------------------------------------------------- +dnl LA_SEARCH_LIB(lib-variable, include-variable, lib-filename, header-filename, prefix) +dnl looks for "lib-filename" and "header-filename" in the area of "prefix". +dnl if found, "lib-variable" and "include-variable" are set to the +dnl respective paths. +dnl prefix is a single path +dnl libs are searched in prefix, prefix/lib +dnl headers are searched in prefix, prefix/include, +dnl +dnl If one of them is not found, both "lib-variable", "include-variable" are +dnl set to the empty string. +dnl +dnl TODO: assert function call to verify lib +dnl +dnl by Florian Bomers +dnl----------------------------------------------------------------------------- +AC_DEFUN(LA_SEARCH_LIB,[ + dnl look for lib + LA_SEARCH_FILE($1, $3, $5 $5/lib ) + dnl look for header. + LA_SEARCH_FILE($2, $4, $5 $5/include ) + if test ".$1" = "." || test ".$2" = "."; then + $1= + $2= + fi +]) + + +dnl----------------------------------------------------------------------------- +dnl funky posix threads checking, thanks to +dnl Steven G. Johnson +dnl and Alejandro Forero Cuervo +dnl see http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html +dnl----------------------------------------------------------------------------- +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +dnl +dnl This macro figures out how to build C programs using POSIX +dnl threads. It sets the PTHREAD_LIBS output variable to the threads +dnl library and linker flags, and the PTHREAD_CFLAGS output variable +dnl to any special C compiler flags that are needed. (The user can also +dnl force certain compiler flags/libs to be tested by setting these +dnl environment variables.) +dnl +dnl Also sets PTHREAD_CC to any special C compiler that is needed for +dnl multi-threaded programs (defaults to the value of CC otherwise). +dnl (This is necessary on AIX to use the special cc_r compiler alias.) +dnl +dnl NOTE: You are assumed to not only compile your program with these +dnl flags, but also link it with them as well. e.g. you should link +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +dnl +dnl If you are only building threads programs, you may wish to +dnl use these variables in your default LIBS, CFLAGS, and CC: +dnl +dnl LIBS="$PTHREAD_LIBS $LIBS" +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +dnl CC="$PTHREAD_CC" +dnl +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE +dnl to that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +dnl +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands +dnl to run it if it is not found. If ACTION-IF-FOUND is not specified, +dnl the default action will define HAVE_PTHREAD. +dnl +dnl Please let the authors know if this macro fails on any platform, +dnl or if you have any other suggestions or comments. This macro was +dnl based on work by SGJ on autoconf scripts for FFTW (www.fftw.org) +dnl (with help from M. Frigo), as well as ac_pthread and hb_pthread +dnl macros posted by AFC to the autoconf macro repository. We are also +dnl grateful for the helpful feedback of numerous users. +dnl +dnl @version $Id$ +dnl @author Steven G. Johnson and Alejandro Forero Cuervo + +AC_DEFUN([ACX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG_C +acx_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on True64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) + AC_MSG_RESULT($acx_pthread_ok) + if test x"$acx_pthread_ok" = xno; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all. + +acx_pthread_flags="pthread-config pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthread-config: use pthread-config program (on NetBSD) +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +# -pthreads: Solaris/gcc +# -mthreads: Mingw32/gcc, Lynx/gcc +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads too; +# also defines -D_REENTRANT) +# pthread: Linux, etcetera +# --thread-safe: KAI C++ + +case "${host_cpu}-${host_os}" in + *solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (We need to link with -pthread or + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather + # a function called by this macro, so we could check for that, but + # who knows whether they'll stub that too in a future libc.) So, + # we'll just look for -pthreads and -lpthread first: + + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" + ;; +esac + +if test x"$acx_pthread_ok" = xno; then +for flag in $acx_pthread_flags; do + + case $flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $flag]) + PTHREAD_CFLAGS="$flag" + ;; + + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$flag]) + PTHREAD_LIBS="-l$flag" + ;; + esac + + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + AC_TRY_LINK([#include ], + [pthread_t th; pthread_join(th, 0); + pthread_attr_init(0); pthread_cleanup_push(0, 0); + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], + [acx_pthread_ok=yes]) + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + AC_MSG_RESULT($acx_pthread_ok) + if test "x$acx_pthread_ok" = xyes; then + break; + fi + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$acx_pthread_ok" = xyes; then + save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + + # Detect AIX lossage: threads are created detached by default + # and the JOINABLE attribute has a nonstandard name (UNDETACHED). + AC_MSG_CHECKING([for joinable pthread attribute]) + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_JOINABLE;], + ok=PTHREAD_CREATE_JOINABLE, ok=unknown) + if test x"$ok" = xunknown; then + AC_TRY_LINK([#include ], + [int attr=PTHREAD_CREATE_UNDETACHED;], + ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) + fi + if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then + AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, + [Define to the necessary symbol if this constant + uses a non-standard name on your system.]) + fi + AC_MSG_RESULT(${ok}) + if test x"$ok" = xunknown; then + AC_MSG_WARN([we do not know how to create joinable pthreads]) + fi + + AC_MSG_CHECKING([if more special flags are required for pthreads]) + flag=no + case "${host_cpu}-${host_os}" in + *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + esac + AC_MSG_RESULT(${flag}) + if test "x$flag" != xno; then + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + fi + + LIBS="$save_LIBS" + CFLAGS="$save_CFLAGS" + + # More AIX lossage: must compile with cc_r + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) +else + PTHREAD_CC="$CC" +fi + +AC_SUBST(PTHREAD_LIBS) +AC_SUBST(PTHREAD_CFLAGS) +AC_SUBST(PTHREAD_CC) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test x"$acx_pthread_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + : +else + acx_pthread_ok=no + $2 +fi +AC_LANG_RESTORE +])dnl ACX_PTHREAD diff --git a/darkice/tags/darkice-0_17_1/autogen.sh b/darkice/tags/darkice-0_17_1/autogen.sh new file mode 100755 index 0000000..9af1fbf --- /dev/null +++ b/darkice/tags/darkice-0_17_1/autogen.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# Run this to set up the build system: configure, makefiles, etc. +# (based on the version in enlightenment's cvs) + +package="darkice" + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +cd "$srcdir" +DIE=0 + +(autoheader --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $package." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed to compile $package." + echo "Download the appropriate package for your system," + echo "or get the source from one of the GNU ftp sites" + echo "listed in http://www.gnu.org/order/ftp.html" + DIE=1 +} + +(libtool --help) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have libtool installed to compile $package." + echo "Download the appropriate package for your system," + echo "or get the source from one of the GNU ftp sites" + echo "listed in http://www.gnu.org/order/ftp.html" + DIE=1 +} + +if test "$DIE" -eq 1; then + exit 1 +fi + +if test -z "$*"; then + echo "I am going to run ./configure with no arguments - if you wish " + echo "to pass any to it, please specify them on the $0 command line." +fi + +echo "Generating configuration files for $package, please wait...." + +echo " aclocal $ACLOCAL_FLAGS" +aclocal $ACLOCAL_FLAGS +echo " autoheader" +autoheader +echo " libtoolize --automake" +libtoolize --automake +echo " automake --add-missing $AUTOMAKE_FLAGS" +automake --add-missing $AUTOMAKE_FLAGS +echo " autoconf" +autoconf + +$srcdir/configure "$@" && echo diff --git a/darkice/tags/darkice-0_17_1/configure.in b/darkice/tags/darkice-0_17_1/configure.in new file mode 100644 index 0000000..be0f30d --- /dev/null +++ b/darkice/tags/darkice-0_17_1/configure.in @@ -0,0 +1,293 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(darkice, 0.17.1) +AC_CONFIG_SRCDIR(src/DarkIce.cpp) +AM_CONFIG_HEADER(src/config.h) + +AM_INIT_AUTOMAKE + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_INSTALL + +dnl AC_STDC_HEADERS +AC_HAVE_HEADERS(errno.h fcntl.h stdio.h stdlib.h string.h unistd.h limits.h) +AC_HAVE_HEADERS(signal.h time.h sys/time.h sys/types.h sys/wait.h math.h) +AC_HAVE_HEADERS(netdb.h netinet/in.h sys/ioctl.h sys/socket.h sys/stat.h) +AC_HAVE_HEADERS(sched.h pthread.h) +AC_HAVE_HEADERS(sys/soundcard.h sys/audio.h sys/audioio.h) +AC_HEADER_SYS_WAIT() + +AC_TYPE_PID_T() +AC_TYPE_SIZE_T() +AC_C_BIGENDIAN() + +AC_CHECK_LIB(socket, socket) +AC_CHECK_LIB(nsl, gethostbyname) +AC_CHECK_LIB(rt, sched_getscheduler) + +AC_CHECK_FUNC(getaddrinfo, AC_DEFINE(HAVE_GETADDRINFO, 1, [Does function getaddrinfo exist?] )) + +dnl----------------------------------------------------------------------------- +dnl funky posix threads checking, thanks to +dnl Steven G. Johnson +dnl and Alejandro Forero Cuervo +dnl see http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html +dnl----------------------------------------------------------------------------- +ACX_PTHREAD(, AC_MSG_ERROR( [pthread library not found] )) + +SYSTEM_INCLUDE=/usr/include + + +dnl----------------------------------------------------------------------------- +dnl link the lame library if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(LAME_INCFLAGS) +AC_SUBST(LAME_LDFLAGS) + +AC_ARG_WITH(lame, +[ --with-lame use lame for encoding mp3 streams [yes] ], + USE_LAME=${withval}, USE_LAME="yes" ) +AC_ARG_WITH(lame-prefix, +[ --with-lame-prefix=DIR alternate location for lame [/usr] + look for libraries in LAME-PREFIX/lib, + for headers in LAME-PREFIX/include], + CONFIG_LAME_PREFIX="${withval}", CONFIG_LAME_PREFIX="/usr") + +if test "x${USE_LAME}" = "xyes" ; then + AC_MSG_CHECKING( [for lame library at ${CONFIG_LAME_PREFIX}] ) + LA_SEARCH_LIB( LAME_LIB_LOC, LAME_INC_LOC, libmp3lame.a, lame/lame.h, + ${CONFIG_LAME_PREFIX}) + if test "x${LAME_LIB_LOC}" != "x" ; then + AC_DEFINE( HAVE_LAME_LIB, 1, [build with lame library] ) + if test "x${LAME_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + LAME_INCFLAGS="-I${LAME_INC_LOC}" + fi + LAME_LDFLAGS="-L${LAME_LIB_LOC} -lmp3lame" + AC_MSG_RESULT( [found at ${CONFIG_LAME_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without lame]) + fi +else + AC_MSG_RESULT( [building without lame] ) +fi + + +dnl----------------------------------------------------------------------------- +dnl link the ogg vorbis libraries if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(VORBIS_INCFLAGS) +AC_SUBST(VORBIS_LDFLAGS) + +AC_ARG_WITH(vorbis, +[ --with-vorbis use Ogg Vorbis for encoding vorbis streams [yes] ], + USE_VORBIS=${withval}, USE_VORBIS="yes" ) +AC_ARG_WITH(vorbis-prefix, +[ --with-vorbis-prefix=DIR alternate location for vorbis [/usr] + look for libraries in VORBIS-PREFIX/lib, + for headers in VORBIS-PREFIX/include], + CONFIG_VORBIS_PREFIX="${withval}", CONFIG_VORBIS_PREFIX="/usr") + +if test "x${USE_VORBIS}" = "xyes" ; then + AC_MSG_CHECKING( [for vorbis libraries at ${CONFIG_VORBIS_PREFIX}] ) + LA_SEARCH_LIB( OGG_LIB_LOC, OGG_INC_LOC, libogg.a, ogg/ogg.h, + ${CONFIG_VORBIS_PREFIX}) + LA_SEARCH_LIB( VORBIS_LIB_LOC, VORBIS_INC_LOC, libvorbis.a, vorbis/codec.h, + ${CONFIG_VORBIS_PREFIX}) + LA_SEARCH_LIB( VORBISENC_LIB_LOC, VORBISENC_INC_LOC, + libvorbisenc.a, vorbis/vorbisenc.h, + ${CONFIG_VORBIS_PREFIX}) + + if test "x${OGG_LIB_LOC}" != "x" -a \ + "x${VORBIS_LIB_LOC}" != "x" -a \ + "x${VORBISENC_LIB_LOC}" != "x" ; then + + AC_DEFINE( HAVE_VORBIS_LIB, 1, [build with Ogg Vorbis library] ) + if test "x${OGG_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + VORBIS_INCFLAGS="-I${OGG_INC_LOC}" + fi + VORBIS_LDFLAGS="-L${OGG_LIB_LOC} -logg -lvorbis -lvorbisenc" + AC_MSG_RESULT( [found at ${CONFIG_VORBIS_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without Ogg Vorbis]) + fi +else + AC_MSG_RESULT( [building without Ogg Vorbis] ) +fi + + +dnl----------------------------------------------------------------------------- +dnl link the faac library if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(FAAC_INCFLAGS) +AC_SUBST(FAAC_LDFLAGS) + +AC_ARG_WITH(faac, +[ --with-faac use faac for encoding AAC streams [yes] ], + USE_FAAC=${withval}, USE_FAAC="yes" ) +AC_ARG_WITH(faac-prefix, +[ --with-faac-prefix=DIR alternate location for faac [/usr] + look for libraries in FAAC-PREFIX/lib, + for headers in FAAC-PREFIX/include], + CONFIG_FAAC_PREFIX="${withval}", CONFIG_FAAC_PREFIX="/usr") + +if test "x${USE_FAAC}" = "xyes" ; then + AC_MSG_CHECKING( [for faac library at ${CONFIG_FAAC_PREFIX}] ) + LA_SEARCH_LIB( FAAC_LIB_LOC, FAAC_INC_LOC, libfaac.a, faac.h, + ${CONFIG_FAAC_PREFIX}) + if test "x${FAAC_LIB_LOC}" != "x" ; then + AC_DEFINE( HAVE_FAAC_LIB, 1, [build with faac library] ) + if test "x${FAAC_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + FAAC_INCFLAGS="-I${FAAC_INC_LOC}" + fi + FAAC_LDFLAGS="-L${FAAC_LIB_LOC} -lfaac" + AC_MSG_RESULT( [found at ${CONFIG_FAAC_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without faac]) + fi +else + AC_MSG_RESULT( [building without faac] ) +fi + + +dnl----------------------------------------------------------------------------- +dnl link the twolame library if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(TWOLAME_INCFLAGS) +AC_SUBST(TWOLAME_LDFLAGS) + +AC_ARG_WITH(twolame, +[ --with-twolame use twolame for encoding MP2 streams [yes] ], + USE_TWOLAME=${withval}, USE_TWOLAME="yes" ) +AC_ARG_WITH(twolame-prefix, +[ --with-twolame-prefix=DIR alternate location for twolame [/usr] + look for libraries in TWOLAME-PREFIX/lib, + for headers in TWOLAME-PREFIX/include], + CONFIG_TWOLAME_PREFIX="${withval}", CONFIG_TWOLAME_PREFIX="/usr") + +if test "x${USE_TWOLAME}" = "xyes" ; then + AC_MSG_CHECKING( [for twolame library at ${CONFIG_TWOLAME_PREFIX}] ) + LA_SEARCH_LIB( TWOLAME_LIB_LOC, TWOLAME_INC_LOC, libtwolame.a, twolame.h, + ${CONFIG_TWOLAME_PREFIX}) + if test "x${TWOLAME_LIB_LOC}" != "x" ; then + AC_DEFINE( HAVE_TWOLAME_LIB, 1, [build with twolame library] ) + if test "x${TWOLAME_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + TWOLAME_INCFLAGS="-I${TWOLAME_INC_LOC}" + fi + TWOLAME_LDFLAGS="-L${TWOLAME_LIB_LOC} -ltwolame" + AC_MSG_RESULT( [found at ${CONFIG_TWOLAME_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without twolame]) + fi +else + AC_MSG_RESULT( [building without twolame] ) +fi + + +dnl----------------------------------------------------------------------------- +dnl make sure at least one of lame and vorbis present +dnl----------------------------------------------------------------------------- +if test "x${LAME_LDFLAGS}" = "x" \ + -a "x${VORBIS_LDFLAGS}" = "x" \ + -a "x${FAAC_LDFLAGS}" = "x" \ + -a "x${TWOLAME_LDFLAGS}" = "x"; then + AC_MSG_ERROR([neither lame, Ogg Vorbis, faac nor twolame configured]) +fi + + +dnl----------------------------------------------------------------------------- +dnl link ALSA sound system if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(ALSA_INCFLAGS) +AC_SUBST(ALSA_LDFLAGS) + +AC_ARG_WITH(alsa, +[ --with-alsa use ALSA sound system [yes] ], + USE_ALSA=${withval}, USE_ALSA="yes" ) +AC_ARG_WITH(alsa-prefix, +[ --with-alsa-prefix=DIR alternate location for ALSA [/usr] + look for libraries in ALSA-PREFIX/lib, + for headers in ALSA-PREFIX/include], + CONFIG_ALSA_PREFIX="${withval}", CONFIG_ALSA_PREFIX="/usr") + +if test "x${USE_ALSA}" = "xyes" ; then + AC_MSG_CHECKING( [for alsa libraries at ${CONFIG_ALSA_PREFIX}] ) + LA_SEARCH_LIB( ALSA_LIB_LOC, ALSA_INC_LOC, libasound.so, alsa/asoundlib.h, + ${CONFIG_ALSA_PREFIX}) + + if test "x${ALSA_LIB_LOC}" != "x" ; then + + AC_DEFINE( HAVE_ALSA_LIB, 1, [build with ALSA sound system] ) + if test "x${ALSA_INC_LOC}" != "x${SYSTEM_INCLUDE}" ; then + ALSA_INCFLAGS="-I${ALSA_INC_LOC}" + fi + ALSA_LDFLAGS="-L${ALSA_LIB_LOC} -lasound" + AC_MSG_RESULT( [found at ${CONFIG_ALSA_PREFIX}] ) + else + AC_MSG_WARN( [not found, building without ALSA support]) + fi +else + AC_MSG_RESULT( [building without ALSA support] ) +fi + + +dnl----------------------------------------------------------------------------- +dnl link JACK sound server if requested +dnl----------------------------------------------------------------------------- +AC_SUBST(JACK_CFLAGS) +AC_SUBST(JACK_LIBS) + +AC_ARG_WITH( jack, +[ --with-jack use JACK audio server [yes] ], + USE_JACK=${withval}, USE_JACK="yes" ) + +if test "x${USE_JACK}" = "xyes" ; then + PKG_CHECK_MODULES(JACK, jack, + [ AC_DEFINE( HAVE_JACK_LIB, 1, [build with JACK audio server support] ) ], + [ HAVE_JACK_LIB=0 ] + ) +else + AC_MSG_RESULT( [building without JACK support] ) +fi + + +dnl----------------------------------------------------------------------------- +dnl check for MSG_NOSIGNAL for the send() function in libsocket +dnl----------------------------------------------------------------------------- +AC_MSG_CHECKING(for MSG_NOSIGNAL) +AC_TRY_COMPILE([#include ], [ + int f = MSG_NOSIGNAL; +], [ + # Yes, we have it... + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_MSG_NOSIGNAL, 1, [use MSG_NOSIGNAL for send()]) +], [ + # We'll have to use signals + AC_MSG_RESULT(no) +]) + + +dnl----------------------------------------------------------------------------- +dnl check for POSIX real-time scheduling +dnl----------------------------------------------------------------------------- +AC_CHECK_FUNCS( sched_getscheduler sched_getparam ) + + +dnl----------------------------------------------------------------------------- +dnl enable compilation with debug flags +dnl----------------------------------------------------------------------------- +AC_SUBST(DEBUG_CXXFLAGS) + +AC_ARG_WITH(debug, +[ --with-debug enable debug mode [no] ], + USE_DEBUG=${withval}, USE_DEBUG="no" ) + +if test "x${USE_DEBUG}" == "xyes" ; then + DEBUG_CXXFLAGS="-g" + AC_MSG_RESULT([compiling in debug mode]) +else + AC_MSG_RESULT([not compiling in debug mode]) +fi + + +AC_OUTPUT(Makefile src/Makefile man/Makefile) + diff --git a/darkice/tags/darkice-0_17_1/darkice.cfg b/darkice/tags/darkice-0_17_1/darkice.cfg new file mode 100644 index 0000000..d1ad212 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/darkice.cfg @@ -0,0 +1,81 @@ +# sample DarkIce configuration file, edit for your needs before using +# see the darkice.cfg man page for details + +# this section describes general aspects of the live streaming session +[general] +duration = 60 # duration of encoding, in seconds. 0 means forever +bufferSecs = 5 # size of internal slip buffer, in seconds +reconnect = yes # reconnect to the server(s) if disconnected + +# this section describes the audio input that will be streamed +[input] +device = /dev/dsp # OSS DSP soundcard device for the audio input +sampleRate = 22050 # sample rate in Hz. try 11025, 22050 or 44100 +bitsPerSample = 16 # bits per sample. try 16 +channel = 2 # channels. 1 = mono, 2 = stereo + +# this section describes a streaming connection to an IceCast server +# there may be up to 8 of these sections, named [icecast-0] ... [icecast-7] +# these can be mixed with [icecast2-x] and [shoutcast-x] sections +[icecast-0] +bitrateMode = cbr # constant bit rate +bitrate = 96 # bitrate of the mp3 stream sent to the server +quality = 0.8 # encoding quality +server = yp.yourserver.com + # host name of the server +port = 8000 # port of the IceCast server, usually 8000 +password = hackme # source password to the IceCast server +mountPoint = sample96 # mount point of this stream on the IceCast server +name = DarkIce trial + # name of the stream +description = This is only a trial + # description of the stream +url = http://www.yourserver.com + # URL related to the stream +genre = my own # genre of the stream +public = yes # advertise this stream? + +# this section describes a streaming connection to an IceCast2 server +# there may be up to 8 of these sections, named [icecast2-0] ... [icecast2-7] +# these can be mixed with [icecast-x] and [shoutcast-x] sections +[icecast2-0] +bitrateMode = abr # average bit rate +format = vorbis # format of the stream: ogg vorbis +bitrate = 96 # bitrate of the stream sent to the server +server = yp.yourserver.com + # host name of the server +port = 8000 # port of the IceCast2 server, usually 8000 +password = hackme # source password to the IceCast2 server +mountPoint = sample96 # mount point of this stream on the IceCast2 server +name = DarkIce trial + # name of the stream +description = This is only a trial + # description of the stream +url = http://www.yourserver.com + # URL related to the stream +genre = my own # genre of the stream +public = yes # advertise this stream? + +# this section describes a streaming connection to a ShoutCast server +# there may be up to 8 of these sections, named [shoutcast-0] ... [shoutcast-7] +# these can be mixed with [icecast-x] and [icecast2-x] sections +[shoutcast-0] +bitrateMode = vbr # variable bit rate mode +quality = 0.5 # encoding quality +server = yp.yourserver.com + # host name of the server +port = 8001 # source port of the ShoutCast server, usually 8001 +password = hackme # source password to the ShoutCast server +name = DarkIce trial + # name of the stream +url = http://www.yourserver.com + # URL related to the stream +genre = my own # genre of the stream +public = yes # advertise this stream? +irc = irc.yourserver.com + # IRC info related to the stream +aim = aim here # AIM info related to the stream +icq = I see you too + # ICQ info related to the stream + + diff --git a/darkice/tags/darkice-0_17_1/etc/doxygen.config b/darkice/tags/darkice-0_17_1/etc/doxygen.config new file mode 100644 index 0000000..4700454 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/doxygen.config @@ -0,0 +1,1150 @@ +#------------------------------------------------------------------------------- +# +# Copyright (c) 2000 Tyrell Corporation. All rights reserved. +# +# Tyrell DarkIce +# +# File : main.cpp +# Version : $Revision$ +# Author : $Author$ +# Location : $Source$ +# +# Abstract : +# +# Program entry point +# +# Copyright notice: +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +#------------------------------------------------------------------------------- + +# Doxyfile 1.3.6 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = DarkIce + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygen + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = YES + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = YES + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES # needed by storageServer docs + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.15.ebuild b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.15.ebuild new file mode 100644 index 0000000..3db3aec --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.15.ebuild @@ -0,0 +1,42 @@ +IUSE="encode oggvorbis alsa jack" + +DESCRIPTION="IceCast live streamer delivering Ogg and mp3 streams simultaneously to multiple hosts." +HOMEPAGE="http://darkice.sourceforge.net/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" +RESTRICT="nomirror" + +SLOT="0" +LICENSE="GPL-2" +KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64" + +DEPEND="encode? ( >=media-sound/lame-3.89 ) + oggvorbis? ( >=media-libs/libvorbis-1.0 ) + alsa? ( >=media-libs/alsa-lib-1.0.0 ) + jack? ( media-sound/jack-audio-connection-kit )" + +src_compile() { + if ! use encode && ! use oggvorbis + then + + eerror "You need support for mp3 or Ogg Vorbis enconding for this" + eerror "package. Please merge again with at least one of the " + eerror "\`encode' and \`oggvorbis' USE flags enabled:" + eerror + eerror " # USE=\"encode\" emerge darkice" + eerror " # USE=\"oggvorbis\" emerge darkice" + die "Won't build without support for lame nor vorbis" + fi + + econf `use_with alsa` \ + `use_with encode lame` \ + `use_with oggvorbis vorbis` \ + `use_with jack` || die + + emake || die "Compilation failed" +} + +src_install() { + einstall darkicedocdir=${D}/usr/share/doc/${PF} || die + + dodoc AUTHORS ChangeLog COPYING NEWS README TODO +} diff --git a/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.16.ebuild b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.16.ebuild new file mode 100644 index 0000000..3c997ad --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.16.ebuild @@ -0,0 +1,45 @@ +IUSE="encode oggvorbis aac alsa jack" + +DESCRIPTION="IceCast live streamer delivering Ogg, mp3 or aac streams simultaneously to multiple hosts." +HOMEPAGE="http://darkice.sourceforge.net/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" +RESTRICT="nomirror" + +SLOT="0" +LICENSE="GPL-2" +KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64" + +DEPEND="encode? ( >=media-sound/lame-3.89 ) + oggvorbis? ( >=media-libs/libvorbis-1.0 ) + aac? ( >=media-libs/faac-1.24 ) + alsa? ( >=media-libs/alsa-lib-1.0.0 ) + jack? ( media-sound/jack-audio-connection-kit )" + +src_compile() { + if ! use encode && ! use oggvorbis && ! use aac + then + + eerror "You need support for mp3, Ogg Vorbis or FAAC enconding for this" + eerror "package. Please merge again with at least one of the " + eerror "\`encode', \`oggvorbis' or \'aac' USE flags enabled:" + eerror + eerror " # USE=\"encode\" emerge darkice" + eerror " # USE=\"oggvorbis\" emerge darkice" + eerror " # USE=\"aac\" emerge darkice" + die "Won't build without support for lame, vorbis or aac" + fi + + econf `use_with alsa` \ + `use_with encode lame` \ + `use_with oggvorbis vorbis` \ + `use_with aac faac` \ + `use_with jack` || die + + emake || die "Compilation failed" +} + +src_install() { + einstall darkicedocdir=${D}/usr/share/doc/${PF} || die + + dodoc AUTHORS ChangeLog COPYING NEWS README TODO +} diff --git a/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.1.ebuild b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.1.ebuild new file mode 100644 index 0000000..ae70ac0 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.1.ebuild @@ -0,0 +1,43 @@ +# Copyright 1999-2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header$ + +DESCRIPTION="IceCast live streamer, delivering ogg and mp3 streams simultaneously to multiple hosts." +HOMEPAGE="http://darkice.sourceforge.net/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~hppa ~ppc ~sparc ~x86" +IUSE="alsa encode jack vorbis" + +DEPEND="encode? ( >=media-sound/lame-1.89 ) + vorbis? ( >=media-libs/libvorbis-1.0 ) + alsa? ( >=media-libs/alsa-lib-1.0.0 ) + jack? ( media-sound/jack-audio-connection-kit )" + +src_compile() { + if ! use encode && ! use vorbis + then + + eerror "You need support for mp3 or Ogg Vorbis enconding for this" + eerror "package. Please merge again with at least one of the " + eerror "\`encode' and \`vorbis' USE flags enabled:" + eerror + eerror " # USE=\"encode\" emerge darkice" + eerror " # USE=\"vorbis\" emerge darkice" + die "Won't build without support for lame nor vorbis" + fi + + econf $(use_with alsa) \ + $(use_with encode lame) \ + $(use_with jack) \ + $(use_with vorbis) || die "configuration failed" + emake || die "Compilation failed" +} + +src_install() { + einstall darkicedocdir=${D}/usr/share/doc/${PF} || die "make install failed" + + dodoc AUTHORS ChangeLog NEWS README TODO +} diff --git a/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.ebuild b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.ebuild new file mode 100644 index 0000000..c40b481 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/ebuild/darkice-0.17.ebuild @@ -0,0 +1,48 @@ +IUSE="encode mp2 oggvorbis aac alsa jack" + +DESCRIPTION="IceCast live streamer delivering Ogg, mp3, mp2 or aac streams simultaneously to multiple hosts." +HOMEPAGE="http://darkice.sourceforge.net/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" +RESTRICT="nomirror" + +SLOT="0" +LICENSE="GPL-2" +KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64" + +DEPEND="encode? ( >=media-sound/lame-3.89 ) + mp2? ( >=media-sound/twolame-0.3.6 ) + oggvorbis? ( >=media-libs/libvorbis-1.0 ) + aac? ( >=media-libs/faac-1.24 ) + alsa? ( >=media-libs/alsa-lib-1.0.0 ) + jack? ( media-sound/jack-audio-connection-kit )" + +src_compile() { + if ! use encode && ! use mp2 && ! use oggvorbis && ! use aac + then + + eerror "You need support for mp3, Ogg Vorbis or FAAC enconding for this" + eerror "package. Please merge again with at least one of the " + eerror "\`encode', \'mp2', \`oggvorbis' or \'aac' USE flags enabled:" + eerror + eerror " # USE=\"encode\" emerge darkice" + eerror " # USE=\"mp2\" emerge darkice" + eerror " # USE=\"oggvorbis\" emerge darkice" + eerror " # USE=\"aac\" emerge darkice" + die "Won't build without support for lame, mp2, vorbis or aac" + fi + + econf `use_with alsa` \ + `use_with encode lame` \ + `use_with mp2 twolame` \ + `use_with oggvorbis vorbis` \ + `use_with aac faac` \ + `use_with jack` || die + + emake || die "Compilation failed" +} + +src_install() { + einstall darkicedocdir=${D}/usr/share/doc/${PF} || die + + dodoc AUTHORS ChangeLog COPYING NEWS README TODO +} diff --git a/darkice/tags/darkice-0_17_1/etc/ebuild/twolame-0.3.6.ebuild b/darkice/tags/darkice-0_17_1/etc/ebuild/twolame-0.3.6.ebuild new file mode 100644 index 0000000..40d3848 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/ebuild/twolame-0.3.6.ebuild @@ -0,0 +1,21 @@ +# Copyright 1999-2006 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header$ + +IUSE="" +DESCRIPTION="TwoLAME is an optimised MPEG Audio Layer 2 (MP2) encoder" +HOMEPAGE="http://www.twolame.org/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" +RESTRICT="nomirror" + +SLOT="0" +LICENSE="GPL-2" +KEYWORDS="~x86 ~ppc ~sparc ~alpha ~hppa ~amd64" + +DEPEND=">=media-libs/libsndfile-1.0.11" + +src_install() { + make DESTDIR=${D} || die + + dodoc AUTHORS ChangeLog COPYING README TODO +} diff --git a/darkice/tags/darkice-0_17_1/etc/rpm/darkice.spec b/darkice/tags/darkice-0_17_1/etc/rpm/darkice.spec new file mode 100644 index 0000000..ee85641 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/rpm/darkice.spec @@ -0,0 +1,60 @@ +%{!?dist: %define dist fc3} + +Summary : DarkIce live IceCast / ShoutCast streamer +Name: darkice +Vendor: Tyrell Hungary +Packager: Akos Maroy +Version: 0.18 +Release: 1.%{dist} +Copyright: GPL +Group: Applications/Multimedia +Source: http://prdownloads.sourceforge.net/darkice/darkice-%{version}.tar.gz +URL: http://darkice.sourceforge.net/ +Provides: darkice +BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildPrereq: lame-devel libogg-devel libvorbis-devel +%if %{dist} != el3 +BuildPrereq: jack-audio-connection-kit-devel +%endif +Prefix: /usr + +%description +DarkIce is an IceCast, IceCast2 and ShoutCast live audio streamer. It +takes audio input from a sound card, encodes it into mp3 and/or Ogg Vorbis, +and sends the mp3 stream to one or more IceCast and/or ShoutCast servers, +the Ogg Vorbis stream to one or more IceCast2 servers. + +%prep +%setup + +%build +%configure \ +%if %{dist} == el3 + --without-alsa --without-jack +%endif + +make all + +%install +rm -fr %{buildroot} +%makeinstall + +%clean +rm -rf %{buildroot} + +%files +%defattr (-, root, root) +%doc COPYING ChangeLog README TODO AUTHORS +%config(noreplace) %{_sysconfdir}/darkice.cfg +%{_bindir}/darkice +%{_mandir}/man1/darkice.1* +%{_mandir}/man5/darkice.cfg.5* + + +%changelog +* Thu May 18 2006 Akos Maroy 0.18-1 +- rewrite the spec file for 0.18 +* Tue Apr 19 2005 Akos Maroy 0.16-1 +- rewrite the spec file for 0.16 +* Tue Apr 19 2005 Akos Maroy 0.15-1 +- rewrite the spec file for 0.15 diff --git a/darkice/tags/darkice-0_17_1/etc/rpm/lame.spec b/darkice/tags/darkice-0_17_1/etc/rpm/lame.spec new file mode 100644 index 0000000..8c6ecbb --- /dev/null +++ b/darkice/tags/darkice-0_17_1/etc/rpm/lame.spec @@ -0,0 +1,151 @@ +#------------------------------------------------------------------------------- +# +# Copyright (c) 2000 Tyrell Corporation. All rights reserved. +# +# Tyrell DarkIce +# +# File : lame.spec +# Version : $Revision$ +# Author : $Author$ +# Location : $Source$ +# +# Abstract : +# +# Specification file to build RPM packages of lame. +# Builds a proper lame executable on a RedHat 7.1 system. +# Based on the official lame RPM spec file by +# cefiar +# +# Copyright notice: +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +#------------------------------------------------------------------------------- + +# ================================================================= local macros +%define name lame +%define ver 3.91 +%define rel 1 +%define prefix /usr + + +# ===================================================================== preamble +Summary : LAME Ain't an MP3 Encoder +Name: %{name} +Version: %{ver} +Release: %{rel} +Copyright: LGPL +Vendor: The LAME Project +Packager: Akos Maroy +URL: http://www.mp3dev.org/mp3/ +Group: Applications/Multimedia +Source: http://prdownloads.sourceforge.net/darkice/%{name}-%{ver}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{ver}-root +Prefix: %{prefix} +Provides: lame + +%description +LAME is an educational tool to be used for learning about MP3 encoding. The +goal of the LAME project is to use the open source model to improve the +psycho acoustics, noise shaping and speed of MP3. Another goal of the LAME +project is to use these improvements for the basis of a patent free audio +compression codec for the GNU project. + +This build is optimized for %{_target}. + +# ============================================================ devel sub-package +%package devel +Summary: Shared and static libraries for LAME. +Group: Development/Libraries +Requires: %{name} = %{version} + +%description devel +LAME is an educational tool to be used for learning about MP3 encoding. +This package contains both the shared and the static libraries from the +LAME project. + +You will also need to install the main lame package in order to install +these libraries. + +This build is optimized for %{_target}. + +# =================================================================== prep stage +%prep +%setup -n %{name}-%{ver} + + +# ================================================================== build stage +%build +export CC=gcc3 +export CFLAGS="-O9" +%configure --with-fileio=lame \ + --without-vorbis \ + --disable-gtktest \ + --enable-nasm \ + --enable-expopt=full +make + + +# ================================================================ install stage +%install +%makeinstall + + +# ======================================================================== clean +%clean +rm -rf $RPM_BUILD_ROOT +make clean + + +# =========================================================== main package files +%files +%defattr (-,root,root) +%doc LICENSE USAGE COPYING TODO README* +%doc doc/html +%{_bindir}/lame +%{_mandir}/man1/lame.1* +%{_libdir}/libmp3lame.so.* + + +# ====================================================== devel sub-package files +%files devel +%defattr (-,root,root) +%doc API HACKING STYLEGUIDE +%{_includedir}/lame/lame.h +%{_libdir}/libmp3lame.la +%{_libdir}/libmp3lame.a +%{_libdir}/libmp3lame.so + + +# =================================================================== change log +# +# $Log$ +# Revision 1.1 2005/04/14 11:58:08 darkeye +# moved directory rpm to etc/rpm +# +# Revision 1.4 2002/02/19 14:52:41 darkeye +# updated for lame 3.91 +# +# Revision 1.3 2001/09/13 05:06:41 darkeye +# removed references to SourceForget FTP sites, as they are phased out +# +# Revision 1.2 2001/09/09 09:06:26 darkeye +# lame RPM is now created with gcc3 and full optimizations +# +# Revision 1.1 2001/09/02 12:46:05 darkeye +# added RPM package creation scripts +# +# + diff --git a/darkice/tags/darkice-0_17_1/install-sh b/darkice/tags/darkice-0_17_1/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/darkice/tags/darkice-0_17_1/man/Makefile.am b/darkice/tags/darkice-0_17_1/man/Makefile.am new file mode 100644 index 0000000..8406ddd --- /dev/null +++ b/darkice/tags/darkice-0_17_1/man/Makefile.am @@ -0,0 +1,4 @@ +man_MANS = darkice.1 darkice.cfg.5 + +EXTRA_DIST = ${man_MANS} + diff --git a/darkice/tags/darkice-0_17_1/man/darkice.1 b/darkice/tags/darkice-0_17_1/man/darkice.1 new file mode 100644 index 0000000..7f6162a --- /dev/null +++ b/darkice/tags/darkice-0_17_1/man/darkice.1 @@ -0,0 +1,137 @@ +.TH darkice 1 "January 25, 2006" "DarkIce" "DarkIce live audio streamer" +.SH NAME +darkice \- an icecast / shoutcast live audio streamer +.SH SYNOPSIS +.B darkice +[options] -c config.file +.SH DESCRIPTION +.PP +DarkIce as a live audio streamer. It records audio from an audio interface (e.g. sound card), encodes it and sends it to a streaming server. +DarkIce can record from: + + * OSS audio devices + * ALSA audio devices + * Solaris audio interface + * Jack sources + +DarkIce can encode in the following formats: + + * mp3 - using the lame library + * mp2 - using the twolame library + * Ogg Vorbis + * AAC - using the faac library + +DarkIce can send the encoded stream to the following streaming servers: + + * ShoutCast + * IceCast 1.3.x and 2.x + * Darwin Streaming Server + +Darkice runs on the following operating systems: + + * FreeBSD + * Linux on intel and PowerPC + * MacOS X + * NetBSD / OpenBSD + * SUN Solaris + +.B DarkIce +uses +.SM POSIX +real-time scheduling to keep up with sound card input. +.SM POSIX +real-time scheduling is only available if the program is run as root. +Therefore it is recommended that +.B DarkIce +is run as root. + +.SH OPTIONS +.TP +.BI "\-c " config.file +Specifies what configuration file to use. + +.TP +.BI "\-v " n +Sets the verbosity level, between 0 and 10. 0 is silent, 10 is loud. +Defaults to 1. + +.TP +.BI "\-h " +Prints the help page and exits. + + +.SH BUGS +.PP +Lots of bugs. + + +.SH "SEE ALSO" +darkice.cfg(5) + + +.SH AUTHOR +Akos Maroy +.I + + +.SH ACKNOWLEDGEMENTS +Developed with contributions by + + Jim Crilly, + aNa|0Gue, + Robin P. Blanchard, + Tom Gray, + Michael Smith, + Julius O. Smith, + the OSALP team, http://osalp.sourceforge.net + Kristjan G. Bjarnason + Nicu Pavel + Kai Krakow + Atsuhiko Yamanaka + Ricardo Galli + John Hay + Christian Forster + John Deeny + Robert Lunnon + Enrico Ardizzoni + Deti Fliegl + Nicholas J. Humfrey + Joel Ebel + + +.SH LINKS +Project homepage: +.I http://darkice.sourceforge.net/ + +.B IceCast +homepage: +.I http://www.icecast.org/ + +.B ShoutCast +homepage: +.I http://www.shoutcast.com/ + +.B Darwin Streaming Server +homepage: +.I http://developer.apple.com/darwin/projects/streaming/ + +.B Lame +homepage: +.I http://www.mp3dev.org/mp3/ + +.B TwoLame +homepage: +.I http://www.twolame.org/ + +.B Ogg Vorbis +homepage: +.I http://www.xiph.org/ogg/vorbis/ + +.B faac +homepage: +.I http://www.audiocoding.com/ + +.B DarkSnow +GTK front-end: +.I http://darksnow.radiolivre.org/index.en.html +written by Rafael Diniz diff --git a/darkice/tags/darkice-0_17_1/man/darkice.cfg.5 b/darkice/tags/darkice-0_17_1/man/darkice.cfg.5 new file mode 100644 index 0000000..842abc2 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/man/darkice.cfg.5 @@ -0,0 +1,648 @@ +.TH darkice.cfg 5 "January 25, 2006" "DarkIce" "DarkIce live audio streamer" +.SH NAME +darkice.cfg \- configuration file for darkice +.SH DESCRIPTION +.PP +The configuration file consists of sections, with key = value pairs +separated with spaces and/or tabs inside each secion: + +.nf +[section1] +# this is a whole line comment +key = value +an ugly key name = long value # this end is a comment too + +[section2] +# this is a whole line comment in section 2 +key = value +an ugly key name = long value # this end is a comment too +.fi + +A proper +.B DarkIce +configuration file contains the following sections: +.nf +[general] +[input] +[icecast-0] ... [icecast-7] +[icecast2-0] ... [icecast2-7] +[shoutcast-0] ... [shoutcast-7] +[file-0] ... [file-7] +.fi + +The order of the sections is not important. Sections [general] and [input] +are required, and at least one of [icecast-x], [icecast2-x], [shoutcast-x] +or [file-x] is needed. + +In particular, the following sections and values are recognized: +.PP +.B [general] + +This section describes general operational parameters (required). + +Required values: + +.TP +.I duration +Time for DarkIce to run, in seconds. If 0, run forever. +.TP +.I bufferSecs +Data read from the sound card is buffered before sent to +the encoder. Each buffer will be able to hold this +many seconds of samples. + +.PP +Optional values: + +.TP +.I reconnect +Try to reconnect to the server(s) if the connection is broken during +streaming, "yes" or "no". (optional parameter, defaults to "yes") +.TP +.I realtime +Use POSIX realtime scheduling, "yes" or "no". +(optional parameter, defaults to "yes") + + +.PP +.B [input] + +This section describes the input (required). + +Required values: + +.TP +.I device +Specify the device to record from, which can be an OSS DSP device, +an ALSA source or you can use Jack audio. +- OSS DSP audio device to record from (e.g. /dev/dsp) +- ALSA DSP device name (e.g. hwplug:0,0) +- the string 'jack', to have an unconnected Jack port, or + 'jack_auto' to automatically make Jack connect to the first source. +.TP +.I sampleRate +The sample rate to record with, samples per second +(e.g. 44100 for 44.1kHz CD-quality audio, 22050 for 22kHz or 11025 +for 11kHz) +.TP +.I bitsPerSample +Number of bits to use for each sample (e.g. 8 bits or 16 bits) +.TP +.I channel +Number of channels to record (e.g. 1 for mono, 2 for stereo) + +.PP +.B [icecast-x] + +This section describes an output to an +.B IceCast 1.3.x +server or +.B Darwin Streaming Server +, while encoding +with a lame encoder. There may be at most 8 outputs, numbered from 0 ... 7. +The number is included in the section name (e.g. [icecast-0] ... [icecast-7]). +The stream will be reachable at +.I http://:/ + +Required values: + +.TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. +.TP +.I bitrate +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.I quality +The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being +the highest quality. Use a value greater than 0.0. Only used when cbr or vbr +bit rate modes are specified. +.TP +.I server +The +.B IceCast +server's name (e.g. yp.yourserver.com) +.TP +.I port +The port to connect to the IceCast server (e.g. 8000) +.TP +.I password +The password to use to connect to the +.B IceCast +server +.TP +.I mountPoint +Mount point for the stream on the server + +.PP +Optional values: + +.TP +.I sampleRate +The sample rate of the encoded mp3 output. If not specified, defaults +to the value of the input sample rate. +.TP +.I channel +Number of channels for the mp3 output (e.g. 1 for mono, 2 for stereo). +If not specified, defaults to the value of the input sample rate. +.TP +.I name +Name of the stream +.TP +.I description +Description of the stream +.TP +.I url +Url related to the stream +.TP +.I genre +Genre of the stream +.TP +.I public +"yes" or "no", wether the stream is public +.TP +.I remoteDumpFile +The file the +.B IceCast +server should dump the contents of +this stream on its side. +.TP +.I localDumpFile +Dump the same mp3 data sent to the +.B IceCast +server to this local file. +.TP +.I fileAddDate +"yes" or "no" if you want to automaticaly insert a date string in +the localDumpFile name before its extension or at the end of file name if +no extension present +.TP +.I lowpass +Lowpass filter setting for the lame encoder, in Hz. Frequencies above +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +.TP +.I highpass +Highpass filter setting for the lame encoder, in Hz. Frequencies below +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. + +.PP +.B [icecast2-x] + +This section describes an output to an +.B IceCast2 +server, while encoding with the ogg vobis encoder. +There may be at most 8 outputs, numbered from 0 ... 7. +The number is included in the section name (e.g. [icecast2-0] ... [icecast2-7]). +The stream will be reachable at +.I http://:/ +.P +.B DarkIce +supports both fixed bitrate and variable bitrate vorbis streams. When +using fixed bitrate, specify the bitrate using the +.I bitrate +field. When using variable bitrate, specify the quality of the stream by the +.I quality +field, which is a value between 0.0 and 1.0. + +Required values: + +.TP +.I format +Format of the stream sent to the +.B IceCast2 +server. Supported formats are 'vorbis', 'mp3', 'mp2' and 'aac'. +.TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. +.TP +.I bitrate +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.I quality +The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being +the highest quality. Use a value greater than 0.0. Only used when vbr +bit rate mode is specified for Ogg Vorbis format, or in vbr and abr +modes for mp3 and mp2 format. +.TP +.I server +The +.B IceCast2 +server's name (e.g. yp.yourserver.com) +.TP +.I port +The port to connect to the IceCast server (e.g. 8000) +.TP +.I password +The password to use to connect to the +.B IceCast2 +server +.TP +.I mountPoint +Mount point for the stream on the server + +.PP +Optional values: + +.TP +.I sampleRate +The sample rate of the encoded output. If not specified, defaults +to the value of the input sample rate. +.TP +.I channel +Number of channels for the output (e.g. 1 for mono, 2 for stereo). +If not specified, defaults to the value of the input sample rate. +Different channels for input and output are only supported for mp3, +but not for Ogg Vorbis. +.TP +.I maxBitrate +The maximum bitrate of the stream. Only used when in cbr mode and in +Ogg Vorbis format. +.TP +.I name +Name of the stream +.TP +.I description +Description of the stream +.TP +.I url +Url related to the stream +.TP +.I genre +Genre of the stream +.TP +.I public +"yes" or "no", wether the stream is public +.TP +.I localDumpFile +Dump the same Ogg Vorbis data sent to the +.B IceCast2 +server to this local file. +.TP +.I fileAddDate +"yes" or "no" if you want to automaticaly insert a date string in +the localDumpFile name before its extension or at the end of file name if +no extension present +.TP +.I lowpass +Lowpass filter setting for the lame encoder, in Hz. Frequencies above +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +Only has effect if the mp3 or mp2 format is used. +.TP +.I highpass +Highpass filter setting for the lame encoder, in Hz. Frequencies below +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +Only has effect if the mp3 or mp2 format is used. + +.PP +.B [shoutcast-x] + +This section describes an output to a +.B ShoutCast +server, while encoding +with a lame encoder. There may be at most 8 outputs, numbered from 0 ... 7. +The number is included in the section name +(e.g. [shoutcast-0] ... [shoutcast-7]). +The stream will be reachable at +.I http://:/ + +Required values: + +.TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. +.TP +.I bitrate +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.I quality +The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being +the highest quality. Use a value greater than 0.0. Only used when cbr or vbr +bit rate modes are specified. +.TP +.I server +The +.B ShoutCast +server's name (e.g. yp.yourserver.com) +.TP +.I port +The source port to connect to the ShoutCast server (e.g. 8001) +.TP +.I password +The password to use to connect to the +.B ShoutCast +server + +.PP +Optional values: + +.TP +.I sampleRate +The sample rate of the encoded mp3 output. If not specified, defaults +to the value of the input sample rate. +.TP +.I channel +Number of channels for the mp3 output (e.g. 1 for mono, 2 for stereo). +If not specified, defaults to the value of the input sample rate. +.TP +.I name +Name of the stream +.TP +.I url +Url related to the stream +.TP +.I genre +Genre of the stream +.TP +.I public +"yes" or "no", wether the stream is public +.TP +.I irc +IRC information related to the stream +.TP +.I aim +AIM information related to the stream +.TP +.I icq +ICQ information related to the stream +.TP +.I lowpass +Lowpass filter setting for the lame encoder, in Hz. Frequencies above +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +.TP +.I highpass +Highpass filter setting for the lame encoder, in Hz. Frequencies below +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +.TP +.I localDumpFile +Dump the same mp3 data sent to the +.B ShoutCast +server to this local file. +.TP +.I fileAddDate +"yes" or "no" if you want to automaticaly insert a date string in +the localDumpFile name before its extension or at the end of file name if +no extension present +.PP +.B [file-x] + +This section describes an output to a local file in either Ogg Vorbis or +mp3 format. +There may be at most 8 outputs, numbered from 0 ... 7. +The number is included in the section name (e.g. [file-0] ... [file-7]). + +Required values: + +.TP +.I format +Format to encode in. Must be either 'mp3', 'vorbis' or 'aac'. +.TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. +.TP +.I bitrate +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.I quality +The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being +the highest quality. Use a value greater than 0.0. Only used when cbr or vbr +bit rate modes are specified. +.TP +.I fileName +The name of the local file to save the encoded data into. + +.PP +Optional values: + +.TP +.I sampleRate +The sample rate of the encoded mp3 output. If not specified, defaults +to the value of the input sample rate. +Only used if the output format is mp3. +.TP +.I lowpass +Lowpass filter setting for the lame encoder, in Hz. Frequencies above +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +Only used if the output format is mp3. +.TP +.I highpass +Highpass filter setting for the lame encoder, in Hz. Frequencies below +the specified value will be cut. +If not set or set to 0, the encoder's default behaviour is used. +If set to -1, the filter is disabled. +Only used if the output format is mp3. + +.PP +A sample configuration file follows. This file makes +.B DarkIce +stream for 1 minute (60 seconds) from the audio device +.I /dev/dsp +at 22.05kHz, 16 bit stereo. +It will build up a connection to the +.B IceCast +server yp.yourserver.com on port 8000 with the password "hackme". +The stream will be encoded to 96 kb/s mp3 with quality 0.8, and will be +reachable at +.I http://yp.yourserver.com:8000/live96 +to mp3 players. +The encoding session will be stored by +.B IceCast +in the file +.I /tmp/server-dump.mp3 +on the server side, and also by +.B DarkIce +in the file +.I /tmp/encoder-dump.mp3 +on the encoder side. + +.nf +[general] +duration = 60 +bufferSecs = 5 + +[input] +device = /dev/dsp +sampleRate = 22050 +bitsPerSample = 16 +channel = 2 + +[icecast-0] +bitrateMode = cbr +bitrate = 96 +quality = 0.8 +server = yp.yourserver.com +port = 8000 +password = hackme +mountPoint = live96 +name = DarkIce trial +description = This is only a trial +url = http://www.yourserver.com +genre = live +public = no +remoteDumpFile = /tmp/server-dump.mp3 +localDumpFile = /tmp/encoder-dump.mp3 +fileAddDate = no +.fi + + +.PP +The following sample configuration file simply encodes the 16 bit stereo +44.1 kHz sound card input into Ogg Vorbis at average bit rate 96 kb/s for 60 +seconds, and saves it in the local file at /tmp/save.ogg. + +.nf +[general] +duration = 60 +bufferSecs = 5 + +[input] +device = /dev/dsp +sampleRate = 44100 +bitsPerSample = 16 +channel = 2 + +[file-0] +format = vorbis +bitrateMode = abr +bitrate = 96 +fileName = /tmp/save.ogg +.fi + + +.PP +A bit more complicated sample follows. This one makes +.B DarkIce +stream for 1 hour (3600 seconds) from the audio device +.I /dev/dsp +at 44.1kHz, 16 bit stereo. + +It will build up a connection to an +.B IceCast +server yp.your-ice-server.com on port 8000 with the password "ice-hackme". +The sound for this stream will be cut at 10500 Hz from above. +The stream will be encoded to average bit rate 96 kb/s mp3 and resampled to +22.05kHz and 1 channel (mono). +The stream will be reachable at +.I http://yp.your-ice-server.com:8000/live96 +to mp3 players. +The encoding session will be stored by +.B IceCast +in the file +.I /tmp/live96.mp3 +on the server side. + +It will also connect to a +.I ShoutCast +server at yp.your-shout-server.com on port 8001 with the password "shout-hackme" +This stream will be encoded to constant bit rate 128 kb/s mp3 with quality +0.8, and will be reachable at +.I http://yp.your-shout-server.com:8000 +to mp3 players. + +.nf +[general] +duration = 3600 +bufferSecs = 5 + +[input] +device = /dev/dsp +sampleRate = 22050 +bitsPerSample = 16 +channel = 2 + +[icecast-0] +sampleRate = 22050 +channel = 1 +bitrateMode = abr +bitrate = 96 +lowpass = 10500 +server = yp.your-ice-server.com +port = 8000 +password = ice-hackme +mountPoint = live96 +name = DarkIce trial +description = This is only a trial +url = http://www.yourserver.com +genre = live +public = yes +remoteDumpFile = /tmp/live96.mp3 + +[shoutcast-0] +bitrateMode = cbr +bitrate = 128 +quality = 0.8 +server = yp.your-shout-server.com +port = 8001 +password = shout-hackme +name = DarkIce trial +url = http://www.yourserver.com +genre = live +public = yes +irc = irc.yourserver.com +aim = aim here +icq = I see you too +.fi + + +.SH BUGS +.PP +Lots of bugs. + + +.SH "SEE ALSO" +darkice(1) + + +.SH AUTHOR +Akos Maroy +.I + + +.SH LINKS +Project homepage: +.I http://darkice.sourceforge.net/ + +.B IceCast +homepage: +.I http://www.icecast.org/ + +.B ShoutCast +homepage: +.I http://www.shoutcast.com/ + +.B Lame +homepage: +.I http://www.mp3dev.org/mp3/ + +.B Ogg Vorbis +homepage: +.I http://www.xiph.org/ogg/vorbis/ diff --git a/darkice/tags/darkice-0_17_1/missing b/darkice/tags/darkice-0_17_1/missing new file mode 100755 index 0000000..7789652 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/darkice/tags/darkice-0_17_1/mkinstalldirs b/darkice/tags/darkice-0_17_1/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/darkice/tags/darkice-0_17_1/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/darkice/tags/darkice-0_17_1/src/AlsaDspSource.cpp b/darkice/tags/darkice-0_17_1/src/AlsaDspSource.cpp new file mode 100644 index 0000000..94eef6d --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/AlsaDspSource.cpp @@ -0,0 +1,310 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : AlsaDspSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "AudioSource.h" + +// compile only if configured for ALSA +#ifdef SUPPORT_ALSA_DSP + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Util.h" +#include "Exception.h" +#include "AlsaDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Tell if source id big endian + *----------------------------------------------------------------------------*/ +bool +AlsaDspSource :: isBigEndian ( void ) const throw () +{ + return SND_PCM_FORMAT_S16 == SND_PCM_FORMAT_S16_BE; +} + + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +AlsaDspSource :: init ( const char * name ) throw ( Exception ) +{ + pcmName = Util::strDup( name); + captureHandle = 0; + bufferTime = 1000000; // Do 1s buffering + running = false; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +AlsaDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] pcmName; +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +AlsaDspSource :: open ( void ) throw ( Exception ) +{ + unsigned int u; + snd_pcm_format_t format; + snd_pcm_hw_params_t *hwParams; + + if ( isOpen() ) { + return false; + } + + switch ( getBitsPerSample() ) { + case 8: + format = SND_PCM_FORMAT_S8; + break; + + case 16: + format = SND_PCM_FORMAT_S16; + break; + + default: + return false; + } + + if (snd_pcm_open(&captureHandle, pcmName, SND_PCM_STREAM_CAPTURE, 0) < 0) { + captureHandle = 0; + return false; + } + + if (snd_pcm_hw_params_malloc(&hwParams) < 0) { + close(); + throw Exception( __FILE__, __LINE__, "can't alloc hardware "\ + "parameter structure"); + } + + if (snd_pcm_hw_params_any(captureHandle, hwParams) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't initialize hardware "\ + "parameter structure"); + } + + if (snd_pcm_hw_params_set_access(captureHandle, hwParams, + SND_PCM_ACCESS_RW_INTERLEAVED) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set access type"); + } + + if (snd_pcm_hw_params_set_format(captureHandle, hwParams, format) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set sample format"); + } + + u = getSampleRate(); + if (snd_pcm_hw_params_set_rate_near(captureHandle, hwParams, &u, 0) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set sample rate", u); + } + + u = getChannel(); + if (snd_pcm_hw_params_set_channels(captureHandle, hwParams, u) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set channels", u); + } + + u = getBufferTime() / 4; + if (snd_pcm_hw_params_set_period_time_near(captureHandle, hwParams, &u, 0) + < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set interrupt frequency"); + } + + u = getBufferTime(); + if (snd_pcm_hw_params_set_buffer_time_near(captureHandle, hwParams, &u, 0) + < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set buffer size"); + } + + if (snd_pcm_hw_params(captureHandle, hwParams) < 0) { + snd_pcm_hw_params_free(hwParams); + close(); + throw Exception( __FILE__, __LINE__, "can't set hardware parameters"); + } + + snd_pcm_hw_params_free(hwParams); + + if (snd_pcm_prepare(captureHandle) < 0) { + close(); + throw Exception( __FILE__, __LINE__, "can't prepare audio interface "\ + "for use"); + } + + bytesPerFrame = getChannel() * getBitsPerSample() / 8; + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +AlsaDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + if ( !isOpen() ) { + return false; + } + + if ( !running ) { + snd_pcm_start(captureHandle); + running = true; + } + + /* + * FIXME How to check for available frames? It + * seems like snd_pcm_wait stops working when + * it comes to ALSA plugins... :-( + * + * int milliDelay = sec * 1000 + usec/1000; + * return snd_pcm_wait(captureHandle, milliDelay)!=0; + */ + return true; // bad!! +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +AlsaDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + snd_pcm_sframes_t ret; + + if ( !isOpen() ) { + return 0; + } + + do { + ret = snd_pcm_readi(captureHandle, buf, len/bytesPerFrame); + + // Check for buffer overrun + if (ret == -EPIPE) { + reportEvent(1, "Buffer overrun!"); + snd_pcm_prepare(captureHandle); + ret = -EAGAIN; + } + } while (ret == -EAGAIN); + + if ( ret < 0 ) { + throw Exception(__FILE__, __LINE__, snd_strerror(ret)); + } + + running = true; + return ret * bytesPerFrame; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +AlsaDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + snd_pcm_close(captureHandle); + + captureHandle = 0; + running = false; +} + +#endif // HAVE_ALSA_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2005/04/04 08:36:16 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.3 2005/04/03 05:00:14 jbebel + Fixing code documentation of buffer overruns + + Revision 1.2 2004/02/15 22:36:57 darkeye + proper checking to see if ALSA support is present / needed + + Revision 1.1 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/AlsaDspSource.h b/darkice/tags/darkice-0_17_1/src/AlsaDspSource.h new file mode 100644 index 0000000..25ec320 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/AlsaDspSource.h @@ -0,0 +1,312 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 + LS Informationstechnik (LIKE) + University of Erlangen Nuremberg + All rights reserved. + + Tyrell DarkIce + + File : AlsaDspSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef ALSA_SOURCE_H +#define ALSA_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "Reporter.h" +#include "AudioSource.h" + +#ifdef HAVE_ALSA_LIB +#include +#else +#error configure for ALSA +#endif + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio input based on the ALSA sound system + * + * @author $Author$ + * @version $Revision$ + */ +class AlsaDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * Name of the capture PCM stream. + */ + char *pcmName; + + /** + * Handle to access PCM stream data. + */ + snd_pcm_t *captureHandle; + + /** + * Stores number of bytes per frame. One frame + * contains all samples per time instance. + */ + int bytesPerFrame; + + /** + * Is the stream running? + */ + bool running; + + /** + * Number of useconds to do buffering in the audio device. + */ + unsigned int bufferTime; + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + AlsaDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the PCM to open. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-iitialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param name the PCM (e.g. "hwplug:0,0"). + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + AlsaDspSource ( const char * name, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( name); + } + + /** + * Copy Constructor. + * + * @param ds the object to copy. + * @exception Exception + */ + inline + AlsaDspSource ( const AlsaDspSource & ds ) throw ( Exception ) + : AudioSource( ds ) + { + init( ds.pcmName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~AlsaDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual AlsaDspSource & + operator= ( const AlsaDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.pcmName); + } + return *this; + } + + /** + * Tell if the data from this source comes in big or little endian. + * + * @return true if the source is big endian, false otherwise + */ + virtual bool + isBigEndian ( void ) const throw (); + + /** + * Open the AlsaDspSource. + * This does not put Alsa device into recording mode. + * To start getting samples, call either canRead() or read(). + * + * @return true if opening was successful, false otherwise + * @exception Exception + * + * @see #canRead + * @see #read + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the AlsaDspSource is open. + * + * @return true if the AlsaDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return captureHandle != 0; + } + + /** + * Check if the AlsaDspSource can be read from. + * Blocks until the specified time for data to be available. + * Puts the PCM into recording mode. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the AlsaDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the AlsaDspSource. + * Puts the PCM into recording mode. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the AlsaDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); + + /** + * Returns the buffer size in useconds. + * + * @return the number of useconds audio will be buffered in ALSA + */ + inline virtual unsigned int + getBufferTime( void ) const + { + return bufferTime; + } + + /** + * Sets the number of useconds to buffer audio in ALSA + * + * @param time buffer time + */ + inline virtual void + setBufferTime( unsigned int time ) { + bufferTime = time; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* ALSA_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.1 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/AudioEncoder.h b/darkice/tags/darkice-0_17_1/src/AudioEncoder.h new file mode 100644 index 0000000..88328dc --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/AudioEncoder.h @@ -0,0 +1,488 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : AudioEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef AUDIO_ENCODER_H +#define AUDIO_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Sink.h" +#include "AudioSource.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio encoder + * + * @author $Author$ + * @version $Revision$ + */ +class AudioEncoder : public Sink, public virtual Referable +{ + public: + /** + * Type to specify bitrate mode. Possible values: + * - cbr - constant bitrate mode + * described by bitrate + * - abr - average bitrate mode + * described by an average bitrate and quality + * - vbr - variable bitrate mode + * described by quality + */ + enum BitrateMode { cbr, abr, vbr }; + + private: + + /** + * Sample rate of the input. + */ + unsigned int inSampleRate; + + /** + * Number of bits per sample of the input. + */ + unsigned int inBitsPerSample; + + /** + * Number of channels of the input. + */ + unsigned int inChannel; + + /** + * Is the input big endian or little endian? + */ + bool inBigEndian; + + /** + * The bitrate mode of the encoder + */ + BitrateMode outBitrateMode; + + /** + * Bit rate of the output in kbits/sec, for fixed bitrate encodings. + */ + unsigned int outBitrate; + + /** + * Quality of the output, for variable bitrate encodings. + */ + double outQuality; + + /** + * Sample rate of the output. + */ + unsigned int outSampleRate; + + /** + * Number of channels of the output. + */ + unsigned int outChannel; + + /** + * Initialize the object. + * + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param inBigEndian shows if the input is big or little endian. + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output. + * @param outSampleRate sample rate of the output. + * @param outChannel number of channels of the output. + * @exception Exception + */ + inline void + init ( unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate, + unsigned int outChannel ) throw ( Exception ) + { + this->inSampleRate = inSampleRate; + this->inBitsPerSample = inBitsPerSample; + this->inChannel = inChannel; + this->inBigEndian = inBigEndian; + this->outBitrateMode = outBitrateMode; + this->outBitrate = outBitrate; + this->outQuality = outQuality; + this->outSampleRate = outSampleRate; + this->outChannel = outChannel; + + if ( outQuality < -0.1 || 1.0 < outQuality ) { + throw Exception( __FILE__, __LINE__, "invalid encoder quality"); + } + } + + /** + * De-iitialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + AudioEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Constructor. + * + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @exception Exception + */ + inline + AudioEncoder ( unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + { + init ( inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate ? outSampleRate : inSampleRate, + outChannel ? outChannel : inChannel ); + } + + /** + * Constructor. + * + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @exception Exception + */ + inline + AudioEncoder ( const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception) + { + init( as->getSampleRate(), + as->getBitsPerSample(), + as->getChannel(), + as->isBigEndian(), + outBitrateMode, + outBitrate, + outQuality, + outSampleRate ? outSampleRate : as->getSampleRate(), + outChannel ? outChannel : as->getChannel() ); + } + + /** + * Copy constructor. + * + * @param encoder the AudioEncoder to copy. + */ + inline + AudioEncoder ( const AudioEncoder & encoder ) throw ( Exception ) + { + init ( encoder.inSampleRate, + encoder.inBitsPerSample, + encoder.inChannel, + encoder.inBigEndian, + encoder.outBitrateMode, + encoder.outBitrate, + encoder.outQuality, + encoder.outSampleRate, + encoder.outChannel ); + } + + /** + * Assignment operator. + * + * @param encoder the AudioEncoder to assign this to. + * @return a reference to this AudioEncoder. + * @exception Exception + */ + inline virtual AudioEncoder & + operator= ( const AudioEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + + init ( encoder.inSampleRate, + encoder.inBitsPerSample, + encoder.inChannel, + encoder.inBigEndian, + encoder.outBitrateMode, + encoder.outBitrate, + encoder.outQuality, + encoder.outSampleRate, + encoder.outChannel ); + } + + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~AudioEncoder ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Get the number of channels of the input. + * + * @return the number of channels of the input. + */ + inline int + getInChannel ( void ) const throw () + { + return inChannel; + } + + /** + * Tell if the input is big or little endian. + * + * @return true if the input is big endian, false if little endian. + */ + inline bool + isInBigEndian ( void ) const throw () + { + return inBigEndian; + } + + /** + * Get the sample rate of the input. + * + * @return the sample rate of the input. + */ + inline int + getInSampleRate ( void ) const throw () + { + return inSampleRate; + } + + /** + * Get the number of bits per sample of the input. + * + * @return the number of bits per sample of the input. + */ + inline int + getInBitsPerSample ( void ) const throw () + { + return inBitsPerSample; + } + + /** + * Get the number of channels of the output. + * + * @return the number of channels of the output. + */ + inline int + getOutChannel ( void ) const throw () + { + return outChannel; + } + + /** + * Get the sample rate of the output. + * + * @return the sample rate of the output. + */ + inline int + getOutSampleRate ( void ) const throw () + { + return outSampleRate; + } + + /** + * Get the bit rate mode of the output. + * + * @return the bit rate mode of the output. + */ + inline BitrateMode + getOutBitrateMode ( void ) const throw () + { + return outBitrateMode; + } + + /** + * Get the bit rate of the output in kbits/sec, for fixed bitrate + * encodings. + * + * @return the bit rate of the output. + */ + inline unsigned int + getOutBitrate ( void ) const throw () + { + return outBitrate; + } + + /** + * Get the encoding quality of the output, for variable bitrate + * encodings. + * + * @return the encoding quality of the output. + */ + inline double + getOutQuality ( void ) const throw () + { + return outQuality; + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + virtual bool + isRunning ( void ) const throw () = 0; + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started in the background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + virtual bool + start ( void ) throw ( Exception ) = 0; + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + virtual void + stop ( void ) throw ( Exception ) = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* AUDIO_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.9 2005/04/13 18:03:43 jbebel + Allow quality settings down to -0.1 for ogg + + Revision 1.8 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + + Revision 1.7 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + + Revision 1.6 2002/03/28 16:39:32 darkeye + added interface for variable bitrate encoding + + Revision 1.5 2002/02/19 15:23:59 darkeye + fixed typo + + Revision 1.4 2001/09/18 14:57:19 darkeye + finalized Solaris port + + Revision 1.3 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + Revision 1.2 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:47 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/AudioSource.cpp b/darkice/tags/darkice-0_17_1/src/AudioSource.cpp new file mode 100644 index 0000000..e9e63d7 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/AudioSource.cpp @@ -0,0 +1,132 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2004 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : AudioSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "AudioSource.h" +#include "Util.h" +#include "Exception.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Return an audio source based on the compiled DSP supports and the + * supplied device name parameter. + *----------------------------------------------------------------------------*/ +AudioSource * +AudioSource :: createDspSource( const char * deviceName, + int sampleRate, + int bitsPerSample, + int channel) + throw ( Exception ) +{ + + if ( Util::strEq( deviceName, "/dev", 4) ) { +#if defined( SUPPORT_OSS_DSP ) + Reporter::reportEvent( 1, "Using OSS DSP input device:", deviceName); + return new OssDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#elif defined( SUPPORT_SOLARIS_DSP ) + Reporter::reportEvent( 1, "Using Solaris DSP input device:",deviceName); + return new SolarisDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#else + throw Exception( __FILE__, __LINE__, + "trying to open OSS or Solaris DSP device " + "without support compiled", deviceName); +#endif + } else if ( Util::strEq( deviceName, "jack", 4) ) { +#if defined( SUPPORT_JACK_DSP ) + Reporter::reportEvent( 1, "Using JACK audio server as input device."); + return new JackDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#else + throw Exception( __FILE__, __LINE__, + "trying to open JACK device without " + "support compiled", deviceName); +#endif + } else { +#if defined( SUPPORT_ALSA_DSP ) + Reporter::reportEvent( 1, "Using ALSA DSP input device:", deviceName); + return new AlsaDspSource( deviceName, + sampleRate, + bitsPerSample, + channel); +#else + throw Exception( __FILE__, __LINE__, + "trying to open ALSA DSP device without " + "support compiled", deviceName); +#endif + } +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2005/04/04 08:36:16 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.2 2004/02/15 22:26:16 darkeye + fixed typo, minimal cosmetic change + + Revision 1.1 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/AudioSource.h b/darkice/tags/darkice-0_17_1/src/AudioSource.h new file mode 100644 index 0000000..211bd47 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/AudioSource.h @@ -0,0 +1,340 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : AudioSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef AUDIO_SOURCE_H +#define AUDIO_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* ============================================================ include files */ + +#include "Source.h" +#include "Reporter.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + +/*------------------------------------------------------------------------------ + * Determine the kind of audio device based on the system + *----------------------------------------------------------------------------*/ +#if defined( HAVE_ALSA_LIB ) +// we have an ALSA sound system available +#define SUPPORT_ALSA_DSP 1 +#endif + +#if defined( HAVE_SYS_SOUNDCARD_H ) +// we have an OSS DSP sound source device available +#define SUPPORT_OSS_DSP 1 +#endif + +#if defined( HAVE_SYS_AUDIO_H ) || defined( HAVE_SYS_AUDIOIO_H ) +// we have a Solaris DSP sound device available (same for OpenBSD) +#define SUPPORT_SOLARIS_DSP 1 +#endif + +#if defined( HAVE_JACK_LIB ) +// we have JACK audio server +#define SUPPORT_JACK_DSP 1 +#endif + +#if !defined( SUPPORT_ALSA_DSP ) \ + && !defined( SUPPORT_OSS_DSP ) \ + && !defined( SUPPORT_JACK_DSP ) \ + && !defined( SUPPORT_SOLARIS_DSP ) +// there was no DSP audio system found +#error No DSP audio input device found on system +#endif + + +/* =============================================================== data types */ + +/** + * Audio data input + * + * @author $Author$ + * @version $Revision$ + */ +class AudioSource : public Source, public virtual Reporter +{ + private: + + /** + * Number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.) + */ + unsigned int channel; + + /** + * Samples per second (e.g. 44100 for 44.1kHz CD quality) + */ + unsigned int sampleRate; + + /** + * Bits per sample (e.g. 8 bits, 16 bits, etc.) + */ + unsigned int bitsPerSample; + + /** + * Initialize the object. + * + * @param sampleRate samples per second. + * @param bitsPerSample bits per sample. + * @param channel number of channels of the audio source. + * @exception Exception + */ + inline void + init ( unsigned int sampleRate, + unsigned int bitsPerSample, + unsigned int channel ) throw ( Exception ) + { + this->sampleRate = sampleRate; + this->bitsPerSample = bitsPerSample; + this->channel = channel; + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Constructor. + * Because all values have defaults, this is also the default + * constructor. + * + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + AudioSource ( unsigned int sampleRate = 44100, + unsigned int bitsPerSample = 16, + unsigned int channel = 2 ) + throw ( Exception ) + { + init ( sampleRate, bitsPerSample, channel); + } + + /** + * Copy Constructor. + * + * @param as the object to copy. + * @exception Exception + */ + inline + AudioSource ( const AudioSource & as ) throw ( Exception ) + : Source( as ) + { + init ( as.sampleRate, as.bitsPerSample, as.channel); + } + + /** + * Assignment operator. + * + * @param as the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual AudioSource & + operator= ( const AudioSource & as ) throw ( Exception ) + { + if ( this != &as ) { + strip(); + Source::operator=( as ); + init ( as.sampleRate, as.bitsPerSample, as.channel); + } + + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + virtual inline + ~AudioSource ( void ) throw ( Exception ) + { + } + + /** + * Get the number of channels for this AudioSource. + * + * @return the number of channels. + */ + inline unsigned int + getChannel ( void ) const throw () + { + return channel; + } + + /** + * Tell if the data from this source comes in big or little endian. + * + * @return true if the data is big endian, false if little endian + */ + virtual bool + isBigEndian ( void ) const throw () + { +#ifdef WORDS_BIGENDIAN + return true; +#else + return false; +#endif + } + + /** + * Get the sample rate per seconds for this AudioSource. + * + * @return the sample rate per seconds. + */ + inline unsigned int + getSampleRate ( void ) const throw () + { + return sampleRate; + } + + + /** + * Get the number of bits per sample for this AudioSource. + * + * @return the number of bits per sample. + */ + inline unsigned int + getBitsPerSample ( void ) const throw () + { + return bitsPerSample; + } + + /** + * Factory method for creating an AudioSource object of the + * appropriate type, based on the compiled DSP support and + * the supplied DSP name parameter. + * + * @param deviceName the audio device (/dev/dspX, hwplug:0,0, etc) + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + static AudioSource * + createDspSource( const char * deviceName, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2) throw ( Exception ); + +}; + + +/* ================================================= external data structures */ + +/*------------------------------------------------------------------------------ + * Determine the kind of audio device based on the system + *----------------------------------------------------------------------------*/ +#if defined( SUPPORT_ALSA_DSP ) +#include "AlsaDspSource.h" +#endif + +#if defined( SUPPORT_OSS_DSP ) +#include "OssDspSource.h" +#endif + +#if defined( SUPPORT_SOLARIS_DSP ) +#include "SolarisDspSource.h" +#endif + +#if defined( SUPPORT_JACK_DSP ) +#include "JackDspSource.h" +#endif + +/* ====================================================== function prototypes */ + + + +#endif /* AUDIO_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.9 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.8 2005/04/04 08:36:16 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.7 2004/02/18 21:08:11 darkeye + ported to OpenBSD (real-time scheduling not yet supported) + + Revision 1.6 2004/02/15 12:06:29 darkeye + added ALSA support, thanks to Christian Forster + + Revision 1.5 2001/09/18 14:57:19 darkeye + finalized Solaris port + + Revision 1.4 2001/09/11 15:05:21 darkeye + added Solaris support + + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:47 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/BufferedSink.cpp b/darkice/tags/darkice-0_17_1/src/BufferedSink.cpp new file mode 100644 index 0000000..d82cbfb --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/BufferedSink.cpp @@ -0,0 +1,395 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : BufferedSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + the buffer is filled like this: + + buffer bufferEnd + | | + +----------+--------------------------+--------------+ + |<---- valid data -------->| + outp inp + + buffer bufferEnd + | | + +----------------+--------------+--------------------+ + -- valid data -->| |--- valid data -----> + inp outp + + + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Exception.h" +#include "BufferedSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +BufferedSink :: init ( Sink * sink, + unsigned int size, + unsigned int chunkSize ) throw ( Exception ) +{ + if ( !sink ) { + throw Exception( __FILE__, __LINE__, "no sink"); + } + + this->sink = sink; // create a reference + this->chunkSize = chunkSize ? chunkSize : 1; + this->bufferSize = size; + // make bufferSize a multiple of chunkSize + this->bufferSize -= this->bufferSize % this->chunkSize; + this->peak = 0; + this->misalignment = 0; + this->buffer = new unsigned char[bufferSize]; + this->bufferEnd = buffer + bufferSize; + this->inp = buffer; + this->outp = buffer; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +BufferedSink :: BufferedSink ( const BufferedSink & buffer ) + throw ( Exception ) +{ + init( buffer.sink.get(), buffer.bufferSize, buffer.chunkSize); + + this->peak = buffer.peak; + this->misalignment = buffer.misalignment; + memcpy( this->buffer, buffer.buffer, this->bufferSize); +} + + +/*------------------------------------------------------------------------------ + * De-initalize the object + *----------------------------------------------------------------------------*/ +void +BufferedSink :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + sink = 0; // delete the reference + delete buffer; +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +BufferedSink & +BufferedSink :: operator= ( const BufferedSink & buffer ) + throw ( Exception ) +{ + if ( this != &buffer ) { + strip(); + Sink::operator=( buffer ); + init( buffer.sink.get(), buffer.bufferSize, buffer.chunkSize); + + this->peak = buffer.peak; + this->misalignment = buffer.misalignment; + memcpy( this->buffer, buffer.buffer, this->bufferSize); + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Store bufferSize bytes into the buffer + * All data is consumed. The return value is less then bufferSize only + * if the BufferedSink's internal buffer is smaller than bufferSize, + * thus can't hold that much + * The data to be stored is treated as parts with chunkSize size + * Only full chunkSize sized parts are stored + *----------------------------------------------------------------------------*/ +unsigned int +BufferedSink :: store ( const void * buffer, + unsigned int bufferSize ) throw ( Exception ) +{ + const unsigned char * buf; + unsigned int size; + unsigned int i; + unsigned char * oldInp; + + if ( !buffer ) { + throw Exception( __FILE__, __LINE__, "buffer is null"); + } + + if ( !bufferSize ) { + return 0; + } + + oldInp = inp; + buf = (const unsigned char *) buffer; + + // adjust so it is a multiple of chunkSize + bufferSize -= bufferSize % chunkSize; + + // cut the front of the supplied buffer if it wouldn't fit + if ( bufferSize > this->bufferSize ) { + size = this->bufferSize - 1; + size -= size % chunkSize; // keep it a multiple of chunkSize + buf += bufferSize - size; + } else { + size = bufferSize; + } + + // copy the data into the buffer + i = bufferEnd - inp; + if ( (i % chunkSize) != 0 ) { + throw Exception( __FILE__, __LINE__, "copy quantity not aligned", i); + } + + if ( size <= i ) { + // the place between inp and bufferEnd is + // big enough to hold the data + + memcpy( inp, buf, size); + inp = slidePointer( inp, size); + + // adjust outp, lose the data that was overwritten, if any + if ( outp > oldInp && outp <= inp ) { + outp = slidePointer( inp, chunkSize); + } + + } else { + // the place between inp and bufferEnd is not + // big enough to hold the data + // writing will take place in two turns, once from + // inp -> bufferEnd, then from buffer -> + + memcpy( inp, buf, i); + i = size - i; + if ( (i % chunkSize) != 0 ) { + throw Exception(__FILE__, __LINE__, "copy quantity not aligned", i); + } + memcpy( this->buffer, buf, i); + inp = slidePointer( this->buffer, i); + + // adjust outp, lose the data that was overwritten, if any + if ( outp <= oldInp ) { + if ( outp < inp ) { + outp = slidePointer( inp, chunkSize); + } + } else { + outp = slidePointer( inp, chunkSize); + } + } + + updatePeak(); + + if ( ((inp - this->buffer) % chunkSize) != 0 ) { + throw Exception( __FILE__, __LINE__, + "inp not aligned", inp - this->buffer); + } + if ( ((outp - this->buffer) % chunkSize) != 0 ) { + throw Exception( __FILE__, __LINE__, + "outp not aligned", outp - this->buffer); + } + + return size; +} + + +/*------------------------------------------------------------------------------ + * Write some data to the sink + * if len == 0, try to flush the buffer + *----------------------------------------------------------------------------*/ +unsigned int +BufferedSink :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + unsigned int length; + unsigned int soFar; + unsigned char * b = (unsigned char *) buf; + + if ( !buf ) { + throw Exception( __FILE__, __LINE__, "buf is null"); + } + + if ( !isOpen() ) { + return 0; + } + + if ( !align() ) { + return 0; + } + + // make it a multiple of chunkSize + len -= len % chunkSize; + + // try to write data from the buffer first, if any + if ( inp != outp ) { + unsigned int size = 0; + unsigned int total = 0; + + if ( outp > inp ) { + // valuable data is between outp -> bufferEnd and buffer -> inp + // try to write the outp -> bufferEnd + // the rest will be written in the next if + + size = bufferEnd - outp - 1; + size -= size % chunkSize; + soFar = 0; + + while ( outp > inp && soFar < size && sink->canWrite( 0, 0) ) { + length = sink->write( outp + soFar, size - soFar); + outp = slidePointer( outp, length); + soFar += length; + } + + total += soFar; + } + + if ( outp < inp ) { + // valuable data is between outp and inp + // in the previous if wrote all data from the end + // this part will write the rest + + size = inp - outp; + soFar = 0; + + while ( soFar < size && sink->canWrite( 0, 0) ) { + length = sink->write( outp + soFar, size - soFar); + outp = slidePointer( outp, length); + soFar += length; + } + + total += soFar; + } + + while ( (outp - buffer) % chunkSize ) { + slidePointer( outp, 1); + } + + // calulate the misalignment to chunkSize boundaries + misalignment = (chunkSize - (total % chunkSize)) % chunkSize; + } + + if ( !align() ) { + return 0; + } + + // the internal buffer is empty, try to write the fresh data + soFar = 0; + if ( inp != outp ) { + while ( soFar < len && sink->canWrite( 0, 0) ) { + soFar += sink->write( b + soFar, len - soFar); + } + } + length = soFar; + + // calulate the misalignment to chunkSize boundaries + misalignment = (chunkSize - (length % chunkSize)) % chunkSize; + + if ( length < len ) { + // if not all fresh could be written, store the remains + + store( b + length, len - length); + } + + // tell them we ate everything up to chunkSize alignment + return len; +} + + +/*------------------------------------------------------------------------------ + * Close the sink, lose all pending data + *----------------------------------------------------------------------------*/ +void +BufferedSink :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + flush(); + sink->close(); + inp = outp = buffer; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.6 2002/10/19 12:21:28 darkeye + fixed comment typo + + Revision 1.5 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/BufferedSink.h b/darkice/tags/darkice-0_17_1/src/BufferedSink.h new file mode 100644 index 0000000..129cabc --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/BufferedSink.h @@ -0,0 +1,421 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : BufferedSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef BUFFERED_SINK_H +#define BUFFERED_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Ref.h" +#include "Reporter.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A Sink First-In First-Out buffer. + * This buffer can always be written to, it overwrites any + * data contained if needed. + * The class is not thread-safe. + * + * @author $Author$ + * @version $Revision$ + */ +class BufferedSink : public Sink, public virtual Reporter +{ + private: + + /** + * The buffer. + */ + unsigned char * buffer; + + /** + * The end of the buffer. + */ + unsigned char * bufferEnd; + + /** + * The size of the buffer. + */ + unsigned int bufferSize; + + /** + * The highest usage of the buffer. + */ + unsigned int peak; + + /** + * All data written to this BufferedSink is handled by chuncks + * of this size. + */ + unsigned int chunkSize; + + /** + * Number of bytes the underlying stream is misaligned with + * chunkSize. (It needs this many bytes more to be aligned.) + */ + unsigned int misalignment; + + /** + * Start of free territory in buffer. + */ + unsigned char * inp; + + /** + * Start of sensible data in buffer. + */ + unsigned char * outp; + + + /** + * The underlying Sink. + */ + Ref sink; + + /** + * Initialize the object. + * + * @param sink the Sink to attach this BufferedSink to. + * @param size the size of the internal buffer to use. + * @param chunkSize size of chunks to handle data in. + * @exception Exception + */ + void + init ( Sink * sink, + unsigned int size, + unsigned int chunkSize ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + /** + * Slide a pointer in the internal buffer by offset. If the pointer + * would reach beyond the end of the buffer, it goes wraps around. + * + * @param p the pointer to slide. + * @param offset the amount to slide with. + * @return pointer p + offset, wrapped around if needed. + */ + inline unsigned char * + slidePointer ( + unsigned char * p, + unsigned int offset ) throw () + { + p += offset; + while ( p >= bufferEnd ) { + p -= bufferSize; + } + + return p; + } + + /** + * Update the peak buffer usage indicator. + * + * @see #peak + */ + inline void + updatePeak ( void ) throw () + { + unsigned int u; + + u = outp <= inp ? inp - outp : (bufferEnd - outp) + (inp - buffer); + if ( peak < u ) { + peak = u; + reportEvent( 4, "BufferedSink, new peak:", peak); + reportEvent( 4, "BufferedSink, remaining:", bufferSize - peak); + } + } + + /** + * If the underlying Sink is misaligned on chunkSize, write as + * many 0s as needed to get it aligned. + * + * @see #misalignment + * @see #chunkSize + */ + inline bool + align ( void ) throw ( Exception ) + { + char b[] = { 0 }; + + while ( misalignment ) { + if ( sink->canWrite( 0, 0) ) { + unsigned int ret; + + if ( !(ret = sink->write( b, 1)) ) { + return false; + } + --misalignment; + + } else { + return false; + } + } + + return true; + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + BufferedSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Get the size of the buffer. + * + * @return the size of the buffer. + */ + inline unsigned int + getSize ( void ) const throw () + { + return bufferSize; + } + + /** + * Store data in the internal buffer. If there is not enough space, + * discard all in the buffer and the beginning of the supplied + * buffer if needed. + * + * @param buffer the data to store. + * @param bufferSize the amount of data to store in bytes. + * @return number of bytes really stored. + */ + unsigned int + store ( const void * buffer, + unsigned int bufferSize ) throw ( Exception ); + + + public: + + /** + * Constructor by an underlying Sink, buffer size and chunk size. + * + * @param sink the Sink to attach this BufferSink to. + * @param size the size of the buffer to use for buffering. + * @param chunkSize hanlde all data in write() as chunks of + * chunkSize + * @exception Exception + */ + inline + BufferedSink ( Sink * sink, + unsigned int size, + unsigned int chunkSize = 1 ) throw ( Exception ) + { + init( sink, size, chunkSize); + } + + /** + * Copy constructor. + * + * @param buffer the object to copy. + * @exception Exception + */ + BufferedSink ( const BufferedSink & buffer ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~BufferedSink ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param bs the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + virtual BufferedSink & + operator= ( const BufferedSink & bs ) throw ( Exception ); + + /** + * Get the peak usage of the internal buffer. + * + * @return the peak usage of the internal buffer. + */ + inline unsigned int + getPeak ( void ) const throw () + { + return peak; + } + + /** + * Open the BufferedSink. Opens the underlying Sink. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + inline virtual bool + open ( void ) throw ( Exception ) + { + return sink->open(); + } + + /** + * Check if a BufferedSink is open. + * + * @return true if the BufferedSink is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return sink->isOpen(); + } + + /** + * Check if the BufferedSink is ready to accept data. + * Always returns true immediately. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + return true; + } + + /** + * Write data to the BufferedSink. + * Always reads the maximum number of chunkSize chunks buf + * holds. If the data can not be written to the underlying + * stream, it is buffered. If the buffer overflows, the oldest + * data is discarded. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the BufferedSink to the + * underlying Sink. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + unsigned char b[1]; + + write( b, 0); + } + + /** + * Close the BufferedSink. Closes the underlying Sink. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* BUFFERED_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.8 2005/04/03 05:01:46 jbebel + Fix peak reporting to report new peak rather than previous + + Revision 1.7 2002/07/21 08:47:06 darkeye + some exception cleanup (throw clauses in function declarations) + + Revision 1.6 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.5 2000/11/15 18:08:42 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/CastSink.cpp b/darkice/tags/darkice-0_17_1/src/CastSink.cpp new file mode 100644 index 0000000..dc3368e --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/CastSink.cpp @@ -0,0 +1,179 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : CastSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "Util.h" +#include "Exception.h" +#include "CastSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +CastSink :: init ( TcpSocket * socket, + Sink * streamDump, + const char * password, + unsigned int bitRate, + const char * name, + const char * url, + const char * genre, + bool isPublic, + unsigned int bufferDuration ) + throw ( Exception ) +{ + this->socket = socket; + this->streamDump = streamDump; + this->password = password ? Util::strDup( password) : 0; + this->bitRate = bitRate; + this->name = name ? Util::strDup( name) : 0; + this->url = url ? Util::strDup( url) : 0; + this->genre = genre ? Util::strDup( genre) : 0; + this->isPublic = isPublic; + this->bufferDuration = bufferDuration; + + int bufferSize = bitRate ? (bitRate * 1024 / 8) * bufferDuration + : (128 * 1024 / 8) * bufferDuration; + + bufferedSink = socket ? new BufferedSink( socket, bufferSize) + : 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +CastSink :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + if ( password ) { + delete[] password; + } + if ( name ) { + delete[] name; + } + if ( url ) { + delete[] url; + } + if ( genre ) { + delete[] genre; + } +} + + +/*------------------------------------------------------------------------------ + * Open the connection + *----------------------------------------------------------------------------*/ +bool +CastSink :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( !bufferedSink->open() ) { + return false; + } + + if ( !sendLogin() ) { + close(); + return false; + } + + if ( streamDump != 0 ) { + if ( !streamDump->isOpen() ) { + if ( !streamDump->open() ) { + reportEvent( 2, "can't open stream dump"); + } + } + } + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.9 2002/04/09 13:10:43 darkeye + resolved memory leak issue introduced in 0.9 + + Revision 1.8 2002/03/28 16:40:55 darkeye + slight changes to allow for variable bitrate streams + (where the value of bitrate is 0) + + Revision 1.7 2002/02/28 09:49:25 darkeye + added possibility to save the encoded stream to a local file only + (no streaming server needed) + + Revision 1.6 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.5 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + Revision 1.4 2001/08/29 21:08:30 darkeye + made some description options in the darkice config file optional + + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/CastSink.h b/darkice/tags/darkice-0_17_1/src/CastSink.h new file mode 100644 index 0000000..cbec626 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/CastSink.h @@ -0,0 +1,500 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : CastSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CAST_SINK_H +#define CAST_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Ref.h" +#include "Reporter.h" +#include "Sink.h" +#include "TcpSocket.h" +#include "BufferedSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Data output to a ShoutCast / IceCast / etc. server + * This is an abstract class. A subclass should override at least + * the sendLogin() function. + * + * @author $Author$ + * @version $Revision$ + */ +class CastSink : public Sink, public virtual Reporter +{ + private: + + /** + * The socket connection to the server. + */ + Ref socket; + + /** + * The BufferedSink encapsulating the socket connection to the server. + */ + Ref bufferedSink; + + /** + * An optional Sink to enable stream dumps. + */ + Ref streamDump; + + /** + * Duration of the BufferedSink buffer in seconds. + */ + unsigned int bufferDuration; + + /** + * Password to the server. + */ + char * password; + + /** + * Name of the stream. + */ + char * name; + + /** + * URL associated with the stream. + */ + char * url; + + /** + * Genre of the stream. + */ + char * genre; + + /** + * Bitrate of the stream (e.g. mp3 bitrate). + */ + unsigned int bitRate; + + /** + * Is the stream public? + */ + bool isPublic; + + /** + * Initalize the object. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param name name of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + void + init ( TcpSocket * socket, + Sink * streamDump, + const char * password, + unsigned int bitRate, + const char * name, + const char * url, + const char * genre, + bool isPublic, + unsigned int bufferDuration ) + throw ( Exception ); + + /** + * De-initalize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + CastSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + virtual bool + sendLogin ( void ) throw ( Exception ) = 0; + + /** + * Get the Sink underneath this CastSink. + * + * @return pointer to the Sink underneath this CastSink. + */ + inline Sink * + getSink ( void ) const throw () + { + return bufferedSink.get(); + } + + /** + * Get the TcpSocket underneath this CastSink. + * + * @return pointer to the TcpSocket underneath this CastSink. + */ + inline TcpSocket * + getSocket ( void ) const throw () + { + return socket.get(); + } + + + public: + + /** + * Constructor. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param name name of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param streamDump a Sink to dump the streamed binary data to + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + inline + CastSink ( TcpSocket * socket, + const char * password, + unsigned int bitRate, + const char * name = 0, + const char * url = 0, + const char * genre = 0, + bool isPublic = false, + Sink * streamDump = 0, + unsigned int bufferDuration = 10 ) + throw ( Exception ) + { + init( socket, + streamDump, + password, + bitRate, + name, + url, + genre, + isPublic, + bufferDuration ); + } + + /** + * Copy constructor. + * + * @param cs the CastSink to copy. + */ + inline + CastSink( const CastSink & cs ) throw ( Exception ) + : Sink( cs ) + { + init( cs.socket.get(), + cs.streamDump.get(), + cs.password, + cs.bitRate, + cs.name, + cs.url, + cs.genre, + cs.isPublic, + cs.bufferDuration ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~CastSink( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param cs the CastSink to assign this to. + * @return a reference to this CastSink. + * @exception Exception + */ + inline virtual CastSink & + operator= ( const CastSink & cs ) throw ( Exception ) + { + if ( this != &cs ) { + strip(); + Sink::operator=( cs ); + init( cs.socket.get(), + cs.streamDump.get(), + cs.password, + cs.bitRate, + cs.name, + cs.url, + cs.genre, + cs.isPublic, + cs.bufferDuration ); + } + return *this; + } + + /** + * Open the CastSink. + * Logs in to the server. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the CastSink is open. + * + * @return true if the CastSink is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return bufferedSink != NULL ? bufferedSink->isOpen() : false; + } + + /** + * Check if the CastSink is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the CastSink is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + return getSink()->canWrite( sec, usec); + } + + /** + * Write data to the CastSink. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + inline virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ) + { + if ( streamDump != 0 ) { + streamDump->write( buf, len); + } + + return getSink()->write( buf, len); + } + + /** + * Flush all data that was written to the CastSink to the server. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + if ( streamDump != 0 ) { + streamDump->flush(); + } + + return getSink()->flush(); + } + + /** + * Close the CastSink. + * + * @exception Exception + */ + inline virtual void + close ( void ) throw ( Exception ) + { + if ( streamDump != 0 ) { + streamDump->close(); + } + + return getSink()->close(); + } + + /** + * Get the password to the server. + * + * @return the password to the server. + */ + inline const char * + getPassword ( void ) const throw () + { + return password; + } + + /** + * Get the name of the stream. + * + * @return the name of the stream. + */ + inline const char * + getName ( void ) const throw () + { + return name; + } + + /** + * Get the URL associated with the stream. + * + * @return the URL associated with the stream. + */ + inline const char * + getUrl ( void ) const throw () + { + return url; + } + + /** + * Get the genre of the stream. + * + * @return the genre of the stream. + */ + inline const char * + getGenre ( void ) const throw () + { + return genre; + } + + /** + * Get the bitrate of the stream (e.g. mp3 bitrate). + * + * @return the bitrate of the stream (e.g. mp3 bitrate). + */ + inline unsigned int + getBitRate ( void ) const throw () + { + return bitRate; + } + + /** + * Get wether this stream is public. + * + * @return true if the stream is public, false otherwise. + */ + inline bool + getIsPublic ( void ) const throw () + { + return isPublic; + } + + /** + * Get the duration of the BufferedSink buffer in seconds. + * + * @return the the duration of the BufferedSink buffer in seconds. + */ + inline unsigned int + getBufferDuration ( void ) const throw () + { + return bufferDuration; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CAST_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.8 2004/01/05 12:00:00 darkeye + fixed possible null pointer problem when destroying the object + + Revision 1.7 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.6 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + Revision 1.5 2001/08/29 21:08:30 darkeye + made some description options in the darkice config file optional + + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:48 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/ConfigSection.cpp b/darkice/tags/darkice-0_17_1/src/ConfigSection.cpp new file mode 100644 index 0000000..929cc20 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/ConfigSection.cpp @@ -0,0 +1,216 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell ConfigSection + + File : ConfigSection.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + + +#include "ConfigSection.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * string containing all white space characters + *----------------------------------------------------------------------------*/ +#define WHITE_SPACE_STR " \t" + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Add a key / value pair + *----------------------------------------------------------------------------*/ +bool +ConfigSection :: add ( const char * key, + const char * value ) throw ( Exception ) +{ + if ( !key || !value ) { + throw Exception( __FILE__, __LINE__, "no key or value"); + } + + std::pair element( key, value); + std::pair res; + + res = table.insert( element); + + return res.second; +} + + +/*------------------------------------------------------------------------------ + * Get a value for a key + *----------------------------------------------------------------------------*/ +const char * +ConfigSection :: get ( const char * key ) const throw ( Exception ) +{ + if ( !key ) { + throw Exception( __FILE__, __LINE__, "no key"); + } + + TableType::const_iterator it = table.find( key); + if ( it == table.end() ) { + return 0; + } + return it->second.c_str(); +} + + +/*------------------------------------------------------------------------------ + * Get a value for a key, in the key does not exist, throw an exception + *----------------------------------------------------------------------------*/ +const char * +ConfigSection :: getForSure ( const char * key, + const char * message1, + const char * message2, + int code ) const + throw ( Exception ) +{ + const char * value; + + if ( !(value = get( key)) ) { + throw Exception( __FILE__, __LINE__, key, message1, message2, code); + } + + return value; +} + + +/*------------------------------------------------------------------------------ + * Add a configuration line + *----------------------------------------------------------------------------*/ +bool +ConfigSection :: addLine ( const char * line ) throw ( Exception ) +{ + if ( !line ) { + throw Exception( __FILE__, __LINE__, "no line"); + } + + std::string::size_type ix; + std::string str( line); + + /* delete everything after the first # */ + if ( (ix = str.find( '#')) != str.npos ) { + str.erase( ix); + } + /* eat up all white space from the front */ + if ( (ix = str.find_first_not_of( WHITE_SPACE_STR)) != str.npos ) { + str.erase( 0, ix); + } + /* eat up all white space from the end */ + if ( (ix = str.find_last_not_of( WHITE_SPACE_STR)) != str.npos ) { + str.erase( ix + 1); + } + if ( !str.length() ) { + return true; + } + + /* find the '=' delimiter between key and value */ + if ( (ix = str.find( '=')) == str.npos ) { + return false; + } + + std::string key( str, 0, ix); + std::string value( str, ix + 1); + + /* eat up all white space from the front of value */ + if ( (ix = value.find_first_not_of( WHITE_SPACE_STR)) != value.npos ) { + value.erase( 0, ix); + } + /* eat up all white space from the end of key */ + if ( (ix = key.find_last_not_of( WHITE_SPACE_STR)) != key.npos ) { + key.erase( ix + 1); + } + + /* now add the new key / value pair */ + return add( key.c_str(), value.c_str()); +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.8 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.7 2001/10/19 09:20:09 darkeye + config file now may contain tabs also as white space + + Revision 1.6 2001/09/09 11:26:43 darkeye + full line comments skipped earlier: commens allowed before the first secion + + Revision 1.5 2001/09/05 20:11:15 darkeye + removed dependency on locally stored SGI STL header files + now compiler-supplied C++ library STL header files are used + compiles under GNU C++ 3 + hash_map (an SGI extension to STL) replaced with map + std:: namespace prefix added to all STL class references + + Revision 1.4 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.3 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/09 22:08:17 darkeye + added function getForSure + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/ConfigSection.h b/darkice/tags/darkice-0_17_1/src/ConfigSection.h new file mode 100644 index 0000000..a20dc47 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/ConfigSection.h @@ -0,0 +1,212 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell ConfigSection + + File : ConfigSection.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CONFIG_SECTION_H +#define CONFIG_SECTION_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include +#include + +#include "Referable.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A configuration file representation. The file is of the syntax: + * + *
+ *  # this is a whole line comment
+ *  key = value
+ *  an ugly key name = long value    # this end is a comment too
+ *  
+ * + * also empty lines are ignored and all white space is removed + * from the front and end of keys / values + * + * Knwon problem: you can't use '#' in any part of a key / value pair + * + * @author $Author$ + * @version $Revision$ + */ +class ConfigSection : public virtual Referable +{ + private: + + /** + * Type of the hash table used in this class. + */ + typedef std::map TableType; + + /** + * Hash table holding the configuration information. + */ + TableType table; + + + protected: + + + public: + + /** + * Default constructor. + * + * @exception Exception + */ + inline + ConfigSection ( void ) throw ( Exception ) + { + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~ConfigSection ( void ) throw ( Exception ) + { + } + + +/* TODO + + inline + ConfigSection ( const ConfigSection & di ) throw ( Exception ) + { + } + + + inline ConfigSection & + operator= ( const ConfigSection * di ) throw ( Exception ) + { + } +*/ + + /** + * Add a key / value pair to the configuration information. + * + * @param key the key to add the value by + * @param value the value to add for the key + * @return true if adding was successful, false otherwise + * @exception Exception + */ + virtual bool + add ( const char * key, + const char * value ) throw ( Exception ); + + /** + * Get a value for a key. + * + * @param key the key to get the value for + * @return the value for the key, or NULL if the key doesn't exist. + * @exception Exception + */ + virtual const char * + get ( const char * key ) const throw ( Exception ); + + /** + * Get a value for a key, or throw an Exception. + * + * @param key the key to get the value for + * @param message1 message part 1 of the Exception to be thrown. + * @param message2 message part 2 of the Exception to be thrown. + * @param code error code of the Exception to be thrown. + * @return the value for the key. The return value is never NULL. + * @exception Exception + */ + virtual const char * + getForSure ( const char * key, + const char * message1 = 0, + const char * message2 = 0, + int code = 0 ) const + throw ( Exception ); + + /** + * Add a line of configuration information. + * + * @param line the line to add. + * @return true if a new key was added, false otherwise. + * @exception Exception + */ + virtual bool + addLine ( const char * line ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONFIG_SECTION_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2001/09/05 20:11:15 darkeye + removed dependency on locally stored SGI STL header files + now compiler-supplied C++ library STL header files are used + compiles under GNU C++ 3 + hash_map (an SGI extension to STL) replaced with map + std:: namespace prefix added to all STL class references + + Revision 1.3 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/09 22:08:17 darkeye + added function getForSure + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Connector.cpp b/darkice/tags/darkice-0_17_1/src/Connector.cpp new file mode 100644 index 0000000..7e17ced --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Connector.cpp @@ -0,0 +1,388 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Connector.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "Exception.h" +#include "Connector.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +Connector :: init ( Source * source ) throw ( Exception ) +{ + this->source = source; + this->sinks = 0; + this->numSinks = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +Connector :: strip ( void ) throw ( Exception ) +{ + source = 0; + + if ( sinks ) { + unsigned int u; + + for ( u = 0; u < numSinks; ++u ) { + sinks[u] = 0; + } + + delete[] sinks; + } +} + + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +Connector :: Connector ( const Connector & connector ) throw ( Exception ) +{ + unsigned int u; + + init( connector.source.get()); + + for ( u = 0; u < connector.numSinks; ++u ) { + attach( connector.sinks[u].get() ); + } +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +Connector & +Connector :: operator= ( const Connector & connector ) throw ( Exception ) +{ + if ( this != &connector ) { + unsigned int u; + + // first free everything + strip(); + + // then fill in + init( connector.source.get() ); + + for ( u = 0; u < connector.numSinks; ++u ) { + attach( connector.sinks[u].get() ); + } + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Attach a sink to the connector + *----------------------------------------------------------------------------*/ +void +Connector :: attach ( Sink * sink ) throw ( Exception ) +{ + if ( !sinks ) { + + numSinks = 1; + sinks = new Ref[1]; + sinks[0] = sink; + + } else { + + unsigned int u; + Ref * s = new Ref[numSinks + 1]; + + for ( u = 0; u < numSinks; ++u ) { + s[u] = sinks[u].get(); + } + + s[numSinks] = sink; + delete[] sinks; + sinks = s; + ++numSinks; + } +} + + +/*------------------------------------------------------------------------------ + * Detach a sink to the connector + *----------------------------------------------------------------------------*/ +bool +Connector :: detach ( Sink * sink ) throw ( Exception ) +{ + if ( numSinks == 0 ) { + + return false; + + } else if ( numSinks == 1 ) { + + if ( sinks[0].get() != sink ) { + return false; + } + + sinks[0] = 0; + delete[] sinks; + sinks = 0; + --numSinks; + + return true; + + } else { + + unsigned int u; + unsigned int v; + unsigned int ix; + Ref * s; + + ix = numSinks; + for ( u = 0; u < numSinks; ++u ) { + + if ( sinks[u].get() == sink ) { + ix = u; + break; + } + } + + if ( ix == numSinks ) { + return false; + } + + s = new Ref[numSinks - 1]; + for ( u = 0, v = 0; u < numSinks; ++u ) { + + if ( u != ix ) { + s[v++] = sinks[u]; + } + } + + sinks[ix] = 0; + delete[] sinks; + sinks = s; + --numSinks; + + return true; + } +} + + +/*------------------------------------------------------------------------------ + * Open the source and all the sinks if needed + *----------------------------------------------------------------------------*/ +bool +Connector :: open ( void ) throw ( Exception ) +{ + unsigned int u; + + if ( !source->isOpen() ) { + if ( !source->open() ) { + return false; + } + } + + for ( u = 0; u < numSinks; ++u ) { + if ( !sinks[u]->isOpen() ) { + if ( !sinks[u]->open() ) { + break; + } + } + } + + // if not all could be opened, close those that were + if ( u < numSinks ) { + unsigned int v; + + for ( v = 0; v < u; ++v ) { + sinks[v]->close(); + } + + source->close(); + + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Transfer some data from the source to the sink + *----------------------------------------------------------------------------*/ +unsigned int +Connector :: transfer ( unsigned long bytes, + unsigned int bufSize, + unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + unsigned int u; + unsigned long b; + + if ( numSinks == 0 ) { + return 0; + } + + if ( bufSize == 0 ) { + return 0; + } + + unsigned char * buf = new unsigned char[bufSize]; + + reportEvent( 6, "Connector :: tranfer, bytes", bytes); + + for ( b = 0; !bytes || b < bytes; ) { + unsigned int d = 0; + unsigned int e = 0; + + if ( source->canRead( sec, usec) ) { + d = source->read( buf, bufSize); + + // check for EOF + if ( d == 0 ) { + reportEvent( 3, "Connector :: transfer, EOF"); + break; + } + + for ( u = 0; u < numSinks; ++u ) { + + if ( sinks[u]->canWrite( sec, usec) ) { + try { + // we expect the sink to accept all data written + e = sinks[u]->write( buf, d); + } catch ( Exception & e ) { + sinks[u]->close(); + detach( sinks[u].get() ); + + reportEvent( 4, + "Connector :: transfer, sink removed, remaining", + numSinks); + + if ( numSinks == 0 ) { + reportEvent( 4, + "Connector :: transfer, no more sinks"); + delete[] buf; + return b; + } + // with the call to detach, numSinks gets 1 lower, + // and the next sink comes to sinks[u] + --u; + } + } + } + + b += d; + } else { + reportEvent( 3, "Connector :: transfer, can't read"); + break; + } + } + + delete[] buf; + return b; +} + + +/*------------------------------------------------------------------------------ + * Close the source and all the sinks if needed + *----------------------------------------------------------------------------*/ +void +Connector :: close ( void ) throw ( Exception ) +{ + unsigned int u; + + source->close(); + for ( u = 0; u < numSinks; ++u ) { + sinks[u]->close(); + } +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.11 2002/10/20 20:42:56 darkeye + cosmetic changes + + Revision 1.10 2002/10/19 12:24:55 darkeye + anged internals so that now each encoding/server connection is + a separate thread + + Revision 1.9 2002/08/02 17:59:17 darkeye + bug fix: when the last server dropped connection, darkice crashed + + Revision 1.8 2002/07/20 16:37:06 darkeye + added fault tolerance in case a server connection is dropped + + Revision 1.7 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.6 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + Revision 1.5 2001/08/26 08:43:13 darkeye + added support for unlimited time encoding + + Revision 1.4 2000/11/15 18:37:37 darkeye + changed the transferable number of bytes to unsigned long + + Revision 1.3 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.2 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Connector.h b/darkice/tags/darkice-0_17_1/src/Connector.h new file mode 100644 index 0000000..d4af39c --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Connector.h @@ -0,0 +1,286 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Connector.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CONNECTOR_H +#define CONNECTOR_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Ref.h" +#include "Reporter.h" +#include "Source.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Connects a source to one or more sinks. + * + * @author $Author$ + * @version $Revision$ + */ +class Connector : public virtual Referable, public virtual Reporter +{ + private: + + /** + * Initialize the object. + * + * @param source the source to read from. + * @exception Exception + */ + void + init ( Source * source ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * The source to read from. + */ + Ref source; + + /** + * The sinks to connect the source to. + */ + Ref * sinks; + + /** + * Total number of sinks. + */ + unsigned int numSinks; + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Connector ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Detach an already attached Sink from the Source of this Connector. + * + * @param sink the Sink to detach. + * @return true if the detachment was successful, false otherwise. + * @exception Exception + */ + virtual bool + detach ( Sink * sink ) throw ( Exception ); + + + public: + + /** + * Constructor based on a Source. + * + * @param source the source to connect to the sinks. + * @exception Exception + */ + inline + Connector ( Source * source ) throw ( Exception ) + { + init( source); + } + + /** + * Constructor based on a Source and a Sink. + * + * @param source the source to connect to the sinks. + * @param sink a sink to connect to the source. + * @exception Exception + */ + inline + Connector ( Source * source, + Sink * sink ) throw ( Exception ) + { + init( source); + attach( sink); + } + + /** + * Copy constructor. + * + * @param connector the object to copy. + * @exception Exception + */ + Connector ( const Connector & connector ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Connector( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param connector the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + virtual Connector & + operator= ( const Connector & connector ) throw ( Exception ); + + /** + * Get the number of Sinks in the Connector. + * + * @return the number of Sinks in the Connector. + * @exception Exception + */ + inline virtual unsigned int + getNumSinks ( void ) const throw () + { + return numSinks; + } + + /** + * Attach a Sink to the Source of this Connector. + * + * @param sink the Sink to attach. + * @exception Exception + */ + virtual void + attach ( Sink * sink ) throw ( Exception ); + + /** + * Open the connector. Opens the Source and the Sinks if necessary. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Transfer a given amount of data from the Source to all the + * Sinks attached. + * If an attached Sink closes or encounteres an error during the + * process, it is detached and the function carries on with the + * rest of the Sinks. If no Sinks remain, or an error is encountered + * with the Source, the function returns prematurely. + * + * @param bytes the amount of data to transfer, in bytes. + * If 0, transfer forever. + * @param bufSize the size of the buffer to use for transfering. + * This amount of data is read from the Source and + * written to each Sink on each turn. + * @param sec the number of seconds to wait for the Source to have + * data available in each turn, and the number of seconds + * to wait for the Sinks to accept data. + * @param usec the number of micro seconds to wait for the Source to + * have data available in each turn, and the number of + * micro seconds to wait for the Sinks to accept data. + * @return the number of bytes read from the Source. + * @exception Exception + */ + virtual unsigned int + transfer ( unsigned long bytes, + unsigned int bufSize, + unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Close the Connector. The Source and all Sinks are closed. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONNECTOR_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.6 2002/10/19 12:24:55 darkeye + anged internals so that now each encoding/server connection is + a separate thread + + Revision 1.5 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + Revision 1.4 2000/11/15 18:37:37 darkeye + changed the transferable number of bytes to unsigned long + + Revision 1.3 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.2 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/DarkIce.cpp b/darkice/tags/darkice-0_17_1/src/DarkIce.cpp new file mode 100644 index 0000000..f6c8d55 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/DarkIce.cpp @@ -0,0 +1,1307 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : DarkIce.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error need stdlib.h +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_SYS_WAIT_H +#include +#else +#error need sys/wait.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + +#ifdef HAVE_SCHED_H +#include +#else +#error need sched.h +#endif + + + +#include "Util.h" +#include "IceCast.h" +#include "IceCast2.h" +#include "ShoutCast.h" +#include "FileCast.h" +#include "MultiThreadedConnector.h" +#include "DarkIce.h" + +#ifdef HAVE_LAME_LIB +#include "LameLibEncoder.h" +#endif + +#ifdef HAVE_TWOLAME_LIB +#include "TwoLameLibEncoder.h" +#endif + +#ifdef HAVE_VORBIS_LIB +#include "VorbisLibEncoder.h" +#endif + +#ifdef HAVE_FAAC_LIB +#include "FaacEncoder.h" +#endif + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Make sure wait-related stuff is what we expect + *----------------------------------------------------------------------------*/ +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +DarkIce :: init ( const Config & config ) throw ( Exception ) +{ + unsigned int bufferSecs; + const ConfigSection * cs; + const char * str; + unsigned int sampleRate; + unsigned int bitsPerSample; + unsigned int channel; + bool reconnect; + const char * device; + + // the [general] section + if ( !(cs = config.get( "general")) ) { + throw Exception( __FILE__, __LINE__, "no section [general] in config"); + } + str = cs->getForSure( "duration", " missing in section [general]"); + duration = Util::strToL( str); + str = cs->getForSure( "bufferSecs", " missing in section [general]"); + bufferSecs = Util::strToL( str); + if (bufferSecs == 0) { + throw Exception(__FILE__, __LINE__, + "setting bufferSecs to 0 not supported"); + } + str = cs->get( "reconnect"); + reconnect = str ? (Util::strEq( str, "yes") ? true : false) : true; + + // real-time scheduling is enabled by default + str = cs->get( "realtime" ); + enableRealTime = str ? (Util::strEq( str, "yes") ? true : false) : true; + + + // the [input] section + if ( !(cs = config.get( "input")) ) { + throw Exception( __FILE__, __LINE__, "no section [input] in config"); + } + + str = cs->getForSure( "sampleRate", " missing in section [input]"); + sampleRate = Util::strToL( str); + str = cs->getForSure( "bitsPerSample", " missing in section [input]"); + bitsPerSample = Util::strToL( str); + str = cs->getForSure( "channel", " missing in section [input]"); + channel = Util::strToL( str); + device = cs->getForSure( "device", " missing in section [input]"); + + dsp = AudioSource::createDspSource( device, + sampleRate, + bitsPerSample, + channel ); + encConnector = new MultiThreadedConnector( dsp.get(), reconnect ); + + noAudioOuts = 0; + configIceCast( config, bufferSecs); + configIceCast2( config, bufferSecs); + configShoutCast( config, bufferSecs); + configFileCast( config); +} + + +/*------------------------------------------------------------------------------ + * Look for the IceCast stream outputs in the config file + *----------------------------------------------------------------------------*/ +void +DarkIce :: configIceCast ( const Config & config, + unsigned int bufferSecs ) + throw ( Exception ) +{ + // look for IceCast encoder output streams, + // sections [icecast-0], [icecast-1], ... + char stream[] = "icecast- "; + size_t streamLen = Util::strLen( stream); + unsigned int u; + + for ( u = noAudioOuts; u < maxOutput; ++u ) { + const ConfigSection * cs; + + // ugly hack to change the section name to "stream0", "stream1", etc. + stream[streamLen-1] = '0' + (u - noAudioOuts); + + if ( !(cs = config.get( stream)) ) { + break; + } + +#if !defined HAVE_LAME_LIB && !defined HAVE_TWOLAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with lame or twolame support, " + "thus can't connect to IceCast 1.x, stream: ", + stream); +#else + + const char * str; + + unsigned int sampleRate = 0; + unsigned int channel = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * mountPoint = 0; + const char * remoteDumpFile = 0; + const char * name = 0; + const char * description = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + int lowpass = 0; + int highpass = 0; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; + bool fileAddDate = false; + + str = cs->get( "sampleRate"); + sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); + str = cs->get( "channel"); + channel = str ? Util::strToL( str) : dsp->getChannel(); + + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + if ( cs->get( "quality" ) == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( cs->get( "quality" ) == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + + + + server = cs->getForSure( "server", " missing in section ", stream); + str = cs->getForSure( "port", " missing in section ", stream); + port = Util::strToL( str); + password = cs->getForSure("password"," missing in section ",stream); + mountPoint = cs->getForSure( "mountPoint", + " missing in section ", + stream); + remoteDumpFile = cs->get( "remoteDumpFile"); + name = cs->get( "name"); + description = cs->get("description"); + url = cs->get( "url"); + genre = cs->get( "genre"); + str = cs->get( "public"); + isPublic = str ? (Util::strEq( str, "yes") ? true : false) : false; + str = cs->get( "lowpass"); + lowpass = str ? Util::strToL( str) : 0; + str = cs->get( "highpass"); + highpass = str ? Util::strToL( str) : 0; + str = cs->get("fileAddDate"); + fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false; + + localDumpName = cs->get( "localDumpFile"); + + // go on and create the things + + // check for and create the local dump file if needed + if ( localDumpName != 0 ) { + if ( fileAddDate ) { + localDumpName = Util::fileAddDate(localDumpName); + } + + localDumpFile = new FileSink( localDumpName); + if ( !localDumpFile->exists() ) { + if ( !localDumpFile->create() ) { + reportEvent( 1, "can't create local dump file", + localDumpName); + localDumpFile = 0; + } + } + if ( fileAddDate ) { + delete[] localDumpFile; + } + } + // streaming related stuff + audioOuts[u].socket = new TcpSocket( server, port); + audioOuts[u].server = new IceCast( audioOuts[u].socket.get(), + password, + mountPoint, + bitrate, + name, + description, + url, + genre, + isPublic, + remoteDumpFile, + localDumpFile, + bufferSecs ); + + str = cs->getForSure( "format", " missing in section ", stream); + + if (!Util::strEq(str, "mp3") && !Util::strEq(str, "mp2")) { + throw Exception( __FILE__, __LINE__, + "unsupported stream format: ", str); + + } + +#ifdef HAVE_LAME_LIB + if ( Util::strEq( str, "mp3") ) { + audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + channel, + lowpass, + highpass ); + } +#endif +#ifdef HAVE_TWOLAME_LIB + if ( Util::strEq( str, "mp2") ) { + audioOuts[u].encoder = new TwoLameLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + sampleRate, + channel ); + } +#endif + + encConnector->attach( audioOuts[u].encoder.get()); +#endif // HAVE_LAME_LIB || HAVE_TWOLAME_LIB + } + + noAudioOuts += u; +} + + +/*------------------------------------------------------------------------------ + * Look for the IceCast2 stream outputs in the config file + *----------------------------------------------------------------------------*/ +void +DarkIce :: configIceCast2 ( const Config & config, + unsigned int bufferSecs ) + throw ( Exception ) +{ + // look for IceCast2 encoder output streams, + // sections [icecast2-0], [icecast2-1], ... + char stream[] = "icecast2- "; + size_t streamLen = Util::strLen( stream); + unsigned int u; + + for ( u = noAudioOuts; u < maxOutput; ++u ) { + const ConfigSection * cs; + + // ugly hack to change the section name to "stream0", "stream1", etc. + stream[streamLen-1] = '0' + (u - noAudioOuts); + + if ( !(cs = config.get( stream)) ) { + break; + } + + const char * str; + + IceCast2::StreamFormat format; + unsigned int sampleRate = 0; + unsigned int channel = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + unsigned int maxBitrate = 0; + double quality = 0.0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * mountPoint = 0; + const char * name = 0; + const char * description = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + int lowpass = 0; + int highpass = 0; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; + bool fileAddDate = false; + + str = cs->getForSure( "format", " missing in section ", stream); + if ( Util::strEq( str, "vorbis") ) { + format = IceCast2::oggVorbis; + } else if ( Util::strEq( str, "mp3") ) { + format = IceCast2::mp3; + } else if ( Util::strEq( str, "mp2") ) { + format = IceCast2::mp2; + } else if ( Util::strEq( str, "aac") ) { + format = IceCast2::aac; + } else { + throw Exception( __FILE__, __LINE__, + "unsupported stream format: ", str); + } + + str = cs->get( "sampleRate"); + sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); + str = cs->get( "channel"); + channel = str ? Util::strToL( str) : dsp->getChannel(); + + // determine fixed bitrate or variable bitrate quality + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "maxBitrate"); + maxBitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( cs->get( "quality" ) == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + + server = cs->getForSure( "server", " missing in section ", stream); + str = cs->getForSure( "port", " missing in section ", stream); + port = Util::strToL( str); + password = cs->getForSure("password"," missing in section ",stream); + mountPoint = cs->getForSure( "mountPoint", + " missing in section ", + stream); + name = cs->get( "name"); + description = cs->get( "description"); + url = cs->get( "url"); + genre = cs->get( "genre"); + str = cs->get( "public"); + isPublic = str ? (Util::strEq( str, "yes") ? true : false) : false; + str = cs->get( "lowpass"); + lowpass = str ? Util::strToL( str) : 0; + str = cs->get( "highpass"); + highpass = str ? Util::strToL( str) : 0; + str = cs->get( "fileAddDate"); + fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false; + + localDumpName = cs->get( "localDumpFile"); + + // go on and create the things + + // check for and create the local dump file if needed + if ( localDumpName != 0 ) { + if ( fileAddDate ) { + localDumpName = Util::fileAddDate(localDumpName); + } + + localDumpFile = new FileSink( localDumpName); + if ( !localDumpFile->exists() ) { + if ( !localDumpFile->create() ) { + reportEvent( 1, "can't create local dump file", + localDumpName); + localDumpFile = 0; + } + } + if ( fileAddDate ) { + delete[] localDumpName; + } + } + + // streaming related stuff + audioOuts[u].socket = new TcpSocket( server, port); + audioOuts[u].server = new IceCast2( audioOuts[u].socket.get(), + password, + mountPoint, + format, + bitrate, + name, + description, + url, + genre, + isPublic, + localDumpFile, + bufferSecs ); + + switch ( format ) { + case IceCast2::mp3: +#ifndef HAVE_LAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with lame support, " + "thus can't create mp3 stream: ", + stream); +#else + audioOuts[u].encoder = new LameLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + channel, + lowpass, + highpass ); +#endif // HAVE_LAME_LIB + break; + + + case IceCast2::oggVorbis: +#ifndef HAVE_VORBIS_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with Ogg Vorbis support, " + "thus can't Ogg Vorbis stream: ", + stream); +#else + audioOuts[u].encoder = new VorbisLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel(), + maxBitrate); +#endif // HAVE_VORBIS_LIB + break; + + case IceCast2::mp2: +#ifndef HAVE_TWOLAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with TwoLame support, " + "thus can't create mp2 stream: ", + stream); +#else + audioOuts[u].encoder = new TwoLameLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + sampleRate, + channel ); +#endif // HAVE_TWOLAME_LIB + break; + + + case IceCast2::aac: +#ifndef HAVE_FAAC_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with AAC support, " + "thus can't aac stream: ", + stream); +#else + audioOuts[u].encoder = new FaacEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel()); +#endif // HAVE_FAAC_LIB + break; + + default: + throw Exception( __FILE__, __LINE__, + "Illegal stream format: ", format); + } + + encConnector->attach( audioOuts[u].encoder.get()); + } + + noAudioOuts += u; +} + + +/*------------------------------------------------------------------------------ + * Look for the ShoutCast stream outputs in the config file + *----------------------------------------------------------------------------*/ +void +DarkIce :: configShoutCast ( const Config & config, + unsigned int bufferSecs ) + throw ( Exception ) +{ + // look for Shoutcast encoder output streams, + // sections [shoutcast-0], [shoutcast-1], ... + char stream[] = "shoutcast- "; + size_t streamLen = Util::strLen( stream); + unsigned int u; + + for ( u = noAudioOuts; u < maxOutput; ++u ) { + const ConfigSection * cs; + + // ugly hack to change the section name to "stream0", "stream1", etc. + stream[streamLen-1] = '0' + (u - noAudioOuts); + + if ( !(cs = config.get( stream)) ) { + break; + } + +#ifndef HAVE_LAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with lame support, " + "thus can't connect to ShoutCast, stream: ", + stream); +#else + + const char * str; + + unsigned int sampleRate = 0; + unsigned int channel = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * name = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + int lowpass = 0; + int highpass = 0; + const char * irc = 0; + const char * aim = 0; + const char * icq = 0; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; + bool fileAddDate = false; + + str = cs->get( "sampleRate"); + sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); + str = cs->get( "channel"); + channel = str ? Util::strToL( str) : dsp->getChannel(); + + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + if ( cs->get( "quality" ) == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( cs->get( "quality" ) == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + + server = cs->getForSure( "server", " missing in section ", stream); + str = cs->getForSure( "port", " missing in section ", stream); + port = Util::strToL( str); + password = cs->getForSure("password"," missing in section ",stream); + name = cs->get( "name"); + url = cs->get( "url"); + genre = cs->get( "genre"); + str = cs->get( "public"); + isPublic = str ? (Util::strEq( str, "yes") ? true : false) : false; + str = cs->get( "lowpass"); + lowpass = str ? Util::strToL( str) : 0; + str = cs->get( "highpass"); + highpass = str ? Util::strToL( str) : 0; + irc = cs->get( "irc"); + aim = cs->get( "aim"); + icq = cs->get( "icq"); + str = cs->get("fileAddDate"); + fileAddDate = str ? (Util::strEq( str, "yes") ? true : false) : false; + + localDumpName = cs->get( "localDumpFile"); + + // go on and create the things + + // check for and create the local dump file if needed + if ( localDumpName != 0 ) { + if ( fileAddDate ) { + localDumpName = Util::fileAddDate(localDumpName); + } + + localDumpFile = new FileSink( localDumpName); + if ( !localDumpFile->exists() ) { + if ( !localDumpFile->create() ) { + reportEvent( 1, "can't create local dump file", + localDumpName); + localDumpFile = 0; + } + } + if ( fileAddDate ) { + delete[] localDumpFile; + } + } + + // streaming related stuff + audioOuts[u].socket = new TcpSocket( server, port); + audioOuts[u].server = new ShoutCast( audioOuts[u].socket.get(), + password, + bitrate, + name, + url, + genre, + isPublic, + irc, + aim, + icq, + localDumpFile, + bufferSecs ); + + audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + channel, + lowpass, + highpass ); + + encConnector->attach( audioOuts[u].encoder.get()); +#endif // HAVE_LAME_LIB + } + + noAudioOuts += u; +} + + +/*------------------------------------------------------------------------------ + * Look for the FileCast stream outputs in the config file + *----------------------------------------------------------------------------*/ +void +DarkIce :: configFileCast ( const Config & config ) + throw ( Exception ) +{ + // look for FileCast encoder output streams, + // sections [file-0], [file-1], ... + char stream[] = "file- "; + size_t streamLen = Util::strLen( stream); + unsigned int u; + + for ( u = noAudioOuts; u < maxOutput; ++u ) { + const ConfigSection * cs; + + // ugly hack to change the section name to "stream0", "stream1", etc. + stream[streamLen-1] = '0' + (u - noAudioOuts); + + if ( !(cs = config.get( stream)) ) { + break; + } + + const char * str; + + const char * format = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * targetFileName = 0; + unsigned int sampleRate = 0; + int lowpass = 0; + int highpass = 0; + + format = cs->getForSure( "format", " missing in section ", stream); + if ( !Util::strEq( format, "vorbis") + && !Util::strEq( format, "mp3") + && !Util::strEq( format, "mp2") + && !Util::strEq( format, "aac") ) { + throw Exception( __FILE__, __LINE__, + "unsupported stream format: ", format); + } + + str = cs->getForSure("bitrate", " missing in section ", stream); + bitrate = Util::strToL( str); + targetFileName = cs->getForSure( "fileName", + " missing in section ", + stream); + str = cs->get( "sampleRate"); + sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); + + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( cs->get( "quality" ) == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + + if (Util::strEq(format, "aac") && bitrateMode != AudioEncoder::abr) { + throw Exception(__FILE__, __LINE__, + "currently the AAC format only supports " + "average bitrate mode"); + } + + str = cs->get( "lowpass"); + lowpass = str ? Util::strToL( str) : 0; + str = cs->get( "highpass"); + highpass = str ? Util::strToL( str) : 0; + + // go on and create the things + + // the underlying file + FileSink * targetFile = new FileSink( targetFileName); + if ( !targetFile->exists() ) { + if ( !targetFile->create() ) { + throw Exception( __FILE__, __LINE__, + "can't create output file", targetFileName); + } + } + + // streaming related stuff + audioOuts[u].socket = 0; + audioOuts[u].server = new FileCast( targetFile ); + + if ( Util::strEq( format, "mp3") ) { +#ifndef HAVE_LAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with lame support, " + "thus can't create mp3 stream: ", + stream); +#else + audioOuts[u].encoder = new LameLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel(), + lowpass, + highpass ); +#endif // HAVE_TWOLAME_LIB + } else if ( Util::strEq( format, "mp2") ) { +#ifndef HAVE_TWOLAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with TwoLAME support, " + "thus can't create MPEG Audio Layer 2 stream: ", + stream); +#else + audioOuts[u].encoder = new TwoLameLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + sampleRate, + dsp->getChannel() ); +#endif // HAVE_TWOLAME_LIB + } else if ( Util::strEq( format, "vorbis") ) { +#ifndef HAVE_VORBIS_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with Ogg Vorbis support, " + "thus can't Ogg Vorbis stream: ", + stream); +#else + audioOuts[u].encoder = new VorbisLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + dsp->getSampleRate(), + dsp->getChannel() ); +#endif // HAVE_VORBIS_LIB + } else if ( Util::strEq( format, "aac") ) { +#ifndef HAVE_FAAC_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with AAC support, " + "thus can't aac stream: ", + stream); +#else + audioOuts[u].encoder = new FaacEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel()); +#endif // HAVE_FAAC_LIB + } else { + throw Exception( __FILE__, __LINE__, + "Illegal stream format: ", format); + } + + encConnector->attach( audioOuts[u].encoder.get()); + } + + noAudioOuts += u; +} + + +/*------------------------------------------------------------------------------ + * Set POSIX real-time scheduling, if super-user + *----------------------------------------------------------------------------*/ +void +DarkIce :: setRealTimeScheduling ( void ) throw ( Exception ) +{ +// Only if the OS has the POSIX real-time scheduling functions implemented. +#if defined( HAVE_SCHED_GETSCHEDULER ) && defined( HAVE_SCHED_GETPARAM ) + uid_t euid; + + euid = geteuid(); + + if ( euid == 0 ) { + int high_priority; + struct sched_param param; + + /* store the old scheduling parameters */ + if ( (origSchedPolicy = sched_getscheduler(0)) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getscheduler", errno); + } + + if ( sched_getparam( 0, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getparam", errno); + } + origSchedPriority = param.sched_priority; + + /* set SCHED_FIFO with max - 1 priority */ + if ( (high_priority = sched_get_priority_max(SCHED_FIFO)) == -1 ) { + throw Exception(__FILE__,__LINE__,"sched_get_priority_max",errno); + } + reportEvent( 8, "scheduler high priority", high_priority); + + param.sched_priority = high_priority - 1; + + if ( sched_setscheduler( 0, SCHED_FIFO, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_setscheduler", errno); + } + + /* ask the new priortiy and report it */ + if ( sched_getparam( 0, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getparam", errno); + } + + reportEvent( 1, + "Using POSIX real-time scheduling, priority", + param.sched_priority ); + } else { + reportEvent( 1, + "Not running as super-user, unable to use POSIX real-time scheduling" ); + reportEvent( 1, + "It is recommended that you run this program as super-user"); + } +#else + reportEvent( 1, "POSIX scheduling not supported on this system, " + "this may cause recording skips"); +#endif // HAVE_SCHED_GETSCHEDULER && HAVE_SCHED_GETPARAM +} + + +/*------------------------------------------------------------------------------ + * Set the original scheduling of the process, the one prior to the + * setRealTimeScheduling call. + * WARNING: make sure you don't call this before setRealTimeScheduling!! + *----------------------------------------------------------------------------*/ +void +DarkIce :: setOriginalScheduling ( void ) throw ( Exception ) +{ +// Only if the OS has the POSIX real-time scheduling functions implemented. +#if defined( HAVE_SCHED_GETSCHEDULER ) && defined( HAVE_SCHED_GETPARAM ) + uid_t euid; + + euid = geteuid(); + + if ( euid == 0 ) { + struct sched_param param; + + if ( sched_getparam( 0, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_getparam", errno); + } + + param.sched_priority = origSchedPriority; + + if ( sched_setscheduler( 0, origSchedPolicy, ¶m) == -1 ) { + throw Exception( __FILE__, __LINE__, "sched_setscheduler", errno); + } + + reportEvent( 5, "reverted to original scheduling"); + } +#endif // HAVE_SCHED_GETSCHEDULER && HAVE_SCHED_GETPARAM +} + + +/*------------------------------------------------------------------------------ + * Run the encoder + *----------------------------------------------------------------------------*/ +bool +DarkIce :: encode ( void ) throw ( Exception ) +{ + unsigned int len; + unsigned long bytes; + + if ( !encConnector->open() ) { + throw Exception( __FILE__, __LINE__, "can't open connector"); + } + + bytes = dsp->getSampleRate() * + (dsp->getBitsPerSample() / 8UL) * + dsp->getChannel() * + duration; + + len = encConnector->transfer( bytes, 4096, 1, 0 ); + + reportEvent( 1, len, "bytes transfered to the encoders"); + + encConnector->close(); + + return true; +} + + +/*------------------------------------------------------------------------------ + * Run + *----------------------------------------------------------------------------*/ +int +DarkIce :: run ( void ) throw ( Exception ) +{ + reportEvent( 3, "encoding"); + + if (enableRealTime) { + setRealTimeScheduling(); + } + encode(); + if (enableRealTime) { + setOriginalScheduling(); + } + reportEvent( 3, "encoding ends"); + + return 0; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.49 2006/03/23 09:34:57 darkeye + fixed checking for mp3 and mp2 lib support for icecast-1.x streams + + Revision 1.48 2006/01/27 15:02:05 darkeye + fixued issue of compiling without lame, but with twolame + + Revision 1.47 2006/01/25 22:47:15 darkeye + added mpeg2 support, thanks to Nicholas J Humfrey + + Revision 1.46 2006/01/19 16:09:05 darkeye + added check for bufferSecs setting not to be 0 + + Revision 1.45 2005/10/22 10:34:21 darkeye + added highpass and lowpass values to icecast2 sections + + Revision 1.44 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + Revision 1.43 2005/04/11 19:27:43 darkeye + added option to turn off automatic reconnect feature + + Revision 1.42 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.41 2005/04/03 05:12:20 jbebel + Changed mechanism for testing the presence of the quality value such that + zero is a valid option. + + Revision 1.40 2004/02/23 19:12:51 darkeye + ported to NetBSD + + Revision 1.39 2004/02/19 06:47:06 darkeye + finalized OpenBSD port + + Revision 1.38 2004/02/18 21:08:11 darkeye + ported to OpenBSD (real-time scheduling not yet supported) + + Revision 1.37 2004/02/15 12:14:38 darkeye + added patch to allow mp3 stream downsampling to mono for icecast2 as well + + Revision 1.36 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + + Revision 1.35 2003/02/09 13:15:57 darkeye + added feature for setting the TITLE comment field for vorbis streams + + Revision 1.34 2003/02/09 12:57:36 darkeye + cosmetic changes to the fileAddDate option + + Revision 1.33 2002/11/20 16:52:05 wandereq + added fileAddDate function + + Revision 1.32 2002/10/19 12:24:55 darkeye + anged internals so that now each encoding/server connection is + a separate thread + + Revision 1.31 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + + Revision 1.30 2002/08/20 18:37:49 darkeye + added mp3 streaming possibility for icecast2 + + Revision 1.29 2002/08/03 12:41:18 darkeye + added possibility to stream in mono when recording in stereo + + Revision 1.28 2002/07/20 10:59:00 darkeye + added support for Ogg Vorbis 1.0, removed support for rc2 + + Revision 1.27 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + + Revision 1.26 2002/03/28 16:43:11 darkeye + enabled resampling and variable bitrates for vorbis (icecast2) streams + + Revision 1.25 2002/02/28 09:49:25 darkeye + added possibility to save the encoded stream to a local file only + (no streaming server needed) + + Revision 1.24 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.23 2002/02/20 10:35:35 darkeye + updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs + + Revision 1.22 2001/10/20 10:56:45 darkeye + added possibility to disable highpass and lowpass filters for lame + + Revision 1.21 2001/10/19 12:39:42 darkeye + created configure options to compile with or without lame / Ogg Vorbis + + Revision 1.20 2001/10/19 09:03:39 darkeye + added support for resampling mp3 streams + + Revision 1.19 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + Revision 1.18 2001/09/11 15:05:21 darkeye + added Solaris support + + Revision 1.17 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + Revision 1.16 2001/09/05 20:11:15 darkeye + removed dependency on locally stored SGI STL header files + now compiler-supplied C++ library STL header files are used + compiles under GNU C++ 3 + hash_map (an SGI extension to STL) replaced with map + std:: namespace prefix added to all STL class references + + Revision 1.15 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.14 2001/08/29 21:08:30 darkeye + made some description options in the darkice config file optional + + Revision 1.13 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + Revision 1.12 2000/12/20 12:36:47 darkeye + added POSIX real-time scheduling + + Revision 1.11 2000/11/18 11:13:27 darkeye + removed direct reference to cout, except from main.cpp + all class use the Reporter interface to report events + + Revision 1.10 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.9 2000/11/15 18:37:37 darkeye + changed the transferable number of bytes to unsigned long + + Revision 1.8 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.7 2000/11/13 19:38:55 darkeye + moved command line parameter parsing from DarkIce.cpp to main.cpp + + Revision 1.6 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.5 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.4 2000/11/09 22:09:46 darkeye + added multiple outputs + added configuration reading + added command line processing + + Revision 1.3 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/DarkIce.h b/darkice/tags/darkice-0_17_1/src/DarkIce.h new file mode 100644 index 0000000..c6edabf --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/DarkIce.h @@ -0,0 +1,374 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : DarkIce.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef DARK_ICE_H +#define DARK_ICE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#include + +#include "Referable.h" +#include "Reporter.h" +#include "Exception.h" +#include "Ref.h" +#include "AudioSource.h" +#include "BufferedSink.h" +#include "Connector.h" +#include "AudioEncoder.h" +#include "TcpSocket.h" +#include "CastSink.h" +#include "DarkIceConfig.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Program main object. + * + * @author $Author$ + * @version $Revision$ + */ +class DarkIce : public virtual Referable, public virtual Reporter +{ + private: + + /** + * The maximum number of supported outputs. This should be + * * + */ + static const unsigned int maxOutput = 4 * 7; + + /** + * Type describing each lame library output. + */ + typedef struct { + Ref encoder; + Ref socket; + Ref server; + } Output; + + /** + * The outputs. + */ + Output audioOuts[maxOutput]; + + /** + * Number of lame library outputs. + */ + unsigned int noAudioOuts; + + /** + * Duration of playing, in seconds. + */ + unsigned int duration; + + /** + * The dsp to record from. + */ + Ref dsp; + + /** + * The encoding Connector, connecting the dsp to the encoders. + */ + Ref encConnector; + + /** + * Should we turn real-time scheduling on ? + */ + int enableRealTime; + + /** + * Original scheduling policy + */ + int origSchedPolicy; + + /** + * Original scheduling priority + */ + int origSchedPriority; + + /** + * Initialize the object. + * + * @param config the config Object to read initialization + * information from. + * @exception Exception + */ + void + init ( const Config & config ) throw ( Exception ); + + /** + * Look for the icecast stream outputs from the config file. + * Called from init() + * + * @param config the config Object to read initialization + * information from. + * @param bufferSecs number of seconds to buffer audio for + * @exception Exception + */ + void + configIceCast ( const Config & config, + unsigned int bufferSecs ) throw ( Exception ); + + /** + * Look for the icecast2 stream outputs from the config file. + * Called from init() + * + * @param config the config Object to read initialization + * information from. + * @param bufferSecs number of seconds to buffer audio for + * @exception Exception + */ + void + configIceCast2 ( const Config & config, + unsigned int bufferSecs ) throw ( Exception ); + + /** + * Look for the shoutcast stream outputs from the config file. + * Called from init() + * + * @param config the config Object to read initialization + * information from. + * @param bufferSecs number of seconds to buffer audio for + * @exception Exception + */ + void + configShoutCast ( const Config & config, + unsigned int bufferSecs ) throw ( Exception ); + + /** + * Look for file outputs from the config file. + * Called from init() + * + * @param config the config Object to read initialization + * information from. + * @exception Exception + */ + void + configFileCast ( const Config & config ) + throw ( Exception ); + + /** + * Set POSIX real-time scheduling for the encoding process, + * if user permissions enable it. + * + * @exception Exception + */ + void + setRealTimeScheduling ( void ) throw ( Exception ); + + /** + * Set the scheduling that was before setting real-time scheduling. + * This function must be called _only_ after setRealTimeScheduling. + * + * @exception Exception + */ + void + setOriginalScheduling ( void ) throw ( Exception ); + + /** + * Start encoding. Spawns all encoders, opens the dsp and + * starts sending data to the encoders. + * + * @return if encoding was successful. + * @exception Exception + */ + bool + encode ( void ) throw ( Exception ); + + /** + * Start shouting. fork()-s a process for each output, reads + * the output of the encoders and sends them to an IceCast server. + * + * @return if shouting was successful. + * @exception Exception + */ + bool + shout ( unsigned int ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + DarkIce ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor based on a configuration object. + * + * @param config the config Object to read initialization + * information from. + * @exception Exception + */ + inline + DarkIce ( const Config & config ) throw ( Exception ) + { + init( config); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~DarkIce ( void ) throw ( Exception ) + { + } + +/* TODO + + inline + DarkIce ( const DarkIce & di ) throw ( Exception ) + { + } + + + inline DarkIce & + operator= ( const DarkIce * di ) throw ( Exception ) + { + } +*/ + + /** + * Run the process of recording / encoding / sending to the servers. + * + * @return 0 on success + * @exception Exception + */ + virtual int + run ( void ) throw ( Exception ); + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* DARK_ICE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.16 2006/01/25 22:47:15 darkeye + added mpeg2 support, thanks to Nicholas J Humfrey + + Revision 1.15 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.14 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.13 2002/02/28 09:49:25 darkeye + added possibility to save the encoded stream to a local file only + (no streaming server needed) + + Revision 1.12 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + Revision 1.11 2001/09/11 15:05:21 darkeye + added Solaris support + + Revision 1.10 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + Revision 1.9 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.8 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + Revision 1.7 2000/12/20 12:36:47 darkeye + added POSIX real-time scheduling + + Revision 1.6 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.5 2000/11/13 19:38:55 darkeye + moved command line parameter parsing from DarkIce.cpp to main.cpp + + Revision 1.4 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:16:21 darkeye + first real tests with multiple streaming + + Revision 1.2 2000/11/09 22:09:46 darkeye + added multiple outputs + added configuration reading + added command line processing + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/DarkIceConfig.cpp b/darkice/tags/darkice-0_17_1/src/DarkIceConfig.cpp new file mode 100644 index 0000000..1584a45 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/DarkIceConfig.cpp @@ -0,0 +1,210 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Config + + File : DarkIceConfig.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + + +#include "DarkIceConfig.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Max line size + *----------------------------------------------------------------------------*/ +#define LINE_SIZE 256 + + +/*------------------------------------------------------------------------------ + * string containing all white space characters + *----------------------------------------------------------------------------*/ +#define WHITE_SPACE_STR " \t" + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Get a value for a key + *----------------------------------------------------------------------------*/ +const ConfigSection * +Config :: get ( const char * key ) const throw ( Exception ) +{ + if ( !key ) { + throw Exception( __FILE__, __LINE__, "no key"); + } + + TableType::const_iterator it = table.find( key); + if ( it == table.end() ) { + return 0; + } + return &(it->second); +} + + +/*------------------------------------------------------------------------------ + * Add a configuration line + *----------------------------------------------------------------------------*/ +bool +Config :: addLine ( const char * line ) throw ( Exception ) +{ + if ( !line ) { + throw Exception( __FILE__, __LINE__, "no line"); + } + + std::string::size_type ix; + std::string str( line); + + /* delete everything after the first # */ + if ( (ix = str.find( '#')) != str.npos ) { + str.erase( ix); + } + /* eat up all white space from the front */ + if ( (ix = str.find_first_not_of( WHITE_SPACE_STR)) != str.npos ) { + str.erase( 0, ix); + } + /* eat up all white space from the end */ + if ( (ix = str.find_last_not_of( WHITE_SPACE_STR)) != str.npos ) { + str.erase( ix + 1); + } + + if ( !str.length() ) { + return true; + } + if ( str[0] == '[' && str[str.size()-1] == ']' ) { + // a new section starts + + std::string section( str, 1, str.size()-2); + ConfigSection cSection; + std::pair + element( section, cSection); + std::pair res; + + res = table.insert( element); + + currentSection = section; + return res.second; + } else { + // it's a line for the current section + + TableType::iterator it = table.find( currentSection); + if ( it == table.end() ) { + throw Exception( __FILE__, __LINE__, "no current section"); + } + + return it->second.addLine( line); + } +} + + +/*------------------------------------------------------------------------------ + * Add a configuration line + *----------------------------------------------------------------------------*/ +void +Config :: read ( std::istream & is ) throw ( Exception ) +{ + char line[LINE_SIZE]; + unsigned int num; + + for ( num = 0; !is.fail() && !is.eof(); ++num ) { + is.getline( line, LINE_SIZE); + if ( is.eof() ) { + break; + } else if ( is.fail() ) { + throw Exception( __FILE__, __LINE__, "line too long", num); + } + + addLine( line); + } +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.7 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.6 2001/10/19 09:20:09 darkeye + config file now may contain tabs also as white space + + Revision 1.5 2001/09/09 11:26:43 darkeye + full line comments skipped earlier: commens allowed before the first secion + + Revision 1.4 2001/09/05 20:11:15 darkeye + removed dependency on locally stored SGI STL header files + now compiler-supplied C++ library STL header files are used + compiles under GNU C++ 3 + hash_map (an SGI extension to STL) replaced with map + std:: namespace prefix added to all STL class references + + Revision 1.3 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.2 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:49 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/DarkIceConfig.h b/darkice/tags/darkice-0_17_1/src/DarkIceConfig.h new file mode 100644 index 0000000..7e390ee --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/DarkIceConfig.h @@ -0,0 +1,247 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Config + + File : DarkIceConfig.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef CONFIG_H +#define CONFIG_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include +#include + +#include + +#include "Referable.h" +#include "ConfigSection.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A configuration file representation. The file is of the syntax: + * + *
+ *  [section1]
+ *  # this is a whole line comment
+ *  key = value
+ *  an ugly key name = long value    # this end is a comment too
+ *
+ *  [section2]
+ *  # this is a whole line comment in section 2
+ *  key = value
+ *  an ugly key name = long value    # this end is a comment too
+ *  
+ * + * also empty lines are ignored and all white space is removed + * from the front and end of keys / values + * + * Knwon problem: you can't use '#' in any part of a key / value pair + * + * @author $Author$ + * @version $Revision$ + */ +class Config : public virtual Referable +{ + private: + + /** + * Type declaration of the hash table type. + */ + typedef std::map TableType; + + /** + * Hash table holding the configuration sections. + * + * @see ConfigSection + */ + TableType table; + + /** + * Hash table holding the configuration sections. + * + * @see ConfigSection + */ + std::string currentSection; + + + protected: + + + public: + + /** + * Default constructor. + * + * @exception Exception + */ + inline + Config ( void ) throw ( Exception ) + { + } + + /** + * Constructor based on an input stream. + * + * @param is configuration will be read from this input stream + * until end of stream is reached. + * @exception Exception + */ + inline + Config ( std::istream & is ) throw ( Exception ) + { + read( is ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Config ( void ) throw ( Exception ) + { + } + + +/* TODO + + inline + Config ( const Config & di ) throw ( Exception ) + { + } + + + inline Config & + operator= ( const Config * di ) throw ( Exception ) + { + } +*/ + + /** + * Delete the configuration information stored in the object. + * Resets the object to a clean state. + * + * @exception Exception + */ + inline virtual void + reset ( void ) throw ( Exception ) + { + table.clear(); + currentSection = ""; + } + + /** + * Read a line of confiugration information. + * + * @param line the line to read. + * @return true if the line was correct, false otherwise. + * @exception Exception + */ + virtual bool + addLine ( const char * line ) throw ( Exception ); + + /** + * Read a line of confiugration information. + * + * @param is the input stream to read from + * @return true if the line was correct, false otherwise. + * @exception Exception + */ + virtual void + read ( std::istream & is ) throw ( Exception ); + + /** + * Get a ConfigSection by name. + * + * @param key the name of the ConfigSection + * @return the ConfigSection requested, or NULL if it doesn't exists. + * @exception Exception + */ + virtual const ConfigSection * + get ( const char * key ) const throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONFIG_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.1 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.5 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.4 2001/09/05 20:11:15 darkeye + removed dependency on locally stored SGI STL header files + now compiler-supplied C++ library STL header files are used + compiles under GNU C++ 3 + hash_map (an SGI extension to STL) replaced with map + std:: namespace prefix added to all STL class references + + Revision 1.3 2000/11/13 18:46:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/09 22:07:19 darkeye + added constructor with istream + + Revision 1.1 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Exception.cpp b/darkice/tags/darkice-0_17_1/src/Exception.cpp new file mode 100644 index 0000000..5bb40e2 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Exception.cpp @@ -0,0 +1,228 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Exception.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Exception.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +Exception :: Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + int code ) throw () +{ + size_t len = 0; + + if ( description1 ) { + len += strlen( description1); + } + if ( description2 ) { + len += strlen( description2); + } + + if ( len ) { + char * str = new char[len+1]; + + str[0] = '\0'; + if ( description1 ) { + strcat( str, description1); + } + if ( description2 ) { + strcat( str, description2); + } + + init( file, line, str, code); + delete[] str; + + } else { + + init( file, line, 0, code); + } +} + + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +Exception :: Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + const char * description3, + int code ) throw () +{ + size_t len = 0; + + if ( description1 ) { + len += strlen( description1); + } + if ( description2 ) { + len += strlen( description2); + } + if ( description3 ) { + len += strlen( description3); + } + + if ( len ) { + char * str = new char[len+1]; + + str[0] = '\0'; + if ( description1 ) { + strcat( str, description1); + } + if ( description2 ) { + strcat( str, description2); + } + if ( description3 ) { + strcat( str, description3); + } + + init( file, line, str, code); + delete[] str; + + } else { + + init( file, line, 0, code); + } +} + + +/*------------------------------------------------------------------------------ + * Initialize the class + *----------------------------------------------------------------------------*/ +void +Exception :: init ( const char * file, + unsigned int line, + const char * description = 0, + int code = 0 ) throw () +{ + if ( !file ) { + this->file = 0; + } else { + size_t len; + + len = strlen( file ) + 1; + this->file = new char[len]; + if ( this->file ) { + memcpy( this->file, file, len); + } + } + + if ( !description ) { + this->description = 0; + } else { + size_t len; + + len = strlen( description ) + 1; + this->description = new char[len]; + if ( this->description ) { + memcpy( this->description, description, len); + } + } + + this->line = line; + this->code = code; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the class + *----------------------------------------------------------------------------*/ +void +Exception :: strip ( void ) throw () +{ + if ( description ) { + delete[] description; + } + + if ( file ) { + delete[] file; + } +} + + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.6 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.5 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/09 22:05:44 darkeye + added multiple-string constructors + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Exception.h b/darkice/tags/darkice-0_17_1/src/Exception.h new file mode 100644 index 0000000..2f58e49 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Exception.h @@ -0,0 +1,325 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Exception.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef EXCEPTION_H +#define EXCEPTION_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An exception class. + * + * This class should not depend on any other class + * should not throw any exceptions itself. + * + * Typical usage: + * + *
+ *  throw Exception( __FILE__, __LINE__, "describe the exception", code);
+ *  
+ * + * @author $Author$ + * @version $Revision$ + */ +class Exception +{ + private: + + /** + * Source file the exception was thrown in. + */ + char * file; + + /** + * Line number in the source file the exception was thrown in. + */ + unsigned int line; + + /** + * Textual description of the exception. + */ + char * description; + + /** + * Numerical error code. + */ + int code; + + /** + * Initalize the object. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description textual description of the exception. + * @param code numerical error code. + */ + void + init ( const char * file, + unsigned int line, + const char * description, + int code ) throw (); + + /** + * De-initalize the object. + */ + void + strip () throw (); + + + protected: + + + public: + + /** + * Default constructor. + */ + inline + Exception ( void ) throw () + { + init( 0, 0, 0, 0); + } + + /** + * Copy constructor. + */ + inline + Exception ( const Exception & e ) throw () + { + init( e.file, e.line, e.description, e.code); + } + + /** + * Construct by a description and error code. + * + * @param description textual description of the exception. + * @param code numerical error code. + */ + inline + Exception ( const char * description, + int code = 0 ) throw () + { + init( 0, 0, description, code); + } + + /** + * Construct by source file information, a description and error code. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description textual description of the exception. + * @param code numerical error code. + */ + inline + Exception ( const char * file, + unsigned int line, + const char * description = 0, + int code = 0 ) throw () + { + init( file, line, description, code); + } + + /** + * Construct by source file information, a description and error code. + * The description is constructed from two strings, any of which + * may be NULL. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description1 textual description of the exception part 1. + * @param description2 textual description of the exception part 2. + * @param code numerical error code. + */ + Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + int code = 0 ) throw (); + + /** + * Construct by source file information, a description and error code. + * The description is constructed from three strings, any of + * which may be NULL. + * + * @param file the source file the exception was thrown in. + * @param line the line in the source file. + * @param description1 textual description of the exception part 1. + * @param description2 textual description of the exception part 2. + * @param description3 textual description of the exception part 3. + * @param code numerical error code. + */ + Exception ( const char * file, + unsigned int line, + const char * description1, + const char * description2, + const char * description3, + int code = 0 ) throw (); + + /** + * Desctructor. + */ + inline + ~Exception ( void ) throw () + { + strip(); + } + + /** + * Assignment operator. + * + * @param e the Exception to assign this to. + * @return a reference to this Exception. + */ + inline Exception & + operator= ( const Exception & e ) throw () + { + if ( this != &e ) { + strip(); + init( e.file, e.line, e.description, e.code); + } + + return *this; + } + + /** + * Return the textual description of the Exception. + * + * @return the textual description of the Exception. + */ + inline const char * + getDescription( void ) const throw () + { + return description; + } + + /** + * Return the line number in the source file this Exception was + * thrown in. + * + * @return the line number in the source file this Exception was + * thrown in. + */ + inline unsigned int + getLine ( void ) const throw () + { + return line; + } + + /** + * Return the source file this Exception was thrown in. + * + * @return the source file this Exception was thrown in. + */ + inline const char * + getFile ( void ) const throw () + { + return file; + } + + /** + * Return the numerical code of the Exception. + * + * @return the numerical code of the Exception. + */ + inline int + getCode ( void ) const throw () + { + return code; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + +/** + * Print an Exception to an ostream. + * + * @param os the output stream to print to. + * @param e the Exception to print. + * @return a reference to the supplied output stream. + */ +inline std::ostream & +operator<< ( std::ostream & os, + const Exception & e ) +{ + os << e.getFile() << ":" << e.getLine() << ": " + << e.getDescription() << " [" << e.getCode() << "]"; + + return os; +} + + + +#endif /* EXCEPTION_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.6 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.5 2000/11/17 15:33:54 darkeye + bug fix: ostream << operator overload didn't return the ostream + + Revision 1.4 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.3 2000/11/09 22:05:44 darkeye + added multiple-string constructors + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:50 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/FaacEncoder.cpp b/darkice/tags/darkice-0_17_1/src/FaacEncoder.cpp new file mode 100644 index 0000000..66588dd --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/FaacEncoder.cpp @@ -0,0 +1,207 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FaacEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// compile the whole file only if faac support configured in +#ifdef HAVE_FAAC_LIB + + + +#include "Exception.h" +#include "Util.h" +#include "FaacEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Open an encoding session + *----------------------------------------------------------------------------*/ +bool +FaacEncoder :: open ( void ) + throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "faac lib opening underlying sink error"); + } + + char * faacVersion; + char * faacCopyright; + faacEncGetVersion(&faacVersion, &faacCopyright); + reportEvent(1, "Using faac codec version", faacVersion); + + encoderHandle = faacEncOpen(getInSampleRate(), + getInChannel(), + &inputSamples, + &maxOutputBytes); + + faacEncConfiguration * faacConfig; + + faacConfig = faacEncGetCurrentConfiguration(encoderHandle); + + faacConfig->aacObjectType = MAIN; + faacConfig->mpegVersion = MPEG2; + faacConfig->useTns = 1; + faacConfig->shortctl = SHORTCTL_NORMAL; + faacConfig->useLfe = 0; + faacConfig->allowMidside = 1; + faacConfig->bitRate = getOutBitrate() * 1000 / getOutChannel(); + faacConfig->bandWidth = lowpass; + faacConfig->quantqual = (unsigned long) (getOutQuality() * 1000.0); + faacConfig->outputFormat = 1; + faacConfig->inputFormat = FAAC_INPUT_16BIT; + + if (!faacEncSetConfiguration(encoderHandle, faacConfig)) { + throw Exception(__FILE__, __LINE__, + "error configuring faac library"); + } + + faacOpen = true; + + return true; +} + + +/*------------------------------------------------------------------------------ + * Write data to the encoder + *----------------------------------------------------------------------------*/ +unsigned int +FaacEncoder :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + if ( !isOpen() || len == 0 ) { + return 0; + } + + unsigned int channels = getInChannel(); + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int sampleSize = (bitsPerSample / 8) * channels; + unsigned char * b = (unsigned char*) buf; + unsigned int processed = len - (len % sampleSize); + unsigned int nSamples = processed / sampleSize; + unsigned char * faacBuf = new unsigned char[maxOutputBytes]; + int samples = (int) nSamples * channels; + int processedSamples = 0; + + while (processedSamples < samples) { + int outputBytes; + int inSamples = samples - processedSamples < (int) inputSamples + ? samples - processedSamples + : inputSamples; + + outputBytes = faacEncEncode(encoderHandle, + (int32_t*) (b + processedSamples/sampleSize), + inSamples, + faacBuf, + maxOutputBytes); + sink->write(faacBuf, outputBytes); + + processedSamples += inSamples; + } + + delete[] faacBuf; + + return processedSamples; +} + + +/*------------------------------------------------------------------------------ + * Flush the data from the encoder + *----------------------------------------------------------------------------*/ +void +FaacEncoder :: flush ( void ) + throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + sink->flush(); +} + + +/*------------------------------------------------------------------------------ + * Close the encoding session + *----------------------------------------------------------------------------*/ +void +FaacEncoder :: close ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + flush(); + faacEncClose(encoderHandle); + faacOpen = false; + + sink->close(); + } +} + + +#endif // HAVE_FAAC_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2005/04/16 22:19:20 darkeye + changed remaining typos + + Revision 1.1 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/FaacEncoder.h b/darkice/tags/darkice-0_17_1/src/FaacEncoder.h new file mode 100644 index 0000000..a01c4dd --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/FaacEncoder.h @@ -0,0 +1,458 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FaacEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef AAC_ENCODER_H +#define AAC_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_FAAC_LIB +#include +#else +#error configure with faac +#endif + + +#include "Ref.h" +#include "Exception.h" +#include "Reporter.h" +#include "AudioEncoder.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing faac AAC encoder. + * + * @author $Author$ + * @version $Revision$ + */ +class FaacEncoder : public AudioEncoder, public virtual Reporter +{ + private: + + /** + * A flag to indicate if the encoding session is open. + */ + bool faacOpen; + + /** + * The handle to the AAC encoder instance. + */ + faacEncHandle encoderHandle; + + /** + * The maximum number of input samples to supply to the encoder. + */ + unsigned long inputSamples; + + /** + * The maximum number of output bytes the encoder returns in one call. + */ + unsigned long maxOutputBytes; + + /** + * Lowpass filter. Sound frequency in Hz, from where up the + * input is cut. + */ + int lowpass; + + /** + * The Sink to dump mp3 data to + */ + Ref sink; + + /** + * Initialize the object. + * + * @param sink the sink to send mp3 output to + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, faac's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline void + init ( Sink * sink, + int lowpass) throw (Exception) + { + this->faacOpen = false; + this->sink = sink; + this->lowpass = lowpass; + + if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getInChannel() != 1 && getInChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of input channels for the encoder", + getInChannel() ); + } + if ( getOutChannel() != 1 && getOutChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of output channels for the encoder", + getOutChannel() ); + } + if ( getInChannel() != getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "input channels and output channels do not match"); + } + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + FaacEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param sink the sink to send mp3 output to + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, faac's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + FaacEncoder ( Sink * sink, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + int lowpass = 0) + throw ( Exception ) + + : AudioEncoder ( inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink, lowpass); + } + + /** + * Constructor. + * + * @param sink the sink to send mp3 output to + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, faac's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + FaacEncoder ( Sink * sink, + const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + int lowpass = 0) + throw ( Exception ) + + : AudioEncoder ( as, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink, lowpass); + } + + /** + * Copy constructor. + * + * @param encoder the FaacEncoder to copy. + */ + inline + FaacEncoder ( const FaacEncoder & encoder ) + throw ( Exception ) + : AudioEncoder( encoder ) + { + init( encoder.sink.get(), encoder.lowpass); + } + + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~FaacEncoder ( void ) throw ( Exception ) + { + if ( isOpen() ) { + close(); + } + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the FaacEncoder to assign this to. + * @return a reference to this FaacEncoder. + * @exception Exception + */ + inline virtual FaacEncoder & + operator= ( const FaacEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + AudioEncoder::operator=( encoder); + init( encoder.sink.get(), encoder.lowpass); + } + + return *this; + } + + /** + * Get the version string of the underlying faac library. + * + * @return the version string of the underlying faac library. + */ + inline const char * + getFaacVersion( void ) + { + char * id; + char * copyright; + + faacEncGetVersion(&id, ©right); + return id; + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + inline virtual bool + isRunning ( void ) const throw () + { + return isOpen(); + } + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started in the background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + inline virtual bool + start ( void ) throw ( Exception ) + { + return open(); + } + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + inline virtual void + stop ( void ) throw ( Exception ) + { + return close(); + } + + /** + * Open an encoding session. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the encoding session is open. + * + * @return true if the encoding session is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return faacOpen; + } + + /** + * Check if the encoder is ready to accept data. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the encoder is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + if ( !isOpen() ) { + return false; + } + + return true; + } + + /** + * Write data to the encoder. + * Buf is expected to be a sequence of big-endian 16 bit values, + * with left and right channels interleaved. Len is the number of + * bytes, must be a multiple of 4. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the encoder to the underlying + * connection. + * + * @exception Exception + */ + virtual void + flush ( void ) throw ( Exception ); + + /** + * Close the encoding session. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +#endif /* AAC_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2006/01/27 08:51:23 darkeye + fixed issue of double colons at the end of the declaration + + Revision 1.2 2005/04/16 22:19:20 darkeye + changed remaining typos + + Revision 1.1 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/FileCast.cpp b/darkice/tags/darkice-0_17_1/src/FileCast.cpp new file mode 100644 index 0000000..1ce1684 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/FileCast.cpp @@ -0,0 +1,103 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileCast.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDIO_H +#include +#else +#error need stdio.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Exception.h" +#include "Source.h" +#include "Sink.h" +#include "Util.h" +#include "FileCast.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Open the connection + *----------------------------------------------------------------------------*/ +bool +FileCast :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( !targetFile->open() ) { + return false; + } + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2002/02/28 09:49:25 darkeye + added possibility to save the encoded stream to a local file only + (no streaming server needed) + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/FileCast.h b/darkice/tags/darkice-0_17_1/src/FileCast.h new file mode 100644 index 0000000..c61afbf --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/FileCast.h @@ -0,0 +1,277 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileCast.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef FILE_CAST_H +#define FILE_CAST_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Ref.h" +#include "Sink.h" +#include "CastSink.h" +#include "FileSink.h" +#include "FileCast.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class representing output to a local file. + * + * @author $Author$ + * @version $Revision$ + */ +class FileCast : public CastSink +{ + private: + + /** + * The file to send the encoded data to. + */ + Ref targetFile; + + /** + * Initalize the object. + * + * @param targetFile the file to send the encoded data to. + * @exception Exception + */ + inline void + init ( FileSink * targetFile ) + throw ( Exception ) + { + this->targetFile = targetFile; + } + + /** + * De-initalize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + if ( isOpen() ) { + close(); + } + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + FileCast ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * No need to log in to a file. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + inline virtual bool + sendLogin ( void ) throw ( Exception ) + { + return true; + } + + + public: + + /** + * Constructor. + * + * @param targetFile the file to send all the data to. + * @exception Exception + */ + inline + FileCast ( FileSink * targetFile ) + throw ( Exception ) + : CastSink( 0, 0, 0) + { + init( targetFile ); + } + + /** + * Copy constructor. + * + * @param cs the FileCast to copy. + */ + inline + FileCast( const FileCast & cs ) throw ( Exception ) + { + init( targetFile.get() ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~FileCast( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param cs the FileCast to assign this to. + * @return a reference to this FileCast. + * @exception Exception + */ + inline virtual FileCast & + operator= ( const FileCast & cs ) throw ( Exception ) + { + if ( this != &cs ) { + strip(); + init( targetFile.get() ); + } + return *this; + } + + /** + * Open the FileCast. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the FileCast is open. + * + * @return true if the FileCast is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return targetFile->isOpen(); + } + + /** + * Check if the FileCast is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the FileCast is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + return targetFile->canWrite( sec, usec); + } + + /** + * Write data to the FileCast. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + inline virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ) + { + return targetFile->write( buf, len); + } + + /** + * Flush all data that was written to the FileCast to the server. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + return targetFile->flush(); + } + + /** + * Close the FileCast. + * + * @exception Exception + */ + inline virtual void + close ( void ) throw ( Exception ) + { + return targetFile->close(); + } + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* FILE_CAST_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2002/02/28 09:49:25 darkeye + added possibility to save the encoded stream to a local file only + (no streaming server needed) + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/FileSink.cpp b/darkice/tags/darkice-0_17_1/src/FileSink.cpp new file mode 100644 index 0000000..c6c369c --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/FileSink.cpp @@ -0,0 +1,341 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileSink.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error need stdlib.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "FileSink.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +FileSink :: init ( const char * name ) throw ( Exception ) +{ + fileName = Util::strDup( name); + fileDescriptor = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +FileSink :: strip ( void) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] fileName; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +FileSink :: FileSink ( const FileSink & fs ) throw ( Exception ) + : Sink( fs ) +{ + int fd; + + init( fs.fileName); + + if ( (fd = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + fileDescriptor = fd; +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +FileSink & +FileSink :: operator= ( const FileSink & fs ) throw ( Exception ) +{ + if ( this != &fs ) { + int fd; + + /* first strip */ + strip(); + + + /* then build up */ + Sink::operator=( fs ); + + init( fs.fileName); + + if ( (fd = fs.fileDescriptor ? dup( fs.fileDescriptor) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + fileDescriptor = fd; + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Check wether a file exists and is regular file + *----------------------------------------------------------------------------*/ +bool +FileSink :: exists ( void ) const throw () +{ + struct stat st; + + if ( stat( (const char*)fileName, &st) == -1 ) { + return false; + } + + return S_ISREG( st.st_mode); +} + + +/*------------------------------------------------------------------------------ + * Create a file, truncate if already exists + *----------------------------------------------------------------------------*/ +bool +FileSink :: create ( void ) throw ( Exception ) +{ + int fd; + + if ( isOpen() ) { + return false; + } + + if ( (fd = ::creat( fileName, S_IRUSR | S_IWUSR)) == -1 ) { + reportEvent( 3, "can't create file", fileName, errno); + return false; + } + + ::close( fd); + return true; +} + + +/*------------------------------------------------------------------------------ + * Open the file + *----------------------------------------------------------------------------*/ +bool +FileSink :: open ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + return false; + } + + if ( (fileDescriptor = ::open( fileName, O_WRONLY | O_TRUNC, 0)) == -1 ) { + fileDescriptor = 0; + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether the file can be written to + *----------------------------------------------------------------------------*/ +bool +FileSink :: canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( fileDescriptor, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( fileDescriptor + 1, NULL, &fdset, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Write to the FileSink + *----------------------------------------------------------------------------*/ +unsigned int +FileSink :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + ssize_t ret; + + if ( !isOpen() ) { + return 0; + } + + ret = ::write( fileDescriptor, buf, len); + + if ( ret == -1 ) { + if ( errno == EAGAIN ) { + ret = 0; + } else { + throw Exception( __FILE__, __LINE__, "write error", errno); + } + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the FileSink + *----------------------------------------------------------------------------*/ +void +FileSink :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + flush(); + ::close( fileDescriptor); + fileDescriptor = 0; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.8 2002/03/28 16:41:49 darkeye + some fixes to typos in comments + + Revision 1.7 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.5 2001/09/11 15:05:21 darkeye + added Solaris support + + Revision 1.4 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + Revision 1.3 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.2 2000/11/05 14:08:27 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:51 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/FileSink.h b/darkice/tags/darkice-0_17_1/src/FileSink.h new file mode 100644 index 0000000..01bd562 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/FileSink.h @@ -0,0 +1,269 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : FileSink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef FILE_SINK_H +#define FILE_SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Reporter.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * File data output + * + * @author $Author$ + * @version $Revision$ + */ +class FileSink : public Sink, public virtual Reporter +{ + private: + + /** + * Name of the file represented by the FileSink. + */ + char * fileName; + + /** + * Initialize the object. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Low-level file descriptor for the file represented by this object. + */ + int fileDescriptor; + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + FileSink ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor by a file name. + * + * @param name name of the file to be represented by the object. + * @exception Exception + */ + inline + FileSink( const char * name ) throw ( Exception ) + { + init( name); + } + + /** + * Copy constructor. + * + * @param fsink the FileSink to copy. + * @exception Exception + */ + FileSink( const FileSink & fsink ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~FileSink( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param fs the FileSink to assign to this object. + * @return a reference to this object. + * @exception Exception + */ + virtual FileSink & + operator= ( const FileSink & fs ) throw ( Exception ); + + /** + * Get the file name this FileSink represents. + * + * @return the file name this FileSink represents. + */ + inline const char * + getFileName ( void ) const throw () + { + return fileName; + } + + /** + * Check for the existence of the file this FileSink represents. + * + * @return true if the file exists and is a regular file, + * false otherwise. + */ + virtual bool + exists ( void ) const throw (); + + /** + * Create the file. + * + * @return true if creation was successful, false otherwise. + * @exception Exception + */ + virtual bool + create ( void ) throw ( Exception ); + + /** + * Open the file. Truncates the file. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the FileSink is open. + * + * @return true if the FileSink is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return fileDescriptor != 0; + } + + /** + * Check if the FileSink is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the Sink is ready to accept data, false otherwise. + * @exception Exception + */ + virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Write data to the FileSink. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * This is a no-op in this FileSink. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + } + + /** + * Close the FileSink. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* FILE_SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.3 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:51 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/IceCast.cpp b/darkice/tags/darkice-0_17_1/src/IceCast.cpp new file mode 100644 index 0000000..5c8f810 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/IceCast.cpp @@ -0,0 +1,254 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : IceCast.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDIO_H +#include +#else +#error need stdio.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_MATH_H +#include +#else +#error need math.h +#endif + + +#include "Exception.h" +#include "Source.h" +#include "Sink.h" +#include "Util.h" +#include "IceCast.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Size of string conversion buffer + *----------------------------------------------------------------------------*/ +#define STRBUF_SIZE 32 + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +IceCast :: init ( const char * mountPoint, + const char * description, + const char * remoteDumpFile ) + throw ( Exception ) +{ + this->mountPoint = Util::strDup( mountPoint); + this->description = description ? Util::strDup( description) : 0; + this->remoteDumpFile = remoteDumpFile ? Util::strDup( remoteDumpFile) : 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +IceCast :: strip ( void ) throw ( Exception ) +{ + delete[] mountPoint; + if ( description ) { + delete[] description; + } + if ( remoteDumpFile ) { + delete[] remoteDumpFile; + } +} + + +/*------------------------------------------------------------------------------ + * Log in to the IceCast server + *----------------------------------------------------------------------------*/ +bool +IceCast :: sendLogin ( void ) throw ( Exception ) +{ + Sink * sink = getSink(); + Source * source = getSocket(); + const char * str; + char resp[STRBUF_SIZE]; + unsigned int len; + + if ( !source->isOpen() ) { + return false; + } + if ( !sink->isOpen() ) { + return false; + } + + /* send the request, a string like: + * "SOURCE /\n" */ + str = "SOURCE "; + sink->write( str, strlen( str)); + str = getPassword(); + sink->write( str, strlen( str)); + str = " /"; + sink->write( str, strlen( str)); + str = getMountPoint(); + sink->write( str, strlen( str)); + + /* send the x-audiocast headers */ + str = "\nx-audiocast-bitrate: "; + sink->write( str, strlen( str)); + if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { + throw Exception( __FILE__, __LINE__, + "bitrate does not fit string buffer", getBitRate()); + } + sprintf( resp, "%d", getBitRate()); + sink->write( resp, strlen( resp)); + + str = "\nx-audiocast-public: "; + sink->write( str, strlen( str)); + str = getIsPublic() ? "1" : "0"; + sink->write( str, strlen( str)); + + if ( getName() ) { + str = "\nx-audiocast-name: "; + sink->write( str, strlen( str)); + str = getName(); + sink->write( str, strlen( str)); + } + + if ( getDescription() ) { + str = "\nx-audiocast-description: "; + sink->write( str, strlen( str)); + str = getDescription(); + sink->write( str, strlen( str)); + } + + if ( getUrl() ) { + str = "\nx-audiocast-url: "; + sink->write( str, strlen( str)); + str = getUrl(); + sink->write( str, strlen( str)); + } + + if ( getGenre() ) { + str = "\nx-audiocast-genre: "; + sink->write( str, strlen( str)); + str = getGenre(); + sink->write( str, strlen( str)); + } + + if ( getRemoteDumpFile() ) { + str = "\nx-audiocast-dumpfile: "; + sink->write( str, strlen( str)); + str = getRemoteDumpFile(); + sink->write( str, strlen( str)); + } + + str = "\n\n"; + sink->write( str, strlen( str)); + sink->flush(); + + /* read the anticipated response: "OK" */ + len = source->read( resp, STRBUF_SIZE); + if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { + return false; + } + + /* suck anything that the other side has to say */ + while ( source->canRead( 0, 0) && + (len = source->read( resp, STRBUF_SIZE)) ) { + ; + } + + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.10 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.9 2001/11/20 09:06:18 darkeye + fixed public stream reporting + + Revision 1.8 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + Revision 1.7 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + Revision 1.6 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.5 2001/08/29 21:08:30 darkeye + made some description options in the darkice config file optional + + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/IceCast.h b/darkice/tags/darkice-0_17_1/src/IceCast.h new file mode 100644 index 0000000..09c3dab --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/IceCast.h @@ -0,0 +1,294 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : IceCast.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef ICE_CAST_H +#define ICE_CAST_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Sink.h" +#include "TcpSocket.h" +#include "CastSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class representing output to an IceCast server with + * x-audiocast login + * + * @author $Author$ + * @version $Revision$ + */ +class IceCast : public CastSink +{ + private: + + /** + * Mount point of the stream on the server. + */ + char * mountPoint; + + /** + * Remote dump file if any. + */ + char * remoteDumpFile; + + /** + * Description of the stream. + */ + char * description; + + /** + * Initalize the object. + * + * @param mountPoint mount point of the stream on the server. + * @param remoteDumpFile remote dump file (may be NULL). + * @param description description of the stream. + * @exception Exception + */ + void + init ( const char * mountPoint, + const char * description, + const char * remoteDumpFile ) + throw ( Exception ); + + /** + * De-initalize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + IceCast ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + virtual bool + sendLogin ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param mountPoint mount point of the stream on the server. + * @param remoteDumpFile remote dump file (may be NULL). + * @param name name of the stream. + * @param description description of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param streamDump an optional sink to dump the binary stream + * data to. + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + inline + IceCast ( TcpSocket * socket, + const char * password, + const char * mountPoint, + unsigned int bitRate, + const char * name = 0, + const char * description = 0, + const char * url = 0, + const char * genre = 0, + bool isPublic = false, + const char * remoteDumpFile = 0, + Sink * streamDump = 0, + unsigned int bufferDuration = 10 ) + throw ( Exception ) + : CastSink( socket, + password, + bitRate, + name, + url, + genre, + isPublic, + streamDump, + bufferDuration ) + { + init( mountPoint, description, remoteDumpFile); + } + + /** + * Copy constructor. + * + * @param cs the IceCast to copy. + */ + inline + IceCast( const IceCast & cs ) throw ( Exception ) + : CastSink( cs ) + { + init( cs.getMountPoint(), + cs.getDescription(), + cs.getRemoteDumpFile() ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~IceCast( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param cs the IceCast to assign this to. + * @return a reference to this IceCast. + * @exception Exception + */ + inline virtual IceCast & + operator= ( const IceCast & cs ) throw ( Exception ) + { + if ( this != &cs ) { + strip(); + CastSink::operator=( cs ); + init( cs.getMountPoint(), + cs.getDescription(), + cs.getRemoteDumpFile() ); + } + return *this; + } + + /** + * Get the mount point of the stream on the server. + * + * @return the mount point of the stream on the server. + */ + inline const char * + getMountPoint ( void ) const throw () + { + return mountPoint; + } + + /** + * Get the remote dump file if any. + * + * @return the remote dump file. May be NULL. + */ + inline const char * + getRemoteDumpFile ( void ) const throw () + { + return remoteDumpFile; + } + + /** + * Get the description of the stream. + * + * @return the description of the stream. + */ + inline const char * + getDescription ( void ) const throw () + { + return description; + } + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* ICE_CAST_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.8 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.7 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.6 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + Revision 1.5 2001/08/29 21:08:30 darkeye + made some description options in the darkice config file optional + + Revision 1.4 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/10 20:14:11 darkeye + added support for remote dump file + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/IceCast2.cpp b/darkice/tags/darkice-0_17_1/src/IceCast2.cpp new file mode 100644 index 0000000..aaa85ed --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/IceCast2.cpp @@ -0,0 +1,306 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : IceCast2.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDIO_H +#include +#else +#error need stdio.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_MATH_H +#include +#else +#error need math.h +#endif + + +#include "Exception.h" +#include "Source.h" +#include "Sink.h" +#include "Util.h" +#include "IceCast2.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Size of string conversion buffer + *----------------------------------------------------------------------------*/ +#define STRBUF_SIZE 32 + + +/*------------------------------------------------------------------------------ + * Expected positive response from server begins like this. + *----------------------------------------------------------------------------*/ +static const char responseOK[] = "HTTP/1.0 200"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +IceCast2 :: init ( StreamFormat format, + const char * mountPoint, + const char * description ) + throw ( Exception ) +{ + this->format = format; + this->mountPoint = Util::strDup( mountPoint); + this->description = description ? Util::strDup( description) : 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +IceCast2 :: strip ( void ) throw ( Exception ) +{ + delete[] mountPoint; + if ( description ) { + delete[] description; + } +} + + +/*------------------------------------------------------------------------------ + * Log in to the IceCast2 server + *----------------------------------------------------------------------------*/ +bool +IceCast2 :: sendLogin ( void ) throw ( Exception ) +{ + Sink * sink = getSink(); + Source * source = getSocket(); + const char * str; + char resp[STRBUF_SIZE]; + unsigned int len; + unsigned int lenExpected; + + if ( !source->isOpen() ) { + return false; + } + if ( !sink->isOpen() ) { + return false; + } + + // send the request, a string like: + // "SOURCE ICE/1.0" + str = "SOURCE /"; + sink->write( str, strlen( str)); + str = getMountPoint(); + sink->write( str, strlen( str)); + str = " HTTP/1.0"; + sink->write( str, strlen( str)); + + // send the content type, Ogg Vorbis + str = "\nContent-type: "; + sink->write( str, strlen( str)); + switch ( format ) { + case mp3: + case mp2: + str = "audio/mpeg"; + break; + + case oggVorbis: + str = "application/ogg"; + break; + + case aac: + str = "audio/aac"; + break; + + default: + throw Exception( __FILE__, __LINE__, + "unsupported stream format", format); + break; + } + sink->write( str, strlen( str)); + + // send the authentication info + str = "\nAuthorization: Basic "; + sink->write( str, strlen(str)); + { + // send source: encoded as base64 + char * source = "source:"; + const char * pwd = getPassword(); + char * tmp = new char[Util::strLen(source) + + Util::strLen(pwd) + 1]; + Util::strCpy( tmp, source); + Util::strCat( tmp, pwd); + char * base64 = Util::base64Encode( tmp); + delete[] tmp; + sink->write( base64, strlen(base64)); + delete[] base64; + } + + // send user agent info + str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.sourceforge.net/)"; + sink->write( str, strlen( str)); + + // send the ice- headers + str = "\nice-bitrate: "; + sink->write( str, strlen( str)); + if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { + throw Exception( __FILE__, __LINE__, + "bitrate does not fit string buffer", getBitRate()); + } + sprintf( resp, "%d", getBitRate()); + sink->write( resp, strlen( resp)); + + str = "\nice-public: "; + sink->write( str, strlen( str)); + str = getIsPublic() ? "1" : "0"; + sink->write( str, strlen( str)); + + if ( getName() ) { + str = "\nice-name: "; + sink->write( str, strlen( str)); + str = getName(); + sink->write( str, strlen( str)); + } + + if ( getDescription() ) { + str = "\nice-description: "; + sink->write( str, strlen( str)); + str = getDescription(); + sink->write( str, strlen( str)); + } + + if ( getUrl() ) { + str = "\nice-url: "; + sink->write( str, strlen( str)); + str = getUrl(); + sink->write( str, strlen( str)); + } + + if ( getGenre() ) { + str = "\nice-genre: "; + sink->write( str, strlen( str)); + str = getGenre(); + sink->write( str, strlen( str)); + } + + str = "\n\n"; + sink->write( str, strlen( str)); + sink->flush(); + + // read the response, expected response begins with responseOK + lenExpected = Util::strLen( responseOK); + if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) { + return false; + } + resp[lenExpected] = 0; + if ( !Util::strEq( resp, responseOK) ) { + return false; + } + + // suck anything that the other side has to say + while ( source->canRead( 0, 0) && + (len = source->read( resp, STRBUF_SIZE-1)) ); + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.13 2006/01/25 22:47:15 darkeye + added mpeg2 support, thanks to Nicholas J Humfrey + + Revision 1.12 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + Revision 1.11 2005/04/11 18:32:32 darkeye + changed MIME type to application/ogg, which is now official + + Revision 1.10 2002/11/29 08:14:47 darkeye + fixed minor bug in IcecCast2.cpp, which could have lead to a buffer + overflow + + Revision 1.9 2002/10/20 21:09:35 darkeye + added processing of server response + + Revision 1.8 2002/08/20 20:16:59 darkeye + added User-Agent header to HTTP login + + Revision 1.7 2002/08/20 19:34:43 darkeye + minor fix + + Revision 1.6 2002/08/20 18:39:13 darkeye + added HTTP Basic authentication for icecast2 logins + + Revision 1.5 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.4 2002/02/20 10:35:35 darkeye + updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs + + Revision 1.3 2002/02/19 15:24:26 darkeye + send Content-type header when logging in to icecast2 servers + + Revision 1.2 2001/11/20 09:06:18 darkeye + fixed public stream reporting + + Revision 1.1 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/IceCast2.h b/darkice/tags/darkice-0_17_1/src/IceCast2.h new file mode 100644 index 0000000..67fc9c5 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/IceCast2.h @@ -0,0 +1,297 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : IceCast2.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef ICE_CAST2_H +#define ICE_CAST2_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Sink.h" +#include "TcpSocket.h" +#include "CastSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class representing output to an IceCast2 server with + * ice login + * + * @author $Author$ + * @version $Revision$ + */ +class IceCast2 : public CastSink +{ + public: + + /** + * Type for specifying the format of the stream. + */ + enum StreamFormat { mp3, mp2, oggVorbis, aac }; + + + private: + + /** + * The format of the stream. + */ + StreamFormat format; + + /** + * Mount point of the stream on the server. + */ + char * mountPoint; + + /** + * Description of the stream. + */ + char * description; + + /** + * Initalize the object. + * + * @param mountPoint mount point of the stream on the server. + * @param remoteDumpFile remote dump file (may be NULL). + * @param description description of the stream. + * @exception Exception + */ + void + init ( StreamFormat format, + const char * mountPoint, + const char * description ) + throw ( Exception ); + + /** + * De-initalize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + IceCast2 ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + virtual bool + sendLogin ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param mountPoint mount point of the stream on the server. + * @param format the format of the stream. + * @param name name of the stream. + * @param description description of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param streamDump an optional sink to dump the binary stream + * data to. + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + inline + IceCast2 ( TcpSocket * socket, + const char * password, + const char * mountPoint, + StreamFormat format, + unsigned int bitRate, + const char * name = 0, + const char * description = 0, + const char * url = 0, + const char * genre = 0, + bool isPublic = false, + Sink * streamDump = 0, + unsigned int bufferDuration = 10 ) + throw ( Exception ) + : CastSink( socket, + password, + bitRate, + name, + url, + genre, + isPublic, + streamDump, + bufferDuration ) + { + init( format, mountPoint, description); + } + + /** + * Copy constructor. + * + * @param cs the IceCast2 to copy. + */ + inline + IceCast2( const IceCast2 & cs ) throw ( Exception ) + : CastSink( cs ) + { + init( cs.getFormat(), + cs.getMountPoint(), + cs.getDescription() ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~IceCast2( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param cs the IceCast2 to assign this to. + * @return a reference to this IceCast2. + * @exception Exception + */ + inline virtual IceCast2 & + operator= ( const IceCast2 & cs ) throw ( Exception ) + { + if ( this != &cs ) { + strip(); + CastSink::operator=( cs ); + init( cs.getFormat(), + cs.getMountPoint(), + cs.getDescription() ); + } + return *this; + } + + /** + * Get the format of the stream. + * + * @return the format of the stream. + */ + inline StreamFormat + getFormat ( void ) const throw () + { + return format; + } + + /** + * Get the mount point of the stream on the server. + * + * @return the mount point of the stream on the server. + */ + inline const char * + getMountPoint ( void ) const throw () + { + return mountPoint; + } + + /** + * Get the description of the stream. + * + * @return the description of the stream. + */ + inline const char * + getDescription ( void ) const throw () + { + return description; + } + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* ICE_CAST2_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.6 2006/01/25 22:47:15 darkeye + added mpeg2 support, thanks to Nicholas J Humfrey + + Revision 1.5 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + Revision 1.4 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.3 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.2 2002/02/20 10:35:35 darkeye + updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs + + Revision 1.1 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/JackDspSource.cpp b/darkice/tags/darkice-0_17_1/src/JackDspSource.cpp new file mode 100644 index 0000000..9420e90 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/JackDspSource.cpp @@ -0,0 +1,454 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Nicholas Humfrey. All rights reserved. + + Tyrell DarkIce + + File : JackDspSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "AudioSource.h" + +#ifdef SUPPORT_JACK_DSP +// only compile this code if there is support for it + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_MATH_H +#include +#else +#error need math.h +#endif + +#include "Util.h" +#include "Exception.h" +#include "JackDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +JackDspSource :: init ( const char* name ) throw ( Exception ) +{ + // Set defaults + ports[0] = NULL; // Left Port + ports[1] = NULL; // Right Port + rb[0] = NULL; // Left Ring Buffer + rb[1] = NULL; // Right Ring Buffer + client = NULL; + auto_connect = false; // Default is to not auto connect the JACK ports + tmp_buffer = NULL; // Buffer big enough for one 'read' of audio + + // Auto connect the ports ? + if ( Util::strEq( name, "jack_auto", 9) ) { + auto_connect = true; + } + + // Check the sample size + if (getBitsPerSample() != 16) { + throw Exception( __FILE__, __LINE__, + "JackDspSource doesn't support non 16-bit samples"); + } +} + + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +JackDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + // Free the temporary buffer + if (tmp_buffer) { + free(tmp_buffer); + tmp_buffer = NULL; + } + +} + +/*------------------------------------------------------------------------------ + * Attempt to connect up the JACK ports automatically + * - Just connect left&right to the first two output ports we find + *----------------------------------------------------------------------------*/ +void +JackDspSource :: do_auto_connect ( void ) throw ( Exception ) +{ + const char **all_ports; + unsigned int ch = 0; + int i; + + Reporter::reportEvent( 10, "JackDspSource :: do_auto_connect"); + + // Get a list of all the jack ports + all_ports = jack_get_ports (client, NULL, NULL, JackPortIsOutput); + if (!ports) { + throw Exception( __FILE__, __LINE__, "jack_get_ports() returned NULL."); + } + + // Step through each port name + for (i = 0; all_ports[i]; ++i) { + + const char* in = all_ports[i]; + const char* out = jack_port_name( ports[ch] ); + + Reporter::reportEvent( 2, "Connecting", in, "to", out); + + if (jack_connect(client, in, out)) { + throw Exception( __FILE__, __LINE__, + "Failed to jack_connect() ports", in, out); + } + + // Found enough ports ? + if (++ch >= getChannel()) break; + } + + free( all_ports ); + +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +JackDspSource :: open ( void ) throw ( Exception ) +{ + char client_name[255]; + size_t rb_size; + unsigned int c; + + if ( isOpen() ) { + return false; + } + + // Register client with Jack + snprintf(client_name, 255, "darkice-%d", getpid()); + if ((client = jack_client_new(client_name)) == NULL) { + throw Exception( __FILE__, __LINE__, "JACK server not running?"); + } + Reporter::reportEvent( 1, "Registering as JACK client", client_name); + + + // Check the sample rate is correct + if (jack_get_sample_rate( client ) != (jack_nframes_t)getSampleRate()) { + throw Exception( __FILE__, __LINE__, + "JACK server sample rate is different than " + "sample rate in darkice config file"); + } + + + // Register ports with Jack + if (getChannel() == 1) { + if (!(ports[0] = jack_port_register(client, + "mono", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, + 0))) { + throw Exception( __FILE__, __LINE__, + "Cannot register input port", "mono"); + } + } else if (getChannel() == 2) { + if (!(ports[0] = jack_port_register(client, + "left", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, + 0))) { + throw Exception( __FILE__, __LINE__, + "Cannot register input port", "left"); + } + if (!(ports[1] = jack_port_register(client, + "right", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsInput, 0))) { + throw Exception( __FILE__, __LINE__, + "Cannot register input port", "right"); + } + } else { + throw Exception( __FILE__, __LINE__, + "Invalid number of channels", getChannel()); + } + + + // Create a ring buffer for each channel + rb_size = 2 + * jack_get_sample_rate(client) + * sizeof (jack_default_audio_sample_t); + for (c=0; c SHRT_MAX) { + output[n*getChannel()+c] = SHRT_MAX; + } else if (tmp < SHRT_MIN) { + output[n*getChannel()+c] = SHRT_MIN; + } else { + output[n*getChannel()+c] = (short) tmp; + } + } + } + + // Didn't get as many samples as we wanted ? + if (getChannel() == 2 && samples_read[0] != samples_read[1]) { + Reporter::reportEvent( 2, + "Warning: Read a different number of samples " + "for left and right channels"); + } + + // Return the number of bytes put in the output buffer + return samples_read[0] * 2 * getChannel(); +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +JackDspSource :: close ( void ) throw ( Exception ) +{ + unsigned int i; + + if ( !isOpen() ) { + return; + } + + for(i = 0; i < getChannel(); i++) { + // Close the port for channel + if ( ports[i] ) { + jack_port_unregister( client, ports[i] ); + ports[i] = NULL; + } + + // Free up the ring buffer for channel + if ( rb[i] ) { + jack_ringbuffer_free( rb[i] ); + rb[i] = NULL; + } + } + + /* Leave the jack graph */ + if (client) { + jack_client_close(client); + client = NULL; + } + +} + + +/*------------------------------------------------------------------------------ + * Callback called by JACK when audio is available + * + * Don't do anything too expensive here + * - just shove audio samples in ring buffer + *----------------------------------------------------------------------------*/ +int +JackDspSource :: process_callback( jack_nframes_t nframes, void *arg ) +{ + JackDspSource* self = (JackDspSource*)arg; + size_t to_write = sizeof (jack_default_audio_sample_t) * nframes; + unsigned int c; + + // Wait until it is ready + if (self->client == NULL) { + return 0; + } + + /* copy data to ringbuffer; one per channel */ + for (c=0; c < self->getChannel(); c++) { + char *buf = (char*)jack_port_get_buffer(self->ports[c], nframes); + size_t len = jack_ringbuffer_write(self->rb[c], buf, to_write); + if (len < to_write) { + Reporter::reportEvent( 1, "failed to write to ring ruffer"); + return 1; + } + } + + // Success + return 0; +} + +/*------------------------------------------------------------------------------ + * Callback called when + *----------------------------------------------------------------------------*/ +void +JackDspSource :: shutdown_callback( void *arg ) +{ + //JackDspSource* self = (JackDspSource*)arg; + + Reporter::reportEvent( 1, "JackDspSource :: shutdown_callback"); +} + + +#endif // SUPPORT_JACK_DSP + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/JackDspSource.h b/darkice/tags/darkice-0_17_1/src/JackDspSource.h new file mode 100644 index 0000000..235a5f3 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/JackDspSource.h @@ -0,0 +1,292 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Nicholas Humfrey. All rights reserved. + + Tyrell DarkIce + + File : JackDspSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef JACK_DSP_SOURCE_H +#define JACK_DSP_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + + +#include "Reporter.h" +#include "AudioSource.h" + +#if defined( HAVE_JACK_LIB ) +#include +#include +#else +#error configure for JACK +#endif + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio input based on JACK + * + * @author $Author$ + * @version $Revision$ + */ +class JackDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * The jack port + */ + jack_port_t * ports[2]; + + /** + * The jack ring buffer. + */ + jack_ringbuffer_t * rb[2]; + + /** + * The jack client. + */ + jack_client_t * client; + + /** + * The jack audio sample buffer. + */ + jack_default_audio_sample_t * tmp_buffer; + + /** + * Automatically connect the jack ports ? (default is to not) + */ + bool auto_connect; + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + JackDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @exception Exception + */ + void + init ( const char* name ) throw ( Exception ); + + /** + * De-initialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + /** + * Attempt to connect up the JACK ports automatically + */ + void + do_auto_connect( ) throw ( Exception ); + + /** + * Callback called by JACK when audio is available + */ + static int + process_callback( jack_nframes_t nframes, void *arg ); + + + /** + * Callback called by JACK when jackd is shutting down + */ + static void + shutdown_callback( void *arg ); + + public: + + /** + * Constructor. + * + * @param name the name of the jack device + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channels number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + JackDspSource ( const char * name, + int sampleRate = 44100, + int bitsPerSample = 16, + int channels = 2 ) + throw ( Exception ) + + : AudioSource( sampleRate, bitsPerSample, channels ) + { + init( name ); + } + + /** + * Copy Constructor. + * + * @param jds the object to copy. + * @exception Exception + */ + inline + JackDspSource ( const JackDspSource & jds ) throw ( Exception ) + : AudioSource( jds ) + { + throw Exception( __FILE__, __LINE__, "JackDspSource doesn't copy"); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~JackDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual JackDspSource & + operator= ( const JackDspSource & ds ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__, "JackDspSource doesn't assign"); + } + + /** + * Open the JackDspSource. + * This does not put the Jack DSP device into recording mode. + * To start getting samples, call either canRead() or read(). + * + * @return true if opening was successful, false otherwise + * @exception Exception + * + * @see #canRead + * @see #read + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the JackDspSource is registered + * + * @return true if Jack client is setup + */ + inline virtual bool + isOpen ( void ) const throw () + { + return client != NULL; + } + + /** + * Check if the JackDspSource can be read from. + * Blocks until the specified time for data to be available. + * Puts the Jack DSP device into recording mode. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the JackDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the JackDspSource. + * Puts the Jack DSP device into recording mode. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the JackDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* JACK_DSP_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.1 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/LameLibEncoder.cpp b/darkice/tags/darkice-0_17_1/src/LameLibEncoder.cpp new file mode 100644 index 0000000..4752f12 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/LameLibEncoder.cpp @@ -0,0 +1,467 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : LameLibEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// compile the whole file only if lame support configured in +#ifdef HAVE_LAME_LIB + + + +#include "Exception.h" +#include "Util.h" +#include "LameLibEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Open an encoding session + *----------------------------------------------------------------------------*/ +bool +LameLibEncoder :: open ( void ) + throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "lame lib opening underlying sink error"); + } + + lameGlobalFlags = lame_init(); + + // ugly lame returns -1 in a pointer on allocation errors + if ( !lameGlobalFlags || ((int)lameGlobalFlags) == -1 ) { + throw Exception( __FILE__, __LINE__, + "lame lib init error", + (int) lameGlobalFlags); + } + + if ( 0 > lame_set_num_channels( lameGlobalFlags, getInChannel()) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting channels error", + getInChannel() ); + } + + if ( 0 > lame_set_mode( lameGlobalFlags, + getOutChannel() == 1 ? MONO : JOINT_STEREO) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting mode error", + JOINT_STEREO ); + } + + reportEvent( 5, "set lame mode", lame_get_mode( lameGlobalFlags)); + + reportEvent( 5, + "set lame channels", + lame_get_num_channels( lameGlobalFlags)); + + if ( 0 > lame_set_in_samplerate( lameGlobalFlags, getInSampleRate()) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting input sample rate error", + getInSampleRate() ); + } + + reportEvent( 5, + "set lame in sample rate", + lame_get_in_samplerate( lameGlobalFlags)); + + if ( 0 > lame_set_out_samplerate( lameGlobalFlags, getOutSampleRate()) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting output sample rate error", + getOutSampleRate() ); + } + + reportEvent( 5, + "set lame out sample rate", + lame_get_out_samplerate( lameGlobalFlags)); + + switch ( getOutBitrateMode() ) { + + case cbr: { + + if ( 0 > lame_set_brate( lameGlobalFlags, getOutBitrate()) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting output bit rate error", + getOutBitrate() ); + } + + reportEvent( 5, + "set lame bit rate", + lame_get_brate( lameGlobalFlags)); + + double d = (1.0 - getOutQuality()) * 10.0; + + if ( d > 9 ) { + d = 9; + } + + int q = int (d); + + if ( 0 > lame_set_quality( lameGlobalFlags, q) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting quality error", q); + } + + reportEvent( 5, + "set lame quality", + lame_get_quality( lameGlobalFlags)); + } break; + + case abr: + + if ( 0 > lame_set_VBR( lameGlobalFlags,vbr_abr)) { + throw Exception( __FILE__, __LINE__, + "lame lib setting abr error", vbr_abr); + } + + reportEvent( 5, + "set lame abr bitrate", + lame_get_VBR( lameGlobalFlags)); + + if ( 0 > lame_set_VBR_mean_bitrate_kbps( lameGlobalFlags, + getOutBitrate())) { + throw Exception( __FILE__, __LINE__, + "lame lib setting abr mean bitrate error", + getOutBitrate()); + } + + reportEvent( 5, + "set lame abr mean bitrate", + lame_get_VBR_mean_bitrate_kbps( lameGlobalFlags)); + break; + + case vbr: { + + if ( 0 > lame_set_VBR( lameGlobalFlags, vbr_mtrh)) { + throw Exception( __FILE__, __LINE__, + "lame lib setting vbr error", vbr_mtrh ); + } + + reportEvent( 5, + "set lame vbr bitrate", + lame_get_VBR( lameGlobalFlags)); + + double d = (1.0 - getOutQuality()) * 10.0; + + if ( d > 9 ) { + d = 9; + } + + int q = int (d); + + if ( 0 > lame_set_VBR_q( lameGlobalFlags, q) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting vbr quality error", q); + } + + reportEvent( 5, + "set lame vbr quality", + lame_get_VBR_q( lameGlobalFlags)); + } break; + } + + + if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting lowpass frequency error", + lowpass ); + } + + reportEvent( 5, + "set lame lowpass frequency", + lame_get_lowpassfreq( lameGlobalFlags)); + + if ( 0 > lame_set_highpassfreq( lameGlobalFlags, highpass) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting highpass frequency error", + lowpass ); + } + + reportEvent( 5, + "set lame highpass frequency", + lame_get_highpassfreq( lameGlobalFlags)); + + + + + // not configurable lame settings + + if ( 0 > lame_set_exp_nspsytune( lameGlobalFlags, 1) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting psycho acoustic model error"); + } + + reportEvent( 5, + "set lame psycho acoustic model", + lame_get_exp_nspsytune( lameGlobalFlags)); + + if ( 0 > lame_set_error_protection( lameGlobalFlags, 1) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting error protection error", + 1 ); + } + + reportEvent( 5, + "set lame error protection", + lame_get_error_protection( lameGlobalFlags)); + + // let lame init its own params based on our settings + if ( 0 > lame_init_params( lameGlobalFlags) ) { + throw Exception( __FILE__, __LINE__, + "lame lib initializing params error" ); + } + + if (getReportVerbosity() >= 3) { + lame_print_config( lameGlobalFlags); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Write data to the encoder + *----------------------------------------------------------------------------*/ +unsigned int +LameLibEncoder :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + if ( !isOpen() || len == 0 ) { + return 0; + } + + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int inChannels = getInChannel(); + + unsigned int sampleSize = (bitsPerSample / 8) * inChannels; + unsigned char * b = (unsigned char*) buf; + unsigned int processed = len - (len % sampleSize); + unsigned int nSamples = processed / sampleSize; + short int * leftBuffer = new short int[nSamples]; + short int * rightBuffer = new short int[nSamples]; + + if ( bitsPerSample == 8 ) { + Util::conv8( b, processed, leftBuffer, rightBuffer, inChannels); + } else if ( bitsPerSample == 16 ) { + Util::conv16( b, + processed, + leftBuffer, + rightBuffer, + inChannels, + isInBigEndian()); + } else { + delete[] leftBuffer; + delete[] rightBuffer; + throw Exception( __FILE__, __LINE__, + "unsupported number of bits per sample for the encoder", + bitsPerSample ); + } + + // data chunk size estimate according to lame documentation + // NOTE: mp3Size is calculated based on the number of input channels + // which may be bigger than need, as output channels can be less + unsigned int mp3Size = (unsigned int) (1.25 * nSamples + 7200); + unsigned char * mp3Buf = new unsigned char[mp3Size]; + int ret; + + ret = lame_encode_buffer( lameGlobalFlags, + leftBuffer, + inChannels == 2 ? rightBuffer : leftBuffer, + nSamples, + mp3Buf, + mp3Size ); + + delete[] leftBuffer; + delete[] rightBuffer; + + if ( ret < 0 ) { + reportEvent( 3, "lame encoding error", ret); + delete[] mp3Buf; + return 0; + } + + unsigned int written = sink->write( mp3Buf, ret); + delete[] mp3Buf; + // just let go data that could not be written + if ( written < (unsigned int) ret ) { + reportEvent( 2, + "couldn't write all from encoder to underlying sink", + ret - written); + } + + return processed; +} + + +/*------------------------------------------------------------------------------ + * Flush the data from the encoder + *----------------------------------------------------------------------------*/ +void +LameLibEncoder :: flush ( void ) + throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + // data chunk size estimate according to lame documentation + unsigned int mp3Size = 7200; + unsigned char * mp3Buf = new unsigned char[mp3Size]; + int ret; + + ret = lame_encode_flush( lameGlobalFlags, mp3Buf, mp3Size ); + + unsigned int written = sink->write( mp3Buf, ret); + delete[] mp3Buf; + + // just let go data that could not be written + if ( written < (unsigned int) ret ) { + reportEvent( 2, + "couldn't write all from encoder to underlying sink", + ret - written); + } + + sink->flush(); +} + + +/*------------------------------------------------------------------------------ + * Close the encoding session + *----------------------------------------------------------------------------*/ +void +LameLibEncoder :: close ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + flush(); + lame_close( lameGlobalFlags); + lameGlobalFlags = 0; + + sink->close(); + } +} + + +#endif // HAVE_LAME_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.20 2006/01/25 22:47:15 darkeye + added mpeg2 support, thanks to Nicholas J Humfrey + + Revision 1.19 2005/04/13 19:04:55 jbebel + Distribute lame qualities better, and prevent values greater than 9 which are invalid. + + Revision 1.18 2002/10/19 13:31:46 darkeye + some cleanup with the open() / close() functions + + Revision 1.17 2002/10/19 12:22:10 darkeye + return 0 immediately for write() if supplied length is 0 + + Revision 1.16 2002/08/04 10:26:06 darkeye + added additional error checking to make sure that outChannel < inChannel + + Revision 1.15 2002/08/03 12:41:18 darkeye + added possibility to stream in mono when recording in stereo + + Revision 1.14 2002/07/28 00:11:58 darkeye + bugfix for the previous fix :) + + Revision 1.13 2002/07/28 00:08:37 darkeye + bugfix: mp3Buf was deleted too early + + Revision 1.12 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.11 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + + Revision 1.10 2002/03/28 16:38:37 darkeye + moved functions conv8() and conv16() to class Util + + Revision 1.9 2001/10/20 10:56:45 darkeye + added possibility to disable highpass and lowpass filters for lame + + Revision 1.8 2001/10/19 12:39:42 darkeye + created configure options to compile with or without lame / Ogg Vorbis + + Revision 1.7 2001/09/18 14:57:19 darkeye + finalized Solaris port + + Revision 1.6 2001/09/15 11:35:08 darkeye + minor fixes + + Revision 1.5 2001/09/02 09:54:12 darkeye + fixed typos in CVS substition keywords + + Revision 1.4 2001/08/31 20:09:05 darkeye + added funcitons conv8() and conv16() + + Revision 1.3 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.2 2001/08/29 21:06:16 darkeye + added real support for 8 / 16 bit mono / stereo input + (8 bit input still has to be spread on 16 bit words) + + Revision 1.1 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/LameLibEncoder.h b/darkice/tags/darkice-0_17_1/src/LameLibEncoder.h new file mode 100644 index 0000000..ada80d5 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/LameLibEncoder.h @@ -0,0 +1,505 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : LameLibEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef LAME_LIB_ENCODER_H +#define LAME_LIB_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_LAME_LIB +#include +#else +#error configure with lame +#endif + + +#include "Ref.h" +#include "Exception.h" +#include "Reporter.h" +#include "AudioEncoder.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing the lame encoder linked as a shared object or as + * a static library. + * + * @author $Author$ + * @version $Revision$ + */ +class LameLibEncoder : public AudioEncoder, public virtual Reporter +{ + private: + + /** + * Lame library global flags + */ + lame_global_flags * lameGlobalFlags; + + /** + * The Sink to dump mp3 data to + */ + Ref sink; + + /** + * Lowpass filter. Sound frequency in Hz, from where up the + * input is cut. + */ + int lowpass; + + /** + * Highpass filter. Sound frequency in Hz, from where down the + * input is cut. + */ + int highpass; + + /** + * Initialize the object. + * + * @param sink the sink to send mp3 output to + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @param highpass frequency threshold for the highpass filter. + * Input below this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline void + init ( Sink * sink, + int lowpass, + int highpass ) throw ( Exception ) + { + this->lameGlobalFlags = NULL; + this->sink = sink; + this->lowpass = lowpass; + this->highpass = highpass; + + if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getInChannel() != 1 && getInChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of input channels for the encoder", + getInChannel() ); + } + if ( getOutChannel() != 1 && getOutChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of output channels for the encoder", + getOutChannel() ); + } + if ( getInChannel() < getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "output channels greater then input channels", + getOutChannel() ); + } + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + LameLibEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param sink the sink to send mp3 output to + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @param highpass frequency threshold for the highpass filter. + * Input below this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + LameLibEncoder ( Sink * sink, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + int lowpass = 0, + int highpass = 0 ) + throw ( Exception ) + + : AudioEncoder ( inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink, lowpass, highpass); + } + + /** + * Constructor. + * + * @param sink the sink to send mp3 output to + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @param lowpass frequency threshold for the lowpass filter. + * Input above this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @param highpass frequency threshold for the highpass filter. + * Input below this frequency is cut. + * If 0, lame's default values are used, + * which depends on the out sample rate. + * @exception Exception + */ + inline + LameLibEncoder ( Sink * sink, + const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + int lowpass = 0, + int highpass = 0 ) + throw ( Exception ) + + : AudioEncoder ( as, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink, lowpass, highpass); + } + + /** + * Copy constructor. + * + * @param encoder the LameLibEncoder to copy. + */ + inline + LameLibEncoder ( const LameLibEncoder & encoder ) + throw ( Exception ) + : AudioEncoder( encoder ) + { + init( encoder.sink.get(), encoder.lowpass, encoder.highpass ); + } + + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~LameLibEncoder ( void ) throw ( Exception ) + { + if ( isOpen() ) { + close(); + } + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the LameLibEncoder to assign this to. + * @return a reference to this LameLibEncoder. + * @exception Exception + */ + inline virtual LameLibEncoder & + operator= ( const LameLibEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + AudioEncoder::operator=( encoder); + init( encoder.sink.get(), encoder.lowpass, encoder.highpass ); + } + + return *this; + } + + /** + * Get the version string of the underlying lame library. + * + * @return the version string of the underlying lame library. + */ + inline const char * + getLameVersion( void ) + { + return get_lame_version(); + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + inline virtual bool + isRunning ( void ) const throw () + { + return isOpen(); + } + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started in the background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + inline virtual bool + start ( void ) throw ( Exception ) + { + return open(); + } + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + inline virtual void + stop ( void ) throw ( Exception ) + { + return close(); + } + + /** + * Open an encoding session. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the encoding session is open. + * + * @return true if the encoding session is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return lameGlobalFlags != 0; + } + + /** + * Check if the encoder is ready to accept data. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the encoder is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + if ( !isOpen() ) { + return false; + } + + return true; + } + + /** + * Write data to the encoder. + * Buf is expected to be a sequence of big-endian 16 bit values, + * with left and right channels interleaved. Len is the number of + * bytes, must be a multiple of 4. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the encoder to the underlying + * connection. + * + * @exception Exception + */ + virtual void + flush ( void ) throw ( Exception ); + + /** + * Close the encoding session. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +#endif /* LAME_LIB_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.16 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + Revision 1.15 2004/01/07 13:18:17 darkeye + commited patch sent by John Hay, fixing FreeBSD problems + + Revision 1.14 2002/08/04 10:26:06 darkeye + added additional error checking to make sure that outChannel < inChannel + + Revision 1.13 2002/08/03 12:41:18 darkeye + added possibility to stream in mono when recording in stereo + + Revision 1.12 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + + Revision 1.11 2002/03/28 16:38:37 darkeye + moved functions conv8() and conv16() to class Util + + Revision 1.10 2001/10/20 10:56:45 darkeye + added possibility to disable highpass and lowpass filters for lame + + Revision 1.9 2001/10/19 12:39:42 darkeye + created configure options to compile with or without lame / Ogg Vorbis + + Revision 1.8 2001/10/19 09:03:39 darkeye + added support for resampling mp3 streams + + Revision 1.7 2001/09/15 11:35:08 darkeye + minor fixes + + Revision 1.6 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + Revision 1.5 2001/09/02 09:54:12 darkeye + fixed typos in CVS substition keywords + + Revision 1.4 2001/08/31 20:09:05 darkeye + added funcitons conv8() and conv16() + + Revision 1.3 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.2 2001/08/29 21:06:16 darkeye + added real support for 8 / 16 bit mono / stereo input + (8 bit input still has to be spread on 16 bit words) + + Revision 1.1 2001/08/26 20:44:30 darkeye + removed external command-line encoder support + replaced it with a shared-object support for lame with the possibility + of static linkage + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Makefile.am b/darkice/tags/darkice-0_17_1/src/Makefile.am new file mode 100644 index 0000000..b5db157 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Makefile.am @@ -0,0 +1,70 @@ +bin_PROGRAMS = darkice +AM_CXXFLAGS = -O2 -pedantic -Wall @DEBUG_CXXFLAGS@ @PTHREAD_CFLAGS@ + @JACK_CFLAGS@ +INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ @FAAC_INCFLAGS@ @TWOLAME_INCFLAGS@ @ALSA_INCFLAGS@ +LDADD = @PTHREAD_LIBS@ @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ @FAAC_LDFLAGS@ @TWOLAME_LDFLAGS@ \ + @ALSA_LDFLAGS@ @JACK_LIBS@ + +darkice_SOURCES = AudioEncoder.h\ + AudioSource.h\ + AudioSource.cpp\ + BufferedSink.cpp\ + BufferedSink.h\ + CastSink.cpp\ + CastSink.h\ + FileSink.h\ + FileSink.cpp\ + Connector.cpp\ + Connector.h\ + MultiThreadedConnector.cpp\ + MultiThreadedConnector.h\ + DarkIce.cpp\ + DarkIce.h\ + Exception.cpp\ + Exception.h\ + IceCast.cpp\ + IceCast.h\ + IceCast2.cpp\ + IceCast2.h\ + ShoutCast.cpp\ + ShoutCast.h\ + FileCast.h\ + FileCast.cpp\ + LameLibEncoder.cpp\ + LameLibEncoder.h\ + TwoLameLibEncoder.cpp\ + TwoLameLibEncoder.h\ + VorbisLibEncoder.cpp\ + VorbisLibEncoder.h\ + FaacEncoder.cpp\ + FaacEncoder.h\ + aflibDebug.h\ + aflibDebug.cc\ + aflibConverter.h\ + aflibConverter.cc\ + aflibConverterLargeFilter.h\ + aflibConverterSmallFilter.h\ + OssDspSource.cpp\ + OssDspSource.h\ + SolarisDspSource.cpp\ + SolarisDspSource.h\ + Ref.h\ + Referable.h\ + Sink.h\ + Source.h\ + TcpSocket.cpp\ + TcpSocket.h\ + Util.cpp\ + Util.h\ + ConfigSection.h\ + ConfigSection.cpp\ + DarkIceConfig.h\ + DarkIceConfig.cpp\ + Reporter.h\ + Reporter.cpp\ + AlsaDspSource.h\ + AlsaDspSource.cpp\ + JackDspSource.h\ + JackDspSource.cpp\ + main.cpp + diff --git a/darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.cpp b/darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.cpp new file mode 100644 index 0000000..5480feb --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.cpp @@ -0,0 +1,443 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : MultiThreadedConnector.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + + +#include "Exception.h" +#include "MultiThreadedConnector.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +MultiThreadedConnector :: init ( bool reconnect ) throw ( Exception ) +{ + this->reconnect = reconnect; + + pthread_mutex_init( &mutexProduce, 0); + pthread_cond_init( &condProduce, 0); + threads = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +MultiThreadedConnector :: strip ( void ) throw ( Exception ) +{ + if ( threads ) { + delete[] threads; + threads = 0; + } + + pthread_cond_destroy( &condProduce); + pthread_mutex_destroy( &mutexProduce); +} + + +/*------------------------------------------------------------------------------ + * Constructor + *----------------------------------------------------------------------------*/ +MultiThreadedConnector :: MultiThreadedConnector ( + const MultiThreadedConnector & connector ) + throw ( Exception ) + : Connector( connector) +{ + reconnect = connector.reconnect; + mutexProduce = connector.mutexProduce; + condProduce = connector.condProduce; + + if ( threads ) { + delete[] threads; + } + threads = new ThreadData[numSinks]; + for ( unsigned int i = 0; i < numSinks; ++i ) { + threads[i] = connector.threads[i]; + } +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +MultiThreadedConnector & +MultiThreadedConnector :: operator= ( const MultiThreadedConnector & connector ) + throw ( Exception ) +{ + if ( this != &connector ) { + Connector::operator=( connector); + + reconnect = connector.reconnect; + mutexProduce = connector.mutexProduce; + condProduce = connector.condProduce; + + if ( threads ) { + delete[] threads; + } + threads = new ThreadData[numSinks]; + for ( unsigned int i = 0; i < numSinks; ++i ) { + threads[i] = connector.threads[i]; + } + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Open the source and all the sinks if needed + * Create the sink threads + *----------------------------------------------------------------------------*/ +bool +MultiThreadedConnector :: open ( void ) throw ( Exception ) +{ + unsigned int i; + size_t st; + + if ( !Connector::open() ) { + return false; + } + + running = true; + + pthread_attr_init( &threadAttr); + pthread_attr_getstacksize(&threadAttr, &st); + if (st < 128 * 1024) { + reportEvent( 5, "MultiThreadedConnector :: open, stack size ", + (long)st); + st = 128 * 1024; + pthread_attr_setstacksize(&threadAttr, st); + } + pthread_attr_setdetachstate( &threadAttr, PTHREAD_CREATE_JOINABLE); + + threads = new ThreadData[numSinks]; + for ( i = 0; i < numSinks; ++i ) { + ThreadData * threadData = threads + i; + + threadData->connector = this; + threadData->ixSink = i; + threadData->accepting = true; + threadData->isDone = true; + if ( pthread_create( &(threadData->thread), + &threadAttr, + ThreadData::threadFunction, + threadData ) ) { + break; + } + } + + // if could not create all, delete the ones created + if ( i < numSinks ) { + unsigned int j; + + // signal to stop for all running threads + pthread_mutex_lock( &mutexProduce); + running = false; + pthread_cond_broadcast( &condProduce); + pthread_mutex_unlock( &mutexProduce); + + for ( j = 0; j < i; ++j ) { + pthread_join( threads[j].thread, 0); + } + + delete[] threads; + threads = 0; + + return false; + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Transfer some data from the source to the sink + *----------------------------------------------------------------------------*/ +unsigned int +MultiThreadedConnector :: transfer ( unsigned long bytes, + unsigned int bufSize, + unsigned int sec, + unsigned int usec ) + throw ( Exception ) +{ + unsigned int b; + + if ( numSinks == 0 ) { + return 0; + } + + if ( bufSize == 0 ) { + return 0; + } + + dataBuffer = new unsigned char[bufSize]; + dataSize = 0; + + reportEvent( 6, "MultiThreadedConnector :: tranfer, bytes", bytes); + + for ( b = 0; !bytes || b < bytes; ) { + if ( source->canRead( sec, usec) ) { + unsigned int i; + + pthread_mutex_lock( &mutexProduce); + dataSize = source->read( dataBuffer, bufSize); + b += dataSize; + + // check for EOF + if ( dataSize == 0 ) { + reportEvent( 3, "MultiThreadedConnector :: transfer, EOF"); + pthread_mutex_unlock( &mutexProduce); + break; + } + + for ( i = 0; i < numSinks; ++i ) { + threads[i].isDone = false; + } + + // tell sink threads that there is some data available + pthread_cond_broadcast( &condProduce); + + // wait for all sink threads to get done with this data + while ( true ) { + for ( i = 0; i < numSinks && threads[i].isDone; ++i ); + if ( i == numSinks ) { + break; + } + pthread_cond_wait( &condProduce, &mutexProduce); + } + pthread_mutex_unlock( &mutexProduce); + } else { + reportEvent( 3, "MultiThreadedConnector :: transfer, can't read"); + break; + } + } + + delete[] dataBuffer; + return b; +} + + +/*------------------------------------------------------------------------------ + * The function for each thread. + * Read the presented data + *----------------------------------------------------------------------------*/ +void +MultiThreadedConnector :: sinkThread( int ixSink ) +{ + ThreadData * threadData = &threads[ixSink]; + Sink * sink = sinks[ixSink].get(); + + while ( running ) { + // wait for some data to become available + pthread_mutex_lock( &mutexProduce); + while ( running && threadData->isDone ) { + pthread_cond_wait( &condProduce, &mutexProduce); + } + if ( !running ) { + pthread_mutex_unlock( &mutexProduce); + break; + } + + if ( threadData->accepting ) { + if ( sink->canWrite( 0, 0) ) { + try { + sink->write( dataBuffer, dataSize); + } catch ( Exception & e ) { + // something wrong. don't accept more data, try to + // reopen the sink next time around + threadData->accepting = false; + } + } else { + reportEvent( 4, + "MultiThreadedConnector :: sinkThread can't write ", + ixSink); + // don't care if we can't write + } + } + threadData->isDone = true; + pthread_cond_broadcast( &condProduce); + pthread_mutex_unlock( &mutexProduce); + + if ( !threadData->accepting ) { + if ( reconnect ) { + reportEvent( 4, + "MultiThreadedConnector :: sinkThread reconnecting ", + ixSink); + // if we're not accepting, try to reopen the sink + try { + sink->close(); + sched_yield(); + sink->open(); + sched_yield(); + threadData->accepting = sink->isOpen(); + } catch ( Exception & e ) { + // don't care, just try and try again + } + } else { + // if !reconnect, just stop the connector + running = false; + } + } + } +} + + +/*------------------------------------------------------------------------------ + * Stop the treads + * Close the source and all the sinks if needed + *----------------------------------------------------------------------------*/ +void +MultiThreadedConnector :: close ( void ) throw ( Exception ) +{ + unsigned int i; + + // signal to stop for all threads + pthread_mutex_lock( &mutexProduce); + running = false; + pthread_cond_broadcast( &condProduce); + pthread_mutex_unlock( &mutexProduce); + + // wait for all the threads to finish + for ( i = 0; i < numSinks; ++i ) { + pthread_join( threads[i].thread, 0); + } + pthread_attr_destroy( &threadAttr); + + Connector::close(); +} + + +/*------------------------------------------------------------------------------ + * The thread function + *----------------------------------------------------------------------------*/ +void * +MultiThreadedConnector :: ThreadData :: threadFunction( void * param ) +{ + struct sched_param sched; + int sched_type; + ThreadData * threadData = (ThreadData*) param; + + pthread_getschedparam( threadData->thread, &sched_type, &sched ); + + reportEvent( 5, + "MultiThreadedConnector :: ThreadData :: threadFunction, " + "was (thread, priority, type): ", + param, + sched.sched_priority, + sched_type == SCHED_FIFO ? "SCHED_FIFO" : + sched_type == SCHED_RR ? "SCHED_RR" : + sched_type == SCHED_OTHER ? "SCHED_OTHER" : + "INVALID" + ); + + sched.sched_priority = 1; + pthread_setschedparam( threadData->thread, SCHED_FIFO, &sched); + + pthread_getschedparam( threadData->thread, &sched_type, &sched ); + reportEvent( 5, + "MultiThreadedConnector :: ThreadData :: threadFunction, " + "now is (thread, priority, type): ", + param, + sched.sched_priority, + sched_type == SCHED_FIFO ? "SCHED_FIFO" : + sched_type == SCHED_RR ? "SCHED_RR" : + sched_type == SCHED_OTHER ? "SCHED_OTHER" : + "INVALID" + ); + + threadData->connector->sinkThread( threadData->ixSink); + + return 0; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.8 2006/05/18 07:13:00 darkeye + cosmetic changes + + Revision 1.7 2006/05/16 09:00:08 darkeye + added yield calls to the connector, when trying to reconnect... + + Revision 1.6 2005/04/13 22:03:32 jbebel + Set priority explicitly for encoding threads. This needs more testing. + + Revision 1.5 2005/04/11 19:27:43 darkeye + added option to turn off automatic reconnect feature + + Revision 1.4 2004/01/07 13:18:17 darkeye + commited patch sent by John Hay, fixing FreeBSD problems + + Revision 1.3 2002/10/20 20:43:17 darkeye + more graceful reconnect + + Revision 1.2 2002/10/19 13:35:21 darkeye + when a connection is dropped, DarkIce tries to reconnect, indefinitely + removed extreme event reporting for thread-related events + + Revision 1.1 2002/10/19 12:25:47 darkeye + changed internals so that now each encoding/server connection is + a separate thread + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.h b/darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.h new file mode 100644 index 0000000..fbbe336 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/MultiThreadedConnector.h @@ -0,0 +1,370 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : MultiThreadedConnector.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef MULTI_THREADED_CONNECTOR_H +#define MULTI_THREADED_CONNECTOR_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// check for __NetBSD__ because it won't be found by AC_CHECK_HEADER on NetBSD +// as pthread.h is in /usr/pkg/include, not /usr/include +#if defined( HAVE_PTHREAD_H ) || defined( __NetBSD__ ) +#include +#else +#error need pthread.h +#endif + +#include "Referable.h" +#include "Ref.h" +#include "Reporter.h" +#include "Source.h" +#include "Sink.h" +#include "Connector.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Connects a source to one or more sinks, using a multi-threaded + * producer - consumer approach. + * + * @author $Author$ + * @version $Revision$ + */ +class MultiThreadedConnector : public virtual Connector +{ + private: + + /** + * Helper class to collect information for starting threads. + */ + class ThreadData + { + public: + /** + * The connector starting the thread + */ + MultiThreadedConnector * connector; + + /** + * The index of the sink this thread writes to. + */ + unsigned int ixSink; + + /** + * The POSIX thread itself. + */ + pthread_t thread; + + /** + * Marks if the thread is accepting data. + */ + bool accepting; + + /** + * Marks if the thread has processed the last batch + * of data. + */ + bool isDone; + + /** + * Default constructor. + */ + inline + ThreadData() + { + this->connector = 0; + this->ixSink = 0; + this->thread = 0; + this->accepting = false; + this->isDone = false; + } + + /** + * The thread function. + * + * @param param thread parameter, a pointer to a + * ThreadData + * @return nothing + */ + static void * + threadFunction( void * param ); + }; + + /** + * The mutex of this object. + */ + pthread_mutex_t mutexProduce; + + /** + * The conditional variable for presenting new data. + */ + pthread_cond_t condProduce; + + /** + * The thread attributes. + */ + pthread_attr_t threadAttr; + + /** + * The threads for the sinks. + */ + ThreadData * threads; + + /** + * Signal if we're running or not, so the threads no if to stop. + */ + bool running; + + /** + * Flag to show if the connector should try to reconnect if + * the connection is dropped on the other side. + */ + bool reconnect; + + /** + * The buffer of information presented to each thread. + */ + unsigned char * dataBuffer; + + /** + * The amount of information presented to each thread. + */ + unsigned int dataSize; + + /** + * Initialize the object. + * + * @param reconnect flag to indicate if the connector should + * try to reconnect if the connection was + * dropped by the other end + * @exception Exception + */ + void + init ( bool reconnect ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + MultiThreadedConnector ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor based on a Source. + * + * @param source the source to connect to the sinks. + * @param reconnect flag to indicate if the connector should + * try to reconnect if the connection was + * dropped by the other end + * @exception Exception + */ + inline + MultiThreadedConnector ( Source * source, + bool reconnect ) + throw ( Exception ) + : Connector( source ) + { + init(reconnect); + } + + /** + * Constructor based on a Source and a Sink. + * + * @param source the source to connect to the sinks. + * @param sink a sink to connect to the source. + * @param reconnect flag to indicate if the connector should + * try to reconnect if the connection was + * dropped by the other end + * @exception Exception + */ + inline + MultiThreadedConnector ( Source * source, + Sink * sink, + bool reconnect ) + throw ( Exception ) + : Connector( source, sink) + { + init(reconnect); + } + + /** + * Copy constructor. + * + * @param connector the object to copy. + * @exception Exception + */ + MultiThreadedConnector ( const MultiThreadedConnector & connector ) + throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~MultiThreadedConnector( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param connector the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + virtual MultiThreadedConnector & + operator= ( const MultiThreadedConnector & connector ) + throw ( Exception ); + + /** + * Open the connector. Opens the Source and the Sinks if necessary. + * + * @return true if opening was successful, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Transfer a given amount of data from the Source to all the + * Sinks attached. + * If an attached Sink closes or encounteres an error during the + * process, it is detached and the function carries on with the + * rest of the Sinks. If no Sinks remain, or an error is encountered + * with the Source, the function returns prematurely. + * + * @param bytes the amount of data to transfer, in bytes. + * If 0, transfer forever. + * @param bufSize the size of the buffer to use for transfering. + * This amount of data is read from the Source and + * written to each Sink on each turn. + * @param sec the number of seconds to wait for the Source to have + * data available in each turn, and the number of seconds + * to wait for the Sinks to accept data. + * @param usec the number of micros seconds to wait for the Source to + * have data available in each turn, and the number of + * micro seconds to wait for the Sinks to accept data. + * @return the number of bytes read from the Source. + * @exception Exception + */ + virtual unsigned int + transfer ( unsigned long bytes, + unsigned int bufSize, + unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Close the Connector. The Source and all Sinks are closed. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); + + /** + * This is the function for each thread. + * This function has to return fast + * + * @param ixSink the index of the sink this thread works on. + */ + void + sinkThread( int ixSink ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* MULTI_THREADED_CONNECTOR_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2005/04/11 19:27:43 darkeye + added option to turn off automatic reconnect feature + + Revision 1.4 2004/02/23 19:12:52 darkeye + ported to NetBSD + + Revision 1.3 2002/11/26 21:41:20 darkeye + bugfix: MultiThreadedConnector::sinkThread() was private, now public + + Revision 1.2 2002/10/19 13:35:21 darkeye + when a connection is dropped, DarkIce tries to reconnect, indefinitely + removed extreme event reporting for thread-related events + + Revision 1.1 2002/10/19 12:25:47 darkeye + changed internals so that now each encoding/server connection is + a separate thread + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/OssDspSource.cpp b/darkice/tags/darkice-0_17_1/src/OssDspSource.cpp new file mode 100644 index 0000000..f39a41e --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/OssDspSource.cpp @@ -0,0 +1,353 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : OssDspSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "OssDspSource.h" + +#ifdef SUPPORT_OSS_DSP +// only compile this code if there is support for it + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#else +#error need sys/ioctl.h +#endif + +#ifdef HAVE_SYS_SOUNDCARD_H +#include +#else +#error need sys/soundcard.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "OssDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + +/*------------------------------------------------------------------------------ + * Define the natural endiannes of 16 bit recording if not defined, + * based on the endiannes of the system + *----------------------------------------------------------------------------*/ +#ifndef AFMT_S16_NE +# ifdef WORDS_BIGENDIAN +# define AFMT_S16_NE AFMT_S16_BE +# else +# define AFMT_S16_NE AFMT_S16_LE +# endif +#endif + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Tell if source id big endian + *----------------------------------------------------------------------------*/ +bool +OssDspSource :: isBigEndian ( void ) const throw () +{ + return AFMT_S16_NE == AFMT_S16_BE; +} + + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +OssDspSource :: init ( const char * name ) throw ( Exception ) +{ + fileName = Util::strDup( name); + fileDescriptor = 0; + running = false; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +OssDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] fileName; +} + + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +OssDspSource :: open ( void ) throw ( Exception ) +{ + int format; + int i; + unsigned int u; + + if ( isOpen() ) { + return false; + } + + switch ( getBitsPerSample() ) { + case 8: + format = AFMT_U8; + break; + + case 16: + format = AFMT_S16_NE; + break; + + default: + return false; + } + + if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) { + fileDescriptor = 0; + return false; + } + + i = format; + if ( ioctl( fileDescriptor, SNDCTL_DSP_SETFMT, &i) == -1 || + i != format ) { + + close(); + throw Exception( __FILE__, __LINE__, "can't set format", i); + } + + u = getChannel(); + if ( ioctl( fileDescriptor, SNDCTL_DSP_CHANNELS, &u) == -1 || + u != getChannel() ) { + + close(); + throw Exception( __FILE__, __LINE__, "can't set channels", u); + } + + u = getSampleRate(); + if ( ioctl( fileDescriptor, SNDCTL_DSP_SPEED, &u) == -1 ) { + + close(); + throw Exception( __FILE__, __LINE__, + "can't set soundcard recording sample rate", u); + } + if ( u != getSampleRate() ) { + reportEvent( 2, "sound card recording sample rate set to ", u, + " while trying to set it to ", getSampleRate()); + reportEvent( 2, "this is probably not a problem, but a slight " + "drift in the sound card driver"); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +OssDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + if ( !running ) { + /* ugly workaround to get the dsp into recording state */ + unsigned char * b = + new unsigned char[getChannel()*getBitsPerSample()/8]; + read( b, getChannel()*getBitsPerSample()/8); + delete[] b; + } + + FD_ZERO( &fdset); + FD_SET( fileDescriptor, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +OssDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + ssize_t ret; + + if ( !isOpen() ) { + return 0; + } + + ret = ::read( fileDescriptor, buf, len); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "read error"); + } + + running = true; + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +OssDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + ::close( fileDescriptor); + fileDescriptor = 0; + running = false; +} + +#endif // SUPPORT_OSS_DSP + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.13 2003/02/12 15:48:22 darkeye + added proper guessing for natural endiannes of 16 bit recording + + Revision 1.12 2002/12/20 10:40:40 darkeye + added support for big endian OSS devices (like Linux PowerPC) + + Revision 1.11 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.10 2001/09/26 16:55:30 darkeye + BSD port + + Revision 1.9 2001/09/11 15:05:21 darkeye + added Solaris support + + Revision 1.8 2001/09/02 14:08:40 darkeye + setting the sound card recording sample rate is now more relaxed + there is no error reported if the sample rate is not exactly the same + + Revision 1.7 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.6 2000/12/01 15:03:28 darkeye + bug fix in error reporting + + Revision 1.5 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.4 2000/11/13 20:05:07 darkeye + changed to workaround to start recording so that it reads one sample + per channel, as opposed to only one sample (which misalignes the channels) + + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/OssDspSource.h b/darkice/tags/darkice-0_17_1/src/OssDspSource.h new file mode 100644 index 0000000..8eb6168 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/OssDspSource.h @@ -0,0 +1,286 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : OssDspSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef OSS_DSP_SOURCE_H +#define OSS_DSP_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Reporter.h" +#include "AudioSource.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio input based on /dev/dsp-like raw devices + * + * @author $Author$ + * @version $Revision$ + */ +class OssDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * The file name of the OSS DSP device (e.g. /dev/dsp or /dev/dsp0). + */ + char * fileName; + + /** + * The low-level file descriptor of the OSS DSP device. + */ + int fileDescriptor; + + /** + * Indicates wether the low-level OSS DSP device is in a recording + * state. + */ + bool running; + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + OssDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the file name of the OSS DSP device. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-iitialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param name the file name of the OSS DSP device + * (e.g. /dev/dsp or /dev/dsp0). + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + OssDspSource ( const char * name, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( name); + } + + /** + * Copy Constructor. + * + * @param ods the object to copy. + * @exception Exception + */ + inline + OssDspSource ( const OssDspSource & ods ) throw ( Exception ) + : AudioSource( ods ) + { + init( ods.fileName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~OssDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual OssDspSource & + operator= ( const OssDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.fileName); + } + return *this; + } + + /** + * Tell if the data from this source comes in big or little endian. + * + * @return true if the source is big endian, false otherwise + */ + virtual bool + isBigEndian ( void ) const throw (); + + /** + * Open the OssDspSource. + * This does not put the OSS DSP device into recording mode. + * To start getting samples, call either canRead() or read(). + * + * @return true if opening was successful, false otherwise + * @exception Exception + * + * @see #canRead + * @see #read + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the OssDspSource is open. + * + * @return true if the OssDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return fileDescriptor != 0; + } + + /** + * Check if the OssDspSource can be read from. + * Blocks until the specified time for data to be available. + * Puts the OSS DSP device into recording mode. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the OssDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the OssDspSource. + * Puts the OSS DSP device into recording mode. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the OssDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* OSS_DSP_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.7 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.6 2002/12/20 10:40:40 darkeye + added support for big endian OSS devices (like Linux PowerPC) + + Revision 1.5 2001/09/18 14:57:19 darkeye + finalized Solaris port + + Revision 1.4 2001/09/02 14:08:40 darkeye + setting the sound card recording sample rate is now more relaxed + there is no error reported if the sample rate is not exactly the same + + Revision 1.3 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:53 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Ref.h b/darkice/tags/darkice-0_17_1/src/Ref.h new file mode 100644 index 0000000..c02c12c --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Ref.h @@ -0,0 +1,320 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Ref.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef REF_H +#define REF_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Java-like object reference class. + * Objects used with this reference class have to be descandents + * of class Referable. + * + * sample usage: + * + *
+ *  #include "Ref.h"
+ *  #include "Referable.h"
+ *
+ *  class  A : public virtual Referable;
+ *
+ *  ...
+ *   
+ *  A        * a = new A();
+ *  Ref     ref1 = a;       // 1 reference to a
+ *  Ref     ref2 = ref1;    // 2 references to a
+ *
+ *  ref1 = 0;      // 1 reference to a
+ *  ref2 = 0;      // at this point object a is destroyed
+ *  
+ * + * Based on Tima Saarinen's work, + * http://gamma.nic.fi/~timosa/comp/refcount.html + * + * @ref Referable + * + * @author $Author$ + * @version $Revision$ + */ +template +class Ref +{ + private: + + /** + * The object referenced by this Ref. + * Must be a descandant of Referable. + */ + T* object; + + + protected: + + + public: + + /** + * Default constructor. + */ + inline + Ref ( void ) throw () + { + object = NULL; + } + + /** + * Copy constructor. + * + * @param other the Ref to copy. + * @exception Exception + */ + inline + Ref ( const Ref & other ) throw ( Exception ) + { + object = NULL; + set( other.object); + } + + /** + * Constructor based on an object to reference. + * + * @param obj the object to reference. + * @exception Exception + */ + inline + Ref ( T * obj ) throw ( Exception ) + { + object = obj; + obj->increaseReferenceCount(); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Ref ( void ) throw ( Exception ) + { + set( 0 ); + } + + /** + * Operator overload to make the reference seem like a pointer. + * + * @return the pointer to the object referenced. + */ + inline T* + operator->() const throw ( Exception ) + { + if ( !object ) { + throw Exception( __FILE__, __LINE__, + "reference to NULL object"); + } + return object; + } + + /** + * Assignment operator. + * + * @param other the Ref to assign to this one. + * @return a reference to this Ref. + * @exception Exception + */ + inline Ref & + operator= ( Ref other ) throw ( Exception ) + { + set( other.object); + return *this; + } + + /** + * Assignment operator. + * + * @param obj pointer to the object to assign to this Ref. + * @return a reference to this Ref. + * @exception Exception + */ + inline Ref & + operator= ( T* obj ) throw ( Exception ) + { + set( obj); + return *this; + } + + /** + * Set the object referenced. + * Deletes the old referenced object is this was it's last reference. + * + * @param newobj pointer to the object to reference by this Ref. + * @exception Exception + */ + inline void + set ( T * newobj ) throw ( Exception ) + { + // If equal do nothing + if ( newobj == object ) { + return; + } + + // Increase reference count + if ( newobj ) { + newobj->increaseReferenceCount(); + } + + // Decrease the reference count of the old referable + if ( object ) { + if ( object->decreaseReferenceCount() == 0 ) { + delete object; + } + } + + // Assign + object = newobj; + } + + /** + * Return object pointer. This method should be used with + * care because it breaks the encapsulation. + * Typically this method is needed for the method calls + * which require literal object pointer. + * + * It may not be bad idea to pass the Ref + * objects as method arguments. + * + * @return Object pointer or NULL. + */ + inline T* + get ( void ) const throw () + { + return object; + } + + /** + * Equality operator. + * + * @param other the pointer to compare this with. + * @return true is this Ref refers to the same object as other, + * false otherwise. + */ + inline bool + operator== ( const T * other ) const throw () + { + return object == other; + } + + /** + * Equality operator. + * + * @param other the Ref to compare this with. + * @return true is the two Refs refer to the same object, + * false otherwise. + */ + inline bool + operator== ( const Ref & other ) const throw () + { + return object == other.object; + } + + /** + * Unequality operator. + * + * @param other the pointer to compare this with. + * @return false is this Ref refers to a different object then other, + * true otherwise. + */ + inline bool + operator!= ( const T * other ) const throw () + { + return object != other; + } + + /** + * Unequality operator. + * + * @param other the Ref to compare this with. + * @return false is the two Refs refer to the same object, + * true otherwise. + */ + inline bool + operator!= ( const Ref & other ) const throw () + { + return object != other.object; + } +}; + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* REF_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2002/08/20 20:07:36 darkeye + minor fixes + + Revision 1.4 2002/02/20 11:51:27 darkeye + added equality operators to compare with pointers + + Revision 1.3 2000/11/11 14:55:31 darkeye + minor bugfix + + Revision 1.2 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Referable.h b/darkice/tags/darkice-0_17_1/src/Referable.h new file mode 100644 index 0000000..87ef065 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Referable.h @@ -0,0 +1,185 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Referable.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef REFERABLE_H +#define REFERABLE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Base class for an object for which references can be made + * with the reference class Ref. + * + * usage: + * + *
+ *  class A : public virtual Referable
+ *  {
+ *     ...
+ *  };
+ *  
+ * + * @ref Ref + * + * @author $Author$ + * @version $Revision$ + */ +class Referable +{ + private: + + /** + * Number of references to the object. + */ + unsigned int referenceCount; + + /** + * Maximum number of references before an overflow occurs. + */ + static const + unsigned int maxCount = ~((unsigned int)0); + + + protected: + + /** + * Default constructor. + */ + inline + Referable ( void ) throw () + { + referenceCount = 0; + } + + + /** + * Desctructor. + * + * @exception Exception + */ + inline virtual + ~Referable ( void ) throw ( Exception ) + { + if ( referenceCount > 0 ) { + throw Exception( __FILE__, __LINE__, + "reference count positive in destructor", + referenceCount); + } + } + + + public: + + /** + * Increase reference count. + * + * @return the new reference count. + * @exception Exception + */ + inline unsigned int + increaseReferenceCount ( void ) throw ( Exception ) + { + if ( referenceCount >= maxCount ) { + throw Exception( __FILE__, + __LINE__, + "reference count overflow", + referenceCount ); + } + return ++referenceCount; + } + + /** + * Decrease reference count. + * + * @return the new reference count. + * @exception Exception + */ + inline unsigned int + decreaseReferenceCount ( void ) throw ( Exception ) + { + if ( referenceCount == 0 ) { + throw Exception( __FILE__, __LINE__, + "reference count underflow", + referenceCount ); + } + return --referenceCount; + } + + /** + * Get the reference count. + * + * @return the reference count. + */ + inline unsigned int + getReferenceCount ( void ) const throw () + { + return referenceCount; + } +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* REFERABLE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Reporter.cpp b/darkice/tags/darkice-0_17_1/src/Reporter.cpp new file mode 100644 index 0000000..87621a0 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Reporter.cpp @@ -0,0 +1,77 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Reporter + + File : Reporter.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include + +#include "Reporter.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Initial values for static members of the class + *----------------------------------------------------------------------------*/ +unsigned int Reporter::verbosity = 1; +std::ostream * Reporter::os = &std::cout; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.1 2000/11/16 08:48:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Reporter.h b/darkice/tags/darkice-0_17_1/src/Reporter.h new file mode 100644 index 0000000..e9cbf97 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Reporter.h @@ -0,0 +1,350 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Reporter + + File : Reporter.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef REPORTER_H +#define REPORTER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_TIME_H +#include +#else +#error need time.h +#endif + + +#include + + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class for reporting events. All objects of this class share + * the same verbosity level. Typical usage is to inherit this class + * and use the report() function to report events. Only reports + * which are of suffucient importance are really reported. + * + * The default verbosity is 1, and the default ostream is cout. + * + * Known problems: this class is not thread-safe. + * + * @author $Author$ + * @version $Revision$ + */ +class Reporter +{ + + private: + + /** + * Verbosity level shared among all Reporter objects + */ + static unsigned int verbosity; + + /** + * The output stream to report to. + */ + static std::ostream * os; + + /** + * Print timestamp for every report only if verbosity level + * is above this value. + */ + static const unsigned int prefixVerbosity = 3; + + /** + * Print a prefix to each report. + */ + static void + printPrefix( void ) throw () + { + if ( verbosity > prefixVerbosity ) { + char str[32]; + time_t now; + + now = time(NULL); + strftime( str, 32, "%d-%b-%Y %H:%M:%S ", localtime(&now) ); + (*(Reporter::os)) << str; + } + } + + + protected: + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Reporter ( void ) throw ( Exception ) + { + (Reporter::os)->flush(); + } + + /** + * Set the verbosity level. This sets the verbosity for all + * Reporter objects. + * + * @param verbosity the new verbosity level. + */ + static inline void + setReportVerbosity ( unsigned int verbosity ) throw () + { + Reporter::verbosity = verbosity; + } + + /** + * Get the verbosity level. + * + * @return the current verbosity level. + */ + static inline unsigned int + getReportVerbosity ( void ) throw () + { + return Reporter::verbosity; + } + + /** + * Set the output stream to report to. This setting effects all + * Reporter objects. + * + * @param os the output stream + */ + static inline void + setReportOutputStream ( std::ostream & os ) throw () + { + Reporter::os = &os; + } + + /** + * Get the output stream to report to. + * + * @return the output stream + */ + static inline std::ostream & + getReportOutputStream ( void ) throw () + { + return *(Reporter::os); + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + */ + template + static inline void + reportEvent ( unsigned int verbosity, + const T t ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << std::endl; + } + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object 1 to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + * @param u the object 2 to report. Must have an + * ostream & operator<<( ostream&, const U) + * operator overload. + */ + template + inline void + static reportEvent ( unsigned int verbosity, + const T t, + const U u ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << " " + << u << std::endl; + } + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object 1 to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + * @param u the object 2 to report. Must have an + * ostream & operator<<( ostream&, const U) + * operator overload. + * @param v the object 3 to report. Must have an + * ostream & operator<<( ostream&, const V) + * operator overload. + */ + template + static inline void + reportEvent ( unsigned int verbosity, + const T t, + const U u, + const V v ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << " " + << u << " " + << v << std::endl; + } + } + + /** + * Report an event with a given verbosity. + * + * @param verbosity the importance of the event, with 0 being + * the most important. + * @param t the object 1 to report. Must have an + * ostream & operator<<( ostream&, const T) + * operator overload. + * @param u the object 2 to report. Must have an + * ostream & operator<<( ostream&, const U) + * operator overload. + * @param v the object 3 to report. Must have an + * ostream & operator<<( ostream&, const V) + * operator overload. + * @param w the object 4 to report. Must have an + * ostream & operator<<( ostream&, const W) + * operator overload. + */ + template + static inline void + reportEvent ( unsigned int verbosity, + const T t, + const U u, + const V v, + const W w ) throw () + { + if ( Reporter::verbosity >= verbosity ) { + printPrefix(); + (*(Reporter::os)) << t << " " + << u << " " + << v << " " + << w << std::endl; + } + } +}; + + + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* REPORTER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.9 2005/04/04 08:36:17 darkeye + commited changes to enable Jack support + thanks to Nicholas J. Humfrey, njh@ecs.soton.ac.uk + + Revision 1.8 2005/04/03 05:14:07 jbebel + Changed timestamp on reported events to include date in addition to time. + + Revision 1.7 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + + Revision 1.6 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.5 2001/09/05 20:11:15 darkeye + removed dependency on locally stored SGI STL header files + now compiler-supplied C++ library STL header files are used + compiles under GNU C++ 3 + hash_map (an SGI extension to STL) replaced with map + std:: namespace prefix added to all STL class references + + Revision 1.4 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.3 2000/12/20 12:47:40 darkeye + added prefixVerbosity value. in a low verbosity setting no time-stamp + prefix is displayed + + Revision 1.2 2000/11/18 11:12:01 darkeye + added timestamp display, removed process id display in reports + changed reportEvent functions to template functions + + Revision 1.1 2000/11/16 08:48:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/ShoutCast.cpp b/darkice/tags/darkice-0_17_1/src/ShoutCast.cpp new file mode 100644 index 0000000..d10ac0a --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/ShoutCast.cpp @@ -0,0 +1,238 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : ShoutCast.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDIO_H +#include +#else +#error need stdio.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_MATH_H +#include +#else +#error need math.h +#endif + + +#include "Exception.h" +#include "Source.h" +#include "Sink.h" +#include "Util.h" +#include "ShoutCast.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/*------------------------------------------------------------------------------ + * Size of string conversion buffer + *----------------------------------------------------------------------------*/ +#define STRBUF_SIZE 32 + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +ShoutCast :: init ( const char * irc, + const char * aim, + const char * icq ) + throw ( Exception ) +{ + this->irc = irc ? Util::strDup( irc) : 0; + this->aim = aim ? Util::strDup( aim) : 0; + this->icq = icq ? Util::strDup( icq) : 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +ShoutCast :: strip ( void ) throw ( Exception ) +{ + if ( irc ) { + delete[] irc; + } + if ( aim ) { + delete[] aim; + } + if ( icq ) { + delete[] icq; + } +} + + +/*------------------------------------------------------------------------------ + * Log in to the ShoutCast server using the icy login scheme + *----------------------------------------------------------------------------*/ +bool +ShoutCast :: sendLogin ( void ) throw ( Exception ) +{ + Sink * sink = getSink(); + Source * source = getSocket(); + const char * str; + char resp[STRBUF_SIZE]; + unsigned int len; + + if ( !source->isOpen() ) { + return false; + } + if ( !sink->isOpen() ) { + return false; + } + + /* first line is the password in itself */ + str = getPassword(); + sink->write( str, strlen( str)); + str = "\n"; + sink->write( str, strlen( str)); + sink->flush(); + + /* send the icy headers */ + if ( getName() ) { + str = "icy-name:"; + sink->write( str, strlen( str)); + str = getName(); + sink->write( str, strlen( str)); + } + + if ( getUrl() ) { + str = "\nicy-url:"; + sink->write( str, strlen( str)); + str = getUrl(); + sink->write( str, strlen( str)); + } + + if ( getGenre() ) { + str = "\nicy-genre:"; + sink->write( str, strlen( str)); + str = getGenre(); + sink->write( str, strlen( str)); + } + + if ( getIrc() ) { + str = "\nicy-irc:"; + sink->write( str, strlen( str)); + str = getIrc(); + sink->write( str, strlen( str)); + } + + if ( getAim() ) { + str = "\nicy-aim:"; + sink->write( str, strlen( str)); + str = getAim(); + sink->write( str, strlen( str)); + } + + if ( getIcq() ) { + str = "\nicy-icq:"; + sink->write( str, strlen( str)); + str = getIcq(); + sink->write( str, strlen( str)); + } + + str = "\nicy-br:"; + sink->write( str, strlen( str)); + if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) { + throw Exception( __FILE__, __LINE__, + "bitrate does not fit string buffer", getBitRate()); + } + sprintf( resp, "%d", getBitRate()); + sink->write( resp, strlen( resp)); + + str = "\nicy-pub:"; + sink->write( str, strlen( str)); + str = getIsPublic() ? "1" : "0"; + sink->write( str, strlen( str)); + + str = "\n\n"; + sink->write( str, strlen( str)); + sink->flush(); + + /* read the anticipated response: "OK" */ + len = source->read( resp, STRBUF_SIZE); + if ( len < 2 || resp[0] != 'O' || resp[1] != 'K' ) { + return false; + } + + /* suck anything that the other side has to say */ + while ( source->canRead( 0, 0) && + (len = source->read( resp, STRBUF_SIZE)) ) { + ; + } + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.2 2001/11/20 09:06:18 darkeye + fixed public stream reporting + + Revision 1.1 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/ShoutCast.h b/darkice/tags/darkice-0_17_1/src/ShoutCast.h new file mode 100644 index 0000000..e030f77 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/ShoutCast.h @@ -0,0 +1,276 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : ShoutCast.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef SHOUT_CAST_H +#define SHOUT_CAST_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Sink.h" +#include "TcpSocket.h" +#include "CastSink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Class representing output to a ShoutCast server with + * icy login + * + * @author $Author$ + * @version $Revision$ + */ +class ShoutCast : public CastSink +{ + private: + + /** + * IRC info string for the stream + */ + char * irc; + + /** + * AIM info string for the stream + */ + char * aim; + + /** + * ICQ info string for the stream + */ + char * icq; + + /** + * Initalize the object. + * + * @param irc IRC info string for the stream. + * @param aim AIM info string for the stream. + * @param icq ICQ info string for the stream. + * @exception Exception + */ + void + init ( const char * irc, + const char * aim, + const char * icq ) + throw ( Exception ); + + /** + * De-initalize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + ShoutCast ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Log in to the server using the socket avialable. + * + * @return true if login was successful, false otherwise. + * @exception Exception + */ + virtual bool + sendLogin ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param socket socket connection to the server. + * @param password password to the server. + * @param name name of the stream. + * @param url URL associated with the stream. + * @param genre genre of the stream. + * @param bitRate bitrate of the stream (e.g. mp3 bitrate). + * @param isPublic is the stream public? + * @param irc IRC info string for the stream. + * @param aim AIM info string for the stream. + * @param icq ICQ info string for the stream. + * @param streamDump an optional sink to dump the binary stream + * data to. + * @param bufferDuration duration of the BufferedSink buffer + * in seconds. + * @exception Exception + */ + inline + ShoutCast ( TcpSocket * socket, + const char * password, + unsigned int bitRate, + const char * name = 0, + const char * url = 0, + const char * genre = 0, + bool isPublic = false, + const char * irc = 0, + const char * aim = 0, + const char * icq = 0, + Sink * streamDump = 0, + unsigned int bufferDuration = 10 ) + throw ( Exception ) + : CastSink( socket, + password, + bitRate, + name, + url, + genre, + isPublic, + streamDump, + bufferDuration ) + { + init( irc, aim, icq); + } + + /** + * Copy constructor. + * + * @param cs the ShoutCast to copy. + */ + inline + ShoutCast( const ShoutCast & cs ) throw ( Exception ) + : CastSink( cs ) + { + init( cs.getIrc(), cs.getAim(), cs.getIcq()); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~ShoutCast( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param cs the ShoutCast to assign this to. + * @return a reference to this ShoutCast. + * @exception Exception + */ + inline virtual ShoutCast & + operator= ( const ShoutCast & cs ) throw ( Exception ) + { + if ( this != &cs ) { + strip(); + CastSink::operator=( cs ); + init( cs.getIrc(), cs.getAim(), cs.getIcq()); + } + return *this; + } + + /** + * Get the IRC info string for the stream. + * + * @return the IRC info string for the stream. + */ + inline const char * + getIrc ( void ) const throw () + { + return irc; + } + + /** + * Get the AIM info string for the stream. + * + * @return the AIM info string for the stream. + */ + inline const char * + getAim ( void ) const throw () + { + return aim; + } + + /** + * Get the ICQ info string for the stream. + * + * @return the ICQ info string for the stream. + */ + inline const char * + getIcq ( void ) const throw () + { + return icq; + } + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* SHOUT_CAST_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.2 2002/02/20 11:54:11 darkeye + added local dump file possibility + + Revision 1.1 2001/09/09 11:27:31 darkeye + added support for ShoutCast servers + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Sink.h b/darkice/tags/darkice-0_17_1/src/Sink.h new file mode 100644 index 0000000..fac29e6 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Sink.h @@ -0,0 +1,198 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Sink.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef SINK_H +#define SINK_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A general data sink + * + * @author $Author$ + * @version $Revision$ + */ +class Sink : public virtual Referable +{ + private: + + + protected: + + /** + * Default constructor. + */ + inline + Sink ( void ) throw () + { + } + + /** + * Copy constructor. + * + * @param sink the Sink to copy. + */ + inline + Sink ( const Sink & sink ) throw () + { + } + + /** + * Assignment operator. + * + * @param sink the Sink to assign this to. + * @return a reference to this Sink. + * @exception Exception + */ + inline virtual Sink & + operator= ( const Sink & sink ) throw ( Exception ) + { + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Sink ( void ) throw ( Exception ) + { + } + + /** + * Open the sink. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ) = 0; + + /** + * Check if the Sink is open. + * + * @return true if the Sink is open, false otherwise. + */ + virtual bool + isOpen ( void ) const throw () = 0; + + /** + * Check if the Sink is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the Sink is ready to accept data, false otherwise. + * @exception Exception + */ + virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) = 0; + + /** + * Write data to the Sink. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ) = 0; + + /** + * Flush all data that was written to the Sink to the underlying + * construct. + * + * @exception Exception + */ + virtual void + flush ( void ) throw ( Exception ) = 0; + + /** + * Close the Sink. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ) = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* SINK_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.4 2000/11/12 14:54:25 darkeye + added Exception to throws clause for the destructor and assignment operator + + Revision 1.3 2000/11/12 13:31:16 darkeye + minor change in documentation + + Revision 1.2 2000/11/11 12:33:13 darkeye + added kdoc-style documentation + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/SolarisDspSource.cpp b/darkice/tags/darkice-0_17_1/src/SolarisDspSource.cpp new file mode 100644 index 0000000..18d9c7a --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/SolarisDspSource.cpp @@ -0,0 +1,281 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : SolarisDspSource.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#include "SolarisDspSource.h" + +#ifdef SUPPORT_SOLARIS_DSP +// only compile this code if there is support for it + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#else +#error need sys/stat.h +#endif + +#ifdef HAVE_FCNTL_H +#include +#else +#error need fcntl.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#else +#error need sys/ioctl.h +#endif + +#if defined( HAVE_SYS_AUDIO_H ) +#include +#elif defined( HAVE_SYS_AUDIOIO_H ) +#include +#else +#error need sys/audio.h or sys/audioio.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "SolarisDspSource.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +SolarisDspSource :: init ( const char * name ) throw ( Exception ) +{ + fileName = Util::strDup( name); + fileDescriptor = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +SolarisDspSource :: strip ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] fileName; +} + +#include + +/*------------------------------------------------------------------------------ + * Open the audio source + *----------------------------------------------------------------------------*/ +bool +SolarisDspSource :: open ( void ) throw ( Exception ) +{ + audio_info_t audioInfo; + + if ( isOpen() ) { + return false; + } + + if ( (fileDescriptor = ::open( fileName, O_RDONLY)) == -1 ) { + fileDescriptor = 0; + return false; + } + + AUDIO_INITINFO( &audioInfo); + audioInfo.record.sample_rate = getSampleRate(); + audioInfo.record.channels = getChannel(); + audioInfo.record.precision = getBitsPerSample(); + audioInfo.record.encoding = AUDIO_ENCODING_LINEAR; + // for stupid OpenBSD we need to add the following, as it masks + // read/write calls when using -pthread + audioInfo.record.pause = 0; + + if ( ioctl( fileDescriptor, AUDIO_SETINFO, &audioInfo) == -1 ) { + + close(); + throw Exception( __FILE__, __LINE__, "ioctl error"); + } + + if ( audioInfo.record.channels != getChannel() ) { + close(); + throw Exception( __FILE__, __LINE__, + "can't set channels", audioInfo.record.channels); + } + + if ( audioInfo.record.precision != getBitsPerSample() ) { + close(); + throw Exception( __FILE__, __LINE__, + "can't set bits per sample", + audioInfo.record.precision); + } + + if ( audioInfo.record.sample_rate != getSampleRate() ) { + reportEvent( 2, "sound card recording sample rate set to ", + audioInfo.record.sample_rate, + " while trying to set it to ", getSampleRate()); + reportEvent( 2, "this is probably not a problem, but a slight " + "drift in the sound card driver"); + } + + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +SolarisDspSource :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( fileDescriptor, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( fileDescriptor + 1, &fdset, NULL, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the audio source + *----------------------------------------------------------------------------*/ +unsigned int +SolarisDspSource :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + ssize_t ret; + + if ( !isOpen() ) { + return 0; + } + + ret = ::read( fileDescriptor, buf, len); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "read error"); + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +SolarisDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + ::close( fileDescriptor); + fileDescriptor = 0; +} + +#endif // SUPPORT_SOLARIS_DSP + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2004/02/18 21:08:11 darkeye + ported to OpenBSD (real-time scheduling not yet supported) + + Revision 1.1 2001/09/11 15:05:21 darkeye + added Solaris support + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/SolarisDspSource.h b/darkice/tags/darkice-0_17_1/src/SolarisDspSource.h new file mode 100644 index 0000000..83b1e48 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/SolarisDspSource.h @@ -0,0 +1,281 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : SolarisDspSource.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef SOLARIS_DSP_SOURCE_H +#define SOLARIS_DSP_SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Reporter.h" +#include "AudioSource.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * An audio input based on Solaris /dev/audio devices + * + * @author $Author$ + * @version $Revision$ + */ +class SolarisDspSource : public AudioSource, public virtual Reporter +{ + private: + + /** + * The file name of the OSS DSP device (e.g. /dev/audio) + */ + char * fileName; + + /** + * The low-level file descriptor of the Solaris DSP device. + */ + int fileDescriptor; + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + SolarisDspSource ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Initialize the object + * + * @param name the file name of the Solaris DSP device. + * @exception Exception + */ + void + init ( const char * name ) throw ( Exception ); + + /** + * De-iitialize the object + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + public: + + /** + * Constructor. + * + * @param name the file name of the Solaris DSP device + * (e.g. /dev/audio or /dev/sound/0) + * @param sampleRate samples per second (e.g. 44100 for 44.1kHz). + * @param bitsPerSample bits per sample (e.g. 16 bits). + * @param channel number of channels of the audio source + * (e.g. 1 for mono, 2 for stereo, etc.). + * @exception Exception + */ + inline + SolarisDspSource ( const char * name, + int sampleRate = 44100, + int bitsPerSample = 16, + int channel = 2 ) + throw ( Exception ) + + : AudioSource( sampleRate, bitsPerSample, channel) + { + init( name); + } + + /** + * Copy Constructor. + * + * @param sds the object to copy. + * @exception Exception + */ + inline + SolarisDspSource ( const SolarisDspSource & sds ) + throw ( Exception ) + : AudioSource( sds ) + { + init( sds.fileName); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~SolarisDspSource ( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ds the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual SolarisDspSource & + operator= ( const SolarisDspSource & ds ) throw ( Exception ) + { + if ( this != &ds ) { + strip(); + AudioSource::operator=( ds); + init( ds.fileName); + } + return *this; + } + + /** + * Tell if the data from this source comes in big or little endian. + * + * @return true + */ + virtual inline bool + isBigEndian ( void ) const throw () + { +#ifdef WORDS_BIGENDIAN + return true; +#else + return false; +#endif + } + + /** + * Open the SolarisDspSource. + * This does not put the Solaris DSP device into recording mode. + * To start getting samples, call either canRead() or read(). + * + * @return true if opening was successful, false otherwise + * @exception Exception + * + * @see #canRead + * @see #read + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the SolarisDspSource is open. + * + * @return true if the SolarisDspSource is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return fileDescriptor != 0; + } + + /** + * Check if the SolarisDspSource can be read from. + * Blocks until the specified time for data to be available. + * Puts the Solaris DSP device into recording mode. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the SolarisDspSource is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the SolarisDspSource. + * Puts the Solaris DSP device into recording mode. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Close the SolarisDspSource. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* SOLARIS_DSP_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.5 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.4 2004/02/19 06:47:06 darkeye + finalized OpenBSD port + + Revision 1.3 2004/02/18 21:08:11 darkeye + ported to OpenBSD (real-time scheduling not yet supported) + + Revision 1.2 2001/09/18 14:57:19 darkeye + finalized Solaris port + + Revision 1.1 2001/09/11 15:05:21 darkeye + added Solaris support + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Source.h b/darkice/tags/darkice-0_17_1/src/Source.h new file mode 100644 index 0000000..a8cac63 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Source.h @@ -0,0 +1,186 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Source.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef SOURCE_H +#define SOURCE_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Referable.h" +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A general data source + * + * @author $Author$ + * @version $Revision$ + */ +class Source : public virtual Referable +{ + private: + + protected: + + /** + * Default Constructor. + * + * @exception Exception + */ + inline + Source ( void ) throw ( Exception ) + { + } + + /** + * Copy Constructor. + * + * @param source the object to copy. + * @exception Exception + */ + inline + Source ( const Source & source ) throw ( Exception ) + { + } + + /** + * Assignment operator. + * + * @param source the object to assign to this one. + * @return a reference to this object. + * @exception Exception + */ + inline virtual Source & + operator= ( const Source & source ) throw ( Exception ) + { + return *this; + } + + + public: + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~Source ( void ) throw ( Exception ) + { + } + + /** + * Open the Source. + * + * @return true if opening was successful, false otherwise + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ) = 0; + + /** + * Check if the Source is open. + * + * @return true if the Source is open, false otherwise. + */ + virtual bool + isOpen ( void ) const throw () = 0; + + /** + * Check if the Source can be read from. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the Source is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) = 0; + + /** + * Read from the Source. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ) = 0; + + /** + * Close the Source. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ) = 0; +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.2 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.1.1.1 2000/11/05 10:05:54 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/TcpSocket.cpp b/darkice/tags/darkice-0_17_1/src/TcpSocket.cpp new file mode 100644 index 0000000..d4c29db --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/TcpSocket.cpp @@ -0,0 +1,418 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : TcpSocket.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#else +#error need sys/types.h +#endif + +#ifdef HAVE_ERRNO_H +#include +#else +#error need errno.h +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#else +#error need sys/socket.h +#endif + +#ifdef HAVE_NETINET_IN_H +#include +#else +#error need netinet/in.h +#endif + +#ifdef HAVE_NETDB_H +#include +#else +#error need netdb.h +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#error need unistd.h +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#else +#error need sys/time.h +#endif + + +#include "Util.h" +#include "Exception.h" +#include "TcpSocket.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +TcpSocket :: init ( const char * host, + unsigned short port ) throw ( Exception ) +{ + this->host = Util::strDup( host); + this->port = port; + this->sockfd = 0; +} + + +/*------------------------------------------------------------------------------ + * De-initialize the object + *----------------------------------------------------------------------------*/ +void +TcpSocket :: strip ( void) throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + delete[] host; +} + + +/*------------------------------------------------------------------------------ + * Copy Constructor + *----------------------------------------------------------------------------*/ +TcpSocket :: TcpSocket ( const TcpSocket & ss ) throw ( Exception ) + : Source( ss), Sink( ss ) +{ + int fd; + + init( ss.host, ss.port); + + if ( (fd = ss.sockfd ? dup( ss.sockfd) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + sockfd = fd; +} + + +/*------------------------------------------------------------------------------ + * Assignment operator + *----------------------------------------------------------------------------*/ +TcpSocket & +TcpSocket :: operator= ( const TcpSocket & ss ) throw ( Exception ) +{ + if ( this != &ss ) { + int fd; + + /* first strip */ + strip(); + + + /* then build up */ + Sink::operator=( ss ); + Source::operator=( ss ); + + init( ss.host, ss.port); + + if ( (fd = ss.sockfd ? dup( ss.sockfd) : 0) == -1 ) { + strip(); + throw Exception( __FILE__, __LINE__, "dup failure"); + } + + sockfd = fd; + } + + return *this; +} + + +/*------------------------------------------------------------------------------ + * Open the file + *----------------------------------------------------------------------------*/ +bool +TcpSocket :: open ( void ) throw ( Exception ) +{ +#ifdef HAVE_ADDRINFO + struct addrinfo hints + struct addrinfo * ptr; + struct sockaddr_storage addr; + char portstr[6]; +#else + struct sockaddr_in addr; + struct hostent * pHostEntry; +#endif + + if ( isOpen() ) { + return false; + } + +#ifdef HAVE_ADDRINFO + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_ANY; + snprintf(portstr, sizeof(portstr), "%d", port); + + if (getaddrinfo(host , portstr, &hints, &ptr)) { + throw Exception( __FILE__, __LINE__, "getaddrinfo error", errno); + } + memcpy ( addr, ptr->ai_addr, ptr->ai_addrlen); + freeaddrinfo(ptr); +#else + if ( !(pHostEntry = gethostbyname( host)) ) { + throw Exception( __FILE__, __LINE__, "gethostbyname error", errno); + } + + if ( (sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1 ) { + throw Exception( __FILE__, __LINE__, "socket error", errno); + } + + memset( &addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = *((long*) pHostEntry->h_addr_list[0]); +#endif + if ( connect( sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1 ) { + ::close( sockfd); + sockfd = 0; + throw Exception( __FILE__, __LINE__, "connect error", errno); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +TcpSocket :: canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( sockfd, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( sockfd + 1, &fdset, NULL, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Read from the socket + *----------------------------------------------------------------------------*/ +unsigned int +TcpSocket :: read ( void * buf, + unsigned int len ) throw ( Exception ) +{ + int ret; + + if ( !isOpen() ) { + return 0; + } + + ret = recv( sockfd, buf, len, 0); + + if ( ret == -1 ) { + switch (errno) { + case ECONNRESET: + // re-open the socket if it has been reset by the peer + close(); + open(); + break; + + default: + throw Exception( __FILE__, __LINE__, "recv error", errno); + } + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Check wether read() would return anything + *----------------------------------------------------------------------------*/ +bool +TcpSocket :: canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) +{ + fd_set fdset; + struct timeval tv; + int ret; + + if ( !isOpen() ) { + return false; + } + + FD_ZERO( &fdset); + FD_SET( sockfd, &fdset); + tv.tv_sec = sec; + tv.tv_usec = usec; + + ret = select( sockfd + 1, NULL, &fdset, NULL, &tv); + + if ( ret == -1 ) { + throw Exception( __FILE__, __LINE__, "select error"); + } + + return ret > 0; +} + + +/*------------------------------------------------------------------------------ + * Write to the socket + *----------------------------------------------------------------------------*/ +unsigned int +TcpSocket :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + int ret; + + if ( !isOpen() ) { + return 0; + } + +#ifdef HAVE_MSG_NOSIGNAL + ret = send( sockfd, buf, len, MSG_NOSIGNAL); +#else + ret = send( sockfd, buf, len, 0); +#endif + + if ( ret == -1 ) { + if ( errno == EAGAIN ) { + ret = 0; + } else { + throw Exception( __FILE__, __LINE__, "send error", errno); + } + } + + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the socket + *----------------------------------------------------------------------------*/ +void +TcpSocket :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + flush(); + ::close( sockfd); + sockfd = 0; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.11 2006/05/19 12:39:19 darkeye + added reconnection capability if the TCP connection is reset by the peer + + Revision 1.10 2005/04/11 19:34:23 darkeye + added IPv6 support, thanks to + + Revision 1.9 2002/10/19 12:22:27 darkeye + cosmetic change + + Revision 1.8 2002/08/28 18:24:46 darkeye + ported to FreeBSD (removed reference to MSG_NOSIGNAL in TcpSocket.cpp) + + Revision 1.7 2002/07/20 16:37:06 darkeye + added fault tolerance in case a server connection is dropped + + Revision 1.6 2001/09/18 16:44:10 darkeye + TcpSocket did not report closed state when could not connect() + + Revision 1.5 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.4 2000/11/17 15:50:48 darkeye + added -Wall flag to compiler and eleminated new warnings + + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/TcpSocket.h b/darkice/tags/darkice-0_17_1/src/TcpSocket.h new file mode 100644 index 0000000..df8d4cb --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/TcpSocket.h @@ -0,0 +1,297 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : TcpSocket.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef TCP_SOCKET_H +#define TCP_SOCKET_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Source.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A TCP network socket + * + * @author $Author$ + * @version $Revision$ + */ +class TcpSocket : public Source, public Sink +{ + private: + + /** + * Name of the host this socket connects to. + */ + char * host; + + /** + * Port to connect to. + */ + unsigned short port; + + /** + * Low-level socket descriptor. + */ + int sockfd; + + /** + * Initialize the object. + * + * @param host name of the host this socket connects to. + * @param port port to connect to. + * @exception Exception + */ + void + init ( const char * host, + unsigned short port ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + void + strip ( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + TcpSocket ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param host name of the host this socket connects to. + * @param port port to connect to. + * @exception Exception + */ + inline + TcpSocket( const char * host, + unsigned short port ) throw ( Exception ) + { + init( host, port); + } + + /** + * Copy constructor. + * + * @param ss the TcpSocket to copy. + * @exception Exception + */ + TcpSocket( const TcpSocket & ss ) throw ( Exception ); + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~TcpSocket( void ) throw ( Exception ) + { + strip(); + } + + /** + * Assignment operator. + * + * @param ss the TcpSocket to assign this to. + * @return a reference to this TcpSocket. + * @exception Exception + */ + inline virtual TcpSocket & + operator= ( const TcpSocket & ss ) throw ( Exception ); + + /** + * Get the host this socket connects to. + * + * @return the host this socket connects to. + */ + inline const char * + getHost ( void ) const throw () + { + return host; + } + + /** + * Get the port this socket connects to. + * + * @return the port this socket connects to. + */ + inline unsigned int + getPort ( void ) const throw () + { + return port; + } + + /** + * Open the TcpSocket. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the TcpSocket is open. + * + * @return true if the TcpSocket is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return sockfd != 0; + } + + /** + * Check if the TcpScoket can be read from. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the TcpSocket is ready to be read from, + * false otherwise. + * @exception Exception + */ + virtual bool + canRead ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Read from the TcpSocket. + * + * @param buf the buffer to read into. + * @param len the number of bytes to read into buf + * @return the number of bytes read (may be less than len). + * @exception Exception + */ + virtual unsigned int + read ( void * buf, + unsigned int len ) throw ( Exception ); + + + /** + * Check if the TcpSocket is ready to accept data. + * Blocks until the specified time for data to be available. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the TcpSocket is ready to accept data, + * false otherwise. + * @exception Exception + */ + virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ); + + /** + * Write data to the TcpSocket. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the TcpSocket to the underlying + * connection. + * + * @exception Exception + */ + inline virtual void + flush ( void ) throw ( Exception ) + { + } + + /** + * Close the TcpSocket. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* TCP_SOCKET_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.3 2000/11/12 14:54:50 darkeye + added kdoc-style documentation comments + + Revision 1.2 2000/11/05 17:37:24 darkeye + removed clone() functions + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.cpp b/darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.cpp new file mode 100644 index 0000000..1e1ced2 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.cpp @@ -0,0 +1,317 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : TwoLameLibEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// compile the whole file only if TwoLame support configured in +#ifdef HAVE_TWOLAME_LIB + + + +#include "Exception.h" +#include "Util.h" +#include "TwoLameLibEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + + + +/*------------------------------------------------------------------------------ + * Initialize the object + *----------------------------------------------------------------------------*/ +void +TwoLameLibEncoder :: init ( Sink * sink ) throw ( Exception ) +{ + this->twolame_opts = NULL; + this->sink = sink; + + if ( getInBitsPerSample() != 16 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getInChannel() != 1 && getInChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of input channels for the encoder", + getInChannel() ); + } + if ( getOutChannel() != 1 && getOutChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of output channels for the encoder", + getOutChannel() ); + } + if ( getInChannel() < getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "output channels greater then input channels", + getOutChannel() ); + } +} + + +/*------------------------------------------------------------------------------ + * Open an encoding session + *----------------------------------------------------------------------------*/ +bool +TwoLameLibEncoder :: open ( void ) + throw ( Exception ) +{ + if ( isOpen() ) { + close(); + } + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib opening underlying sink error"); + } + + twolame_opts = ::twolame_init(); + + // ugly twolame returns -1 in a pointer on allocation errors + if ( !twolame_opts ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib init error", + (int) twolame_opts); + } + + if ( 0 > twolame_set_num_channels( twolame_opts, getInChannel()) ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib setting channels error", + getInChannel() ); + } + + if ( 0 > twolame_set_mode( twolame_opts, + getOutChannel() == 1 ? TWOLAME_MONO : TWOLAME_JOINT_STEREO) ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib setting mode error", + TWOLAME_JOINT_STEREO ); + } + + if ( 0 > twolame_set_in_samplerate( twolame_opts, getInSampleRate()) ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib setting input sample rate error", + getInSampleRate() ); + } + + if ( 0 > twolame_set_out_samplerate( twolame_opts, getOutSampleRate()) ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib setting output sample rate error", + getOutSampleRate() ); + } + + switch ( getOutBitrateMode() ) { + + case cbr: { + + if ( 0 > twolame_set_brate( twolame_opts, getOutBitrate()) ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib setting output bit rate error", + getOutBitrate() ); + } + } break; + + default: { + throw Exception( __FILE__, __LINE__, + "Unsupported bitrate mode." ); + } + } + + + // let TwoLAME init its own params based on our settings + if ( 0 > twolame_init_params( twolame_opts) ) { + throw Exception( __FILE__, __LINE__, + "TwoLAME lib initializing params error" ); + } + + // Information about TwoLame's setup + if (getReportVerbosity() >= 3) { + twolame_print_config( twolame_opts); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Write data to the encoder + *----------------------------------------------------------------------------*/ +unsigned int +TwoLameLibEncoder :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + if ( !isOpen() || len == 0 ) { + return 0; + } + + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int inChannels = getInChannel(); + + unsigned int sampleSize = (bitsPerSample / 8) * inChannels; + unsigned char * b = (unsigned char*) buf; + unsigned int processed = len - (len % sampleSize); + unsigned int nSamples = processed / sampleSize; + short int * leftBuffer = new short int[nSamples]; + short int * rightBuffer = new short int[nSamples]; + + if ( bitsPerSample == 8 ) { + Util::conv8( b, processed, leftBuffer, rightBuffer, inChannels); + } else if ( bitsPerSample == 16 ) { + Util::conv16( b, + processed, + leftBuffer, + rightBuffer, + inChannels, + isInBigEndian()); + } else { + delete[] leftBuffer; + delete[] rightBuffer; + throw Exception( __FILE__, __LINE__, + "unsupported number of bits per sample for the encoder", + bitsPerSample ); + } + + // data chunk size estimate according to TwoLAME documentation + // NOTE: mp2Size is calculated based on the number of input channels + // which may be bigger than need, as output channels can be less + unsigned int mp2Size = (unsigned int) (1.25 * nSamples + 7200); + unsigned char * mp2Buf = new unsigned char[mp2Size]; + int ret; + + ret = twolame_encode_buffer( twolame_opts, + leftBuffer, + inChannels == 2 ? rightBuffer : leftBuffer, + nSamples, + mp2Buf, + mp2Size ); + + delete[] leftBuffer; + delete[] rightBuffer; + + if ( ret < 0 ) { + reportEvent( 3, "TwoLAME encoding error", ret); + delete[] mp2Buf; + return 0; + } + + unsigned int written = sink->write( mp2Buf, ret); + delete[] mp2Buf; + // just let go data that could not be written + if ( written < (unsigned int) ret ) { + reportEvent( 2, + "couldn't write all from encoder to underlying sink", + ret - written); + } + + return processed; +} + + +/*------------------------------------------------------------------------------ + * Flush the data from the encoder + *----------------------------------------------------------------------------*/ +void +TwoLameLibEncoder :: flush ( void ) + throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + // data chunk size estimate according to TwoLAME documentation + unsigned int mp2Size = 7200; + unsigned char * mp2Buf = new unsigned char[mp2Size]; + int ret; + + ret = twolame_encode_flush( twolame_opts, mp2Buf, mp2Size ); + + unsigned int written = sink->write( mp2Buf, ret); + delete[] mp2Buf; + + // just let go data that could not be written + if ( written < (unsigned int) ret ) { + reportEvent( 2, + "couldn't write all from encoder to underlying sink", + ret - written); + } + + sink->flush(); +} + + +/*------------------------------------------------------------------------------ + * Close the encoding session + *----------------------------------------------------------------------------*/ +void +TwoLameLibEncoder :: close ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + flush(); + twolame_close( &twolame_opts ); + sink->close(); + } +} + + +#endif // HAVE_TWOLAME_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2006/01/25 22:49:59 darkeye + added mpeg2 support thanks to Nicholas J Humfrey + + + Revision 1.1 2005/05/02 23:05:02 nhumfrey + initial version - based on LameLibEncoder 1.19 + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.h b/darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.h new file mode 100644 index 0000000..0e519e1 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/TwoLameLibEncoder.h @@ -0,0 +1,385 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2005 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : TwoLameLibEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef TWOLAME_LIB_ENCODER_H +#define TWOLAME_LIB_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_TWOLAME_LIB +#include +#else +#error configure with twolame +#endif + + +#include "Ref.h" +#include "Exception.h" +#include "Reporter.h" +#include "AudioEncoder.h" +#include "Sink.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing the TwoLame encoder linked as a shared object or as + * a static library. + * + * @author $Author$ + * @version $Revision$ + */ +class TwoLameLibEncoder : public AudioEncoder, public virtual Reporter +{ + private: + + /** + * TwoLame library global flags + */ + twolame_options * twolame_opts; + + /** + * The Sink to dump mp2 data to + */ + Ref sink; + + /** + * Initialize the object. + * + * @param sink the sink to send mp2 output to + * @exception Exception + */ + void + init ( Sink * sink ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + TwoLameLibEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param sink the sink to send mp2 output to + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @exception Exception + */ + inline + TwoLameLibEncoder ( Sink * sink, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + + : AudioEncoder ( inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + 0.0f, // outQuality + outSampleRate, + outChannel ) + { + init( sink ); + } + + /** + * Constructor. + * + * @param sink the sink to send mp2 output to + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @exception Exception + */ + inline + TwoLameLibEncoder ( Sink * sink, + const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + + : AudioEncoder ( as, + outBitrateMode, + outBitrate, + 0.0f, // outQuality + outSampleRate, + outChannel ) + { + init( sink ); + } + + /** + * Copy constructor. + * + * @param encoder the TwoLameLibEncoder to copy. + */ + inline + TwoLameLibEncoder ( const TwoLameLibEncoder & encoder ) + throw ( Exception ) + : AudioEncoder( encoder ) + { + init( encoder.sink.get() ); + } + + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~TwoLameLibEncoder ( void ) throw ( Exception ) + { + if ( isOpen() ) { + close(); + } + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the TwoLameLibEncoder to assign this to. + * @return a reference to this TwoLameLibEncoder. + * @exception Exception + */ + inline virtual TwoLameLibEncoder & + operator= ( const TwoLameLibEncoder & encoder ) throw ( Exception ) + { + if ( this != &encoder ) { + strip(); + AudioEncoder::operator=( encoder); + init( encoder.sink.get() ); + } + + return *this; + } + + /** + * Get the version string of the underlying lame library. + * + * @return the version string of the underlying lame library. + */ + inline const char * + getLameVersion( void ) + { + return get_twolame_version(); + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + inline virtual bool + isRunning ( void ) const throw () + { + return isOpen(); + } + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started in the background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + inline virtual bool + start ( void ) throw ( Exception ) + { + return open(); + } + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + inline virtual void + stop ( void ) throw ( Exception ) + { + return close(); + } + + /** + * Open an encoding session. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the encoding session is open. + * + * @return true if the encoding session is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return twolame_opts != 0; + } + + /** + * Check if the encoder is ready to accept data. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the encoder is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + if ( !isOpen() ) { + return false; + } + + return true; + } + + /** + * Write data to the encoder. + * Buf is expected to be a sequence of big-endian 16 bit values, + * with left and right channels interleaved. Len is the number of + * bytes, must be a multiple of 4. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the encoder to the underlying + * connection. + * + * @exception Exception + */ + virtual void + flush ( void ) throw ( Exception ); + + /** + * Close the encoding session. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + +#endif /* TWOLAME_LIB_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2006/01/25 22:49:59 darkeye + added mpeg2 support thanks to Nicholas J Humfrey + + + Revision 1.1 2005/05/02 23:05:02 nhumfrey + initial version - based on LameLibEncoder 1.19 + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Util.cpp b/darkice/tags/darkice-0_17_1/src/Util.cpp new file mode 100644 index 0000000..2072869 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Util.cpp @@ -0,0 +1,538 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Util.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STRING_H +#include +#else +#error need string.h +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error need stdlib.h +#endif + +#ifdef HAVE_LIMITS_H +#include +#else +#error need limits.h +#endif + +#ifdef HAVE_MATH_H +#include +#else +#error need math.h +#endif + +#ifdef HAVE_TIME_H +#include +#else +#error need time.h +#endif + + +#include "Util.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +char +Util :: base64Table[] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' +}; + + +/*------------------------------------------------------------------------------ + * Calculate the length of a zero-terminated C string, + * w/o the zero-termination + *----------------------------------------------------------------------------*/ +unsigned int +Util :: strLen( const char * str ) throw ( Exception ) +{ + size_t len; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + len = strlen( str); + + return len; +} + + +/*------------------------------------------------------------------------------ + * Copy the contents of a string into another + *----------------------------------------------------------------------------*/ +void +Util :: strCpy ( char * dest, + const char * src ) throw ( Exception ) +{ + if ( !dest || !src ) { + throw Exception( __FILE__, __LINE__, "no src or dest"); + } + + strcpy( dest, src); +} + + +/*------------------------------------------------------------------------------ + * Concatenate the contents of a string onto another + *----------------------------------------------------------------------------*/ +void +Util :: strCat ( char * dest, + const char * src ) throw ( Exception ) +{ + if ( !dest || !src ) { + throw Exception( __FILE__, __LINE__, "no src or dest"); + } + + strcat( dest, src); +} + + +/*------------------------------------------------------------------------------ + * Duplicate a string by allocating space with new[] + * The returned string must be freed with delete[] + *----------------------------------------------------------------------------*/ +char * +Util :: strDup( const char * str ) throw ( Exception ) +{ + size_t len; + char * s; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + len = strlen( str) + 1; + s = new char[len]; + memcpy( s, str, len); + + return s; +} + + +/*------------------------------------------------------------------------------ + * Convert a string into base64 encoding. + *----------------------------------------------------------------------------*/ +char * +Util :: base64Encode( const char * str ) throw ( Exception ) +{ + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + const char * data = str; + size_t len = strlen( data); + char * out = new char[len * 4 / 3 + 4]; + char * result = out; + unsigned chunk; + + while ( len > 0 ) { + chunk = (len > 3) ? 3 : len; + *out++ = base64Table[(*data & 0xfc) >> 2]; + *out++ = base64Table[((*data & 0x03) << 4) | ((*(data+1) & 0xf0) >> 4)]; + switch ( chunk ) { + case 3: + *out++ = base64Table[((*(data+1) & 0x0f) << 2) | + ((*(data+2) & 0xc0) >> 6)]; + *out++ = base64Table[(*(data+2)) & 0x3f]; + break; + case 2: + *out++ = base64Table[((*(data+1) & 0x0f) << 2)]; + *out++ = '='; + break; + case 1: + *out++ = '='; + *out++ = '='; + break; + } + data += chunk; + len -= chunk; + } + *out = 0; + + return result; +} + + +/*------------------------------------------------------------------------------ + * Check wether two strings are equal + *----------------------------------------------------------------------------*/ +bool +Util :: strEq( const char * str1, + const char * str2, + unsigned int len ) throw ( Exception ) +{ + if ( !str1 || !str2 ) { + throw Exception( __FILE__, __LINE__, "no str1 or no str2"); + } + + return len == 0 ? !strcmp( str1, str2) : !strncmp( str1, str2, len); +} + + +/*------------------------------------------------------------------------------ + * Convert a string to a long integer + *----------------------------------------------------------------------------*/ +long int +Util :: strToL( const char * str, + int base ) throw ( Exception ) +{ + long int val; + char * s; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + val = strtol( str, &s, base); + if ( s == str || val == LONG_MIN || val == LONG_MAX ) { + throw Exception( __FILE__, __LINE__, "number conversion error"); + } + + return val; +} + + +/*------------------------------------------------------------------------------ + * Convert a string to a double + *----------------------------------------------------------------------------*/ +double +Util :: strToD( const char * str ) throw ( Exception ) +{ + double val; + char * s; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + val = strtod( str, &s); + if ( s == str || val == HUGE_VAL ) { + throw Exception( __FILE__, __LINE__, "number conversion error"); + } + + return val; +} + +/*------------------------------------------------------------------------------ + * add current date to a file name, before the file extension (if any) + *----------------------------------------------------------------------------*/ +char * +Util :: fileAddDate ( const char * str ) throw ( Exception ) +{ + unsigned int size; + char * s; + char * strdate; + char * last; + time_t now; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + strdate = new char[128]; + now = time(NULL); + strftime( strdate, 128, "[%m-%d-%Y-%H-%M-%S]", localtime (&now)); + + // search for the part before the extension of the file name + if ( !(last = strrchr( str, '.')) ) { + last = (char *) str + strlen( str); + } + + size = strlen( str) + strlen( strdate) + 1; + s = new char [size]; + + memcpy( s, str, strlen (str)-strlen(last)); + memcpy( s + strlen(str) - strlen(last), strdate, strlen (strdate)); + memcpy( s + strlen(str) - strlen(last) + strlen(strdate), + last, + strlen(last)); + s[size-1] = '\0'; + + delete[] strdate; + return s; +} + +/*------------------------------------------------------------------------------ + * Convert an unsigned char buffer holding 8 or 16 bit PCM values with + * channels interleaved to a short int buffer, still with channels interleaved + *----------------------------------------------------------------------------*/ +void +Util :: conv ( unsigned int bitsPerSample, + unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * outBuffer, + bool isBigEndian ) throw ( Exception ) +{ + if ( bitsPerSample == 8 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + outBuffer[j] = pcmBuffer[i++]; + ++j; + } + } else if ( bitsPerSample == 16 ) { + + if ( isBigEndian ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + short int value; + + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + outBuffer[j] = value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + short int value; + + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + outBuffer[j] = value; + ++j; + } + } + } else { + throw Exception( __FILE__, __LINE__, + "this number of bits per sample not supported", + bitsPerSample); + } +} + + +/*------------------------------------------------------------------------------ + * Convert a short buffer holding PCM values with channels interleaved + * to one or more float buffers, one for each channel + *----------------------------------------------------------------------------*/ +void +Util :: conv ( short int * shortBuffer, + unsigned int lenShortBuffer, + float ** floatBuffers, + unsigned int channels ) throw ( Exception ) +{ + unsigned int i, j; + + for ( i = 0, j = 0; i < lenShortBuffer; ) { + for ( unsigned int c = 0; c < channels; ++c ) { + floatBuffers[c][j] = ((float) shortBuffer[i++]) / 32768.f; + } + ++j; + } +} + + +/*------------------------------------------------------------------------------ + * Convert an unsigned char buffer holding 8 bit PCM values with channels + * interleaved to two short int buffers (one for each channel) + *----------------------------------------------------------------------------*/ +void +Util :: conv8 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels ) throw ( Exception ) +{ + if ( channels == 1 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + ++j; + } + } else if ( channels == 2 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + value = pcmBuffer[i++]; + rightBuffer[j] = (short int) value; + ++j; + } + } else { + throw Exception( __FILE__, __LINE__, + "this number of channels not supported", channels); + } +} + + +/*------------------------------------------------------------------------------ + * Convert an unsigned char buffer holding 16 bit PCM values with channels + * interleaved to two short int buffers (one for each channel) + *----------------------------------------------------------------------------*/ +void +Util :: conv16 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels, + bool isBigEndian ) throw ( Exception ) +{ + if ( isBigEndian ) { + if ( channels == 1 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + rightBuffer[j] = (short int) value; + ++j; + } + } + } else { + if ( channels == 1 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + leftBuffer[j] = (short int) value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + leftBuffer[j] = (short int) value; + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + rightBuffer[j] = (short int) value; + ++j; + } + } + } +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.13 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + + Revision 1.12 2003/02/09 12:57:36 darkeye + cosmetic changes to the fileAddDate option + + Revision 1.11 2002/12/22 01:20:32 darkeye + time.h include file was missing + + Revision 1.10 2002/11/20 16:52:07 wandereq + added fileAddDate function + + Revision 1.9 2002/08/20 18:39:14 darkeye + added HTTP Basic authentication for icecast2 logins + + Revision 1.8 2002/07/21 08:47:06 darkeye + some exception cleanup (throw clauses in function declarations) + + Revision 1.7 2002/03/28 16:45:46 darkeye + added functions strToD(), conv8(), conv16() and conv() + + Revision 1.6 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.5 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.4 2000/11/09 22:04:33 darkeye + added functions strLen strCpy and strCat + + Revision 1.3 2000/11/09 06:44:21 darkeye + added strEq and strToL functions + + Revision 1.2 2000/11/05 14:08:28 darkeye + changed builting to an automake / autoconf environment + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/Util.h b/darkice/tags/darkice-0_17_1/src/Util.h new file mode 100644 index 0000000..e6f46bc --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/Util.h @@ -0,0 +1,360 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : Util.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef UTIL_H +#define UTIL_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#include "Exception.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Widely used utilities. + * This class can not be instantiated, but contains useful (?) static + * functions. + * + * Typical usage: + * + *
+ *  #include "Util.h"
+ *  
+ *  char  * str = Util::strDup( otherStr);
+ *  
+ * + * @author $Author$ + * @version $Revision$ + */ +class Util +{ + private: + + /** + * Helper table for base64 encoding. + */ + static char base64Table[]; + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Util ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Copy constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Util ( const Util & e ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Destructor. Always throws an Exception. + * + * @exception Exception + */ + inline + ~Util ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + /** + * Assignment operator. Always throws an Exception. + * + * @param u the object to assign to this one. + * @exception Exception + */ + inline Util & + operator= ( const Util & u ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + + public: + + /** + * Determine a C string's length. + * + * @param str a zero-terminated C string. + * @return length of str + * @exception Exception + */ + static unsigned int + strLen ( const char * str ) throw ( Exception ); + + /** + * Copy a C string into another. + * + * @param dest place for the copy. Storage size must be at least + * Util::strLen(src) + 1 long. + * @param src the string to copy. + * @exception Exception + */ + static void + strCpy ( char * dest, + const char * src ) throw ( Exception ); + + /** + * Concatenate a string to another's end. + * + * @param dest the string to concatenate to. + * Storage size of dest must be at least + * Util::strLen(dest) + Util::strLen(src) + 1 long. + * @param src the string to concatenate. + * @exception Exception + */ + static void + strCat ( char * dest, + const char * src ) throw ( Exception ); + + /** + * Duplicate a string by allocating space with new[]. + * The returned string must be freed with delete[]. + * + * @param str the string to duplicate. + * @exception Exception + */ + static char * + strDup ( const char * str ) throw ( Exception ); + + /** + * Determine wether two string are equal. + * + * @param str1 one of the strings. + * @param str2 the other string. + * @param len check the first most len characters. if 0, check + * the whole string + * @return true if the two strings are equal, false othersize. + * @exception Exception + */ + static bool + strEq ( const char * str1, + const char * str2, + unsigned int len = 0 ) throw ( Exception ); + + /** + * Convert a string to long. + * + * @param str the string to convert. + * @param base numeric base of number in str. + * @return the value of str as a long int + * @exception Exception + */ + static long int + strToL ( const char * str, + int base = 10 ) throw ( Exception ); + + /** + * Convert a string to double. + * + * @param str the string to convert. + * @return the value of str as a double + * @exception Exception + */ + static double + strToD ( const char * str ) throw ( Exception ); + + /** + * Add current date to a file name, before the file extension (if any) + * + * @param str the string to convert (file name). + * @return the new string with the date appended before + * extension of the file name. the string has to be + * deleted with delete[] after it is not needed + * @exception Exception + */ + static char * + fileAddDate ( const char * str ) throw ( Exception ); + + /** + * Convert a string into base64 encoding. + * base64 is described in RFC 2045, section 6.8 + * The returned string must be freed with delete[]. + * + * @param str the string to convert. + * @return the supplied string in base64 encoding. + * @exception Exception + */ + static char * + base64Encode ( const char * str ) throw ( Exception ); + + /** + * Convert an unsigned char buffer holding 8 or 16 bit PCM values + * with channels interleaved to a short int buffer, still + * with channels interleaved. + * + * @param bitsPerSample the number of bits per sample in the input + * @param pcmBuffer the input buffer + * @param lenPcmBuffer the number of samples total in pcmBuffer + * (e.g. if 2 channel input, this is twice the + * number of sound samples) + * @param outBuffer the output buffer, must be big enough + * @param isBigEndian true if the input is big endian, false otherwise + */ + static void + conv ( unsigned int bitsPerSample, + unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * outBuffer, + bool isBigEndian = true ) throw ( Exception ); + + + /** + * Convert a short buffer holding PCM values with channels interleaved + * to one or more float buffers, one for each channel + * + * @param shortBuffer the input buffer + * @param lenShortBuffer total length of the input buffer + * @param floatBuffers an array of float buffers, each + * (lenShortBuffer / channels) long + * @param channels number of channels to separate the input to + */ + static void + conv ( short int * shortBuffer, + unsigned int lenShortBuffer, + float ** floatBuffers, + unsigned int channels ) throw ( Exception ); + + /** + * Convert a char buffer holding 8 bit PCM values to a short buffer + * + * @param pcmBuffer buffer holding 8 bit PCM audio values, + * channels are interleaved + * @param lenPcmBuffer length of pcmBuffer + * @param leftBuffer put the left channel here (must be big enough) + * @param rightBuffer put the right channel here (not touched if mono, + * must be big enough) + * @param channels number of channels (1 = mono, 2 = stereo) + */ + static void + conv8 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels ) throw ( Exception ); + + /** + * Convert a char buffer holding 16 bit PCM values to a short buffer + * + * @param pcmBuffer buffer holding 16 bit PCM audio values, + * channels are interleaved + * @param lenPcmBuffer length of pcmBuffer + * @param leftBuffer put the left channel here (must be big enough) + * @param rightBuffer put the right channel here (not touched if mono, + * must be big enough) + * @param channels number of channels (1 = mono, 2 = stereo) + * @param isBigEndian true if input is big endian, false otherwise + */ + static void + conv16 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels, + bool isBigEndian ) throw ( Exception ); + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* UTIL_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.11 2005/04/14 11:53:17 darkeye + fixed API documentation issues + + Revision 1.10 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + + Revision 1.9 2003/02/09 12:57:36 darkeye + cosmetic changes to the fileAddDate option + + Revision 1.8 2002/11/20 16:52:08 wandereq + added fileAddDate function + + Revision 1.7 2002/08/20 18:39:14 darkeye + added HTTP Basic authentication for icecast2 logins + + Revision 1.6 2002/07/21 08:47:06 darkeye + some exception cleanup (throw clauses in function declarations) + + Revision 1.5 2002/03/28 16:45:46 darkeye + added functions strToD(), conv8(), conv16() and conv() + + Revision 1.4 2000/11/12 13:31:40 darkeye + added kdoc-style documentation comments + + Revision 1.3 2000/11/09 22:04:33 darkeye + added functions strLen strCpy and strCat + + Revision 1.2 2000/11/09 06:44:21 darkeye + added strEq and strToL functions + + Revision 1.1.1.1 2000/11/05 10:05:55 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.cpp b/darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.cpp new file mode 100644 index 0000000..373f949 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.cpp @@ -0,0 +1,494 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : VorbisLibEncoder.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// compile only if configured for Ogg Vorbis +#ifdef HAVE_VORBIS_LIB + + +#include "Exception.h" +#include "Util.h" +#include "VorbisLibEncoder.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Initialize the encoder + *----------------------------------------------------------------------------*/ +void +VorbisLibEncoder :: init ( CastSink * sink, + unsigned int outMaxBitrate ) + throw ( Exception ) +{ + this->sink = sink; + this->outMaxBitrate = outMaxBitrate; + + if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getInChannel() != 1 && getInChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of channels for the encoder", + getInChannel() ); + } + + if ( getOutSampleRate() == getInSampleRate() ) { + resampleRatio = 1; + converter = 0; + } else { + resampleRatio = ( (double) getOutSampleRate() / + (double) getInSampleRate() ); + + // Determine if we can use linear interpolation. + // The inverse of the ratio must be a power of two for linear mode to + // be of sufficient quality. + + bool useLinear = true; + double inverse = 1 / resampleRatio; + int integer = (int) inverse; + + // Check that the inverse of the ratio is an integer + if( integer == inverse ) { + while( useLinear && integer ) { // Loop through the bits + // If the lowest order bit is not the only one set + if( integer & 1 && integer != 1 ) { + // Not a power of two; cannot use linear + useLinear = false; + } else { + // Shift all the bits over and try again + integer >>= 1; + } + } + } else { + useLinear = false; + } + + // If we get here and useLinear is still true, then we have + // a power of two. + + // open the aflibConverter in + // - high quality + // - linear or quadratic (non-linear) based on algorithm + // - not filter interpolation + converter = new aflibConverter( true, useLinear, false); + } + + encoderOpen = false; +} + + +/*------------------------------------------------------------------------------ + * Open an encoding session + *----------------------------------------------------------------------------*/ +bool +VorbisLibEncoder :: open ( void ) + throw ( Exception ) +{ + int ret; + + if ( isOpen() ) { + close(); + } + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "vorbis lib opening underlying sink error"); + } + + vorbis_info_init( &vorbisInfo); + + switch ( getOutBitrateMode() ) { + + case cbr: { + int maxBitrate = getOutMaxBitrate() * 1000; + if ( !maxBitrate ) { + maxBitrate = -1; + } + if ( (ret = vorbis_encode_init( &vorbisInfo, + getOutChannel(), + getOutSampleRate(), + maxBitrate, + getOutBitrate() * 1000, + -1)) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + } break; + + case abr: + /* set non-managed VBR around the average bitrate */ + ret = vorbis_encode_setup_managed( &vorbisInfo, + getOutChannel(), + getOutSampleRate(), + -1, + getOutBitrate() * 1000, + -1 ) + || vorbis_encode_ctl( &vorbisInfo, OV_ECTL_RATEMANAGE_SET, NULL) + || vorbis_encode_setup_init( &vorbisInfo); + if ( ret ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + break; + + case vbr: + if ( (ret = vorbis_encode_init_vbr( &vorbisInfo, + getOutChannel(), + getOutSampleRate(), + getOutQuality() )) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + break; + } + + if ( (ret = vorbis_analysis_init( &vorbisDspState, &vorbisInfo)) ) { + throw Exception( __FILE__, __LINE__, "vorbis analysis init error", ret); + } + + if ( (ret = vorbis_block_init( &vorbisDspState, &vorbisBlock)) ) { + throw Exception( __FILE__, __LINE__, "vorbis block init error", ret); + } + + if ( (ret = ogg_stream_init( &oggStreamState, 0)) ) { + throw Exception( __FILE__, __LINE__, "ogg stream init error", ret); + } + + // create an empty vorbis_comment structure + vorbis_comment_init( &vorbisComment); + // Add comment to vorbis headers to show title in players + // stupid cast to (char*) because of stupid vorbis API + if ( sink->getName() ) { + vorbis_comment_add_tag(&vorbisComment, "TITLE", (char*)sink->getName()); + } + + // create the vorbis stream headers and send them to the underlying sink + ogg_packet header; + ogg_packet commentHeader; + ogg_packet codeHeader; + + if ( (ret = vorbis_analysis_headerout( &vorbisDspState, + &vorbisComment, + &header, + &commentHeader, + &codeHeader )) ) { + throw Exception( __FILE__, __LINE__, "vorbis header init error", ret); + } + + ogg_stream_packetin( &oggStreamState, &header); + ogg_stream_packetin( &oggStreamState, &commentHeader); + ogg_stream_packetin( &oggStreamState, &codeHeader); + + ogg_page oggPage; + while ( ogg_stream_flush( &oggStreamState, &oggPage) ) { + sink->write( oggPage.header, oggPage.header_len); + sink->write( oggPage.body, oggPage.body_len); + } + + vorbis_comment_clear( &vorbisComment ); + + // initialize the resampling coverter if needed + if ( converter ) { + converter->initialize( resampleRatio, getInChannel()); + } + + encoderOpen = true; + + return true; +} + + +/*------------------------------------------------------------------------------ + * Write data to the encoder + *----------------------------------------------------------------------------*/ +unsigned int +VorbisLibEncoder :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + if ( !isOpen() || len == 0 ) { + return 0; + } + + unsigned int channels = getInChannel(); + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int sampleSize = (bitsPerSample / 8) * channels; + + unsigned int i; + + if ( getInChannel() == 2 && getOutChannel() == 1 ) { + for ( i = 0; i < len/sampleSize; i++) { + if ( bitsPerSample == 8 ) { + char * buf8 = (char *) buf; + unsigned int ix = sampleSize * i; + buf8[i] = (buf8[ix] + buf8[++ix]) / 2; + } + if ( bitsPerSample == 16 ) { + short * buf16 = (short *) buf; + unsigned int ix = (bitsPerSample >> 3) * i; + buf16[i] = (buf16[ix] + buf16[++ix]) / 2; + } + } + len >>= 1; + channels = 1; + } + + sampleSize = (bitsPerSample / 8) * channels; + unsigned char * b = (unsigned char*) buf; + unsigned int processed = len - (len % sampleSize); + unsigned int nSamples = processed / sampleSize; + float ** vorbisBuffer; + + + // convert the byte-based raw input into a short buffer + // with channels still interleaved + unsigned int totalSamples = nSamples * channels; + short int * shortBuffer = new short int[totalSamples]; + + + Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); + + if ( converter ) { + // resample if needed + int inCount = nSamples; + int outCount = (int) (inCount * resampleRatio); + short int * resampledBuffer = new short int[outCount * channels]; + int converted; + + converted = converter->resample( inCount, + outCount, + shortBuffer, + resampledBuffer ); + + vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState, + converted); + Util::conv( resampledBuffer, + converted * channels, + vorbisBuffer, + channels); + delete[] resampledBuffer; + + vorbis_analysis_wrote( &vorbisDspState, converted); + + } else { + + vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState, nSamples); + Util::conv( shortBuffer, totalSamples, vorbisBuffer, channels); + vorbis_analysis_wrote( &vorbisDspState, nSamples); + } + + delete[] shortBuffer; + vorbisBlocksOut(); + + return processed; +} + + +/*------------------------------------------------------------------------------ + * Flush the data from the encoder + *----------------------------------------------------------------------------*/ +void +VorbisLibEncoder :: flush ( void ) + throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + vorbis_analysis_wrote( &vorbisDspState, 0); + vorbisBlocksOut(); + sink->flush(); +} + + +/*------------------------------------------------------------------------------ + * Send pending Vorbis blocks to the underlying stream + *----------------------------------------------------------------------------*/ +void +VorbisLibEncoder :: vorbisBlocksOut ( void ) throw ( Exception ) +{ + while ( 1 == vorbis_analysis_blockout( &vorbisDspState, &vorbisBlock) ) { + ogg_packet oggPacket; + ogg_page oggPage; + + vorbis_analysis( &vorbisBlock, &oggPacket); + vorbis_bitrate_addblock( &vorbisBlock); + + while ( vorbis_bitrate_flushpacket( &vorbisDspState, &oggPacket) ) { + + ogg_stream_packetin( &oggStreamState, &oggPacket); + + while ( ogg_stream_pageout( &oggStreamState, &oggPage) ) { + int written; + + written = sink->write( oggPage.header, oggPage.header_len); + written += sink->write( oggPage.body, oggPage.body_len); + + if ( written < oggPage.header_len + oggPage.body_len ) { + // just let go data that could not be written + reportEvent( 2, + "couldn't write full vorbis data to underlying sink", + oggPage.header_len + oggPage.body_len - written); + } + } + } + } +} + + +/*------------------------------------------------------------------------------ + * Close the encoding session + *----------------------------------------------------------------------------*/ +void +VorbisLibEncoder :: close ( void ) throw ( Exception ) +{ + if ( isOpen() ) { + flush(); + + ogg_stream_clear( &oggStreamState); + vorbis_block_clear( &vorbisBlock); + vorbis_dsp_clear( &vorbisDspState); + vorbis_comment_clear( &vorbisComment); + vorbis_info_clear( &vorbisInfo); + + encoderOpen = false; + + sink->close(); + } +} + + +#endif // HAVE_VORBIS_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.22 2005/04/16 21:57:34 darkeye + added AAC support through the faac codec, http://www.audiocoding.com/ + + Revision 1.21 2005/04/11 19:26:55 darkeye + cosmetic changes + fixed warning for implicit cast from doulbe to int + + Revision 1.20 2005/04/03 05:18:24 jbebel + Add test to determine if the sample rate conversion ratio is a power of 2. + If so, use linear interpolation. Otherwise use more complicated quadratic + interpolation which tends to sound terrible, but is better than trying to + use linear for a non-standard conversion. + + Revision 1.19 2004/03/13 10:41:39 darkeye + added possibility to downsample from stereo to mono when encoding + to Ogg Vorbis + + Revision 1.18 2004/02/15 13:07:42 darkeye + ogg vorbis recording to only a file caused a segfault. now fixed + + Revision 1.17 2003/02/09 13:15:57 darkeye + added feature for setting the TITLE comment field for vorbis streams + + Revision 1.16 2002/10/19 13:31:46 darkeye + some cleanup with the open() / close() functions + + Revision 1.15 2002/10/19 12:22:10 darkeye + return 0 immediately for write() if supplied length is 0 + + Revision 1.14 2002/08/22 21:52:08 darkeye + bug fix: maximum bitrate setting fixed for Ogg Vorbis streams + + Revision 1.13 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + + Revision 1.12 2002/08/03 10:30:46 darkeye + resampling bugs fixed for vorbis streams + + Revision 1.11 2002/07/20 16:37:06 darkeye + added fault tolerance in case a server connection is dropped + + Revision 1.10 2002/07/20 10:59:00 darkeye + added support for Ogg Vorbis 1.0, removed support for rc2 + + Revision 1.9 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.8 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + + Revision 1.7 2002/03/28 16:47:38 darkeye + moved functions conv8() and conv16() to class Util (as conv()) + added resampling functionality + added support for variable bitrates + + Revision 1.6 2002/02/20 10:35:35 darkeye + updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs + + Revision 1.5 2001/10/21 13:08:18 darkeye + fixed incorrect vorbis bitrate setting + + Revision 1.4 2001/10/19 12:39:42 darkeye + created configure options to compile with or without lame / Ogg Vorbis + + Revision 1.3 2001/09/18 14:57:19 darkeye + finalized Solaris port + + Revision 1.2 2001/09/15 11:36:22 darkeye + added function vorbisBlocksOut(), finalized vorbis support + + Revision 1.1 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.h b/darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.h new file mode 100644 index 0000000..a956f42 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/VorbisLibEncoder.h @@ -0,0 +1,479 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : VorbisLibEncoder.h + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ +#ifndef VORBIS_LIB_ENCODER_H +#define VORBIS_LIB_ENCODER_H + +#ifndef __cplusplus +#error This is a C++ include file +#endif + + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_VORBIS_LIB +#include +#else +#error configure for Ogg Vorbis +#endif + + +#include "Ref.h" +#include "Exception.h" +#include "Reporter.h" +#include "AudioEncoder.h" +#include "CastSink.h" +#include "aflibConverter.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * A class representing the ogg vorbis encoder linked as a shared object or + * as a static library. + * + * @author $Author$ + * @version $Revision$ + */ +class VorbisLibEncoder : public AudioEncoder, public virtual Reporter +{ + private: + + /** + * Value indicating if the encoding process is going on + */ + bool encoderOpen; + + /** + * Ogg Vorbis library global info + */ + vorbis_info vorbisInfo; + + /** + * Ogg Vorbis library global DSP state + */ + vorbis_dsp_state vorbisDspState; + + /** + * Ogg Vorbis library global block + */ + vorbis_block vorbisBlock; + + /** + * Ogg Vorbis library global comment + */ + vorbis_comment vorbisComment; + + /** + * Ogg library global stream state + */ + ogg_stream_state oggStreamState; + + /** + * The Sink to dump encoded data to + */ + Ref sink; + + /** + * Maximum bitrate of the output in kbits/sec. If 0, don't care. + */ + unsigned int outMaxBitrate; + + /** + * Resample ratio + */ + double resampleRatio; + + /** + * aflibConverter object for possible resampling + */ + aflibConverter * converter; + + /** + * Initialize the object. + * + * @param sink the sink to send encoded output to + * @param the maximum bit rate + * @exception Exception + */ + void + init ( CastSink * sink, + unsigned int outMaxBitrate ) throw ( Exception ); + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + if ( converter ) { + delete converter; + } + } + + /** + * Send pending Vorbis blocks to the underlying stream + */ + void + vorbisBlocksOut( void ) throw ( Exception ); + + + protected: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + VorbisLibEncoder ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + public: + + /** + * Constructor. + * + * @param sink the sink to send encoded output to + * @param inSampleRate sample rate of the input. + * @param inBitsPerSample number of bits per sample of the input. + * @param inChannel number of channels of the input. + * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, inSampleRate is used. + * @param outMaxBitrate maximum output bitrate. + * 0 if not used. + * @param outChannel number of channels of the output. + * If 0, inChannel is used. + * @exception Exception + */ + inline + VorbisLibEncoder ( CastSink * sink, + unsigned int inSampleRate, + unsigned int inBitsPerSample, + unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + unsigned int outMaxBitrate = 0 ) + throw ( Exception ) + + : AudioEncoder ( inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink, outMaxBitrate); + } + + /** + * Constructor. + * + * @param sink the sink to send encoded output to + * @param as get input sample rate, bits per sample and channels + * from this AudioSource. + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. + * @param outSampleRate sample rate of the output. + * If 0, input sample rate is used. + * @param outMaxBitrate maximum output bitrate. + * 0 if not used. + * @param outChannel number of channels of the output. + * If 0, input channel is used. + * @exception Exception + */ + inline + VorbisLibEncoder ( CastSink * sink, + const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0, + unsigned int outMaxBitrate = 0 ) + throw ( Exception ) + + : AudioEncoder ( as, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink, outMaxBitrate); + } + + /** + * Copy constructor. + * + * @param encoder the VorbisLibEncoder to copy. + */ + inline + VorbisLibEncoder ( const VorbisLibEncoder & encoder ) + throw ( Exception ) + : AudioEncoder( encoder ) + { + if( encoder.isOpen() ) { + throw Exception(__FILE__, __LINE__, "don't copy open encoders"); + } + init( encoder.sink.get(), encoder.getOutMaxBitrate() ); + } + + /** + * Destructor. + * + * @exception Exception + */ + inline virtual + ~VorbisLibEncoder ( void ) throw ( Exception ) + { + if ( isOpen() ) { + close(); + } + strip(); + } + + /** + * Assignment operator. + * + * @param encoder the VorbisLibEncoder to assign this to. + * @return a reference to this VorbisLibEncoder. + * @exception Exception + */ + inline virtual VorbisLibEncoder & + operator= ( const VorbisLibEncoder & encoder ) throw ( Exception ) + { + if( encoder.isOpen() ) { + throw Exception(__FILE__, __LINE__, "don't copy open encoders"); + } + + if ( this != &encoder ) { + strip(); + AudioEncoder::operator=( encoder); + init( encoder.sink.get(), encoder.getOutMaxBitrate() ); + } + + return *this; + } + + /** + * Get the maximum bit rate of the output in kbits/sec, + * for fixed / average bitrate encodings. + * + * @return the maximum bit rate of the output, or 0 if not set. + */ + inline unsigned int + getOutMaxBitrate ( void ) const throw () + { + return outMaxBitrate; + } + + /** + * Check wether encoding is in progress. + * + * @return true if encoding is in progress, false otherwise. + */ + inline virtual bool + isRunning ( void ) const throw () + { + return isOpen(); + } + + /** + * Start encoding. This function returns as soon as possible, + * with encoding started in the background. + * + * @return true if encoding has started, false otherwise. + * @exception Exception + */ + inline virtual bool + start ( void ) throw ( Exception ) + { + return open(); + } + + /** + * Stop encoding. Stops the encoding running in the background. + * + * @exception Exception + */ + inline virtual void + stop ( void ) throw ( Exception ) + { + return close(); + } + + /** + * Open an encoding session. + * + * @return true if opening was successfull, false otherwise. + * @exception Exception + */ + virtual bool + open ( void ) throw ( Exception ); + + /** + * Check if the encoding session is open. + * + * @return true if the encoding session is open, false otherwise. + */ + inline virtual bool + isOpen ( void ) const throw () + { + return encoderOpen; + } + + /** + * Check if the encoder is ready to accept data. + * + * @param sec the maximum seconds to block. + * @param usec micro seconds to block after the full seconds. + * @return true if the encoder is ready to accept data, + * false otherwise. + * @exception Exception + */ + inline virtual bool + canWrite ( unsigned int sec, + unsigned int usec ) throw ( Exception ) + { + if ( !isOpen() ) { + return false; + } + + return true; + } + + /** + * Write data to the encoder. + * Buf is expected to be a sequence of big-endian 16 bit values, + * with left and right channels interleaved. Len is the number of + * bytes, must be a multiple of 4. + * + * @param buf the data to write. + * @param len number of bytes to write from buf. + * @return the number of bytes written (may be less than len). + * @exception Exception + */ + virtual unsigned int + write ( const void * buf, + unsigned int len ) throw ( Exception ); + + /** + * Flush all data that was written to the encoder to the underlying + * connection. + * + * @exception Exception + */ + virtual void + flush ( void ) throw ( Exception ); + + /** + * Close the encoding session. + * + * @exception Exception + */ + virtual void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* VORBIS_LIB_ENCODER_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.9 2003/02/09 13:15:57 darkeye + added feature for setting the TITLE comment field for vorbis streams + + Revision 1.8 2002/08/20 20:07:36 darkeye + minor fixes + + Revision 1.7 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + + Revision 1.6 2002/07/20 16:37:06 darkeye + added fault tolerance in case a server connection is dropped + + Revision 1.5 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + + Revision 1.4 2002/03/28 16:47:38 darkeye + moved functions conv8() and conv16() to class Util (as conv()) + added resampling functionality + added support for variable bitrates + + Revision 1.3 2001/10/19 12:39:42 darkeye + created configure options to compile with or without lame / Ogg Vorbis + + Revision 1.2 2001/09/15 11:36:22 darkeye + added function vorbisBlocksOut(), finalized vorbis support + + Revision 1.1 2001/09/14 19:31:06 darkeye + added IceCast2 / vorbis support + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/src/aflibConverter.cc b/darkice/tags/darkice-0_17_1/src/aflibConverter.cc new file mode 100644 index 0000000..99bdffe --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/aflibConverter.cc @@ -0,0 +1,797 @@ +/* + * Copyright: (C) 2000 Julius O. Smith + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Julius O. Smith jos@ccrma.stanford.edu + * + */ +/* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it + into a C++ class +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "aflibConverter.h" +#include "aflibConverterLargeFilter.h" +#include "aflibConverterSmallFilter.h" + +#include "aflibDebug.h" + +#if (!defined(TRUE) || !defined(FALSE)) +# define TRUE 1 +# define FALSE 0 +#endif + + +/* + * The configuration constants below govern + * the number of bits in the input sample and filter coefficients, the + * number of bits to the right of the binary-point for fixed-point math, etc. + */ + +/* Conversion constants */ +#define Nhc 8 +#define Na 7 +#define Np (Nhc+Na) +#define Npc (1< (inCount - (int)framecount)) + { + Nsamps = inCount - framecount; + } + + for (c = 0; c < _nChans; c++) + { + ptr = outPtr[c]; + ptr += Xoff; /* Start at designated sample number */ + + for (i = 0; i < Nsamps; i++) + *ptr++ = (short) inArray[c * inCount + i + framecount]; + } + + framecount += Nsamps; + + if ((int)framecount >= inCount) /* return index of last samp */ + return (((Nsamps - (framecount - inCount)) - 1) + Xoff); + else + return 0; +} + +int +aflibConverter::SrcLinear( + short X[], + short Y[], + double factor, + unsigned int *Time, + unsigned short& Nx, + unsigned short Nout) +{ + short iconst; + short *Xp, *Ystart; + int v,x1,x2; + + double dt; /* Step through input signal */ + unsigned int dtb; /* Fixed-point version of Dt */ +// unsigned int endTime; /* When Time reaches EndTime, return to user */ + unsigned int start_sample, end_sample; + + dt = 1.0/factor; /* Output sampling period */ + dtb = (unsigned int)(dt*(1<>Np; + Ystart = Y; +// endTime = *Time + (1<>Np]; /* Ptr to current input sample */ + x1 = *Xp++; + x2 = *Xp; + x1 *= ((1<>Np; + Nx = end_sample - start_sample; + return (Y - Ystart); /* Return number of output samples */ +} + + +int +aflibConverter::SrcUp( + short X[], + short Y[], + double factor, + unsigned int *Time, + unsigned short& Nx, + unsigned short Nout, + unsigned short Nwing, + unsigned short LpScl, + short Imp[], + short ImpD[], + bool Interp) +{ + short *Xp, *Ystart; + int v; + + double dt; /* Step through input signal */ + unsigned int dtb; /* Fixed-point version of Dt */ +// unsigned int endTime; /* When Time reaches EndTime, return to user */ + unsigned int start_sample, end_sample; + + dt = 1.0/factor; /* Output sampling period */ + dtb = (unsigned int)(dt*(1<>Np; + Ystart = Y; +// endTime = *Time + (1<>Np]; /* Ptr to current input sample */ + /* Perform left-wing inner product */ + v = FilterUp(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask),-1); + /* Perform right-wing inner product */ + v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1, + (short)((((*Time)^Pmask)+1)&Pmask), 1); + v >>= Nhg; /* Make guard bits */ + v *= LpScl; /* Normalize for unity filter gain */ + *Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */ + *Time += dtb; /* Move to next sample by time increment */ + } + end_sample = (*Time)>>Np; + Nx = end_sample - start_sample; + return (Y - Ystart); /* Return the number of output samples */ +} + + + +int +aflibConverter::SrcUD( + short X[], + short Y[], + double factor, + unsigned int *Time, + unsigned short& Nx, + unsigned short Nout, + unsigned short Nwing, + unsigned short LpScl, + short Imp[], + short ImpD[], + bool Interp) +{ + short *Xp, *Ystart; + int v; + + double dh; /* Step through filter impulse response */ + double dt; /* Step through input signal */ +// unsigned int endTime; /* When Time reaches EndTime, return to user */ + unsigned int dhb, dtb; /* Fixed-point versions of Dh,Dt */ + unsigned int start_sample, end_sample; + + dt = 1.0/factor; /* Output sampling period */ + dtb = (unsigned int)(dt*(1<>Np; + Ystart = Y; +// endTime = *Time + (1<>Np]; /* Ptr to current input sample */ + v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (short)(*Time&Pmask), + -1, dhb); /* Perform left-wing inner product */ + v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, + (short)((((*Time)^Pmask)+1)&Pmask), 1, dhb); /* Perform right-wing inner product */ + v >>= Nhg; /* Make guard bits */ + v *= LpScl; /* Normalize for unity filter gain */ + *Y++ = WordToHword(v,NLpScl); /* strip guard bits, deposit output */ + *Time += dtb; /* Move to next sample by time increment */ + } + + end_sample = (*Time)>>Np; + Nx = end_sample - start_sample; + return (Y - Ystart); /* Return the number of output samples */ +} + + +int +aflibConverter::resampleFast( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + short inArray[], /* input data */ + short outArray[]) /* output data */ +{ + unsigned int Time2; /* Current time/pos in input sample */ +#if 0 + unsigned short Ncreep; +#endif + unsigned short Xp, Xoff, Xread; + int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor); + unsigned short Nout = 0, Nx, orig_Nx; + unsigned short maxOutput; + int total_inCount = 0; + int c, i, Ycount, last; + bool first_pass = TRUE; + + + Xoff = 10; + + Nx = IBUFFSIZE - 2*Xoff; /* # of samples to process each iteration */ + last = 0; /* Have not read last input sample yet */ + Ycount = 0; /* Current sample and length of output file */ + + Xp = Xoff; /* Current "now"-sample pointer for input */ + Xread = Xoff; /* Position in input array to read into */ + + if (_initial == TRUE) + _Time = (Xoff< (OBUFFSIZE - (2*Xoff*_factor)) ) + maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor); + else + maxOutput = outCount-Ycount; + + for (c = 0; c < _nChans; c++) + { + orig_Nx = Nx; + Time2 = _Time; + /* Resample stuff in input buffer */ + Nout=SrcLinear(_II[c],_JJ[c],_factor,&Time2,orig_Nx,maxOutput); + } + Nx = orig_Nx; + _Time = Time2; + + _Time -= (Nx<>Np) - Xoff; /* Calc time accumulation in Time */ + if (Ncreep) { + Time -= (Ncreep<outCount) { + Nout -= (Ycount-outCount); + Ycount = outCount; + } + + if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */ + return err_ret("Output array overflow"); + + for (c = 0; c < _nChans; c++) + for (i = 0; i < Nout; i++) + outArray[c * outCount + i + Ycount - Nout] = _JJ[c][i]; + + total_inCount += Nx; + + } while (Ycount < outCount); /* Continue until done */ + + inCount = total_inCount; + + return(Ycount); /* Return # of samples in output file */ +} + + +int +aflibConverter::resampleWithFilter( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + short inArray[], /* input data */ + short outArray[], /* output data */ + short Imp[], short ImpD[], + unsigned short LpScl, unsigned short Nmult, unsigned short Nwing) +{ + unsigned int Time2; /* Current time/pos in input sample */ +#if 0 + unsigned short Ncreep; +#endif + unsigned short Xp, Xoff, Xread; + int OBUFFSIZE = (int)(((double)IBUFFSIZE)*_factor); + unsigned short Nout = 0, Nx, orig_Nx; + unsigned short maxOutput; + int total_inCount = 0; + int c, i, Ycount, last; + bool first_pass = TRUE; + + + /* Account for increased filter gain when using factors less than 1 */ + if (_factor < 1) + LpScl = (unsigned short)(LpScl*_factor + 0.5); + + /* Calc reach of LP filter wing & give some creeping room */ + Xoff = (unsigned short)(((Nmult+1)/2.0) * MAX(1.0,1.0/_factor) + 10); + + if (IBUFFSIZE < 2*Xoff) /* Check input buffer size */ + return err_ret("IBUFFSIZE (or factor) is too small"); + + Nx = IBUFFSIZE - 2*Xoff; /* # of samples to process each iteration */ + + last = 0; /* Have not read last input sample yet */ + Ycount = 0; /* Current sample and length of output file */ + Xp = Xoff; /* Current "now"-sample pointer for input */ + Xread = Xoff; /* Position in input array to read into */ + + if (_initial == TRUE) + _Time = (Xoff< (OBUFFSIZE - (2*Xoff*_factor)) ) + maxOutput = OBUFFSIZE - (unsigned short)(2*Xoff*_factor); + else + maxOutput = outCount-Ycount; + + for (c = 0; c < _nChans; c++) + { + orig_Nx = Nx; + Time2 = _Time; + /* Resample stuff in input buffer */ + if (_factor >= 1) { /* SrcUp() is faster if we can use it */ + Nout=SrcUp(_II[c],_JJ[c],_factor, + &Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt); + } + else { + Nout=SrcUD(_II[c],_JJ[c],_factor, + &Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt); + } + } + _Time = Time2; + + _Time -= (Nx<>Np) - Xoff; /* Calc time accumulation in Time */ + if (Ncreep) { + Time -= (Ncreep< outCount) { + Nout -= (Ycount - outCount); + Ycount = outCount; + } + + if (Nout > OBUFFSIZE) /* Check to see if output buff overflowed */ + return err_ret("Output array overflow"); + + for (c = 0; c < _nChans; c++) + { + for (i = 0; i < Nout; i++) + { + outArray[c * outCount + i + Ycount - Nout] = _JJ[c][i]; + } + } + + int act_incount = (int)Nx; + + for (c = 0; c < _nChans; c++) + { + for (i=0; i>Na]; + End = &Imp[Nwing]; + + if (Interp) + { + Hdp = &ImpD[Ph>>Na]; + a = Ph & Amask; + } + + if (Inc == 1) /* If doing right wing... */ + { /* ...drop extra coeff, so when Ph is */ + End--; /* 0.5, we don't do too many mult's */ + if (Ph == 0) /* If the phase is zero... */ + { /* ...then we've already skipped the */ + Hp += Npc; /* first sample, so we must also */ + Hdp += Npc; /* skip ahead in Imp[] and ImpD[] */ + } + } + + if (Interp) + { + while (Hp < End) + { + t = *Hp; /* Get filter coeff */ + t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */ + Hdp += Npc; /* Filter coeff differences step */ + t *= *Xp; /* Mult coeff by input sample */ + if (t & (1<<(Nhxn-1))) /* Round, if needed */ + t += (1<<(Nhxn-1)); + t >>= Nhxn; /* Leave some guard bits, but come back some */ + v += t; /* The filter output */ + Hp += Npc; /* Filter coeff step */ + Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ + } + } + else + { + while (Hp < End) + { + t = *Hp; /* Get filter coeff */ + t *= *Xp; /* Mult coeff by input sample */ + if (t & (1<<(Nhxn-1))) /* Round, if needed */ + t += (1<<(Nhxn-1)); + t >>= Nhxn; /* Leave some guard bits, but come back some */ + v += t; /* The filter output */ + Hp += Npc; /* Filter coeff step */ + Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ + } + } + return(v); +} + + +int +aflibConverter::FilterUD( + short Imp[], + short ImpD[], + unsigned short Nwing, + bool Interp, + short *Xp, + short Ph, + short Inc, + unsigned short dhb) +{ + short a; + short *Hp, *Hdp, *End; + int v, t; + unsigned int Ho; + + v=0; + Ho = (Ph*(unsigned int)dhb)>>Np; + End = &Imp[Nwing]; + if (Inc == 1) /* If doing right wing... */ + { /* ...drop extra coeff, so when Ph is */ + End--; /* 0.5, we don't do too many mult's */ + if (Ph == 0) /* If the phase is zero... */ + Ho += dhb; /* ...then we've already skipped the */ + } /* first sample, so we must also */ + /* skip ahead in Imp[] and ImpD[] */ + + if (Interp) + { + while ((Hp = &Imp[Ho>>Na]) < End) + { + t = *Hp; /* Get IR sample */ + Hdp = &ImpD[Ho>>Na]; /* get interp (lower Na) bits from diff table*/ + a = Ho & Amask; /* a is logically between 0 and 1 */ + t += (((int)*Hdp)*a)>>Na; /* t is now interp'd filter coeff */ + t *= *Xp; /* Mult coeff by input sample */ + if (t & 1<<(Nhxn-1)) /* Round, if needed */ + t += 1<<(Nhxn-1); + t >>= Nhxn; /* Leave some guard bits, but come back some */ + v += t; /* The filter output */ + Ho += dhb; /* IR step */ + Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ + } + } + else + { + while ((Hp = &Imp[Ho>>Na]) < End) + { + t = *Hp; /* Get IR sample */ + t *= *Xp; /* Mult coeff by input sample */ + if (t & 1<<(Nhxn-1)) /* Round, if needed */ + t += 1<<(Nhxn-1); + t >>= Nhxn; /* Leave some guard bits, but come back some */ + v += t; /* The filter output */ + Ho += dhb; /* IR step */ + Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */ + } + } + return(v); +} + diff --git a/darkice/tags/darkice-0_17_1/src/aflibConverter.h b/darkice/tags/darkice-0_17_1/src/aflibConverter.h new file mode 100644 index 0000000..32573eb --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/aflibConverter.h @@ -0,0 +1,236 @@ +/* + * Copyright: (C) 2000 Julius O. Smith + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Julius O. Smith jos@ccrma.stanford.edu + * + */ +/* This code was modified by Bruce Forsberg (forsberg@tns.net) to make it + into a C++ class +*/ + + +#ifndef _AFLIBCONVERTER_H_ +#define _AFLIBCONVERTER_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef MAX +#define MAX(x,y) ((x)>(y) ?(x):(y)) +#endif +#ifndef MIN +#define MIN(x,y) ((x)<(y) ?(x):(y)) +#endif + +#define MAX_HWORD (32767) +#define MIN_HWORD (-32768) + +#define IBUFFSIZE 4096 /* Input buffer size */ + +/*! \class aflibConverter + \brief Provides sample rate conversion. + + This class will perform audio resampling. With the constructor you can choose the + type of resampling to be done. Simple linear interpolation can be done by setting + linear_interpolation to be TRUE in the constructor. The other two flags are + ignored if this is set. If linear_interpolation is FALSE then some form of filtering + will be done. IF high_quality is FALSE then a small filter will be performed. + If high_quality is TRUE then a large filter (higher quality) will be performed. For + both the small and large filters another parameter can be specified, filter_interpolation. + With filter_interpolation set then the filter coefficients used for both the small and + large filtering will be interpolated as well. + + This class was designed to stream audio data. It also expects audio data as 16 bit values. + Each time a new stream is started some initialization needs to be done. Thus the function + initialize should be called to initialize everything. This initialize function will set + the conversion factor as well as a multiplecation factor for volume. The volume only + applies to the small and large filter. Since this filter uses a history of the audio data + it is possible for it to vary in amplitude. This allows users to scale the data. This + class will work on any number of channels. Once everything is specified then resample + should be called as many times as is necessary to process all the data. The value + inCount will be returned indicating how many inArray samples were actually used to + produce the output. This value can be used to indicate where the next block of + inArray data should start. The resample function is driven by the outCount value + specified. The inArray should contain at least: + outCount / factor + extra_samples. + extra_samples depends on the type of filtering done. As a rule of thumb 50 should be + adequate for any type of filter. +*/ + +class aflibData; + +class aflibConverter { + +public: + + // Available contructors and destructors + aflibConverter ( + bool high_quality, + bool linear_interpolation, + bool filter_interpolation); + + ~aflibConverter(); + + void + initialize( + double factor, /* factor = Sndout/Sndin */ + int channels, /* number of sound channels */ + double volume = 1.0); /* factor to multiply amplitude */ + + int + resample( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + short inArray[], /* input array data (length inCount * nChans) */ + short outArray[]);/* output array data (length outCount * nChans) */ + + +private: + + aflibConverter(); + + aflibConverter(const aflibConverter& op); + + const aflibConverter& + operator=(const aflibConverter& op); + + int + err_ret(char *s); + + void + deleteMemory(); + + int + readData( + int inCount, /* _total_ number of frames in input file */ + short inArray[], /* input data */ + short *outPtr[], /* array receiving chan samps */ + int dataArraySize, /* size of these arrays */ + int Xoff, /* read into input array starting at this index */ + bool init_count); + + + inline short + WordToHword(int v, int scl) + { + short out; + int llsb = (1<<(scl-1)); + v += llsb; /* round */ + v >>= scl; + if (v>MAX_HWORD) { + v = MAX_HWORD; + } else if (v < MIN_HWORD) { + v = MIN_HWORD; + } + out = (short) v; + return out; + }; + + int + SrcLinear( + short X[], + short Y[], + double factor, + unsigned int *Time, + unsigned short& Nx, + unsigned short Nout); + + int + SrcUp( + short X[], + short Y[], + double factor, + unsigned int *Time, + unsigned short& Nx, + unsigned short Nout, + unsigned short Nwing, + unsigned short LpScl, + short Imp[], + short ImpD[], + bool Interp); + + int + SrcUD( + short X[], + short Y[], + double factor, + unsigned int *Time, + unsigned short& Nx, + unsigned short Nout, + unsigned short Nwing, + unsigned short LpScl, + short Imp[], + short ImpD[], + bool Interp); + + int + FilterUp( + short Imp[], + short ImpD[], + unsigned short Nwing, + bool Interp, + short *Xp, + short Ph, + short Inc); + + int + FilterUD( + short Imp[], + short ImpD[], + unsigned short Nwing, + bool Interp, + short *Xp, + short Ph, + short Inc, + unsigned short dhb); + + int + resampleFast( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + short inArray[], /* input array data (length inCount * nChans) */ + short outArray[]);/* output array data (length outCount * nChans) */ + + int + resampleWithFilter( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + short inArray[], /* input array data (length inCount * nChans) */ + short outArray[], /* output array data (length outCount * nChans) */ + short Imp[], short ImpD[], + unsigned short LpScl, unsigned short Nmult, unsigned short Nwing); + + +static short SMALL_FILTER_IMP[]; +static short LARGE_FILTER_IMP[]; + +bool interpFilt; +bool largeFilter; +bool linearInterp; +short ** _II; +short ** _JJ; +unsigned int _Time; +double _factor; +int _nChans; +bool _initial; +double _vol; + +}; + + +#endif diff --git a/darkice/tags/darkice-0_17_1/src/aflibConverterLargeFilter.h b/darkice/tags/darkice-0_17_1/src/aflibConverterLargeFilter.h new file mode 100644 index 0000000..5d5b05b --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/aflibConverterLargeFilter.h @@ -0,0 +1,16432 @@ +/* + * Copyright: (C) 2000 Julius O. Smith + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Julius O. Smith jos@ccrma.stanford.edu + * + */ + +/* + +The default filter requires an +oversampling factor of around 20% to avoid aliasing. The expensive +filter is five times more computationally expensive and requires only +about a 5-10% oversampling factor. Both filters have comparable +stop-band attenuations (approximately 80 dB). The +expensive filter is not yet documented because its cut-off frequency +should be retuned slightly for optimal performance. Also, we plan to +compute truly optimized resampling filters sometime in the future. In +the meantime, the default filter is fast, well tuned, and works very +well for its level of computational expense. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#define LARGE_FILTER_NMULT ((short)65) +#define LARGE_FILTER_SCALE 14746 /* Unity-gain scale factor */ +#define LARGE_FILTER_NWING 8192 /* Filter table length */ + +short aflibConverter::LARGE_FILTER_IMP[] /* Impulse response */ = { +32767, +32766, +32764, +32761, +32756, +32750, +32743, +32734, +32724, +32713, +32700, +32686, +32671, +32654, +32636, +32617, +32596, +32574, +32551, +32526, +32500, +32473, +32445, +32415, +32383, +32351, +32317, +32282, +32246, +32208, +32169, +32129, +32087, +32044, +32000, +31955, +31908, +31860, +31811, +31760, +31708, +31655, +31601, +31545, +31489, +31431, +31371, +31311, +31249, +31186, +31122, +31056, +30990, +30922, +30853, +30783, +30711, +30639, +30565, +30490, +30414, +30337, +30258, +30179, +30098, +30016, +29933, +29849, +29764, +29677, +29590, +29501, +29411, +29321, +29229, +29136, +29042, +28947, +28851, +28753, +28655, +28556, +28456, +28354, +28252, +28149, +28044, +27939, +27833, +27725, +27617, +27508, +27398, +27287, +27175, +27062, +26948, +26833, +26717, +26601, +26483, +26365, +26246, +26125, +26005, +25883, +25760, +25637, +25512, +25387, +25261, +25135, +25007, +24879, +24750, +24620, +24490, +24358, +24226, +24094, +23960, +23826, +23691, +23556, +23420, +23283, +23146, +23008, +22869, +22730, +22590, +22449, +22308, +22166, +22024, +21881, +21738, +21594, +21449, +21304, +21159, +21013, +20866, +20719, +20572, +20424, +20275, +20127, +19977, +19828, +19678, +19527, +19376, +19225, +19073, +18921, +18769, +18616, +18463, +18310, +18157, +18003, +17849, +17694, +17539, +17384, +17229, +17074, +16918, +16762, +16606, +16450, +16294, +16137, +15980, +15823, +15666, +15509, +15352, +15195, +15037, +14880, +14722, +14564, +14407, +14249, +14091, +13933, +13775, +13618, +13460, +13302, +13144, +12987, +12829, +12671, +12514, +12356, +12199, +12042, +11885, +11728, +11571, +11414, +11257, +11101, +10945, +10789, +10633, +10477, +10322, +10167, +10012, +9857, +9702, +9548, +9394, +9241, +9087, +8934, +8781, +8629, +8477, +8325, +8174, +8023, +7872, +7722, +7572, +7422, +7273, +7124, +6976, +6828, +6681, +6534, +6387, +6241, +6096, +5951, +5806, +5662, +5518, +5375, +5233, +5091, +4949, +4808, +4668, +4528, +4389, +4250, +4112, +3975, +3838, +3702, +3566, +3431, +3297, +3163, +3030, +2898, +2766, +2635, +2505, +2375, +2246, +2118, +1990, +1864, +1738, +1612, +1487, +1364, +1240, +1118, +996, +875, +755, +636, +517, +400, +283, +166, +51, +-63, +-176, +-289, +-401, +-513, +-623, +-733, +-841, +-949, +-1056, +-1162, +-1268, +-1372, +-1476, +-1578, +-1680, +-1781, +-1881, +-1980, +-2078, +-2176, +-2272, +-2367, +-2462, +-2556, +-2648, +-2740, +-2831, +-2921, +-3010, +-3098, +-3185, +-3271, +-3356, +-3441, +-3524, +-3606, +-3688, +-3768, +-3848, +-3926, +-4004, +-4080, +-4156, +-4231, +-4304, +-4377, +-4449, +-4519, +-4589, +-4658, +-4726, +-4792, +-4858, +-4923, +-4987, +-5050, +-5111, +-5172, +-5232, +-5291, +-5349, +-5406, +-5462, +-5517, +-5571, +-5624, +-5675, +-5726, +-5776, +-5825, +-5873, +-5920, +-5966, +-6011, +-6055, +-6098, +-6140, +-6181, +-6222, +-6261, +-6299, +-6336, +-6372, +-6407, +-6441, +-6475, +-6507, +-6538, +-6569, +-6598, +-6626, +-6654, +-6680, +-6706, +-6730, +-6754, +-6777, +-6798, +-6819, +-6839, +-6858, +-6876, +-6893, +-6909, +-6924, +-6938, +-6951, +-6964, +-6975, +-6986, +-6995, +-7004, +-7012, +-7019, +-7025, +-7030, +-7035, +-7038, +-7040, +-7042, +-7043, +-7043, +-7042, +-7040, +-7038, +-7034, +-7030, +-7025, +-7019, +-7012, +-7004, +-6996, +-6986, +-6976, +-6965, +-6954, +-6941, +-6928, +-6914, +-6899, +-6884, +-6867, +-6850, +-6832, +-6814, +-6794, +-6774, +-6753, +-6732, +-6709, +-6686, +-6663, +-6638, +-6613, +-6587, +-6561, +-6534, +-6506, +-6478, +-6448, +-6419, +-6388, +-6357, +-6325, +-6293, +-6260, +-6226, +-6192, +-6157, +-6122, +-6086, +-6049, +-6012, +-5975, +-5936, +-5897, +-5858, +-5818, +-5778, +-5737, +-5695, +-5653, +-5611, +-5568, +-5524, +-5480, +-5436, +-5391, +-5345, +-5300, +-5253, +-5207, +-5159, +-5112, +-5064, +-5015, +-4966, +-4917, +-4868, +-4818, +-4767, +-4716, +-4665, +-4614, +-4562, +-4510, +-4457, +-4404, +-4351, +-4298, +-4244, +-4190, +-4136, +-4081, +-4026, +-3971, +-3916, +-3860, +-3804, +-3748, +-3692, +-3635, +-3578, +-3521, +-3464, +-3406, +-3349, +-3291, +-3233, +-3175, +-3117, +-3058, +-3000, +-2941, +-2882, +-2823, +-2764, +-2705, +-2646, +-2587, +-2527, +-2468, +-2408, +-2349, +-2289, +-2229, +-2169, +-2110, +-2050, +-1990, +-1930, +-1870, +-1811, +-1751, +-1691, +-1631, +-1571, +-1512, +-1452, +-1392, +-1333, +-1273, +-1214, +-1154, +-1095, +-1036, +-977, +-918, +-859, +-800, +-741, +-683, +-624, +-566, +-508, +-450, +-392, +-335, +-277, +-220, +-163, +-106, +-49, +6, +63, +119, +175, +230, +286, +341, +396, +450, +505, +559, +613, +667, +720, +773, +826, +878, +931, +983, +1034, +1086, +1137, +1187, +1238, +1288, +1337, +1387, +1436, +1484, +1533, +1581, +1628, +1675, +1722, +1769, +1815, +1861, +1906, +1951, +1996, +2040, +2084, +2127, +2170, +2212, +2255, +2296, +2338, +2378, +2419, +2459, +2498, +2538, +2576, +2615, +2652, +2690, +2727, +2763, +2799, +2834, +2870, +2904, +2938, +2972, +3005, +3038, +3070, +3102, +3133, +3164, +3194, +3224, +3253, +3282, +3310, +3338, +3365, +3392, +3418, +3444, +3469, +3494, +3518, +3542, +3566, +3588, +3611, +3632, +3653, +3674, +3694, +3714, +3733, +3752, +3770, +3788, +3805, +3821, +3837, +3853, +3868, +3882, +3896, +3910, +3923, +3935, +3947, +3958, +3969, +3980, +3989, +3999, +4007, +4016, +4023, +4031, +4037, +4044, +4049, +4054, +4059, +4063, +4067, +4070, +4073, +4075, +4076, +4077, +4078, +4078, +4078, +4077, +4076, +4074, +4071, +4068, +4065, +4061, +4057, +4052, +4047, +4041, +4035, +4028, +4021, +4013, +4005, +3997, +3988, +3978, +3968, +3958, +3947, +3936, +3924, +3912, +3899, +3886, +3872, +3858, +3844, +3829, +3814, +3798, +3782, +3766, +3749, +3731, +3714, +3696, +3677, +3658, +3639, +3619, +3599, +3578, +3558, +3536, +3515, +3493, +3470, +3448, +3425, +3401, +3378, +3353, +3329, +3304, +3279, +3254, +3228, +3202, +3175, +3149, +3122, +3094, +3067, +3039, +3011, +2982, +2953, +2924, +2895, +2865, +2835, +2805, +2775, +2744, +2713, +2682, +2651, +2619, +2587, +2555, +2523, +2490, +2457, +2424, +2391, +2358, +2324, +2290, +2256, +2222, +2188, +2153, +2119, +2084, +2049, +2014, +1978, +1943, +1907, +1872, +1836, +1800, +1764, +1727, +1691, +1655, +1618, +1581, +1545, +1508, +1471, +1434, +1397, +1360, +1322, +1285, +1248, +1210, +1173, +1135, +1098, +1060, +1023, +985, +947, +910, +872, +834, +797, +759, +721, +684, +646, +608, +571, +533, +496, +458, +421, +383, +346, +308, +271, +234, +197, +160, +123, +86, +49, +12, +-23, +-60, +-96, +-133, +-169, +-205, +-241, +-277, +-313, +-348, +-384, +-419, +-455, +-490, +-525, +-559, +-594, +-628, +-663, +-697, +-731, +-765, +-798, +-832, +-865, +-898, +-931, +-963, +-996, +-1028, +-1060, +-1092, +-1124, +-1155, +-1186, +-1217, +-1248, +-1279, +-1309, +-1339, +-1369, +-1398, +-1428, +-1457, +-1486, +-1514, +-1542, +-1571, +-1598, +-1626, +-1653, +-1680, +-1707, +-1733, +-1760, +-1785, +-1811, +-1836, +-1862, +-1886, +-1911, +-1935, +-1959, +-1982, +-2006, +-2029, +-2051, +-2074, +-2096, +-2118, +-2139, +-2160, +-2181, +-2202, +-2222, +-2242, +-2261, +-2280, +-2299, +-2318, +-2336, +-2354, +-2372, +-2389, +-2406, +-2423, +-2439, +-2455, +-2470, +-2486, +-2500, +-2515, +-2529, +-2543, +-2557, +-2570, +-2583, +-2595, +-2607, +-2619, +-2631, +-2642, +-2652, +-2663, +-2673, +-2683, +-2692, +-2701, +-2710, +-2718, +-2726, +-2734, +-2741, +-2748, +-2754, +-2760, +-2766, +-2772, +-2777, +-2782, +-2786, +-2790, +-2794, +-2797, +-2800, +-2803, +-2805, +-2807, +-2809, +-2810, +-2811, +-2812, +-2812, +-2812, +-2812, +-2811, +-2810, +-2808, +-2807, +-2804, +-2802, +-2799, +-2796, +-2792, +-2789, +-2785, +-2780, +-2775, +-2770, +-2765, +-2759, +-2753, +-2746, +-2740, +-2732, +-2725, +-2717, +-2709, +-2701, +-2692, +-2683, +-2674, +-2664, +-2655, +-2644, +-2634, +-2623, +-2612, +-2601, +-2589, +-2577, +-2565, +-2552, +-2539, +-2526, +-2513, +-2499, +-2485, +-2471, +-2457, +-2442, +-2427, +-2412, +-2396, +-2380, +-2364, +-2348, +-2331, +-2315, +-2297, +-2280, +-2263, +-2245, +-2227, +-2209, +-2190, +-2171, +-2152, +-2133, +-2114, +-2094, +-2075, +-2055, +-2034, +-2014, +-1993, +-1972, +-1951, +-1930, +-1909, +-1887, +-1865, +-1843, +-1821, +-1799, +-1776, +-1754, +-1731, +-1708, +-1685, +-1662, +-1638, +-1614, +-1591, +-1567, +-1543, +-1519, +-1494, +-1470, +-1445, +-1421, +-1396, +-1371, +-1346, +-1321, +-1295, +-1270, +-1244, +-1219, +-1193, +-1167, +-1142, +-1116, +-1090, +-1064, +-1037, +-1011, +-985, +-958, +-932, +-905, +-879, +-852, +-826, +-799, +-772, +-745, +-719, +-692, +-665, +-638, +-611, +-584, +-557, +-530, +-503, +-476, +-449, +-422, +-395, +-368, +-341, +-314, +-287, +-260, +-234, +-207, +-180, +-153, +-126, +-100, +-73, +-46, +-20, +6, +32, +59, +85, +111, +138, +164, +190, +216, +242, +268, +294, +319, +345, +370, +396, +421, +446, +471, +496, +521, +546, +571, +595, +619, +644, +668, +692, +716, +739, +763, +787, +810, +833, +856, +879, +902, +924, +947, +969, +991, +1013, +1035, +1056, +1078, +1099, +1120, +1141, +1162, +1182, +1202, +1223, +1243, +1262, +1282, +1301, +1320, +1339, +1358, +1377, +1395, +1413, +1431, +1449, +1467, +1484, +1501, +1518, +1535, +1551, +1567, +1583, +1599, +1615, +1630, +1645, +1660, +1674, +1689, +1703, +1717, +1731, +1744, +1757, +1770, +1783, +1795, +1808, +1820, +1831, +1843, +1854, +1865, +1876, +1886, +1897, +1907, +1916, +1926, +1935, +1944, +1953, +1961, +1970, +1978, +1985, +1993, +2000, +2007, +2014, +2020, +2026, +2032, +2038, +2043, +2048, +2053, +2058, +2062, +2066, +2070, +2073, +2077, +2080, +2083, +2085, +2087, +2089, +2091, +2093, +2094, +2095, +2095, +2096, +2096, +2096, +2096, +2095, +2094, +2093, +2092, +2090, +2088, +2086, +2084, +2081, +2079, +2075, +2072, +2069, +2065, +2061, +2056, +2052, +2047, +2042, +2037, +2031, +2025, +2019, +2013, +2006, +2000, +1993, +1986, +1978, +1971, +1963, +1955, +1946, +1938, +1929, +1920, +1911, +1901, +1892, +1882, +1872, +1862, +1851, +1841, +1830, +1819, +1807, +1796, +1784, +1772, +1760, +1748, +1735, +1723, +1710, +1697, +1684, +1670, +1657, +1643, +1629, +1615, +1601, +1586, +1572, +1557, +1542, +1527, +1512, +1496, +1481, +1465, +1449, +1433, +1417, +1401, +1384, +1368, +1351, +1334, +1317, +1300, +1283, +1265, +1248, +1230, +1212, +1195, +1177, +1159, +1140, +1122, +1104, +1085, +1067, +1048, +1029, +1010, +991, +972, +953, +934, +915, +895, +876, +856, +837, +817, +797, +777, +758, +738, +718, +698, +678, +658, +637, +617, +597, +577, +556, +536, +516, +495, +475, +454, +434, +414, +393, +373, +352, +332, +311, +291, +270, +250, +229, +208, +188, +168, +147, +127, +106, +86, +65, +45, +25, +5, +-15, +-35, +-55, +-75, +-95, +-115, +-135, +-155, +-175, +-195, +-215, +-234, +-254, +-274, +-293, +-313, +-332, +-351, +-370, +-390, +-409, +-428, +-446, +-465, +-484, +-503, +-521, +-539, +-558, +-576, +-594, +-612, +-630, +-648, +-666, +-683, +-701, +-718, +-735, +-752, +-769, +-786, +-803, +-819, +-836, +-852, +-868, +-885, +-900, +-916, +-932, +-947, +-963, +-978, +-993, +-1008, +-1023, +-1038, +-1052, +-1066, +-1081, +-1095, +-1108, +-1122, +-1136, +-1149, +-1162, +-1175, +-1188, +-1201, +-1214, +-1226, +-1238, +-1250, +-1262, +-1274, +-1285, +-1297, +-1308, +-1319, +-1330, +-1340, +-1351, +-1361, +-1371, +-1381, +-1390, +-1400, +-1409, +-1418, +-1427, +-1436, +-1445, +-1453, +-1461, +-1469, +-1477, +-1485, +-1492, +-1499, +-1506, +-1513, +-1520, +-1526, +-1532, +-1538, +-1544, +-1550, +-1555, +-1560, +-1566, +-1570, +-1575, +-1579, +-1584, +-1588, +-1592, +-1595, +-1599, +-1602, +-1605, +-1608, +-1610, +-1613, +-1615, +-1617, +-1619, +-1620, +-1622, +-1623, +-1624, +-1625, +-1625, +-1626, +-1626, +-1626, +-1626, +-1625, +-1625, +-1624, +-1623, +-1622, +-1621, +-1619, +-1617, +-1615, +-1613, +-1611, +-1608, +-1605, +-1603, +-1599, +-1596, +-1593, +-1589, +-1585, +-1581, +-1577, +-1572, +-1568, +-1563, +-1558, +-1553, +-1547, +-1542, +-1536, +-1530, +-1524, +-1518, +-1511, +-1505, +-1498, +-1491, +-1484, +-1477, +-1469, +-1462, +-1454, +-1446, +-1438, +-1430, +-1421, +-1413, +-1404, +-1395, +-1386, +-1377, +-1367, +-1358, +-1348, +-1338, +-1328, +-1318, +-1308, +-1297, +-1287, +-1276, +-1265, +-1254, +-1243, +-1232, +-1221, +-1209, +-1198, +-1186, +-1174, +-1162, +-1150, +-1138, +-1125, +-1113, +-1100, +-1087, +-1075, +-1062, +-1049, +-1035, +-1022, +-1009, +-995, +-982, +-968, +-954, +-941, +-927, +-913, +-898, +-884, +-870, +-856, +-841, +-827, +-812, +-797, +-783, +-768, +-753, +-738, +-723, +-708, +-692, +-677, +-662, +-647, +-631, +-616, +-600, +-585, +-569, +-554, +-538, +-522, +-506, +-491, +-475, +-459, +-443, +-427, +-411, +-395, +-379, +-363, +-347, +-331, +-315, +-299, +-283, +-267, +-251, +-235, +-218, +-202, +-186, +-170, +-154, +-138, +-122, +-106, +-90, +-74, +-58, +-42, +-26, +-10, +5, +21, +37, +53, +69, +85, +100, +116, +132, +147, +163, +179, +194, +209, +225, +240, +256, +271, +286, +301, +316, +331, +346, +361, +376, +391, +405, +420, +434, +449, +463, +477, +492, +506, +520, +534, +548, +561, +575, +589, +602, +615, +629, +642, +655, +668, +681, +694, +706, +719, +731, +744, +756, +768, +780, +792, +804, +816, +827, +839, +850, +861, +872, +883, +894, +905, +915, +926, +936, +946, +956, +966, +976, +986, +995, +1005, +1014, +1023, +1032, +1041, +1049, +1058, +1066, +1075, +1083, +1091, +1099, +1106, +1114, +1121, +1128, +1135, +1142, +1149, +1156, +1162, +1169, +1175, +1181, +1187, +1192, +1198, +1203, +1208, +1214, +1218, +1223, +1228, +1232, +1237, +1241, +1245, +1249, +1252, +1256, +1259, +1262, +1265, +1268, +1271, +1273, +1276, +1278, +1280, +1282, +1284, +1285, +1287, +1288, +1289, +1290, +1291, +1292, +1292, +1292, +1293, +1293, +1292, +1292, +1292, +1291, +1290, +1289, +1288, +1287, +1285, +1284, +1282, +1280, +1278, +1276, +1274, +1271, +1269, +1266, +1263, +1260, +1257, +1253, +1250, +1246, +1242, +1238, +1234, +1230, +1225, +1221, +1216, +1211, +1206, +1201, +1196, +1190, +1185, +1179, +1173, +1167, +1161, +1155, +1149, +1142, +1136, +1129, +1122, +1115, +1108, +1101, +1094, +1086, +1078, +1071, +1063, +1055, +1047, +1039, +1030, +1022, +1013, +1005, +996, +987, +978, +969, +960, +951, +941, +932, +922, +913, +903, +893, +883, +873, +863, +853, +842, +832, +821, +811, +800, +789, +778, +768, +757, +746, +734, +723, +712, +701, +689, +678, +666, +654, +643, +631, +619, +607, +596, +584, +572, +559, +547, +535, +523, +511, +498, +486, +474, +461, +449, +436, +424, +411, +399, +386, +373, +361, +348, +335, +322, +310, +297, +284, +271, +258, +246, +233, +220, +207, +194, +181, +168, +156, +143, +130, +117, +104, +91, +78, +65, +53, +40, +27, +14, +1, +-10, +-23, +-36, +-48, +-61, +-74, +-86, +-99, +-111, +-124, +-136, +-149, +-161, +-174, +-186, +-198, +-211, +-223, +-235, +-247, +-259, +-271, +-283, +-295, +-307, +-319, +-330, +-342, +-354, +-365, +-377, +-388, +-399, +-411, +-422, +-433, +-444, +-455, +-466, +-477, +-488, +-499, +-509, +-520, +-530, +-541, +-551, +-561, +-571, +-581, +-591, +-601, +-611, +-621, +-631, +-640, +-650, +-659, +-668, +-677, +-686, +-695, +-704, +-713, +-722, +-730, +-739, +-747, +-755, +-763, +-771, +-779, +-787, +-795, +-803, +-810, +-817, +-825, +-832, +-839, +-846, +-853, +-859, +-866, +-873, +-879, +-885, +-891, +-897, +-903, +-909, +-915, +-920, +-926, +-931, +-936, +-941, +-946, +-951, +-955, +-960, +-964, +-969, +-973, +-977, +-981, +-985, +-988, +-992, +-995, +-999, +-1002, +-1005, +-1008, +-1011, +-1013, +-1016, +-1018, +-1020, +-1023, +-1025, +-1026, +-1028, +-1030, +-1031, +-1033, +-1034, +-1035, +-1036, +-1037, +-1038, +-1038, +-1039, +-1039, +-1039, +-1039, +-1039, +-1039, +-1039, +-1038, +-1038, +-1037, +-1036, +-1036, +-1034, +-1033, +-1032, +-1031, +-1029, +-1027, +-1026, +-1024, +-1022, +-1019, +-1017, +-1015, +-1012, +-1010, +-1007, +-1004, +-1001, +-998, +-995, +-991, +-988, +-984, +-980, +-977, +-973, +-969, +-965, +-960, +-956, +-951, +-947, +-942, +-937, +-932, +-927, +-922, +-917, +-912, +-906, +-901, +-895, +-889, +-883, +-877, +-871, +-865, +-859, +-853, +-846, +-840, +-833, +-826, +-819, +-812, +-805, +-798, +-791, +-784, +-777, +-769, +-762, +-754, +-746, +-739, +-731, +-723, +-715, +-707, +-699, +-691, +-682, +-674, +-665, +-657, +-648, +-640, +-631, +-622, +-614, +-605, +-596, +-587, +-578, +-569, +-559, +-550, +-541, +-532, +-522, +-513, +-503, +-494, +-484, +-474, +-465, +-455, +-445, +-436, +-426, +-416, +-406, +-396, +-386, +-376, +-366, +-356, +-346, +-336, +-325, +-315, +-305, +-295, +-285, +-274, +-264, +-254, +-243, +-233, +-223, +-212, +-202, +-192, +-181, +-171, +-161, +-150, +-140, +-129, +-119, +-108, +-98, +-88, +-77, +-67, +-57, +-46, +-36, +-25, +-15, +-5, +5, +15, +25, +35, +46, +56, +66, +76, +86, +97, +107, +117, +127, +137, +147, +157, +167, +177, +186, +196, +206, +216, +225, +235, +245, +254, +264, +273, +283, +292, +301, +311, +320, +329, +338, +347, +356, +365, +374, +383, +392, +400, +409, +418, +426, +435, +443, +451, +460, +468, +476, +484, +492, +500, +508, +515, +523, +531, +538, +546, +553, +560, +568, +575, +582, +589, +596, +602, +609, +616, +622, +629, +635, +642, +648, +654, +660, +666, +672, +678, +683, +689, +694, +700, +705, +710, +715, +720, +725, +730, +735, +739, +744, +748, +753, +757, +761, +765, +769, +773, +777, +780, +784, +787, +791, +794, +797, +800, +803, +806, +809, +811, +814, +816, +818, +821, +823, +825, +827, +828, +830, +832, +833, +835, +836, +837, +838, +839, +840, +841, +841, +842, +842, +843, +843, +843, +843, +843, +843, +843, +842, +842, +841, +840, +840, +839, +838, +837, +835, +834, +833, +831, +830, +828, +826, +824, +822, +820, +818, +816, +813, +811, +808, +806, +803, +800, +797, +794, +791, +788, +784, +781, +777, +774, +770, +766, +763, +759, +755, +750, +746, +742, +738, +733, +729, +724, +719, +714, +710, +705, +700, +694, +689, +684, +679, +673, +668, +662, +657, +651, +645, +639, +633, +627, +621, +615, +609, +603, +596, +590, +584, +577, +571, +564, +557, +551, +544, +537, +530, +523, +516, +509, +502, +495, +487, +480, +473, +465, +458, +450, +443, +435, +428, +420, +413, +405, +397, +389, +381, +374, +366, +358, +350, +342, +334, +326, +318, +310, +301, +293, +285, +277, +269, +260, +252, +244, +236, +227, +219, +211, +202, +194, +185, +177, +169, +160, +152, +143, +135, +126, +118, +110, +101, +93, +84, +76, +67, +59, +50, +42, +34, +25, +17, +8, +0, +-7, +-16, +-24, +-32, +-41, +-49, +-57, +-66, +-74, +-82, +-90, +-98, +-106, +-115, +-123, +-131, +-139, +-147, +-155, +-163, +-171, +-179, +-186, +-194, +-202, +-210, +-217, +-225, +-233, +-240, +-248, +-255, +-263, +-270, +-278, +-285, +-292, +-299, +-307, +-314, +-321, +-328, +-335, +-342, +-349, +-356, +-362, +-369, +-376, +-382, +-389, +-396, +-402, +-408, +-415, +-421, +-427, +-433, +-439, +-445, +-451, +-457, +-463, +-469, +-475, +-480, +-486, +-491, +-497, +-502, +-507, +-513, +-518, +-523, +-528, +-533, +-538, +-542, +-547, +-552, +-556, +-561, +-565, +-570, +-574, +-578, +-582, +-586, +-590, +-594, +-598, +-602, +-605, +-609, +-612, +-616, +-619, +-622, +-625, +-629, +-632, +-634, +-637, +-640, +-643, +-645, +-648, +-650, +-653, +-655, +-657, +-659, +-661, +-663, +-665, +-667, +-668, +-670, +-671, +-673, +-674, +-675, +-676, +-678, +-679, +-679, +-680, +-681, +-682, +-682, +-683, +-683, +-683, +-684, +-684, +-684, +-684, +-684, +-684, +-683, +-683, +-682, +-682, +-681, +-681, +-680, +-679, +-678, +-677, +-676, +-675, +-674, +-672, +-671, +-669, +-668, +-666, +-664, +-662, +-661, +-659, +-657, +-654, +-652, +-650, +-648, +-645, +-643, +-640, +-637, +-635, +-632, +-629, +-626, +-623, +-620, +-617, +-613, +-610, +-607, +-603, +-600, +-596, +-593, +-589, +-585, +-581, +-577, +-573, +-569, +-565, +-561, +-557, +-552, +-548, +-544, +-539, +-534, +-530, +-525, +-520, +-516, +-511, +-506, +-501, +-496, +-491, +-486, +-481, +-475, +-470, +-465, +-460, +-454, +-449, +-443, +-438, +-432, +-426, +-421, +-415, +-409, +-403, +-398, +-392, +-386, +-380, +-374, +-368, +-362, +-355, +-349, +-343, +-337, +-331, +-324, +-318, +-312, +-305, +-299, +-292, +-286, +-280, +-273, +-266, +-260, +-253, +-247, +-240, +-234, +-227, +-220, +-213, +-207, +-200, +-193, +-187, +-180, +-173, +-166, +-159, +-153, +-146, +-139, +-132, +-125, +-118, +-112, +-105, +-98, +-91, +-84, +-77, +-70, +-64, +-57, +-50, +-43, +-36, +-29, +-22, +-16, +-9, +-2, +4, +11, +17, +24, +31, +38, +44, +51, +58, +64, +71, +78, +84, +91, +98, +104, +111, +117, +124, +130, +137, +143, +149, +156, +162, +168, +175, +181, +187, +193, +199, +205, +212, +218, +224, +230, +236, +241, +247, +253, +259, +265, +270, +276, +282, +287, +293, +298, +304, +309, +314, +320, +325, +330, +335, +340, +345, +350, +355, +360, +365, +370, +375, +380, +384, +389, +393, +398, +402, +407, +411, +415, +419, +424, +428, +432, +436, +440, +443, +447, +451, +455, +458, +462, +465, +469, +472, +475, +479, +482, +485, +488, +491, +494, +497, +499, +502, +505, +507, +510, +512, +515, +517, +519, +522, +524, +526, +528, +530, +532, +533, +535, +537, +538, +540, +541, +543, +544, +545, +546, +548, +549, +550, +550, +551, +552, +553, +553, +554, +554, +555, +555, +555, +556, +556, +556, +556, +556, +556, +555, +555, +555, +554, +554, +553, +553, +552, +551, +551, +550, +549, +548, +547, +546, +545, +543, +542, +541, +539, +538, +536, +534, +533, +531, +529, +527, +525, +523, +521, +519, +517, +514, +512, +510, +507, +505, +502, +500, +497, +494, +492, +489, +486, +483, +480, +477, +474, +471, +467, +464, +461, +457, +454, +450, +447, +443, +440, +436, +432, +429, +425, +421, +417, +413, +409, +405, +401, +397, +393, +388, +384, +380, +375, +371, +367, +362, +358, +353, +349, +344, +339, +335, +330, +325, +321, +316, +311, +306, +301, +296, +291, +286, +281, +276, +271, +266, +261, +256, +251, +245, +240, +235, +230, +225, +219, +214, +209, +203, +198, +193, +187, +182, +176, +171, +165, +160, +154, +149, +144, +138, +132, +127, +121, +116, +110, +105, +99, +94, +88, +83, +77, +71, +66, +60, +55, +49, +44, +38, +33, +27, +21, +16, +10, +5, +0, +-5, +-11, +-16, +-22, +-27, +-33, +-38, +-43, +-49, +-54, +-60, +-65, +-70, +-76, +-81, +-86, +-92, +-97, +-102, +-107, +-113, +-118, +-123, +-128, +-133, +-138, +-143, +-148, +-153, +-158, +-163, +-168, +-173, +-178, +-183, +-188, +-192, +-197, +-202, +-207, +-211, +-216, +-221, +-225, +-230, +-234, +-239, +-243, +-247, +-252, +-256, +-260, +-265, +-269, +-273, +-277, +-281, +-285, +-289, +-293, +-297, +-301, +-305, +-308, +-312, +-316, +-319, +-323, +-327, +-330, +-334, +-337, +-340, +-344, +-347, +-350, +-353, +-357, +-360, +-363, +-366, +-369, +-372, +-374, +-377, +-380, +-383, +-385, +-388, +-390, +-393, +-395, +-398, +-400, +-402, +-405, +-407, +-409, +-411, +-413, +-415, +-417, +-419, +-420, +-422, +-424, +-425, +-427, +-429, +-430, +-431, +-433, +-434, +-435, +-436, +-438, +-439, +-440, +-441, +-442, +-442, +-443, +-444, +-445, +-445, +-446, +-446, +-447, +-447, +-448, +-448, +-448, +-448, +-449, +-449, +-449, +-449, +-449, +-448, +-448, +-448, +-448, +-447, +-447, +-446, +-446, +-445, +-445, +-444, +-443, +-442, +-442, +-441, +-440, +-439, +-438, +-437, +-435, +-434, +-433, +-432, +-430, +-429, +-427, +-426, +-424, +-423, +-421, +-419, +-418, +-416, +-414, +-412, +-410, +-408, +-406, +-404, +-402, +-400, +-397, +-395, +-393, +-390, +-388, +-385, +-383, +-380, +-378, +-375, +-373, +-370, +-367, +-364, +-361, +-359, +-356, +-353, +-350, +-347, +-344, +-340, +-337, +-334, +-331, +-328, +-324, +-321, +-318, +-314, +-311, +-307, +-304, +-300, +-297, +-293, +-290, +-286, +-282, +-279, +-275, +-271, +-267, +-263, +-260, +-256, +-252, +-248, +-244, +-240, +-236, +-232, +-228, +-224, +-220, +-216, +-212, +-207, +-203, +-199, +-195, +-191, +-186, +-182, +-178, +-174, +-169, +-165, +-161, +-156, +-152, +-148, +-143, +-139, +-134, +-130, +-126, +-121, +-117, +-112, +-108, +-103, +-99, +-95, +-90, +-86, +-81, +-77, +-72, +-68, +-63, +-59, +-54, +-50, +-45, +-41, +-36, +-32, +-27, +-23, +-18, +-14, +-9, +-5, +0, +3, +7, +12, +16, +21, +25, +29, +34, +38, +43, +47, +51, +56, +60, +64, +69, +73, +77, +81, +85, +90, +94, +98, +102, +106, +110, +115, +119, +123, +127, +131, +135, +139, +143, +146, +150, +154, +158, +162, +166, +169, +173, +177, +181, +184, +188, +192, +195, +199, +202, +206, +209, +212, +216, +219, +223, +226, +229, +232, +236, +239, +242, +245, +248, +251, +254, +257, +260, +263, +266, +268, +271, +274, +277, +279, +282, +284, +287, +289, +292, +294, +297, +299, +301, +304, +306, +308, +310, +312, +314, +316, +318, +320, +322, +324, +326, +328, +329, +331, +333, +334, +336, +337, +339, +340, +341, +343, +344, +345, +346, +348, +349, +350, +351, +352, +353, +354, +354, +355, +356, +357, +357, +358, +358, +359, +359, +360, +360, +361, +361, +361, +361, +362, +362, +362, +362, +362, +362, +362, +361, +361, +361, +361, +360, +360, +360, +359, +359, +358, +358, +357, +356, +356, +355, +354, +353, +352, +351, +350, +349, +348, +347, +346, +345, +344, +343, +341, +340, +339, +337, +336, +334, +333, +331, +330, +328, +326, +324, +323, +321, +319, +317, +315, +313, +311, +309, +307, +305, +303, +301, +299, +297, +294, +292, +290, +288, +285, +283, +280, +278, +275, +273, +270, +268, +265, +263, +260, +257, +254, +252, +249, +246, +243, +240, +238, +235, +232, +229, +226, +223, +220, +217, +214, +211, +208, +204, +201, +198, +195, +192, +188, +185, +182, +179, +175, +172, +169, +165, +162, +159, +155, +152, +149, +145, +142, +138, +135, +131, +128, +124, +121, +117, +114, +110, +107, +103, +100, +96, +93, +89, +85, +82, +78, +75, +71, +67, +64, +60, +57, +53, +49, +46, +42, +39, +35, +31, +28, +24, +21, +17, +14, +10, +6, +3, +0, +-3, +-7, +-10, +-14, +-18, +-21, +-25, +-28, +-32, +-35, +-39, +-42, +-45, +-49, +-52, +-56, +-59, +-63, +-66, +-69, +-73, +-76, +-79, +-83, +-86, +-89, +-93, +-96, +-99, +-102, +-105, +-109, +-112, +-115, +-118, +-121, +-124, +-127, +-130, +-133, +-136, +-139, +-142, +-145, +-148, +-151, +-154, +-157, +-160, +-162, +-165, +-168, +-171, +-173, +-176, +-179, +-181, +-184, +-186, +-189, +-191, +-194, +-196, +-199, +-201, +-204, +-206, +-208, +-211, +-213, +-215, +-217, +-219, +-221, +-224, +-226, +-228, +-230, +-232, +-234, +-236, +-237, +-239, +-241, +-243, +-245, +-246, +-248, +-250, +-251, +-253, +-254, +-256, +-257, +-259, +-260, +-262, +-263, +-264, +-266, +-267, +-268, +-269, +-270, +-271, +-273, +-274, +-275, +-275, +-276, +-277, +-278, +-279, +-280, +-281, +-281, +-282, +-283, +-283, +-284, +-284, +-285, +-285, +-286, +-286, +-286, +-287, +-287, +-287, +-287, +-288, +-288, +-288, +-288, +-288, +-288, +-288, +-288, +-288, +-288, +-287, +-287, +-287, +-287, +-286, +-286, +-286, +-285, +-285, +-284, +-284, +-283, +-283, +-282, +-281, +-281, +-280, +-279, +-278, +-277, +-277, +-276, +-275, +-274, +-273, +-272, +-271, +-270, +-269, +-267, +-266, +-265, +-264, +-262, +-261, +-260, +-258, +-257, +-256, +-254, +-253, +-251, +-250, +-248, +-247, +-245, +-243, +-242, +-240, +-238, +-236, +-235, +-233, +-231, +-229, +-227, +-225, +-223, +-221, +-219, +-217, +-215, +-213, +-211, +-209, +-207, +-205, +-203, +-201, +-198, +-196, +-194, +-192, +-189, +-187, +-185, +-182, +-180, +-178, +-175, +-173, +-170, +-168, +-165, +-163, +-160, +-158, +-155, +-153, +-150, +-148, +-145, +-142, +-140, +-137, +-135, +-132, +-129, +-127, +-124, +-121, +-118, +-116, +-113, +-110, +-108, +-105, +-102, +-99, +-96, +-94, +-91, +-88, +-85, +-82, +-80, +-77, +-74, +-71, +-68, +-65, +-63, +-60, +-57, +-54, +-51, +-48, +-45, +-42, +-40, +-37, +-34, +-31, +-28, +-25, +-22, +-20, +-17, +-14, +-11, +-8, +-5, +-2, +0, +2, +5, +8, +11, +13, +16, +19, +22, +25, +27, +30, +33, +36, +38, +41, +44, +47, +49, +52, +55, +57, +60, +63, +65, +68, +71, +73, +76, +78, +81, +83, +86, +88, +91, +93, +96, +98, +101, +103, +106, +108, +110, +113, +115, +117, +120, +122, +124, +127, +129, +131, +133, +135, +137, +140, +142, +144, +146, +148, +150, +152, +154, +156, +158, +160, +161, +163, +165, +167, +169, +171, +172, +174, +176, +177, +179, +181, +182, +184, +185, +187, +188, +190, +191, +193, +194, +195, +197, +198, +199, +201, +202, +203, +204, +205, +207, +208, +209, +210, +211, +212, +213, +214, +215, +216, +216, +217, +218, +219, +219, +220, +221, +222, +222, +223, +223, +224, +224, +225, +225, +226, +226, +227, +227, +227, +227, +228, +228, +228, +228, +228, +229, +229, +229, +229, +229, +229, +229, +229, +228, +228, +228, +228, +228, +228, +227, +227, +227, +226, +226, +225, +225, +225, +224, +224, +223, +222, +222, +221, +221, +220, +219, +218, +218, +217, +216, +215, +214, +214, +213, +212, +211, +210, +209, +208, +207, +206, +205, +203, +202, +201, +200, +199, +197, +196, +195, +194, +192, +191, +190, +188, +187, +185, +184, +182, +181, +179, +178, +176, +175, +173, +172, +170, +168, +167, +165, +163, +162, +160, +158, +156, +155, +153, +151, +149, +147, +146, +144, +142, +140, +138, +136, +134, +132, +130, +128, +126, +124, +122, +120, +118, +116, +114, +112, +110, +108, +106, +104, +102, +99, +97, +95, +93, +91, +89, +87, +84, +82, +80, +78, +76, +73, +71, +69, +67, +64, +62, +60, +58, +56, +53, +51, +49, +47, +44, +42, +40, +38, +35, +33, +31, +28, +26, +24, +22, +19, +17, +15, +13, +10, +8, +6, +4, +1, +0, +-2, +-4, +-6, +-9, +-11, +-13, +-15, +-17, +-20, +-22, +-24, +-26, +-28, +-30, +-33, +-35, +-37, +-39, +-41, +-43, +-45, +-47, +-49, +-52, +-54, +-56, +-58, +-60, +-62, +-64, +-66, +-68, +-70, +-72, +-74, +-76, +-77, +-79, +-81, +-83, +-85, +-87, +-89, +-90, +-92, +-94, +-96, +-98, +-99, +-101, +-103, +-105, +-106, +-108, +-110, +-111, +-113, +-114, +-116, +-118, +-119, +-121, +-122, +-124, +-125, +-127, +-128, +-130, +-131, +-132, +-134, +-135, +-136, +-138, +-139, +-140, +-142, +-143, +-144, +-145, +-146, +-148, +-149, +-150, +-151, +-152, +-153, +-154, +-155, +-156, +-157, +-158, +-159, +-160, +-161, +-162, +-162, +-163, +-164, +-165, +-166, +-166, +-167, +-168, +-168, +-169, +-170, +-170, +-171, +-171, +-172, +-172, +-173, +-173, +-174, +-174, +-175, +-175, +-175, +-176, +-176, +-176, +-177, +-177, +-177, +-177, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-178, +-177, +-177, +-177, +-177, +-177, +-176, +-176, +-176, +-175, +-175, +-175, +-174, +-174, +-173, +-173, +-172, +-172, +-171, +-171, +-170, +-170, +-169, +-168, +-168, +-167, +-166, +-166, +-165, +-164, +-163, +-163, +-162, +-161, +-160, +-159, +-158, +-158, +-157, +-156, +-155, +-154, +-153, +-152, +-151, +-150, +-149, +-148, +-147, +-145, +-144, +-143, +-142, +-141, +-140, +-139, +-137, +-136, +-135, +-134, +-132, +-131, +-130, +-128, +-127, +-126, +-124, +-123, +-122, +-120, +-119, +-118, +-116, +-115, +-113, +-112, +-110, +-109, +-107, +-106, +-104, +-103, +-101, +-100, +-98, +-97, +-95, +-94, +-92, +-90, +-89, +-87, +-86, +-84, +-82, +-81, +-79, +-77, +-76, +-74, +-72, +-71, +-69, +-67, +-66, +-64, +-62, +-60, +-59, +-57, +-55, +-54, +-52, +-50, +-48, +-47, +-45, +-43, +-41, +-40, +-38, +-36, +-34, +-33, +-31, +-29, +-27, +-25, +-24, +-22, +-20, +-18, +-17, +-15, +-13, +-11, +-10, +-8, +-6, +-4, +-3, +-1, +0, +2, +3, +5, +7, +8, +10, +12, +14, +15, +17, +19, +20, +22, +24, +25, +27, +29, +30, +32, +34, +35, +37, +39, +40, +42, +43, +45, +47, +48, +50, +51, +53, +54, +56, +57, +59, +60, +62, +63, +65, +66, +68, +69, +70, +72, +73, +75, +76, +77, +79, +80, +81, +83, +84, +85, +87, +88, +89, +90, +92, +93, +94, +95, +96, +97, +99, +100, +101, +102, +103, +104, +105, +106, +107, +108, +109, +110, +111, +112, +113, +114, +115, +116, +117, +117, +118, +119, +120, +121, +121, +122, +123, +124, +124, +125, +126, +126, +127, +128, +128, +129, +129, +130, +130, +131, +131, +132, +132, +133, +133, +134, +134, +135, +135, +135, +136, +136, +136, +136, +137, +137, +137, +137, +138, +138, +138, +138, +138, +138, +138, +138, +139, +139, +139, +139, +139, +139, +139, +138, +138, +138, +138, +138, +138, +138, +138, +137, +137, +137, +137, +136, +136, +136, +136, +135, +135, +134, +134, +134, +133, +133, +132, +132, +132, +131, +131, +130, +129, +129, +128, +128, +127, +127, +126, +125, +125, +124, +123, +123, +122, +121, +121, +120, +119, +118, +117, +117, +116, +115, +114, +113, +113, +112, +111, +110, +109, +108, +107, +106, +105, +104, +103, +102, +101, +100, +99, +98, +97, +96, +95, +94, +93, +92, +91, +90, +89, +87, +86, +85, +84, +83, +82, +81, +79, +78, +77, +76, +75, +73, +72, +71, +70, +68, +67, +66, +65, +63, +62, +61, +60, +58, +57, +56, +54, +53, +52, +50, +49, +48, +47, +45, +44, +43, +41, +40, +39, +37, +36, +34, +33, +32, +30, +29, +28, +26, +25, +24, +22, +21, +20, +18, +17, +16, +14, +13, +11, +10, +9, +7, +6, +5, +3, +2, +1, +0, +-1, +-2, +-4, +-5, +-6, +-8, +-9, +-10, +-11, +-13, +-14, +-15, +-17, +-18, +-19, +-20, +-22, +-23, +-24, +-26, +-27, +-28, +-29, +-30, +-32, +-33, +-34, +-35, +-37, +-38, +-39, +-40, +-41, +-42, +-44, +-45, +-46, +-47, +-48, +-49, +-50, +-51, +-53, +-54, +-55, +-56, +-57, +-58, +-59, +-60, +-61, +-62, +-63, +-64, +-65, +-66, +-67, +-68, +-69, +-70, +-71, +-71, +-72, +-73, +-74, +-75, +-76, +-77, +-77, +-78, +-79, +-80, +-81, +-81, +-82, +-83, +-84, +-84, +-85, +-86, +-87, +-87, +-88, +-89, +-89, +-90, +-90, +-91, +-92, +-92, +-93, +-93, +-94, +-94, +-95, +-95, +-96, +-96, +-97, +-97, +-98, +-98, +-99, +-99, +-99, +-100, +-100, +-100, +-101, +-101, +-101, +-102, +-102, +-102, +-102, +-103, +-103, +-103, +-103, +-103, +-104, +-104, +-104, +-104, +-104, +-104, +-104, +-105, +-105, +-105, +-105, +-105, +-105, +-105, +-105, +-105, +-105, +-105, +-105, +-104, +-104, +-104, +-104, +-104, +-104, +-104, +-104, +-103, +-103, +-103, +-103, +-103, +-102, +-102, +-102, +-102, +-101, +-101, +-101, +-100, +-100, +-100, +-99, +-99, +-99, +-98, +-98, +-97, +-97, +-97, +-96, +-96, +-95, +-95, +-94, +-94, +-93, +-93, +-92, +-92, +-91, +-90, +-90, +-89, +-89, +-88, +-87, +-87, +-86, +-86, +-85, +-84, +-84, +-83, +-82, +-81, +-81, +-80, +-79, +-79, +-78, +-77, +-76, +-76, +-75, +-74, +-73, +-72, +-72, +-71, +-70, +-69, +-68, +-67, +-67, +-66, +-65, +-64, +-63, +-62, +-61, +-61, +-60, +-59, +-58, +-57, +-56, +-55, +-54, +-53, +-52, +-51, +-50, +-49, +-48, +-48, +-47, +-46, +-45, +-44, +-43, +-42, +-41, +-40, +-39, +-38, +-37, +-36, +-35, +-34, +-33, +-32, +-31, +-30, +-29, +-28, +-27, +-26, +-25, +-24, +-23, +-21, +-20, +-19, +-18, +-17, +-16, +-15, +-14, +-13, +-12, +-11, +-10, +-9, +-8, +-7, +-6, +-5, +-4, +-3, +-2, +-1, +0, +0, +1, +2, +3, +4, +5, +6, +7, +8, +9, +10, +11, +12, +13, +14, +15, +16, +17, +18, +19, +20, +21, +22, +22, +23, +24, +25, +26, +27, +28, +29, +30, +31, +32, +32, +33, +34, +35, +36, +37, +38, +38, +39, +40, +41, +42, +42, +43, +44, +45, +46, +46, +47, +48, +49, +49, +50, +51, +52, +52, +53, +54, +54, +55, +56, +56, +57, +58, +58, +59, +59, +60, +61, +61, +62, +62, +63, +64, +64, +65, +65, +66, +66, +67, +67, +68, +68, +69, +69, +69, +70, +70, +71, +71, +72, +72, +72, +73, +73, +73, +74, +74, +74, +75, +75, +75, +76, +76, +76, +76, +77, +77, +77, +77, +77, +78, +78, +78, +78, +78, +78, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +79, +78, +78, +78, +78, +78, +78, +77, +77, +77, +77, +77, +76, +76, +76, +76, +75, +75, +75, +74, +74, +74, +74, +73, +73, +72, +72, +72, +71, +71, +71, +70, +70, +69, +69, +69, +68, +68, +67, +67, +66, +66, +65, +65, +64, +64, +63, +63, +62, +62, +61, +61, +60, +60, +59, +59, +58, +57, +57, +56, +56, +55, +55, +54, +53, +53, +52, +51, +51, +50, +50, +49, +48, +48, +47, +46, +46, +45, +44, +44, +43, +42, +41, +41, +40, +39, +39, +38, +37, +37, +36, +35, +34, +34, +33, +32, +31, +31, +30, +29, +28, +28, +27, +26, +25, +25, +24, +23, +22, +22, +21, +20, +19, +19, +18, +17, +16, +16, +15, +14, +13, +12, +12, +11, +10, +9, +9, +8, +7, +6, +6, +5, +4, +3, +3, +2, +1, +0, +0, +0, +-1, +-2, +-2, +-3, +-4, +-5, +-5, +-6, +-7, +-8, +-8, +-9, +-10, +-10, +-11, +-12, +-13, +-13, +-14, +-15, +-15, +-16, +-17, +-17, +-18, +-19, +-19, +-20, +-21, +-21, +-22, +-23, +-23, +-24, +-25, +-25, +-26, +-27, +-27, +-28, +-28, +-29, +-30, +-30, +-31, +-31, +-32, +-33, +-33, +-34, +-34, +-35, +-35, +-36, +-36, +-37, +-37, +-38, +-38, +-39, +-39, +-40, +-40, +-41, +-41, +-42, +-42, +-43, +-43, +-44, +-44, +-45, +-45, +-45, +-46, +-46, +-47, +-47, +-47, +-48, +-48, +-49, +-49, +-49, +-50, +-50, +-50, +-51, +-51, +-51, +-51, +-52, +-52, +-52, +-53, +-53, +-53, +-53, +-54, +-54, +-54, +-54, +-54, +-55, +-55, +-55, +-55, +-55, +-56, +-56, +-56, +-56, +-56, +-56, +-56, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-57, +-56, +-56, +-56, +-56, +-56, +-56, +-56, +-55, +-55, +-55, +-55, +-55, +-54, +-54, +-54, +-54, +-54, +-53, +-53, +-53, +-53, +-52, +-52, +-52, +-52, +-51, +-51, +-51, +-50, +-50, +-50, +-50, +-49, +-49, +-49, +-48, +-48, +-48, +-47, +-47, +-46, +-46, +-46, +-45, +-45, +-45, +-44, +-44, +-43, +-43, +-43, +-42, +-42, +-41, +-41, +-40, +-40, +-40, +-39, +-39, +-38, +-38, +-37, +-37, +-36, +-36, +-35, +-35, +-35, +-34, +-34, +-33, +-33, +-32, +-32, +-31, +-31, +-30, +-30, +-29, +-29, +-28, +-28, +-27, +-26, +-26, +-25, +-25, +-24, +-24, +-23, +-23, +-22, +-22, +-21, +-21, +-20, +-19, +-19, +-18, +-18, +-17, +-17, +-16, +-16, +-15, +-15, +-14, +-13, +-13, +-12, +-12, +-11, +-11, +-10, +-9, +-9, +-8, +-8, +-7, +-7, +-6, +-6, +-5, +-4, +-4, +-3, +-3, +-2, +-2, +-1, +-1, +0, +0, +0, +1, +1, +2, +2, +3, +3, +4, +4, +5, +5, +6, +7, +7, +8, +8, +9, +9, +10, +10, +11, +11, +12, +12, +13, +13, +14, +14, +15, +15, +16, +16, +17, +17, +18, +18, +18, +19, +19, +20, +20, +21, +21, +22, +22, +22, +23, +23, +24, +24, +25, +25, +25, +26, +26, +27, +27, +27, +28, +28, +28, +29, +29, +30, +30, +30, +31, +31, +31, +32, +32, +32, +33, +33, +33, +33, +34, +34, +34, +35, +35, +35, +35, +36, +36, +36, +36, +37, +37, +37, +37, +38, +38, +38, +38, +38, +39, +39, +39, +39, +39, +40, +40, +40, +40, +40, +40, +40, +41, +41, +41, +41, +41, +41, +41, +41, +41, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +42, +41, +41, +41, +41, +41, +41, +41, +41, +41, +41, +40, +40, +40, +40, +40, +40, +40, +39, +39, +39, +39, +39, +38, +38, +38, +38, +38, +37, +37, +37, +37, +37, +36, +36, +36, +36, +35, +35, +35, +35, +34, +34, +34, +34, +33, +33, +33, +33, +32, +32, +32, +31, +31, +31, +30, +30, +30, +30, +29, +29, +29, +28, +28, +28, +27, +27, +27, +26, +26, +26, +25, +25, +25, +24, +24, +23, +23, +23, +22, +22, +22, +21, +21, +21, +20, +20, +19, +19, +19, +18, +18, +18, +17, +17, +16, +16, +16, +15, +15, +14, +14, +14, +13, +13, +12, +12, +12, +11, +11, +10, +10, +10, +9, +9, +8, +8, +8, +7, +7, +6, +6, +6, +5, +5, +4, +4, +4, +3, +3, +2, +2, +2, +1, +1, +1, +0, +0, +0, +0, +0, +-1, +-1, +-2, +-2, +-2, +-3, +-3, +-3, +-4, +-4, +-5, +-5, +-5, +-6, +-6, +-6, +-7, +-7, +-7, +-8, +-8, +-9, +-9, +-9, +-10, +-10, +-10, +-11, +-11, +-11, +-12, +-12, +-12, +-13, +-13, +-13, +-14, +-14, +-14, +-14, +-15, +-15, +-15, +-16, +-16, +-16, +-17, +-17, +-17, +-17, +-18, +-18, +-18, +-19, +-19, +-19, +-19, +-20, +-20, +-20, +-20, +-21, +-21, +-21, +-21, +-21, +-22, +-22, +-22, +-22, +-23, +-23, +-23, +-23, +-23, +-24, +-24, +-24, +-24, +-24, +-25, +-25, +-25, +-25, +-25, +-25, +-26, +-26, +-26, +-26, +-26, +-26, +-26, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-29, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-28, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-27, +-26, +-26, +-26, +-26, +-26, +-26, +-26, +-25, +-25, +-25, +-25, +-25, +-25, +-25, +-24, +-24, +-24, +-24, +-24, +-24, +-23, +-23, +-23, +-23, +-23, +-22, +-22, +-22, +-22, +-22, +-21, +-21, +-21, +-21, +-21, +-20, +-20, +-20, +-20, +-20, +-19, +-19, +-19, +-19, +-18, +-18, +-18, +-18, +-17, +-17, +-17, +-17, +-16, +-16, +-16, +-16, +-15, +-15, +-15, +-15, +-14, +-14, +-14, +-14, +-13, +-13, +-13, +-13, +-12, +-12, +-12, +-12, +-11, +-11, +-11, +-11, +-10, +-10, +-10, +-9, +-9, +-9, +-9, +-8, +-8, +-8, +-7, +-7, +-7, +-7, +-6, +-6, +-6, +-6, +-5, +-5, +-5, +-4, +-4, +-4, +-4, +-3, +-3, +-3, +-2, +-2, +-2, +-2, +-1, +-1, +-1, +-1, +0, +0, +0, +0, +0, +0, +0, +1, +1, +1, +1, +2, +2, +2, +2, +3, +3, +3, +3, +4, +4, +4, +5, +5, +5, +5, +6, +6, +6, +6, +6, +7, +7, +7, +7, +8, +8, +8, +8, +9, +9, +9, +9, +10, +10, +10, +10, +10, +11, +11, +11, +11, +11, +12, +12, +12, +12, +12, +13, +13, +13, +13, +13, +14, +14, +14, +14, +14, +14, +15, +15, +15, +15, +15, +15, +16, +16, +16, +16, +16, +16, +16, +17, +17, +17, +17, +17, +17, +17, +17, +18, +18, +18, +18, +18, +18, +18, +18, +18, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +20, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +19, +18, +18, +18, +18, +18, +18, +18, +18, +18, +18, +17, +17, +17, +17, +17, +17, +17, +17, +16, +16, +16, +16, +16, +16, +16, +16, +15, +15, +15, +15, +15, +15, +15, +14, +14, +14, +14, +14, +14, +14, +13, +13, +13, +13, +13, +13, +12, +12, +12, +12, +12, +12, +11, +11, +11, +11, +11, +11, +10, +10, +10, +10, +10, +9, +9, +9, +9, +9, +9, +8, +8, +8, +8, +8, +7, +7, +7, +7, +7, +7, +6, +6, +6, +6, +6, +5, +5, +5, +5, +5, +4, +4, +4, +4, +4, +4, +3, +3, +3, +3, +3, +2, +2, +2, +2, +2, +2, +1, +1, +1, +1, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-3, +-3, +-3, +-3, +-3, +-4, +-4, +-4, +-4, +-4, +-4, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +3, +3, +3, +3, +3, +3, +3, +3, +3, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +8, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +7, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +6, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0}; + +static short LARGE_FILTER_IMPD[] /* Impulse response differences */ = { +-1, +-2, +-3, +-5, +-6, +-7, +-9, +-10, +-11, +-13, +-14, +-15, +-17, +-18, +-19, +-21, +-22, +-23, +-25, +-26, +-27, +-28, +-30, +-32, +-32, +-34, +-35, +-36, +-38, +-39, +-40, +-42, +-43, +-44, +-45, +-47, +-48, +-49, +-51, +-52, +-53, +-54, +-56, +-56, +-58, +-60, +-60, +-62, +-63, +-64, +-66, +-66, +-68, +-69, +-70, +-72, +-72, +-74, +-75, +-76, +-77, +-79, +-79, +-81, +-82, +-83, +-84, +-85, +-87, +-87, +-89, +-90, +-90, +-92, +-93, +-94, +-95, +-96, +-98, +-98, +-99, +-100, +-102, +-102, +-103, +-105, +-105, +-106, +-108, +-108, +-109, +-110, +-111, +-112, +-113, +-114, +-115, +-116, +-116, +-118, +-118, +-119, +-121, +-120, +-122, +-123, +-123, +-125, +-125, +-126, +-126, +-128, +-128, +-129, +-130, +-130, +-132, +-132, +-132, +-134, +-134, +-135, +-135, +-136, +-137, +-137, +-138, +-139, +-139, +-140, +-141, +-141, +-142, +-142, +-143, +-143, +-144, +-145, +-145, +-145, +-146, +-147, +-147, +-147, +-148, +-149, +-148, +-150, +-149, +-150, +-151, +-151, +-151, +-152, +-152, +-152, +-153, +-153, +-153, +-153, +-154, +-154, +-155, +-155, +-155, +-155, +-155, +-156, +-156, +-156, +-156, +-156, +-157, +-157, +-157, +-157, +-157, +-157, +-157, +-158, +-157, +-158, +-158, +-157, +-158, +-158, +-158, +-158, +-157, +-158, +-158, +-158, +-157, +-158, +-158, +-157, +-158, +-157, +-157, +-157, +-157, +-157, +-157, +-157, +-156, +-156, +-156, +-156, +-156, +-155, +-155, +-155, +-155, +-155, +-154, +-154, +-153, +-154, +-153, +-153, +-152, +-152, +-152, +-151, +-151, +-151, +-150, +-150, +-150, +-149, +-149, +-148, +-148, +-147, +-147, +-147, +-146, +-145, +-145, +-145, +-144, +-144, +-143, +-142, +-142, +-142, +-141, +-140, +-140, +-139, +-139, +-138, +-137, +-137, +-136, +-136, +-135, +-134, +-134, +-133, +-132, +-132, +-131, +-130, +-130, +-129, +-128, +-128, +-126, +-126, +-126, +-125, +-123, +-124, +-122, +-122, +-121, +-120, +-119, +-119, +-117, +-117, +-117, +-115, +-114, +-113, +-113, +-112, +-112, +-110, +-110, +-108, +-108, +-107, +-106, +-106, +-104, +-104, +-102, +-102, +-101, +-100, +-99, +-98, +-98, +-96, +-95, +-95, +-94, +-92, +-92, +-91, +-90, +-89, +-88, +-87, +-86, +-85, +-85, +-83, +-82, +-82, +-80, +-80, +-78, +-78, +-76, +-76, +-75, +-73, +-73, +-72, +-70, +-70, +-69, +-68, +-66, +-66, +-65, +-64, +-63, +-61, +-61, +-60, +-59, +-58, +-57, +-56, +-55, +-54, +-53, +-51, +-51, +-50, +-49, +-48, +-47, +-46, +-45, +-44, +-43, +-42, +-41, +-41, +-39, +-38, +-37, +-36, +-35, +-34, +-34, +-32, +-31, +-31, +-29, +-28, +-28, +-26, +-26, +-24, +-24, +-23, +-21, +-21, +-20, +-19, +-18, +-17, +-16, +-15, +-14, +-13, +-13, +-11, +-11, +-9, +-9, +-8, +-7, +-6, +-5, +-5, +-3, +-2, +-2, +-1, +0, +1, +2, +2, +4, +4, +5, +6, +7, +8, +8, +10, +10, +11, +11, +13, +13, +14, +15, +15, +17, +17, +18, +18, +20, +20, +21, +21, +23, +23, +23, +25, +25, +26, +26, +27, +28, +28, +30, +29, +31, +31, +32, +32, +33, +34, +34, +35, +35, +36, +37, +37, +37, +39, +39, +39, +40, +40, +41, +42, +42, +42, +43, +44, +44, +44, +45, +46, +45, +47, +46, +48, +47, +48, +49, +49, +49, +49, +50, +51, +51, +51, +51, +52, +52, +53, +53, +53, +53, +54, +54, +54, +55, +55, +55, +55, +56, +56, +56, +56, +57, +57, +57, +57, +58, +57, +58, +58, +58, +58, +59, +58, +59, +59, +59, +59, +59, +59, +59, +60, +59, +60, +59, +60, +60, +60, +59, +60, +60, +60, +60, +59, +60, +60, +60, +60, +59, +60, +60, +59, +60, +59, +60, +59, +59, +59, +59, +59, +59, +59, +58, +59, +58, +58, +58, +58, +57, +58, +57, +57, +57, +57, +55, +57, +56, +56, +55, +56, +55, +55, +54, +55, +54, +54, +54, +53, +53, +53, +52, +53, +52, +51, +52, +51, +50, +51, +50, +49, +50, +49, +48, +49, +48, +47, +47, +47, +47, +46, +46, +45, +45, +45, +44, +44, +43, +43, +42, +43, +41, +42, +40, +41, +40, +39, +40, +38, +39, +37, +38, +37, +36, +36, +35, +36, +34, +34, +34, +33, +33, +32, +32, +31, +31, +30, +30, +29, +29, +28, +28, +27, +27, +26, +26, +25, +25, +24, +24, +24, +22, +23, +21, +21, +21, +20, +20, +19, +19, +18, +18, +17, +16, +16, +16, +15, +14, +14, +14, +13, +12, +12, +11, +11, +11, +9, +10, +8, +9, +7, +8, +6, +7, +5, +5, +5, +4, +4, +3, +3, +2, +1, +1, +1, +0, +0, +-1, +-1, +-2, +-3, +-3, +-3, +-4, +-4, +-5, +-5, +-6, +-6, +-7, +-7, +-8, +-8, +-8, +-9, +-10, +-10, +-10, +-11, +-11, +-12, +-12, +-13, +-13, +-14, +-14, +-14, +-15, +-15, +-16, +-16, +-16, +-17, +-18, +-17, +-18, +-19, +-19, +-19, +-20, +-20, +-21, +-20, +-22, +-21, +-22, +-23, +-22, +-23, +-24, +-23, +-25, +-24, +-25, +-25, +-25, +-26, +-26, +-27, +-26, +-27, +-28, +-27, +-28, +-28, +-29, +-29, +-29, +-29, +-30, +-30, +-30, +-30, +-31, +-31, +-31, +-31, +-32, +-32, +-32, +-32, +-33, +-33, +-33, +-33, +-33, +-34, +-34, +-34, +-34, +-34, +-35, +-34, +-35, +-35, +-35, +-36, +-35, +-36, +-35, +-36, +-36, +-36, +-37, +-36, +-36, +-37, +-37, +-36, +-37, +-37, +-37, +-37, +-37, +-38, +-37, +-37, +-38, +-37, +-38, +-37, +-38, +-37, +-38, +-38, +-37, +-38, +-38, +-37, +-38, +-38, +-37, +-38, +-38, +-37, +-38, +-37, +-38, +-37, +-38, +-37, +-38, +-37, +-37, +-37, +-37, +-37, +-37, +-37, +-37, +-35, +-37, +-36, +-37, +-36, +-36, +-36, +-36, +-36, +-35, +-36, +-35, +-36, +-35, +-35, +-34, +-35, +-34, +-35, +-34, +-34, +-34, +-33, +-34, +-33, +-33, +-33, +-32, +-33, +-32, +-32, +-32, +-32, +-31, +-31, +-31, +-31, +-31, +-30, +-30, +-30, +-29, +-30, +-29, +-29, +-28, +-28, +-29, +-27, +-28, +-27, +-27, +-27, +-26, +-27, +-25, +-26, +-25, +-26, +-24, +-25, +-24, +-24, +-23, +-24, +-23, +-22, +-23, +-22, +-22, +-21, +-21, +-21, +-21, +-20, +-20, +-19, +-19, +-19, +-19, +-18, +-18, +-18, +-17, +-17, +-17, +-16, +-16, +-15, +-16, +-14, +-15, +-14, +-14, +-14, +-13, +-13, +-12, +-12, +-12, +-12, +-11, +-10, +-11, +-10, +-10, +-9, +-9, +-9, +-8, +-8, +-8, +-7, +-7, +-6, +-6, +-6, +-6, +-5, +-5, +-4, +-4, +-4, +-3, +-3, +-3, +-2, +-2, +-2, +-1, +-1, +-1, +0, +0, +0, +1, +1, +2, +1, +3, +2, +3, +3, +4, +3, +4, +5, +5, +5, +5, +6, +6, +7, +6, +8, +7, +8, +8, +8, +9, +9, +9, +10, +9, +11, +10, +11, +11, +11, +12, +12, +12, +13, +13, +13, +13, +14, +14, +14, +14, +15, +15, +15, +16, +16, +16, +16, +17, +16, +18, +17, +17, +18, +18, +18, +19, +19, +19, +19, +19, +20, +19, +20, +21, +20, +21, +21, +21, +21, +21, +22, +22, +22, +22, +22, +23, +22, +23, +23, +23, +23, +24, +24, +23, +24, +24, +24, +25, +24, +25, +24, +25, +25, +25, +25, +26, +25, +26, +25, +26, +26, +25, +26, +26, +26, +27, +26, +26, +27, +26, +27, +26, +27, +26, +27, +27, +27, +26, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +27, +26, +27, +27, +27, +27, +26, +27, +27, +26, +26, +26, +27, +26, +26, +27, +26, +26, +26, +26, +26, +26, +25, +26, +25, +26, +25, +25, +25, +25, +25, +25, +25, +24, +24, +25, +24, +24, +24, +23, +24, +24, +23, +23, +23, +23, +23, +22, +23, +22, +22, +22, +22, +21, +22, +21, +21, +21, +21, +20, +20, +21, +20, +19, +20, +19, +19, +19, +19, +19, +18, +18, +18, +18, +18, +17, +17, +17, +17, +16, +16, +16, +16, +16, +15, +15, +15, +14, +15, +14, +14, +14, +13, +13, +13, +13, +12, +13, +12, +11, +12, +11, +11, +11, +10, +11, +10, +9, +10, +9, +9, +9, +8, +9, +8, +7, +8, +7, +7, +7, +6, +6, +6, +6, +5, +5, +5, +5, +4, +4, +4, +3, +4, +3, +3, +2, +2, +2, +2, +2, +1, +1, +0, +1, +0, +0, +0, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-3, +-2, +-4, +-3, +-3, +-4, +-4, +-5, +-4, +-5, +-5, +-5, +-6, +-6, +-6, +-6, +-7, +-6, +-7, +-7, +-8, +-7, +-8, +-8, +-9, +-8, +-9, +-9, +-9, +-10, +-9, +-10, +-10, +-10, +-11, +-10, +-11, +-11, +-12, +-11, +-12, +-12, +-12, +-12, +-13, +-12, +-13, +-13, +-13, +-14, +-13, +-14, +-14, +-14, +-14, +-15, +-14, +-15, +-15, +-15, +-15, +-16, +-15, +-16, +-16, +-16, +-16, +-16, +-17, +-16, +-17, +-17, +-17, +-17, +-17, +-18, +-17, +-18, +-18, +-17, +-18, +-18, +-19, +-18, +-18, +-19, +-18, +-19, +-19, +-19, +-19, +-19, +-19, +-19, +-19, +-20, +-19, +-20, +-19, +-20, +-20, +-20, +-19, +-20, +-20, +-20, +-20, +-20, +-21, +-20, +-20, +-20, +-21, +-20, +-20, +-21, +-20, +-21, +-20, +-20, +-21, +-20, +-21, +-20, +-21, +-20, +-21, +-20, +-21, +-21, +-20, +-20, +-21, +-20, +-21, +-20, +-21, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-20, +-19, +-20, +-20, +-19, +-20, +-19, +-19, +-19, +-20, +-19, +-19, +-18, +-19, +-19, +-19, +-18, +-18, +-19, +-18, +-18, +-18, +-18, +-18, +-18, +-17, +-18, +-17, +-17, +-17, +-17, +-17, +-17, +-16, +-17, +-16, +-16, +-17, +-15, +-16, +-16, +-15, +-16, +-15, +-15, +-15, +-15, +-15, +-14, +-14, +-15, +-14, +-13, +-14, +-14, +-13, +-13, +-13, +-13, +-13, +-13, +-12, +-12, +-12, +-12, +-12, +-11, +-12, +-11, +-11, +-11, +-10, +-11, +-10, +-10, +-10, +-9, +-10, +-9, +-9, +-9, +-9, +-9, +-8, +-8, +-8, +-8, +-8, +-7, +-7, +-7, +-7, +-7, +-6, +-6, +-6, +-6, +-6, +-5, +-5, +-6, +-4, +-5, +-4, +-5, +-4, +-4, +-3, +-4, +-3, +-3, +-3, +-2, +-3, +-2, +-2, +-2, +-1, +-2, +-1, +-1, +-1, +0, +-1, +0, +0, +0, +1, +0, +1, +1, +1, +1, +2, +2, +2, +2, +2, +3, +3, +2, +4, +3, +3, +4, +4, +4, +4, +5, +4, +5, +5, +5, +6, +5, +6, +6, +6, +6, +7, +6, +7, +7, +7, +7, +8, +7, +8, +8, +8, +8, +9, +8, +9, +9, +9, +9, +10, +9, +10, +10, +10, +10, +10, +11, +10, +11, +11, +11, +11, +11, +11, +12, +11, +12, +12, +12, +12, +12, +13, +12, +13, +13, +12, +13, +13, +14, +13, +13, +14, +13, +14, +14, +13, +14, +14, +15, +14, +14, +14, +15, +14, +15, +15, +14, +15, +15, +15, +15, +15, +16, +15, +15, +15, +16, +15, +16, +15, +16, +15, +16, +16, +16, +15, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +17, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +16, +15, +16, +16, +16, +16, +16, +15, +16, +16, +15, +16, +16, +15, +15, +16, +15, +16, +15, +15, +15, +15, +15, +15, +15, +15, +15, +14, +15, +14, +15, +14, +14, +15, +14, +14, +14, +14, +13, +14, +14, +13, +13, +14, +13, +13, +13, +13, +13, +12, +13, +12, +13, +12, +12, +12, +12, +12, +12, +11, +12, +11, +11, +11, +11, +11, +11, +10, +11, +10, +10, +10, +10, +10, +10, +9, +10, +9, +9, +9, +9, +8, +9, +8, +9, +8, +8, +8, +7, +8, +7, +7, +7, +7, +7, +7, +6, +7, +6, +6, +6, +5, +6, +5, +5, +6, +4, +5, +5, +4, +5, +4, +4, +4, +3, +4, +3, +3, +3, +3, +3, +2, +3, +2, +2, +2, +2, +1, +2, +1, +1, +1, +1, +1, +0, +0, +1, +0, +-1, +0, +0, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-3, +-3, +-3, +-3, +-4, +-3, +-4, +-4, +-4, +-4, +-4, +-5, +-4, +-5, +-5, +-5, +-5, +-5, +-6, +-5, +-6, +-6, +-6, +-6, +-6, +-6, +-7, +-6, +-7, +-7, +-7, +-7, +-7, +-7, +-8, +-8, +-7, +-8, +-8, +-8, +-8, +-9, +-8, +-9, +-8, +-9, +-9, +-9, +-9, +-9, +-9, +-10, +-9, +-10, +-9, +-10, +-10, +-10, +-10, +-10, +-10, +-11, +-10, +-11, +-10, +-11, +-11, +-11, +-10, +-11, +-11, +-12, +-11, +-11, +-11, +-12, +-11, +-12, +-12, +-11, +-12, +-12, +-12, +-11, +-12, +-12, +-13, +-12, +-12, +-12, +-12, +-13, +-12, +-12, +-13, +-12, +-13, +-12, +-13, +-12, +-13, +-13, +-12, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-11, +-13, +-13, +-12, +-13, +-13, +-12, +-13, +-12, +-13, +-12, +-13, +-12, +-13, +-12, +-12, +-13, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-11, +-12, +-12, +-11, +-12, +-11, +-11, +-12, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-10, +-11, +-10, +-11, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-10, +-9, +-10, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-9, +-8, +-9, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-7, +-7, +-8, +-7, +-7, +-7, +-7, +-6, +-7, +-7, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-5, +-6, +-5, +-5, +-5, +-5, +-5, +-4, +-5, +-4, +-5, +-4, +-4, +-4, +-4, +-3, +-4, +-3, +-4, +-3, +-3, +-3, +-3, +-2, +-3, +-2, +-2, +-3, +-2, +-1, +-2, +-2, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +0, +-1, +0, +0, +0, +0, +0, +0, +1, +0, +1, +1, +0, +2, +1, +1, +1, +2, +2, +1, +2, +2, +3, +2, +2, +3, +2, +3, +3, +3, +3, +3, +4, +3, +4, +4, +3, +4, +4, +4, +5, +4, +5, +4, +5, +5, +5, +5, +5, +5, +5, +6, +5, +6, +6, +6, +6, +6, +6, +6, +6, +7, +6, +7, +7, +7, +7, +7, +7, +7, +7, +7, +8, +7, +8, +8, +7, +8, +8, +8, +8, +8, +8, +9, +8, +9, +8, +9, +8, +9, +9, +8, +9, +9, +9, +9, +9, +10, +9, +9, +9, +10, +9, +10, +9, +10, +10, +9, +10, +10, +9, +10, +10, +10, +10, +10, +10, +10, +10, +10, +10, +11, +10, +10, +10, +10, +11, +10, +10, +11, +10, +10, +11, +10, +10, +11, +10, +10, +11, +10, +11, +10, +11, +10, +10, +11, +10, +10, +11, +10, +11, +10, +10, +10, +10, +10, +10, +11, +10, +10, +10, +10, +11, +10, +10, +10, +10, +10, +10, +10, +10, +9, +10, +10, +10, +9, +10, +10, +9, +10, +9, +10, +9, +9, +10, +9, +9, +9, +9, +9, +9, +9, +9, +9, +8, +9, +9, +8, +9, +8, +8, +9, +8, +8, +8, +8, +8, +8, +7, +8, +8, +7, +8, +7, +7, +8, +7, +7, +7, +7, +6, +7, +7, +6, +7, +6, +7, +6, +6, +6, +6, +6, +6, +5, +6, +5, +6, +5, +5, +5, +5, +5, +5, +5, +4, +5, +4, +5, +4, +4, +4, +4, +4, +4, +3, +4, +3, +4, +3, +3, +3, +3, +3, +3, +2, +3, +2, +2, +3, +2, +2, +2, +1, +2, +2, +1, +2, +1, +1, +1, +1, +1, +1, +0, +1, +0, +1, +0, +0, +0, +0, +0, +0, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-3, +-2, +-3, +-3, +-3, +-3, +-3, +-3, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-4, +-5, +-4, +-4, +-4, +-5, +-4, +-5, +-5, +-5, +-4, +-5, +-5, +-6, +-5, +-5, +-5, +-6, +-5, +-6, +-5, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-7, +-6, +-6, +-7, +-6, +-7, +-7, +-6, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-8, +-7, +-7, +-8, +-7, +-8, +-7, +-8, +-7, +-8, +-7, +-8, +-8, +-8, +-8, +-7, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-9, +-8, +-8, +-8, +-8, +-9, +-8, +-8, +-8, +-9, +-8, +-8, +-9, +-8, +-9, +-8, +-8, +-9, +-8, +-9, +-8, +-9, +-8, +-8, +-9, +-8, +-9, +-8, +-9, +-8, +-9, +-8, +-8, +-9, +-8, +-9, +-8, +-7, +-9, +-8, +-8, +-9, +-8, +-8, +-9, +-8, +-8, +-8, +-8, +-8, +-9, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-8, +-7, +-8, +-8, +-8, +-7, +-8, +-8, +-7, +-8, +-7, +-8, +-7, +-8, +-7, +-7, +-7, +-8, +-7, +-7, +-7, +-7, +-7, +-7, +-7, +-6, +-7, +-7, +-6, +-7, +-7, +-6, +-6, +-7, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-6, +-5, +-6, +-5, +-6, +-5, +-5, +-6, +-5, +-5, +-5, +-5, +-5, +-4, +-5, +-5, +-4, +-5, +-4, +-5, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-3, +-4, +-3, +-4, +-3, +-3, +-3, +-4, +-3, +-2, +-3, +-3, +-3, +-2, +-3, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +0, +-1, +-1, +-1, +0, +-1, +0, +0, +-1, +0, +0, +0, +0, +0, +1, +0, +1, +0, +1, +0, +1, +1, +1, +1, +1, +1, +1, +2, +1, +2, +1, +2, +2, +2, +1, +2, +2, +3, +2, +2, +2, +3, +2, +3, +3, +2, +3, +3, +3, +3, +3, +3, +4, +3, +3, +4, +3, +4, +3, +4, +4, +4, +4, +4, +4, +4, +4, +4, +5, +4, +4, +5, +5, +4, +5, +5, +4, +5, +5, +5, +5, +5, +5, +5, +6, +5, +5, +5, +6, +5, +6, +5, +6, +6, +5, +6, +6, +6, +5, +6, +6, +6, +6, +6, +6, +7, +6, +6, +6, +6, +7, +6, +6, +7, +6, +7, +6, +6, +7, +7, +6, +7, +6, +7, +6, +7, +7, +7, +6, +7, +7, +6, +7, +7, +7, +7, +6, +7, +7, +7, +7, +7, +6, +7, +7, +7, +7, +7, +7, +6, +7, +7, +7, +7, +7, +7, +6, +7, +7, +6, +7, +6, +7, +7, +7, +6, +7, +7, +6, +7, +7, +6, +7, +7, +6, +7, +6, +7, +6, +7, +6, +6, +7, +6, +6, +7, +6, +6, +6, +6, +6, +7, +6, +6, +6, +6, +5, +6, +6, +6, +6, +5, +6, +6, +5, +6, +5, +6, +5, +5, +6, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +5, +4, +5, +4, +5, +4, +5, +4, +4, +4, +5, +4, +4, +4, +4, +3, +4, +4, +4, +3, +4, +3, +4, +3, +3, +4, +3, +3, +3, +3, +3, +3, +2, +3, +3, +2, +3, +2, +3, +2, +2, +3, +2, +2, +2, +2, +2, +1, +2, +2, +1, +2, +1, +2, +1, +1, +1, +2, +1, +1, +0, +1, +1, +1, +0, +1, +0, +1, +0, +0, +1, +0, +0, +0, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-3, +-2, +-3, +-2, +-3, +-3, +-2, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-4, +-3, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-5, +-4, +-4, +-5, +-4, +-4, +-5, +-4, +-5, +-4, +-5, +-5, +-4, +-5, +-5, +-4, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-6, +-5, +-5, +-5, +-5, +-6, +-5, +-5, +-6, +-5, +-5, +-6, +-5, +-6, +-5, +-6, +-5, +-6, +-5, +-5, +-6, +-6, +-5, +-6, +-5, +-6, +-5, +-6, +-5, +-6, +-5, +-6, +-6, +-5, +-6, +-5, +-6, +-5, +-6, +-5, +-6, +-6, +-5, +-6, +-5, +-5, +-5, +-6, +-5, +-6, +-5, +-6, +-5, +-5, +-6, +-5, +-6, +-5, +-5, +-6, +-5, +-5, +-6, +-5, +-5, +-5, +-6, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-4, +-5, +-5, +-5, +-4, +-5, +-5, +-4, +-5, +-4, +-5, +-4, +-4, +-5, +-4, +-4, +-5, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-4, +-3, +-4, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-3, +-4, +-3, +-3, +-3, +-3, +-3, +-2, +-3, +-3, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-1, +-2, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +1, +0, +1, +0, +1, +1, +1, +0, +1, +1, +1, +1, +1, +2, +1, +1, +1, +2, +1, +2, +1, +2, +1, +2, +2, +1, +2, +2, +2, +2, +2, +2, +2, +2, +2, +3, +2, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +4, +3, +3, +4, +3, +4, +3, +4, +3, +4, +3, +4, +4, +3, +4, +4, +4, +4, +3, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +4, +5, +4, +4, +4, +4, +5, +4, +4, +4, +5, +4, +4, +5, +4, +4, +5, +4, +5, +4, +4, +5, +4, +5, +4, +5, +4, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +4, +5, +3, +4, +5, +4, +5, +4, +4, +5, +4, +5, +4, +4, +5, +4, +4, +5, +4, +4, +4, +4, +5, +4, +4, +4, +4, +4, +5, +4, +4, +4, +4, +4, +4, +4, +3, +4, +4, +4, +4, +4, +3, +4, +4, +4, +3, +4, +4, +3, +4, +3, +4, +3, +3, +4, +3, +4, +3, +3, +3, +4, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +2, +3, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +1, +2, +2, +1, +2, +1, +2, +1, +1, +2, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-3, +-3, +-2, +-3, +-3, +-3, +-3, +-2, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-4, +-3, +-3, +-3, +-3, +-4, +-3, +-3, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-4, +-3, +-3, +-3, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-3, +-4, +-3, +-4, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-3, +-3, +-4, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-3, +-2, +-3, +-3, +-3, +-2, +-3, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-3, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +0, +-1, +-1, +-1, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +1, +1, +2, +1, +1, +1, +2, +1, +1, +2, +1, +1, +2, +1, +2, +1, +2, +1, +2, +2, +1, +2, +2, +2, +1, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +3, +2, +2, +2, +3, +2, +2, +3, +2, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +3, +2, +3, +2, +3, +3, +2, +3, +3, +3, +2, +3, +3, +2, +3, +3, +3, +3, +2, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +2, +2, +3, +3, +3, +2, +3, +3, +3, +3, +2, +3, +3, +3, +2, +3, +3, +3, +2, +3, +3, +2, +3, +3, +2, +3, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +3, +2, +2, +3, +2, +2, +3, +2, +2, +3, +2, +2, +2, +2, +2, +3, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +1, +2, +2, +2, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +0, +1, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-2, +-1, +-2, +-2, +-1, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-3, +-1, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-2, +-1, +-2, +-2, +-2, +-1, +-2, +-2, +-1, +-2, +-1, +-2, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +1, +0, +1, +1, +1, +0, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +2, +1, +1, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +2, +1, +2, +1, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +2, +2, +1, +2, +2, +1, +2, +2, +2, +1, +2, +2, +2, +1, +2, +2, +2, +1, +2, +2, +2, +2, +1, +2, +2, +2, +1, +2, +2, +2, +1, +2, +2, +2, +1, +2, +1, +2, +1, +2, +2, +1, +2, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +2, +1, +2, +1, +2, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +2, +1, +1, +2, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +1, +2, +1, +1, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +0, +1, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +1, +0, +1, +1, +1, +0, +1, +1, +0, +1, +1, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +0, +1, +1, +1, +0, +1, +1, +0, +1, +1, +0, +1, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +0, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +1, +0, +0, +1, +0, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +1, +0, +0, +1, +0, +0, +1, +0, +1, +0, +0, +1, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0}; diff --git a/darkice/tags/darkice-0_17_1/src/aflibConverterSmallFilter.h b/darkice/tags/darkice-0_17_1/src/aflibConverterSmallFilter.h new file mode 100644 index 0000000..d7d6b71 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/aflibConverterSmallFilter.h @@ -0,0 +1,4643 @@ +/* + * Copyright: (C) 2000 Julius O. Smith + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Julius O. Smith jos@ccrma.stanford.edu + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define SMALL_FILTER_NMULT ((short)13) +#define SMALL_FILTER_SCALE 13128 /* Unity-gain scale factor */ +#define SMALL_FILTER_NWING 1536 /* Filter table length */ + +short aflibConverter::SMALL_FILTER_IMP[] /* Impulse response */ = { +32767, +32766, +32764, +32760, +32755, +32749, +32741, +32731, +32721, +32708, +32695, +32679, +32663, +32645, +32625, +32604, +32582, +32558, +32533, +32506, +32478, +32448, +32417, +32385, +32351, +32316, +32279, +32241, +32202, +32161, +32119, +32075, +32030, +31984, +31936, +31887, +31836, +31784, +31731, +31676, +31620, +31563, +31504, +31444, +31383, +31320, +31256, +31191, +31124, +31056, +30987, +30916, +30845, +30771, +30697, +30621, +30544, +30466, +30387, +30306, +30224, +30141, +30057, +29971, +29884, +29796, +29707, +29617, +29525, +29433, +29339, +29244, +29148, +29050, +28952, +28852, +28752, +28650, +28547, +28443, +28338, +28232, +28125, +28017, +27908, +27797, +27686, +27574, +27461, +27346, +27231, +27115, +26998, +26879, +26760, +26640, +26519, +26398, +26275, +26151, +26027, +25901, +25775, +25648, +25520, +25391, +25262, +25131, +25000, +24868, +24735, +24602, +24467, +24332, +24197, +24060, +23923, +23785, +23647, +23507, +23368, +23227, +23086, +22944, +22802, +22659, +22515, +22371, +22226, +22081, +21935, +21789, +21642, +21494, +21346, +21198, +21049, +20900, +20750, +20600, +20449, +20298, +20146, +19995, +19842, +19690, +19537, +19383, +19230, +19076, +18922, +18767, +18612, +18457, +18302, +18146, +17990, +17834, +17678, +17521, +17365, +17208, +17051, +16894, +16737, +16579, +16422, +16264, +16106, +15949, +15791, +15633, +15475, +15317, +15159, +15001, +14843, +14685, +14527, +14369, +14212, +14054, +13896, +13739, +13581, +13424, +13266, +13109, +12952, +12795, +12639, +12482, +12326, +12170, +12014, +11858, +11703, +11548, +11393, +11238, +11084, +10929, +10776, +10622, +10469, +10316, +10164, +10011, +9860, +9708, +9557, +9407, +9256, +9106, +8957, +8808, +8659, +8511, +8364, +8216, +8070, +7924, +7778, +7633, +7488, +7344, +7200, +7057, +6914, +6773, +6631, +6490, +6350, +6210, +6071, +5933, +5795, +5658, +5521, +5385, +5250, +5115, +4981, +4848, +4716, +4584, +4452, +4322, +4192, +4063, +3935, +3807, +3680, +3554, +3429, +3304, +3180, +3057, +2935, +2813, +2692, +2572, +2453, +2335, +2217, +2101, +1985, +1870, +1755, +1642, +1529, +1418, +1307, +1197, +1088, +979, +872, +765, +660, +555, +451, +348, +246, +145, +44, +-54, +-153, +-250, +-347, +-443, +-537, +-631, +-724, +-816, +-908, +-998, +-1087, +-1175, +-1263, +-1349, +-1435, +-1519, +-1603, +-1685, +-1767, +-1848, +-1928, +-2006, +-2084, +-2161, +-2237, +-2312, +-2386, +-2459, +-2531, +-2603, +-2673, +-2742, +-2810, +-2878, +-2944, +-3009, +-3074, +-3137, +-3200, +-3261, +-3322, +-3381, +-3440, +-3498, +-3554, +-3610, +-3665, +-3719, +-3772, +-3824, +-3875, +-3925, +-3974, +-4022, +-4069, +-4116, +-4161, +-4205, +-4249, +-4291, +-4333, +-4374, +-4413, +-4452, +-4490, +-4527, +-4563, +-4599, +-4633, +-4666, +-4699, +-4730, +-4761, +-4791, +-4820, +-4848, +-4875, +-4901, +-4926, +-4951, +-4974, +-4997, +-5019, +-5040, +-5060, +-5080, +-5098, +-5116, +-5133, +-5149, +-5164, +-5178, +-5192, +-5205, +-5217, +-5228, +-5238, +-5248, +-5257, +-5265, +-5272, +-5278, +-5284, +-5289, +-5293, +-5297, +-5299, +-5301, +-5303, +-5303, +-5303, +-5302, +-5300, +-5298, +-5295, +-5291, +-5287, +-5282, +-5276, +-5270, +-5263, +-5255, +-5246, +-5237, +-5228, +-5217, +-5206, +-5195, +-5183, +-5170, +-5157, +-5143, +-5128, +-5113, +-5097, +-5081, +-5064, +-5047, +-5029, +-5010, +-4991, +-4972, +-4952, +-4931, +-4910, +-4889, +-4867, +-4844, +-4821, +-4797, +-4774, +-4749, +-4724, +-4699, +-4673, +-4647, +-4620, +-4593, +-4566, +-4538, +-4510, +-4481, +-4452, +-4422, +-4393, +-4363, +-4332, +-4301, +-4270, +-4238, +-4206, +-4174, +-4142, +-4109, +-4076, +-4042, +-4009, +-3975, +-3940, +-3906, +-3871, +-3836, +-3801, +-3765, +-3729, +-3693, +-3657, +-3620, +-3584, +-3547, +-3510, +-3472, +-3435, +-3397, +-3360, +-3322, +-3283, +-3245, +-3207, +-3168, +-3129, +-3091, +-3052, +-3013, +-2973, +-2934, +-2895, +-2855, +-2816, +-2776, +-2736, +-2697, +-2657, +-2617, +-2577, +-2537, +-2497, +-2457, +-2417, +-2377, +-2337, +-2297, +-2256, +-2216, +-2176, +-2136, +-2096, +-2056, +-2016, +-1976, +-1936, +-1896, +-1856, +-1817, +-1777, +-1737, +-1698, +-1658, +-1619, +-1579, +-1540, +-1501, +-1462, +-1423, +-1384, +-1345, +-1306, +-1268, +-1230, +-1191, +-1153, +-1115, +-1077, +-1040, +-1002, +-965, +-927, +-890, +-854, +-817, +-780, +-744, +-708, +-672, +-636, +-600, +-565, +-530, +-494, +-460, +-425, +-391, +-356, +-322, +-289, +-255, +-222, +-189, +-156, +-123, +-91, +-59, +-27, +4, +35, +66, +97, +127, +158, +188, +218, +247, +277, +306, +334, +363, +391, +419, +447, +474, +501, +528, +554, +581, +606, +632, +657, +683, +707, +732, +756, +780, +803, +827, +850, +872, +895, +917, +939, +960, +981, +1002, +1023, +1043, +1063, +1082, +1102, +1121, +1139, +1158, +1176, +1194, +1211, +1228, +1245, +1262, +1278, +1294, +1309, +1325, +1340, +1354, +1369, +1383, +1397, +1410, +1423, +1436, +1448, +1461, +1473, +1484, +1496, +1507, +1517, +1528, +1538, +1548, +1557, +1566, +1575, +1584, +1592, +1600, +1608, +1616, +1623, +1630, +1636, +1643, +1649, +1654, +1660, +1665, +1670, +1675, +1679, +1683, +1687, +1690, +1694, +1697, +1700, +1702, +1704, +1706, +1708, +1709, +1711, +1712, +1712, +1713, +1713, +1713, +1713, +1712, +1711, +1710, +1709, +1708, +1706, +1704, +1702, +1700, +1697, +1694, +1691, +1688, +1685, +1681, +1677, +1673, +1669, +1664, +1660, +1655, +1650, +1644, +1639, +1633, +1627, +1621, +1615, +1609, +1602, +1596, +1589, +1582, +1575, +1567, +1560, +1552, +1544, +1536, +1528, +1520, +1511, +1503, +1494, +1485, +1476, +1467, +1458, +1448, +1439, +1429, +1419, +1409, +1399, +1389, +1379, +1368, +1358, +1347, +1337, +1326, +1315, +1304, +1293, +1282, +1271, +1260, +1248, +1237, +1225, +1213, +1202, +1190, +1178, +1166, +1154, +1142, +1130, +1118, +1106, +1094, +1081, +1069, +1057, +1044, +1032, +1019, +1007, +994, +981, +969, +956, +943, +931, +918, +905, +892, +879, +867, +854, +841, +828, +815, +802, +790, +777, +764, +751, +738, +725, +713, +700, +687, +674, +662, +649, +636, +623, +611, +598, +585, +573, +560, +548, +535, +523, +510, +498, +486, +473, +461, +449, +437, +425, +413, +401, +389, +377, +365, +353, +341, +330, +318, +307, +295, +284, +272, +261, +250, +239, +228, +217, +206, +195, +184, +173, +163, +152, +141, +131, +121, +110, +100, +90, +80, +70, +60, +51, +41, +31, +22, +12, +3, +-5, +-14, +-23, +-32, +-41, +-50, +-59, +-67, +-76, +-84, +-93, +-101, +-109, +-117, +-125, +-133, +-140, +-148, +-156, +-163, +-170, +-178, +-185, +-192, +-199, +-206, +-212, +-219, +-226, +-232, +-239, +-245, +-251, +-257, +-263, +-269, +-275, +-280, +-286, +-291, +-297, +-302, +-307, +-312, +-317, +-322, +-327, +-332, +-336, +-341, +-345, +-349, +-354, +-358, +-362, +-366, +-369, +-373, +-377, +-380, +-384, +-387, +-390, +-394, +-397, +-400, +-402, +-405, +-408, +-411, +-413, +-416, +-418, +-420, +-422, +-424, +-426, +-428, +-430, +-432, +-433, +-435, +-436, +-438, +-439, +-440, +-442, +-443, +-444, +-445, +-445, +-446, +-447, +-447, +-448, +-448, +-449, +-449, +-449, +-449, +-449, +-449, +-449, +-449, +-449, +-449, +-449, +-448, +-448, +-447, +-447, +-446, +-445, +-444, +-443, +-443, +-442, +-441, +-440, +-438, +-437, +-436, +-435, +-433, +-432, +-430, +-429, +-427, +-426, +-424, +-422, +-420, +-419, +-417, +-415, +-413, +-411, +-409, +-407, +-405, +-403, +-400, +-398, +-396, +-393, +-391, +-389, +-386, +-384, +-381, +-379, +-376, +-374, +-371, +-368, +-366, +-363, +-360, +-357, +-355, +-352, +-349, +-346, +-343, +-340, +-337, +-334, +-331, +-328, +-325, +-322, +-319, +-316, +-313, +-310, +-307, +-304, +-301, +-298, +-294, +-291, +-288, +-285, +-282, +-278, +-275, +-272, +-269, +-265, +-262, +-259, +-256, +-252, +-249, +-246, +-243, +-239, +-236, +-233, +-230, +-226, +-223, +-220, +-217, +-213, +-210, +-207, +-204, +-200, +-197, +-194, +-191, +-187, +-184, +-181, +-178, +-175, +-172, +-168, +-165, +-162, +-159, +-156, +-153, +-150, +-147, +-143, +-140, +-137, +-134, +-131, +-128, +-125, +-122, +-120, +-117, +-114, +-111, +-108, +-105, +-102, +-99, +-97, +-94, +-91, +-88, +-86, +-83, +-80, +-78, +-75, +-72, +-70, +-67, +-65, +-62, +-59, +-57, +-55, +-52, +-50, +-47, +-45, +-43, +-40, +-38, +-36, +-33, +-31, +-29, +-27, +-25, +-22, +-20, +-18, +-16, +-14, +-12, +-10, +-8, +-6, +-4, +-2, +0, +0, +2, +4, +6, +8, +9, +11, +13, +14, +16, +17, +19, +21, +22, +24, +25, +27, +28, +29, +31, +32, +33, +35, +36, +37, +38, +40, +41, +42, +43, +44, +45, +46, +47, +48, +49, +50, +51, +52, +53, +54, +55, +56, +56, +57, +58, +59, +59, +60, +61, +62, +62, +63, +63, +64, +64, +65, +66, +66, +66, +67, +67, +68, +68, +69, +69, +69, +70, +70, +70, +70, +71, +71, +71, +71, +71, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +72, +71, +71, +71, +71, +71, +70, +70, +70, +70, +69, +69, +69, +69, +68, +68, +68, +67, +67, +67, +66, +66, +66, +65, +65, +64, +64, +64, +63, +63, +62, +62, +62, +61, +61, +60, +60, +59, +59, +58, +58, +58, +57, +57, +56, +56, +55, +55, +54, +54, +53, +53, +52, +52, +51, +51, +50, +50, +49, +48, +48, +47, +47, +46, +46, +45, +45, +44, +44, +43, +43, +42, +42, +41, +41, +40, +39, +39, +38, +38, +37, +37, +36, +36, +35, +35, +34, +34, +33, +33, +32, +32, +31, +31, +30, +30, +29, +29, +28, +28, +27, +27, +26, +26, +25, +25, +24, +24, +23, +23, +23, +22, +22, +21, +21, +20, +20, +20, +19, +19, +18, +18, +17, +17, +17, +16, +16, +15, +15, +15, +14, +14, +14, +13, +13, +12, +12, +12, +11, +11, +11, +10, +10, +10, +9, +9, +9, +9, +8, +8, +8, +7, +7, +7, +7, +6, +6, +6, +6, +5, +5, +5, +5, +4, +4, +4, +4, +3, +3, +3, +3, +3, +2, +2, +2, +2, +2, +1, +1, +1, +1, +1, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1, +-1 +}; + +static short SMALL_FILTER_IMPD[] = { +-1, +-2, +-4, +-5, +-6, +-8, +-10, +-10, +-13, +-13, +-16, +-16, +-18, +-20, +-21, +-22, +-24, +-25, +-27, +-28, +-30, +-31, +-32, +-34, +-35, +-37, +-38, +-39, +-41, +-42, +-44, +-45, +-46, +-48, +-49, +-51, +-52, +-53, +-55, +-56, +-57, +-59, +-60, +-61, +-63, +-64, +-65, +-67, +-68, +-69, +-71, +-71, +-74, +-74, +-76, +-77, +-78, +-79, +-81, +-82, +-83, +-84, +-86, +-87, +-88, +-89, +-90, +-92, +-92, +-94, +-95, +-96, +-98, +-98, +-100, +-100, +-102, +-103, +-104, +-105, +-106, +-107, +-108, +-109, +-111, +-111, +-112, +-113, +-115, +-115, +-116, +-117, +-119, +-119, +-120, +-121, +-121, +-123, +-124, +-124, +-126, +-126, +-127, +-128, +-129, +-129, +-131, +-131, +-132, +-133, +-133, +-135, +-135, +-135, +-137, +-137, +-138, +-138, +-140, +-139, +-141, +-141, +-142, +-142, +-143, +-144, +-144, +-145, +-145, +-146, +-146, +-147, +-148, +-148, +-148, +-149, +-149, +-150, +-150, +-151, +-151, +-152, +-151, +-153, +-152, +-153, +-154, +-153, +-154, +-154, +-155, +-155, +-155, +-155, +-156, +-156, +-156, +-156, +-157, +-156, +-157, +-157, +-157, +-157, +-158, +-157, +-158, +-158, +-157, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-157, +-158, +-158, +-157, +-158, +-157, +-158, +-157, +-157, +-157, +-156, +-157, +-156, +-156, +-156, +-156, +-155, +-155, +-155, +-155, +-154, +-155, +-153, +-154, +-153, +-153, +-152, +-153, +-151, +-152, +-151, +-150, +-151, +-150, +-149, +-149, +-149, +-148, +-147, +-148, +-146, +-146, +-146, +-145, +-145, +-144, +-144, +-143, +-143, +-141, +-142, +-141, +-140, +-140, +-139, +-138, +-138, +-137, +-137, +-136, +-135, +-135, +-134, +-133, +-132, +-132, +-132, +-130, +-130, +-129, +-128, +-128, +-127, +-126, +-125, +-125, +-124, +-123, +-122, +-122, +-121, +-120, +-119, +-118, +-118, +-116, +-116, +-115, +-115, +-113, +-113, +-111, +-111, +-110, +-109, +-109, +-107, +-107, +-105, +-105, +-104, +-103, +-102, +-101, +-101, +-98, +-99, +-97, +-97, +-96, +-94, +-94, +-93, +-92, +-92, +-90, +-89, +-88, +-88, +-86, +-86, +-84, +-84, +-82, +-82, +-81, +-80, +-78, +-78, +-77, +-76, +-75, +-74, +-73, +-72, +-72, +-70, +-69, +-68, +-68, +-66, +-65, +-65, +-63, +-63, +-61, +-61, +-59, +-59, +-58, +-56, +-56, +-55, +-54, +-53, +-52, +-51, +-50, +-49, +-48, +-47, +-47, +-45, +-44, +-44, +-42, +-42, +-41, +-39, +-39, +-38, +-37, +-36, +-36, +-34, +-33, +-33, +-31, +-31, +-30, +-29, +-28, +-27, +-26, +-25, +-25, +-23, +-23, +-22, +-21, +-20, +-20, +-18, +-18, +-17, +-16, +-15, +-14, +-14, +-13, +-12, +-11, +-10, +-10, +-9, +-8, +-7, +-6, +-6, +-5, +-4, +-4, +-2, +-2, +-2, +0, +0, +1, +2, +2, +3, +4, +4, +5, +6, +6, +7, +8, +9, +9, +9, +11, +11, +11, +12, +13, +13, +14, +15, +15, +16, +16, +17, +17, +18, +19, +19, +19, +20, +21, +21, +21, +22, +23, +23, +24, +23, +25, +25, +25, +26, +26, +27, +27, +27, +28, +28, +29, +29, +30, +29, +30, +31, +31, +31, +32, +32, +32, +32, +33, +33, +34, +33, +34, +35, +34, +35, +35, +35, +36, +36, +36, +36, +37, +36, +37, +37, +38, +37, +38, +37, +38, +39, +38, +38, +39, +39, +38, +39, +39, +40, +39, +39, +40, +39, +40, +40, +39, +40, +40, +40, +40, +40, +40, +40, +40, +40, +40, +41, +40, +40, +40, +40, +40, +40, +40, +40, +40, +40, +39, +40, +40, +39, +40, +39, +40, +39, +39, +39, +39, +39, +39, +39, +38, +38, +39, +38, +38, +38, +37, +38, +37, +38, +37, +36, +37, +37, +36, +36, +36, +36, +36, +35, +35, +36, +34, +35, +34, +35, +34, +33, +34, +33, +33, +33, +33, +32, +32, +32, +31, +31, +31, +31, +30, +31, +30, +30, +29, +30, +29, +28, +29, +28, +28, +28, +27, +27, +27, +26, +27, +25, +26, +25, +26, +24, +25, +24, +24, +23, +24, +23, +22, +23, +22, +22, +21, +21, +21, +21, +20, +20, +19, +20, +19, +18, +19, +18, +18, +17, +17, +17, +17, +16, +16, +15, +16, +15, +14, +15, +14, +14, +13, +13, +13, +12, +13, +12, +11, +12, +11, +10, +11, +10, +10, +9, +9, +9, +9, +8, +8, +8, +8, +7, +7, +6, +7, +6, +5, +6, +5, +5, +5, +4, +4, +4, +3, +4, +3, +3, +2, +2, +2, +2, +1, +2, +1, +0, +1, +0, +0, +0, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-3, +-3, +-3, +-3, +-3, +-4, +-4, +-4, +-4, +-5, +-4, +-5, +-5, +-6, +-5, +-6, +-6, +-6, +-6, +-6, +-7, +-6, +-7, +-7, +-7, +-8, +-7, +-8, +-8, +-8, +-8, +-8, +-9, +-8, +-9, +-9, +-9, +-9, +-9, +-10, +-9, +-10, +-10, +-10, +-10, +-10, +-10, +-11, +-10, +-11, +-10, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-12, +-11, +-12, +-12, +-11, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-13, +-12, +-12, +-13, +-12, +-13, +-12, +-13, +-13, +-12, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-12, +-13, +-13, +-12, +-13, +-12, +-13, +-12, +-13, +-12, +-12, +-13, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-11, +-12, +-11, +-12, +-11, +-12, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-10, +-11, +-11, +-10, +-10, +-11, +-10, +-10, +-10, +-10, +-10, +-9, +-10, +-10, +-9, +-10, +-9, +-8, +-9, +-9, +-9, +-9, +-9, +-9, +-8, +-9, +-8, +-9, +-8, +-8, +-8, +-8, +-8, +-7, +-8, +-8, +-7, +-7, +-8, +-7, +-7, +-7, +-7, +-6, +-7, +-7, +-6, +-7, +-6, +-6, +-6, +-6, +-6, +-6, +-5, +-6, +-5, +-6, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-4, +-5, +-4, +-4, +-5, +-4, +-4, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-2, +-3, +-3, +-3, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +2, +1, +1, +1, +2, +1, +2, +1, +2, +1, +2, +2, +2, +1, +2, +2, +2, +2, +2, +2, +2, +2, +3, +2, +2, +3, +2, +2, +3, +2, +3, +2, +3, +2, +3, +3, +2, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +2, +3, +3, +2, +3, +3, +2, +3, +2, +3, +3, +2, +2, +3, +2, +3, +2, +2, +3, +2, +2, +3, +2, +2, +2, +2, +3, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +0, +2, +2, +2, +2, +1, +2, +2, +1, +2, +1, +2, +2, +1, +2, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +0, +1, +1, +1, +0, +1, +0, +1, +0, +1, +1, +0, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +-1, +-2, +-4, +-5, +-6, +-8, +-10, +-10, +-13, +-13, +-16, +-16, +-18, +-20, +-21, +-22, +-24, +-25, +-27, +-28, +-30, +-31, +-32, +-34, +-35, +-37, +-38, +-39, +-41, +-42, +-44, +-45, +-46, +-48, +-49, +-51, +-52, +-53, +-55, +-56, +-57, +-59, +-60, +-61, +-63, +-64, +-65, +-67, +-68, +-69, +-71, +-71, +-74, +-74, +-76, +-77, +-78, +-79, +-81, +-82, +-83, +-84, +-86, +-87, +-88, +-89, +-90, +-92, +-92, +-94, +-95, +-96, +-98, +-98, +-100, +-100, +-102, +-103, +-104, +-105, +-106, +-107, +-108, +-109, +-111, +-111, +-112, +-113, +-115, +-115, +-116, +-117, +-119, +-119, +-120, +-121, +-121, +-123, +-124, +-124, +-126, +-126, +-127, +-128, +-129, +-129, +-131, +-131, +-132, +-133, +-133, +-135, +-135, +-135, +-137, +-137, +-138, +-138, +-140, +-139, +-141, +-141, +-142, +-142, +-143, +-144, +-144, +-145, +-145, +-146, +-146, +-147, +-148, +-148, +-148, +-149, +-149, +-150, +-150, +-151, +-151, +-152, +-151, +-153, +-152, +-153, +-154, +-153, +-154, +-154, +-155, +-155, +-155, +-155, +-156, +-156, +-156, +-156, +-157, +-156, +-157, +-157, +-157, +-157, +-158, +-157, +-158, +-158, +-157, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-158, +-157, +-158, +-158, +-157, +-158, +-157, +-158, +-157, +-157, +-157, +-156, +-157, +-156, +-156, +-156, +-156, +-155, +-155, +-155, +-155, +-154, +-155, +-153, +-154, +-153, +-153, +-152, +-153, +-151, +-152, +-151, +-150, +-151, +-150, +-149, +-149, +-149, +-148, +-147, +-148, +-146, +-146, +-146, +-145, +-145, +-144, +-144, +-143, +-143, +-141, +-142, +-141, +-140, +-140, +-139, +-138, +-138, +-137, +-137, +-136, +-135, +-135, +-134, +-133, +-132, +-132, +-132, +-130, +-130, +-129, +-128, +-128, +-127, +-126, +-125, +-125, +-124, +-123, +-122, +-122, +-121, +-120, +-119, +-118, +-118, +-116, +-116, +-115, +-115, +-113, +-113, +-111, +-111, +-110, +-109, +-109, +-107, +-107, +-105, +-105, +-104, +-103, +-102, +-101, +-101, +-98, +-99, +-97, +-97, +-96, +-94, +-94, +-93, +-92, +-92, +-90, +-89, +-88, +-88, +-86, +-86, +-84, +-84, +-82, +-82, +-81, +-80, +-78, +-78, +-77, +-76, +-75, +-74, +-73, +-72, +-72, +-70, +-69, +-68, +-68, +-66, +-65, +-65, +-63, +-63, +-61, +-61, +-59, +-59, +-58, +-56, +-56, +-55, +-54, +-53, +-52, +-51, +-50, +-49, +-48, +-47, +-47, +-45, +-44, +-44, +-42, +-42, +-41, +-39, +-39, +-38, +-37, +-36, +-36, +-34, +-33, +-33, +-31, +-31, +-30, +-29, +-28, +-27, +-26, +-25, +-25, +-23, +-23, +-22, +-21, +-20, +-20, +-18, +-18, +-17, +-16, +-15, +-14, +-14, +-13, +-12, +-11, +-10, +-10, +-9, +-8, +-7, +-6, +-6, +-5, +-4, +-4, +-2, +-2, +-2, +0, +0, +1, +2, +2, +3, +4, +4, +5, +6, +6, +7, +8, +9, +9, +9, +11, +11, +11, +12, +13, +13, +14, +15, +15, +16, +16, +17, +17, +18, +19, +19, +19, +20, +21, +21, +21, +22, +23, +23, +24, +23, +25, +25, +25, +26, +26, +27, +27, +27, +28, +28, +29, +29, +30, +29, +30, +31, +31, +31, +32, +32, +32, +32, +33, +33, +34, +33, +34, +35, +34, +35, +35, +35, +36, +36, +36, +36, +37, +36, +37, +37, +38, +37, +38, +37, +38, +39, +38, +38, +39, +39, +38, +39, +39, +40, +39, +39, +40, +39, +40, +40, +39, +40, +40, +40, +40, +40, +40, +40, +40, +40, +40, +41, +40, +40, +40, +40, +40, +40, +40, +40, +40, +40, +39, +40, +40, +39, +40, +39, +40, +39, +39, +39, +39, +39, +39, +39, +38, +38, +39, +38, +38, +38, +37, +38, +37, +38, +37, +36, +37, +37, +36, +36, +36, +36, +36, +35, +35, +36, +34, +35, +34, +35, +34, +33, +34, +33, +33, +33, +33, +32, +32, +32, +31, +31, +31, +31, +30, +31, +30, +30, +29, +30, +29, +28, +29, +28, +28, +28, +27, +27, +27, +26, +27, +25, +26, +25, +26, +24, +25, +24, +24, +23, +24, +23, +22, +23, +22, +22, +21, +21, +21, +21, +20, +20, +19, +20, +19, +18, +19, +18, +18, +17, +17, +17, +17, +16, +16, +15, +16, +15, +14, +15, +14, +14, +13, +13, +13, +12, +13, +12, +11, +12, +11, +10, +11, +10, +10, +9, +9, +9, +9, +8, +8, +8, +8, +7, +7, +6, +7, +6, +5, +6, +5, +5, +5, +4, +4, +4, +3, +4, +3, +3, +2, +2, +2, +2, +1, +2, +1, +0, +1, +0, +0, +0, +-1, +-1, +-1, +-1, +-1, +-2, +-2, +-2, +-2, +-3, +-3, +-3, +-3, +-3, +-4, +-4, +-4, +-4, +-5, +-4, +-5, +-5, +-6, +-5, +-6, +-6, +-6, +-6, +-6, +-7, +-6, +-7, +-7, +-7, +-8, +-7, +-8, +-8, +-8, +-8, +-8, +-9, +-8, +-9, +-9, +-9, +-9, +-9, +-10, +-9, +-10, +-10, +-10, +-10, +-10, +-10, +-11, +-10, +-11, +-10, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-12, +-11, +-12, +-12, +-11, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-13, +-12, +-12, +-13, +-12, +-13, +-12, +-13, +-13, +-12, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-12, +-13, +-13, +-13, +-12, +-13, +-13, +-12, +-13, +-12, +-13, +-12, +-13, +-12, +-12, +-13, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-12, +-11, +-12, +-11, +-12, +-11, +-12, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-11, +-10, +-11, +-11, +-10, +-10, +-11, +-10, +-10, +-10, +-10, +-10, +-9, +-10, +-10, +-9, +-10, +-9, +-8, +-9, +-9, +-9, +-9, +-9, +-9, +-8, +-9, +-8, +-9, +-8, +-8, +-8, +-8, +-8, +-7, +-8, +-8, +-7, +-7, +-8, +-7, +-7, +-7, +-7, +-6, +-7, +-7, +-6, +-7, +-6, +-6, +-6, +-6, +-6, +-6, +-5, +-6, +-5, +-6, +-5, +-5, +-5, +-5, +-5, +-5, +-5, +-4, +-5, +-4, +-4, +-5, +-4, +-4, +-4, +-3, +-4, +-4, +-3, +-4, +-3, +-3, +-4, +-3, +-3, +-2, +-3, +-3, +-3, +-2, +-3, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-2, +-1, +-2, +-1, +-2, +-1, +-1, +-2, +-1, +-1, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +1, +0, +1, +1, +1, +1, +0, +1, +1, +1, +2, +1, +1, +1, +2, +1, +2, +1, +2, +1, +2, +2, +2, +1, +2, +2, +2, +2, +2, +2, +2, +2, +3, +2, +2, +3, +2, +2, +3, +2, +3, +2, +3, +2, +3, +3, +2, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +4, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +3, +3, +3, +4, +3, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +3, +3, +3, +3, +2, +3, +3, +3, +2, +3, +3, +2, +3, +3, +2, +3, +2, +3, +3, +2, +2, +3, +2, +3, +2, +2, +3, +2, +2, +3, +2, +2, +2, +2, +3, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +2, +0, +2, +2, +2, +2, +1, +2, +2, +1, +2, +1, +2, +2, +1, +2, +1, +2, +1, +1, +2, +1, +1, +2, +1, +1, +1, +2, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +1, +0, +1, +1, +1, +0, +1, +1, +1, +0, +1, +0, +1, +0, +1, +1, +0, +0, +1, +0, +1, +0, +1, +0, +0, +1, +0, +0, +0, +1, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +-1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +1 +}; diff --git a/darkice/tags/darkice-0_17_1/src/aflibDebug.cc b/darkice/tags/darkice-0_17_1/src/aflibDebug.cc new file mode 100644 index 0000000..d78aa01 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/aflibDebug.cc @@ -0,0 +1,228 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + */ + +#include "aflibDebug.h" +#include +#include +#include +#include + +static int aflib_debug_level = ::aflibDebug::lInfo; +static bool aflib_debug_abort = false; +static const char *aflib_debug_prefix = ""; +static char *messageAppName = 0; + + +/* +static char* status_strs[] = +{ + "Success", + "Error Open", + "Unsupported", + "AFLIB_ERROR_INITIALIZATION_FAILURE", + "AFLIB_NOT_FOUND", + "AFLIB_END_OF_FILE", + "AFLIB_NO_DATA", + 0 +}; + + +static char* data_size_strs[] = +{ + "UNDEFINED", + "8 bit signed", + "8 bit unsigned", + "16 bit signed", + "16 bit unsigned", + "32 bit signed", + "32 bit unsigned", + 0 +}; + +static char* data_endian_strs[] = +{ + "UNDEFINED", + "ENDIAN_LITTLE", + "ENDIAN_BIG", + 0 +}; +*/ + +/* + * Call the graphical application to display a message, if + * defined. Otherwise, send to standard error. Debug messages are + * always sent to standard error because they tend to be very verbose. + * Note that the external application is run in the background to + * avoid blocking the sound server. + */ +void output_message(::aflibDebug::Level level, const char *msg) { + char buff[1024]; + + /* default to text output if no message app is defined or if it is a debug message. */ + if (messageAppName == 0 || !strcmp(messageAppName, "") || (level == ::aflibDebug::lDebug)) + { + fprintf(stderr, "%s\n", msg); + return; + } + + switch (level) { + case ::aflibDebug::lFatal: + sprintf(buff, "%s -e \"aflib fatal error:\n\n%s\" &", messageAppName, msg); + break; + case ::aflibDebug::lWarning: + sprintf(buff, "%s -w \"aflib warning message:\n\n%s\" &", messageAppName, msg); + break; + case ::aflibDebug::lInfo: + sprintf(buff, "%s -i \"aflib informational message:\n\n%s\" &", messageAppName, msg); + break; + default: + break; // avoid compile warning + } + system(buff); +} + +/* + * Display a message using output_message. If the message is the same + * as the previous one, just increment a count but don't display + * it. This prevents flooding the user with duplicate warnings. If the + * message is not the same as the previous one, then we report the + * previously repeated message (if any) and reset the last message and + * count. + */ +void display_message(::aflibDebug::Level level, const char *msg) { + static char lastMsg[1024]; + static ::aflibDebug::Level lastLevel; + static int msgCount = 0; + + if (!strncmp(msg, lastMsg, 1024)) + { + msgCount++; + } else { + if (msgCount > 0) + { + char buff[1024]; + sprintf(buff, "%s\n(The previous message was repeated %d times.)", lastMsg, msgCount); + output_message(lastLevel, buff); + } + + strncpy(lastMsg, msg, 1024); + lastLevel = level; + msgCount = 0; + output_message(level, msg); + } + +} + +static class DebugInitFromEnv { + + public: + DebugInitFromEnv() { + const char *env = getenv("AFLIB_DEBUG"); + if(env) + { + if(strcmp(env,"debug") == 0) + aflib_debug_level = ::aflibDebug::lDebug; + else if(strcmp(env,"info") == 0) + aflib_debug_level = ::aflibDebug::lInfo; + else if(strcmp(env,"warning") == 0) + aflib_debug_level = ::aflibDebug::lWarning; + else if(strcmp(env,"quiet") == 0) + aflib_debug_level = ::aflibDebug::lFatal; + else + { + fprintf(stderr, + "AFLIB_DEBUG must be one of debug,info,warning,quiet\n"); + } + } + + env = getenv("AFLIB_DEBUG_ABORT"); + if(env) + aflib_debug_abort = true; + } +} + +debugInitFromEnv; + + +void aflibDebug::init(const char *prefix, Level level) +{ + aflib_debug_level = level; + aflib_debug_prefix = prefix; +} + +void aflibDebug::fatal(const char *fmt, ...) +{ + char buff[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buff, fmt, ap); + va_end(ap); + display_message(::aflibDebug::lFatal, buff); + + if(aflib_debug_abort) abort(); + exit(1); +} + +void aflibDebug::warning(const char *fmt, ...) +{ + if(lWarning >= aflib_debug_level) + { + char buff[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buff, fmt, ap); + va_end(ap); + display_message(::aflibDebug::lWarning, buff); + } +} + +void aflibDebug::info(const char *fmt, ...) +{ + if(lInfo >= aflib_debug_level) + { + char buff[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buff, fmt, ap); + va_end(ap); + display_message(::aflibDebug::lInfo, buff); + } +} + +void aflibDebug::debug(const char *fmt, ...) +{ + if(lDebug >= aflib_debug_level) + { + char buff[1024]; + va_list ap; + va_start(ap, fmt); + vsprintf(buff, fmt, ap); + va_end(ap); + display_message(::aflibDebug::lDebug, buff); + } +} + +void aflibDebug::messageApp(const char *appName) +{ + messageAppName = (char*) realloc(messageAppName, strlen(appName)+1); + strcpy(messageAppName, appName); +} diff --git a/darkice/tags/darkice-0_17_1/src/aflibDebug.h b/darkice/tags/darkice-0_17_1/src/aflibDebug.h new file mode 100644 index 0000000..ea7dd99 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/aflibDebug.h @@ -0,0 +1,118 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + + Some inspiration taken from glib. + Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + Modified by the GLib Team and others 1997-1999. + + */ + +#ifndef _AFLIBDEBUG_H_ +#define _AFLIBDEBUG_H_ + +/* + * BC - Status (2000-09-30): Debug. + * + * Collection class, no instance, no members. Thus binary compatible (will + * be kept). + */ + +#define aflib_fatal ::aflibDebug::fatal +#define aflib_warning ::aflibDebug::warning +#define aflib_info ::aflibDebug::info +#define aflib_debug ::aflibDebug::debug + +/* source compatibility with older sources */ +#define aflibdebug ::aflibDebug::debug +#define setaflibdebug(x) aflib_warning("setaflibdebug is obsolete") + +#ifdef __GNUC__ + +#define aflib_return_if_fail(expr) \ + if (!(expr)) \ + { \ + aflib_warning ("file %s: line %d (%s): assertion failed: (%s)", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \ + return; \ + } + +#define aflib_return_val_if_fail(expr,val) \ + if (!(expr)) \ + { \ + aflib_warning ("file %s: line %d (%s): assertion failed: (%s)", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \ + return (val); \ + } + +#define aflib_assert(expr) \ + if (!(expr)) \ + aflib_fatal ("file %s: line %d (%s): assertion failed: (%s)", \ + __FILE__, __LINE__, __PRETTY_FUNCTION__, #expr); \ + +#else + +#define aflib_return_if_fail(expr) \ + if (!(expr)) \ + { \ + aflib_warning ("file %s: line %d: assertion failed: (%s)", \ + __FILE__, __LINE__, #expr); \ + return; \ + } + +#define aflib_return_val_if_fail(expr,val) \ + if (!(expr)) \ + { \ + aflib_warning ("file %s: line %d: assertion failed: (%s)", \ + __FILE__, __LINE__, #expr); \ + return (val); \ + } + +#define aflib_assert(expr) \ + if (!(expr)) \ + aflib_fatal ("file %s: line %d: assertion failed: (%s)", \ + __FILE__, __LINE__, #expr); \ + +#endif + +class aflibDebug { + public: + enum Level { lFatal = 3, lWarning = 2, lInfo = 1, lDebug = 0 }; + + /** + * Initializes at which is the minimum level to react to. If you + * call this, call this before creating the Arts::Dispatcher object. + */ + static void init(const char *prefix, Level level); + + static void fatal(const char *fmt,...); // print on stderr & abort + static void warning(const char *fmt,...); // print on stderr + static void info(const char *fmt,...); // print on stdout + static void debug(const char *fmt,...); // print on stdout + + /** + * This method sets the name of an external application to + * display messages graphically. + */ + static void messageApp(const char *appName); + + }; + +#endif diff --git a/darkice/tags/darkice-0_17_1/src/main.cpp b/darkice/tags/darkice-0_17_1/src/main.cpp new file mode 100644 index 0000000..ace0328 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/src/main.cpp @@ -0,0 +1,227 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell DarkIce + + File : main.cpp + Version : $Revision$ + Author : $Author$ + Location : $Source$ + + Abstract : + + Program entry point + + Copyright notice: + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +------------------------------------------------------------------------------*/ + +/* ============================================================ include files */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_STDLIB_H +#include +#else +#error needs stdlib.h +#endif + +#include +#include + +#include "Ref.h" +#include "Exception.h" +#include "Util.h" +#include "DarkIce.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + +/*------------------------------------------------------------------------------ + * Show program usage + *----------------------------------------------------------------------------*/ +static void +showUsage ( std::ostream & os ); + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * Program entry point + *----------------------------------------------------------------------------*/ +int +main ( + int argc, + char * argv[] ) +{ + int res = -1; + + std::cout << "DarkIce " << VERSION + << " live audio streamer, http://darkice.sourceforge.net" + << std::endl + << "Copyright (c) 2000-2006, Tyrell Hungary, http://tyrell.hu" + << std::endl << std::endl; + + try { + const char * configFileName = 0; + unsigned int verbosity = 1; + int i; + const char opts[] = "hc:v:"; + + while ( (i = getopt( argc, argv, opts)) != -1 ) { + switch ( i ) { + case 'c': + configFileName = optarg; + break; + + case 'v': + verbosity = Util::strToL( optarg); + break; + + default: + case ':': + case '?': + case 'h': + showUsage( std::cout); + return 1; + } + } + + if ( !configFileName ) { + showUsage( std::cout); + throw Exception( __FILE__, __LINE__, + "no configuration file specified"); + } + + std::cout << "Using config file: " << configFileName << std::endl; + + std::ifstream configFile( configFileName); + Reporter::setReportVerbosity( verbosity ); + Reporter::setReportOutputStream( std::cout ); + Config config( configFile); + Ref di = new DarkIce( config); + + res = di->run(); + + } catch ( Exception & e ) { + std::cout << "DarkIce: " << e << std::endl << std::flush; + } + + return res; +} + + +/*------------------------------------------------------------------------------ + * Show program usage + *----------------------------------------------------------------------------*/ +static void +showUsage ( std::ostream & os ) +{ + os + << "usage: darkice [-v n] -c config.file" + << std::endl + << std::endl + << "options:" + << std::endl + << " -c config.file use configuration file config.file" + << std::endl + << " -v n verbosity level (0 = silent, 10 = loud)" + << std::endl + << " -h print this message and exit" + << std::endl + << std::endl; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.16 2006/01/25 22:47:15 darkeye + added mpeg2 support, thanks to Nicholas J Humfrey + + Revision 1.15 2005/04/14 11:24:42 darkeye + updated copyright notice to extend to 2005 + + Revision 1.14 2005/04/03 05:10:07 jbebel + Moved initialization of Reporter class so it would happen before + instantiation of Darkice class. Any logging that might be reported + during the construction of the Darkice class could not function. + Originally the Reporter initialization was done through the instance + of Darkice (which inherits Reporter), but that obviously isn't possible + before Darkice is instantiated. Since Reporter is largely a static class, + it is reasonable to call it via the scope resolution operator rather + than via an instance of the class, so that's what I did. + + Revision 1.13 2004/02/15 12:06:30 darkeye + added ALSA support, thanks to Christian Forster + + Revision 1.12 2003/02/09 15:09:41 darkeye + for version 0.13 + + Revision 1.11 2002/05/28 12:35:41 darkeye + code cleanup: compiles under gcc-c++ 3.1, using -pedantic option + + Revision 1.10 2002/02/20 15:08:52 darkeye + minor changes + + Revision 1.9 2001/09/11 15:05:21 darkeye + added Solaris support + + Revision 1.8 2001/09/02 12:24:29 darkeye + now displays usage info when no command line parameters given + + Revision 1.7 2001/08/30 17:25:56 darkeye + renamed configure.h to config.h + + Revision 1.6 2001/08/26 08:43:13 darkeye + added support for unlimited time encoding + + Revision 1.5 2000/11/15 18:08:43 darkeye + added multiple verbosity-level event reporting and verbosity command + line option + + Revision 1.4 2000/11/13 20:21:29 darkeye + added program version display on startup + + Revision 1.3 2000/11/13 19:38:55 darkeye + moved command line parameter parsing from DarkIce.cpp to main.cpp + + Revision 1.2 2000/11/08 17:29:50 darkeye + added configuration file reader + + Revision 1.1.1.1 2000/11/05 10:05:52 darkeye + initial version + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_17_1/stamp-h.in b/darkice/tags/darkice-0_17_1/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/darkice/tags/darkice-0_17_1/stamp-h.in @@ -0,0 +1 @@ +timestamp