diff --git a/darkice/tags/darkice-0_10/AUTHORS b/darkice/tags/darkice-0_10/AUTHORS new file mode 100644 index 0000000..a2b89b9 --- /dev/null +++ b/darkice/tags/darkice-0_10/AUTHORS @@ -0,0 +1,16 @@ +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 + diff --git a/darkice/tags/darkice-0_10/COPYING b/darkice/tags/darkice-0_10/COPYING new file mode 100644 index 0000000..598598b --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/ChangeLog b/darkice/tags/darkice-0_10/ChangeLog new file mode 100644 index 0000000..5c3ef40 --- /dev/null +++ b/darkice/tags/darkice-0_10/ChangeLog @@ -0,0 +1,94 @@ +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_10/INSTALL b/darkice/tags/darkice-0_10/INSTALL new file mode 100644 index 0000000..9c330dc --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/INSTALL.lame b/darkice/tags/darkice-0_10/INSTALL.lame new file mode 100644 index 0000000..f49d27c --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/INSTALL.vorbis b/darkice/tags/darkice-0_10/INSTALL.vorbis new file mode 100644 index 0000000..233cd26 --- /dev/null +++ b/darkice/tags/darkice-0_10/INSTALL.vorbis @@ -0,0 +1,39 @@ +Installing Ogg Vorbis +--------------------- + +To install DarkIce, you need the Ogg Vorbis 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.0rc3.tar.gz and libvorbis-1.0rc3.tar.gz. Go to the +directory where you saved them, and issue the following commands: + +tar xfz libogg-1.0rc3.tar.gz +cd libogg-1.0rc3 +./configure --prefix=/usr +make +make install +cd .. + +tar xfz libvorbis-1.0rc3.tar.gz +cd libvorbis-1.0rc3 +./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_10/Makefile.am b/darkice/tags/darkice-0_10/Makefile.am new file mode 100644 index 0000000..ecff092 --- /dev/null +++ b/darkice/tags/darkice-0_10/Makefile.am @@ -0,0 +1,16 @@ +KDOC_DIR=kdoc + +SUBDIRS = src man + +sysconf_DATA = darkice.cfg + +EXTRA_DIST = $(KDOC_DIR) darkice.cfg INSTALL.lame INSTALL.vorbis + +$(KDOC_DIR): kdocs + +kdocs: src kdocs_clean + cd src; kdoc --private --strip-h-path --name DarkIce --outputdir ../$(KDOC_DIR)/ *.h + +kdocs_clean: + rm -rf $(KDOC_DIR) + diff --git a/darkice/tags/darkice-0_10/NEWS b/darkice/tags/darkice-0_10/NEWS new file mode 100644 index 0000000..a215818 --- /dev/null +++ b/darkice/tags/darkice-0_10/NEWS @@ -0,0 +1,60 @@ +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_10/README b/darkice/tags/darkice-0_10/README new file mode 100644 index 0000000..d901462 --- /dev/null +++ b/darkice/tags/darkice-0_10/README @@ -0,0 +1,40 @@ +DarkIce live audio streamer, http://darkice.sourceforge.net +Copyright (c) 2000-2001, Tyrell Hungary, http://tyrell.hu + + +Contents +-------- + +1. What is DarkIce? +2. Compiling and installing + + +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. + + +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 + + diff --git a/darkice/tags/darkice-0_10/TODO b/darkice/tags/darkice-0_10/TODO new file mode 100644 index 0000000..0aa88d4 --- /dev/null +++ b/darkice/tags/darkice-0_10/TODO @@ -0,0 +1,8 @@ +o change Ref to follow inheritance +o make a master config file, and a small one ? +o reconnect to server if connection is dropped +o add support for multiple servers for one stream ? +o libtoolize ? +o revisit real-time scheduling and one-thread-per-connection +o look into performance +o create proper error-reporting module diff --git a/darkice/tags/darkice-0_10/acinclude.m4 b/darkice/tags/darkice-0_10/acinclude.m4 new file mode 100644 index 0000000..f905328 --- /dev/null +++ b/darkice/tags/darkice-0_10/acinclude.m4 @@ -0,0 +1,55 @@ +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 +]) + + diff --git a/darkice/tags/darkice-0_10/configure.in b/darkice/tags/darkice-0_10/configure.in new file mode 100644 index 0000000..00d4415 --- /dev/null +++ b/darkice/tags/darkice-0_10/configure.in @@ -0,0 +1,112 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(src/DarkIce.cpp) +AM_INIT_AUTOMAKE(darkice, 0.10) + +AM_CONFIG_HEADER(config.h) + +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) +AC_HAVE_HEADERS(sys/soundcard.h sys/audio.h) +AC_HEADER_SYS_WAIT() + +AC_TYPE_PID_T() +AC_TYPE_SIZE_T() + +AC_CHECK_LIB( socket, socket) +AC_CHECK_LIB( nsl, gethostbyname) +AC_CHECK_LIB( rt, sched_getscheduler) + +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 + LAME_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 make sure at least one of lame and vorbis present +if test "x${LAME_LDFLAGS}" = "x" -a "x${VORBIS_LDFLAGS}" = "x" ; then + AC_MSG_ERROR( [neither lame nor Ogg Vorbis configured]) +fi + + +AC_OUTPUT(Makefile src/Makefile man/Makefile) + diff --git a/darkice/tags/darkice-0_10/darkice.cfg b/darkice/tags/darkice-0_10/darkice.cfg new file mode 100644 index 0000000..0547de9 --- /dev/null +++ b/darkice/tags/darkice-0_10/darkice.cfg @@ -0,0 +1,80 @@ +# 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 + +# 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_10/install-sh b/darkice/tags/darkice-0_10/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/man/Makefile.am b/darkice/tags/darkice-0_10/man/Makefile.am new file mode 100644 index 0000000..8406ddd --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/man/darkice.1 b/darkice/tags/darkice-0_10/man/darkice.1 new file mode 100644 index 0000000..61cea60 --- /dev/null +++ b/darkice/tags/darkice-0_10/man/darkice.1 @@ -0,0 +1,106 @@ +.TH darkice 1 "April 13, 2002" "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 +.B DarkIce +is an +.B IceCast +, +.B IceCast2 +and +.B 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 +.B IceCast +and/or +.B ShoutCast +servers, the Ogg Vorbis stream to one or more +.B IceCast2 +servers. + +.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. + +.B DarkIce +uses the +.B Lame +mp3 encoder as a library to encode audio intput to mp3, and uses the +.B Ogg Vorbis +library to encode into Ogg Vorbis. + +.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 exists. + + +.SH BUGS +.PP +Lots of bugs. + + +.SH "SEE ALSO" +darkice.cfg(5) + + +.SH AUTHOR +Akos Maroy +.I + + +.SH ACKNOWLEDGEMENTS +Some contributions by Jim Crilly +.I +and Tom Gray +.I + +Ogg Vorbis encoding code based on the contribution of aNa|0Gue +.I + +BSD porting help from Robin P. Blanchard +.I + +CBR, ABR and VBR and encoding quality setting feature from Nicu Pavel +.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_10/man/darkice.cfg.5 b/darkice/tags/darkice-0_10/man/darkice.cfg.5 new file mode 100644 index 0000000..9f012f2 --- /dev/null +++ b/darkice/tags/darkice-0_10/man/darkice.cfg.5 @@ -0,0 +1,573 @@ +.TH darkice.cfg 5 "April 13, 2002" "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 +.B [input] + +This section describes the input (required). + +Required values: + +.TP +.I device +OSS DSP audio device to record from (e.g. /dev/dsp) +.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 +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 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 lowpass +Lowpass filter setting for the lame encoder. 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. 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. Currently the only supported value here is 'vorbis'. +.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. +.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 mp3 output. 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 localDumpFile +Dump the same Ogg Vorbis data sent to the +.B IceCast2 +server to this local file. + +.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 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. 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. 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. + +.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' or 'vorbis'. +.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. 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. 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 +.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. +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 +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_10/missing b/darkice/tags/darkice-0_10/missing new file mode 100755 index 0000000..7789652 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/mkinstalldirs b/darkice/tags/darkice-0_10/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/rpm/darkice.spec b/darkice/tags/darkice-0_10/rpm/darkice.spec new file mode 100644 index 0000000..65cd7a6 --- /dev/null +++ b/darkice/tags/darkice-0_10/rpm/darkice.spec @@ -0,0 +1,143 @@ +#------------------------------------------------------------------------------- +# +# Copyright (c) 2000 Tyrell Corporation. All rights reserved. +# +# Tyrell DarkIce +# +# File : darkice.spec +# Version : $Revision$ +# Author : $Author$ +# Location : $Source$ +# +# Abstract : +# +# Specification file to build RPM packages of DarkIce +# +# 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. +# +#------------------------------------------------------------------------------- + +# ===================================================================== preamble +Summary : DarkIce live IceCast / ShoutCast streamer +Name: darkice +Vendor: Tyrell Hungary +Packager: Akos Maroy +Version: 0.10 +Release: 1 +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 +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 stage +%prep +%setup + + +# ================================================================== build stage +%build +%configure +make all + + +# ================================================================ install stage +%install +%makeinstall + + +# ========================================================== pre-install scripts +%pre + + +# ========================================================= post-install scripts +%post + + +# ======================================================================== clean +%clean +rm -rf $RPM_BUILD_ROOT +make clean + + +# =========================================================== main package files +%files +%defattr (-, root, root) +%doc COPYING ChangeLog README TODO AUTHORS +%config %{_sysconfdir}/darkice.cfg +%{_bindir}/darkice +%{_mandir}/man1/darkice.1* +%{_mandir}/man5/darkice.cfg.5* + + +# =================================================================== change log +# +# $Log$ +# Revision 1.14 2002/07/20 16:46:12 darkeye +# for version 0.10 +# +# Revision 1.13 2002/04/09 13:10:43 darkeye +# resolved memory leak issue introduced in 0.9 +# +# Revision 1.12 2002/03/28 17:11:18 darkeye +# added file AUTHORS to set of distributed files +# +# Revision 1.11 2002/03/28 16:56:14 darkeye +# for version 0.9 +# +# Revision 1.10 2002/02/20 14:26:51 darkeye +# version 0.8 +# +# 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:48:03 darkeye +# for new version +# +# Revision 1.7 2001/09/18 18:00:02 darkeye +# removed --enable-static configure option +# +# Revision 1.6 2001/09/18 17:35:15 darkeye +# for version 0.6 +# +# Revision 1.5 2001/09/13 05:06:41 darkeye +# removed references to SourceForget FTP sites, as they are phased out +# +# Revision 1.4 2001/09/09 12:26:33 darkeye +# updated to reflect that DarkIce is now both an IceCast and ShoutCast streamer +# +# Revision 1.3 2001/09/09 11:48:09 darkeye +# added man page darkice.cfg.5 +# +# Revision 1.2 2001/09/02 14:44:14 darkeye +# added system level configuration file +# +# Revision 1.1 2001/09/02 12:46:05 darkeye +# added RPM package creation scripts +# +# + diff --git a/darkice/tags/darkice-0_10/rpm/lame.spec b/darkice/tags/darkice-0_10/rpm/lame.spec new file mode 100644 index 0000000..71c770d --- /dev/null +++ b/darkice/tags/darkice-0_10/rpm/lame.spec @@ -0,0 +1,148 @@ +#------------------------------------------------------------------------------- +# +# 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.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_10/src/AudioEncoder.h b/darkice/tags/darkice-0_10/src/AudioEncoder.h new file mode 100644 index 0000000..b7dd035 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/AudioEncoder.h @@ -0,0 +1,482 @@ +/*------------------------------------------------------------------------------ + + 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.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 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.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_10/src/AudioSource.h b/darkice/tags/darkice-0_10/src/AudioSource.h new file mode 100644 index 0000000..a08f631 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/AudioSource.h @@ -0,0 +1,272 @@ +/*------------------------------------------------------------------------------ + + 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 + + +/* ============================================================ include files */ + +#include "Source.h" + + +/* ================================================================ constants */ + + +/* =================================================================== macros */ + + +/* =============================================================== data types */ + +/** + * Audio data input + * + * @author $Author$ + * @version $Revision$ + */ +class AudioSource : public Source +{ + 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 source 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 () = 0; + + /** + * 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; + } +}; + + +/* ================================================= external data structures */ + +/*------------------------------------------------------------------------------ + * Determine the kind of audio device based on the system + *----------------------------------------------------------------------------*/ +#if defined( HAVE_SYS_SOUNDCARD_H ) + +// we have an OSS DSP sound source device available +#define SUPPORT_OSS_DSP +#include "OssDspSource.h" +typedef class OssDspSource DspSource; + +#elif defined( HAVE_SYS_AUDIO_H ) + +// we have a Solaris DSP sound device available +#define SUPPORT_SOLARIS_DSP +#include "SolarisDspSource.h" +typedef class SolarisDspSource DspSource; + +#else + +// there was no DSP audio system found +#error No DSP audio input device found on system + +#endif + + +/* ====================================================== function prototypes */ + + + +#endif /* AUDIO_SOURCE_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/BufferedSink.cpp b/darkice/tags/darkice-0_10/src/BufferedSink.cpp new file mode 100644 index 0000000..b69668b --- /dev/null +++ b/darkice/tags/darkice-0_10/src/BufferedSink.cpp @@ -0,0 +1,392 @@ +/*------------------------------------------------------------------------------ + + 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 + // if 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.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_10/src/BufferedSink.h b/darkice/tags/darkice-0_10/src/BufferedSink.h new file mode 100644 index 0000000..64d357c --- /dev/null +++ b/darkice/tags/darkice-0_10/src/BufferedSink.h @@ -0,0 +1,415 @@ +/*------------------------------------------------------------------------------ + + 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 ) { + reportEvent( 4, "BufferedSink, new peak:", peak); + reportEvent( 4, "BufferedSink, remaining:", bufferSize - peak); + peak = u; + } + } + + /** + * 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 ) + { + 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.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_10/src/CastSink.cpp b/darkice/tags/darkice-0_10/src/CastSink.cpp new file mode 100644 index 0000000..dc3368e --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/CastSink.h b/darkice/tags/darkice-0_10/src/CastSink.h new file mode 100644 index 0000000..09e55ae --- /dev/null +++ b/darkice/tags/darkice-0_10/src/CastSink.h @@ -0,0 +1,497 @@ +/*------------------------------------------------------------------------------ + + 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->isOpen(); + } + + /** + * 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.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_10/src/Config.cpp b/darkice/tags/darkice-0_10/src/Config.cpp new file mode 100644 index 0000000..9286278 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Config.cpp @@ -0,0 +1,206 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Config + + File : Config.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 "Config.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.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_10/src/Config.h b/darkice/tags/darkice-0_10/src/Config.h new file mode 100644 index 0000000..0259af6 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Config.h @@ -0,0 +1,240 @@ +/*------------------------------------------------------------------------------ + + Copyright (c) 2000 Tyrell Corporation. All rights reserved. + + Tyrell Config + + File : Config.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 line the line to read. + * @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.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_10/src/ConfigSection.cpp b/darkice/tags/darkice-0_10/src/ConfigSection.cpp new file mode 100644 index 0000000..929cc20 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/ConfigSection.h b/darkice/tags/darkice-0_10/src/ConfigSection.h new file mode 100644 index 0000000..a20dc47 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/Connector.cpp b/darkice/tags/darkice-0_10/src/Connector.cpp new file mode 100644 index 0000000..5ad455e --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Connector.cpp @@ -0,0 +1,370 @@ +/*------------------------------------------------------------------------------ + + 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 ) { + + sinks[0] = 0; + delete[] sinks; + sinks = 0; + + 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; + unsigned char * buf = new unsigned char[bufSize]; + + if ( numSinks == 0 ) { + return 0; + } + + if ( bufSize == 0 ) { + return 0; + } + + 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 { + e = sinks[u]->write( buf, d); + } catch ( Exception & e ) { + sinks[u]->close(); + detach( sinks[u].get() ); + /* with the call to detach, numSinks gets 1 lower, + * and the next sink comes to sinks[u] */ + --u; + + reportEvent( 4, + "Connector :: transfer, sink removed, remaining", + numSinks); + + if ( numSinks == 0 ) { + reportEvent( 4, + "Connector :: transfer, no more sinks"); + break; + } + } + } + } + + 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.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_10/src/Connector.h b/darkice/tags/darkice-0_10/src/Connector.h new file mode 100644 index 0000000..903e999 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Connector.h @@ -0,0 +1,282 @@ +/*------------------------------------------------------------------------------ + + 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: + + /** + * The source to read from. + */ + Ref source; + + /** + * The sinks to connect the source to. + */ + Ref * sinks; + + /** + * Total number of sinks. + */ + unsigned int numSinks; + + /** + * 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: + + /** + * Default constructor. Always throws an Exception. + * + * @exception Exception + */ + inline + Connector ( void ) throw ( Exception ) + { + throw Exception( __FILE__, __LINE__); + } + + + 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 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 + */ + void + attach ( Sink * sink ) throw ( Exception ); + + /** + * 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 + */ + bool + detach ( 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 + */ + 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 + */ + 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 + */ + void + close ( void ) throw ( Exception ); +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* CONNECTOR_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/DarkIce.cpp b/darkice/tags/darkice-0_10/src/DarkIce.cpp new file mode 100644 index 0000000..c2bf526 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/DarkIce.cpp @@ -0,0 +1,1076 @@ +/*------------------------------------------------------------------------------ + + 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 "DarkIce.h" + +#ifdef HAVE_LAME_LIB +#include "LameLibEncoder.h" +#endif + +#ifdef HAVE_VORBIS_LIB +#include "VorbisLibEncoder.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; + 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); + + + // the [input] section + if ( !(cs = config.get( "input")) ) { + throw Exception( __FILE__, __LINE__, "no section [general] 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 = new DspSource( device, + sampleRate, + bitsPerSample, + channel ); + encConnector = new Connector( dsp.get()); + + 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; + } + +#ifndef HAVE_LAME_LIB + throw Exception( __FILE__, __LINE__, + "DarkIce not compiled with lame support, " + "thus can't connect to IceCast 1.x, stream: ", + stream); +#else + + const char * str; + + unsigned int sampleRate = 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; + + 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"); + } + if ( 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 ( 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; + + localDumpName = cs->get( "localDumpFile"); + + // go on and create the things + + // check for and create the local dump file if needed + if ( localDumpName != 0 ) { + localDumpFile = new FileSink( localDumpName); + if ( !localDumpFile->exists() ) { + if ( !localDumpFile->create() ) { + reportEvent( 1, "can't create local dump file", + localDumpName); + localDumpFile = 0; + } + } + } + + // encoder related stuff + unsigned int bs = bufferSecs * + (dsp->getBitsPerSample() / 8) * + dsp->getChannel() * + dsp->getSampleRate(); + reportEvent( 6, "using buffer size", bs); + + // 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 ); + + audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel(), + lowpass, + highpass ); + + encConnector->attach( audioOuts[u].encoder.get()); +#endif // HAVE_LAME_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; + 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 * name = 0; + const char * description = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; + + 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; + // TODO: enable this format in the future, when icecast2 + // supports it as well + throw Exception( __FILE__, __LINE__, + "unsupported stream format: ", str); + } else { + throw Exception( __FILE__, __LINE__, + "unsupported stream format: ", str); + } + + str = cs->get( "sampleRate"); + sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); + + // determine fixed bitrate or variable bitrate quality + 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 ( 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; + localDumpName = cs->get( "localDumpFile"); + + // go on and create the things + + // check for and create the local dump file if needed + if ( localDumpName != 0 ) { + localDumpFile = new FileSink( localDumpName); + if ( !localDumpFile->exists() ) { + if ( !localDumpFile->create() ) { + reportEvent( 1, "can't create local dump file", + localDumpName); + localDumpFile = 0; + } + } + } + + // encoder related stuff + unsigned int bs = bufferSecs * + (dsp->getBitsPerSample() / 8) * + dsp->getChannel() * + dsp->getSampleRate(); + reportEvent( 6, "using buffer size", bs); + + // 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 ); + + 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, + dsp->getChannel() ); +#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() ); +#endif // HAVE_VORBIS_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; + 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; + + 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"); + } + if ( 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 ( 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"); + localDumpName = cs->get( "localDumpFile"); + + // go on and create the things + + // check for and create the local dump file if needed + if ( localDumpName != 0 ) { + localDumpFile = new FileSink( localDumpName); + if ( !localDumpFile->exists() ) { + if ( !localDumpFile->create() ) { + reportEvent( 1, "can't create local dump file", + localDumpName); + localDumpFile = 0; + } + } + } + + // encoder related stuff + unsigned int bs = bufferSecs * + (dsp->getBitsPerSample() / 8) * + dsp->getChannel() * + dsp->getSampleRate(); + reportEvent( 6, "using buffer size", bs); + + // 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 ); + + audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel(), + 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") ) { + 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"); + } + if ( 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 ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + + 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_LAME_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, + quality, + dsp->getSampleRate(), + dsp->getChannel() ); +#endif // HAVE_VORBIS_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 ) +{ + 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"); + } +} + + +/*------------------------------------------------------------------------------ + * 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 ) +{ + 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"); + } +} + + +/*------------------------------------------------------------------------------ + * 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"); + setRealTimeScheduling(); + encode(); + setOriginalScheduling(); + reportEvent( 3, "encoding ends"); + + return 0; +} + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/DarkIce.h b/darkice/tags/darkice-0_10/src/DarkIce.h new file mode 100644 index 0000000..19a3181 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/DarkIce.h @@ -0,0 +1,362 @@ +/*------------------------------------------------------------------------------ + + 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 "Config.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; + + /** + * 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.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_10/src/Exception.cpp b/darkice/tags/darkice-0_10/src/Exception.cpp new file mode 100644 index 0000000..5bb40e2 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/Exception.h b/darkice/tags/darkice-0_10/src/Exception.h new file mode 100644 index 0000000..2f58e49 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/FileCast.cpp b/darkice/tags/darkice-0_10/src/FileCast.cpp new file mode 100644 index 0000000..1ce1684 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/FileCast.h b/darkice/tags/darkice-0_10/src/FileCast.h new file mode 100644 index 0000000..c61afbf --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/FileSink.cpp b/darkice/tags/darkice-0_10/src/FileSink.cpp new file mode 100644 index 0000000..c6c369c --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/FileSink.h b/darkice/tags/darkice-0_10/src/FileSink.h new file mode 100644 index 0000000..01bd562 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/IceCast.cpp b/darkice/tags/darkice-0_10/src/IceCast.cpp new file mode 100644 index 0000000..5c8f810 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/IceCast.h b/darkice/tags/darkice-0_10/src/IceCast.h new file mode 100644 index 0000000..35d95ef --- /dev/null +++ b/darkice/tags/darkice-0_10/src/IceCast.h @@ -0,0 +1,289 @@ +/*------------------------------------------------------------------------------ + + 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 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.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_10/src/IceCast2.cpp b/darkice/tags/darkice-0_10/src/IceCast2.cpp new file mode 100644 index 0000000..b95badc --- /dev/null +++ b/darkice/tags/darkice-0_10/src/IceCast2.cpp @@ -0,0 +1,238 @@ +/*------------------------------------------------------------------------------ + + 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 + + +/* =============================================== 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]; + + 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 = " ICE/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: + str = "audio/mpeg"; + break; + + case oggVorbis: + str = "application/x-ogg"; + break; + + default: + throw Exception( __FILE__, __LINE__, + "unsupported stream format", format); + break; + } + sink->write( str, strlen( str)); + + /* send the ice- headers */ + str = "\nice-password: "; + sink->write( str, strlen(str)); + str = getPassword(); + sink->write( str, strlen(str)); + + 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(); + + return true; +} + + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/IceCast2.h b/darkice/tags/darkice-0_10/src/IceCast2.h new file mode 100644 index 0000000..0590c58 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/IceCast2.h @@ -0,0 +1,285 @@ +/*------------------------------------------------------------------------------ + + 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, oggVorbis }; + + + 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 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 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.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_10/src/LameLibEncoder.cpp b/darkice/tags/darkice-0_10/src/LameLibEncoder.cpp new file mode 100644 index 0000000..e606350 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/LameLibEncoder.cpp @@ -0,0 +1,432 @@ +/*------------------------------------------------------------------------------ + + 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(); + } + + 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, + getInChannel() == 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; + int q = int (d + 0.499999); + + 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; + int q = int (d + 0.499999); + + 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" ); + } + + lame_print_config( lameGlobalFlags); + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "lame lib opening underlying sink error"); + } + + return true; +} + + +/*------------------------------------------------------------------------------ + * Write data to the encoder + *----------------------------------------------------------------------------*/ +unsigned int +LameLibEncoder :: write ( const void * buf, + unsigned int len ) throw ( Exception ) +{ + if ( !isOpen() ) { + return 0; + } + + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int channels = getInChannel(); + + if ( channels != 1 && channels != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of channels for the encoder", + channels ); + } + + unsigned int sampleSize = (bitsPerSample / 8) * channels; + 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, channels); + } else if ( bitsPerSample == 16 ) { + Util::conv16( b, + processed, + leftBuffer, + rightBuffer, + channels, + 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 + unsigned int mp3Size = (unsigned int) (1.25 * nSamples + 7200); + unsigned char * mp3Buf = new unsigned char[mp3Size]; + int ret; + + ret = lame_encode_buffer( lameGlobalFlags, + leftBuffer, + channels == 2 ? rightBuffer : leftBuffer, + nSamples, + mp3Buf, + mp3Size ); + + delete[] mp3Buf; + delete[] leftBuffer; + delete[] rightBuffer; + + if ( ret < 0 ) { + reportEvent( 3, "lame encoding error", ret); + return 0; + } + + unsigned int written = sink->write( mp3Buf, ret); + // 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; + } +} + + +#endif // HAVE_LAME_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/LameLibEncoder.h b/darkice/tags/darkice-0_10/src/LameLibEncoder.h new file mode 100644 index 0000000..4714726 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/LameLibEncoder.h @@ -0,0 +1,481 @@ +/*------------------------------------------------------------------------------ + + 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->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() != getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "different in and out channels not supported"); + } + } + + /** + * 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 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 inBigEndian shows if the input is big or little endian + * @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.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_10/src/Makefile.am b/darkice/tags/darkice-0_10/src/Makefile.am new file mode 100644 index 0000000..fa8e0b4 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Makefile.am @@ -0,0 +1,55 @@ +bin_PROGRAMS = darkice +CXXFLAGS = -O2 -pedantic -Wall +INCLUDES = @LAME_INCFLAGS@ @VORBIS_INCFLAGS@ +LDADD = @LAME_LDFLAGS@ @VORBIS_LDFLAGS@ + +darkice_SOURCES = AudioEncoder.h\ + AudioSource.h\ + BufferedSink.cpp\ + BufferedSink.h\ + CastSink.cpp\ + CastSink.h\ + FileSink.h\ + FileSink.cpp\ + Connector.cpp\ + Connector.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\ + VorbisLibEncoder.cpp\ + VorbisLibEncoder.h\ + 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\ + Config.h\ + Config.cpp\ + Reporter.h\ + Reporter.cpp\ + main.cpp + diff --git a/darkice/tags/darkice-0_10/src/OssDspSource.cpp b/darkice/tags/darkice-0_10/src/OssDspSource.cpp new file mode 100644 index 0000000..31be6d3 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/OssDspSource.cpp @@ -0,0 +1,325 @@ +/*------------------------------------------------------------------------------ + + 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$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * 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_LE; + 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.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_10/src/OssDspSource.h b/darkice/tags/darkice-0_10/src/OssDspSource.h new file mode 100644 index 0000000..281ce56 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/OssDspSource.h @@ -0,0 +1,283 @@ +/*------------------------------------------------------------------------------ + + 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 source the object to copy. + * @exception Exception + */ + inline + OssDspSource ( const OssDspSource & ds ) throw ( Exception ) + : AudioSource( ds ) + { + init( ds.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 false + */ + virtual inline bool + isBigEndian ( void ) const throw () + { + return false; + } + + /** + * 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.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_10/src/Ref.h b/darkice/tags/darkice-0_10/src/Ref.h new file mode 100644 index 0000000..2e0968d --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Ref.h @@ -0,0 +1,317 @@ +/*------------------------------------------------------------------------------ + + 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 () + { + 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.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_10/src/Referable.h b/darkice/tags/darkice-0_10/src/Referable.h new file mode 100644 index 0000000..87ef065 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/Reporter.cpp b/darkice/tags/darkice-0_10/src/Reporter.cpp new file mode 100644 index 0000000..87621a0 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/Reporter.h b/darkice/tags/darkice-0_10/src/Reporter.h new file mode 100644 index 0000000..c5fd248 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Reporter.h @@ -0,0 +1,340 @@ +/*------------------------------------------------------------------------------ + + 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 unistdt.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. + */ + void + printPrefix( void ) throw () + { + if ( verbosity > prefixVerbosity ) { + char str[32]; + time_t now; + + now = time(NULL); + strftime( str, 32, "%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. + */ + inline void + setReportVerbosity ( unsigned int verbosity ) throw () + { + Reporter::verbosity = verbosity; + } + + /** + * Get the verbosity level. + * + * @return the current verbosity level. + */ + 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 + */ + inline void + setReportOutputStream ( std::ostream & os ) throw () + { + Reporter::os = &os; + } + + /** + * Get the output stream to report to. + * + * @return the output stream + */ + 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 + 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 + 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 + 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 + 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.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_10/src/ShoutCast.cpp b/darkice/tags/darkice-0_10/src/ShoutCast.cpp new file mode 100644 index 0000000..d10ac0a --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/ShoutCast.h b/darkice/tags/darkice-0_10/src/ShoutCast.h new file mode 100644 index 0000000..192b786 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/ShoutCast.h @@ -0,0 +1,271 @@ +/*------------------------------------------------------------------------------ + + 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 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.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_10/src/Sink.h b/darkice/tags/darkice-0_10/src/Sink.h new file mode 100644 index 0000000..fac29e6 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/SolarisDspSource.cpp b/darkice/tags/darkice-0_10/src/SolarisDspSource.cpp new file mode 100644 index 0000000..3aa12d5 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/SolarisDspSource.cpp @@ -0,0 +1,282 @@ +/*------------------------------------------------------------------------------ + + 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 + +#ifdef HAVE_SYS_AUDIO_H +#include +#else +#error need sys/audio.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; + running = false; +} + + +/*------------------------------------------------------------------------------ + * 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; + + 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; + } + + if ( !running ) { + /* ugly workaround to get the dsp into recording state */ + unsigned char b[getChannel()*getBitsPerSample()/8]; + + read( b, getChannel()*getBitsPerSample()/8); + } + + 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"); + } + + running = true; + return ret; +} + + +/*------------------------------------------------------------------------------ + * Close the audio source + *----------------------------------------------------------------------------*/ +void +SolarisDspSource :: close ( void ) throw ( Exception ) +{ + if ( !isOpen() ) { + return; + } + + ::close( fileDescriptor); + fileDescriptor = 0; + running = false; +} + +#endif // SUPPORT_SOLARIS_DSP + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + Revision 1.1 2001/09/11 15:05:21 darkeye + added Solaris support + + + +------------------------------------------------------------------------------*/ + diff --git a/darkice/tags/darkice-0_10/src/SolarisDspSource.h b/darkice/tags/darkice-0_10/src/SolarisDspSource.h new file mode 100644 index 0000000..5c8ce4b --- /dev/null +++ b/darkice/tags/darkice-0_10/src/SolarisDspSource.h @@ -0,0 +1,274 @@ +/*------------------------------------------------------------------------------ + + 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; + + /** + * Indicates wether the low-level Solaris DSP device is in a recording + * state. + */ + bool running; + + + 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 source the object to copy. + * @exception Exception + */ + inline + SolarisDspSource ( const SolarisDspSource & ds ) + throw ( Exception ) + : AudioSource( ds ) + { + init( ds.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 () + { + return true; + } + + /** + * 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.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_10/src/Source.h b/darkice/tags/darkice-0_10/src/Source.h new file mode 100644 index 0000000..a8cac63 --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/TcpSocket.cpp b/darkice/tags/darkice-0_10/src/TcpSocket.cpp new file mode 100644 index 0000000..619e93e --- /dev/null +++ b/darkice/tags/darkice-0_10/src/TcpSocket.cpp @@ -0,0 +1,375 @@ +/*------------------------------------------------------------------------------ + + 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 ) +{ + struct sockaddr_in addr; + struct hostent * pHostEntry; + + if ( isOpen() ) { + return false; + } + + 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]); + + 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 ) { + 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; + } + +// ret = send( sockfd, buf, len, MSG_DONTWAIT); + ret = send( sockfd, buf, len, MSG_NOSIGNAL); + + 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.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_10/src/TcpSocket.h b/darkice/tags/darkice-0_10/src/TcpSocket.h new file mode 100644 index 0000000..df8d4cb --- /dev/null +++ b/darkice/tags/darkice-0_10/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_10/src/Util.cpp b/darkice/tags/darkice-0_10/src/Util.cpp new file mode 100644 index 0000000..6977eb0 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Util.cpp @@ -0,0 +1,419 @@ +/*------------------------------------------------------------------------------ + + 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 + + +#include "Util.h" + + +/* =================================================== local data structures */ + + +/* ================================================ local constants & macros */ + +/*------------------------------------------------------------------------------ + * File identity + *----------------------------------------------------------------------------*/ +static const char fileid[] = "$Id$"; + + +/* =============================================== local function prototypes */ + + +/* ============================================================= module code */ + +/*------------------------------------------------------------------------------ + * 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; +} + + +/*------------------------------------------------------------------------------ + * Check wether two strings are equal + *----------------------------------------------------------------------------*/ +bool +Util :: strEq( const char * str1, + const char * str2 ) throw ( Exception ) +{ + if ( !str1 || !str2 ) { + throw Exception( __FILE__, __LINE__, "no str1 or no str2"); + } + + return !strcmp( str1, str2); +} + + +/*------------------------------------------------------------------------------ + * 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; +} + + +/*------------------------------------------------------------------------------ + * 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 ) +{ + 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 { + 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; + } + } +} + + +/*------------------------------------------------------------------------------ + * 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 ) +{ + 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.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_10/src/Util.h b/darkice/tags/darkice-0_10/src/Util.h new file mode 100644 index 0000000..c22b241 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/Util.h @@ -0,0 +1,311 @@ +/*------------------------------------------------------------------------------ + + 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: + + + 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 str 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 str 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. + * @return true if the two strings are equal, false othersize. + * @exception Exception + */ + static bool + strEq ( const char * str1, + const char * str2 ) 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 ); + + /** + * 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 ); + + /** + * 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 ); + +}; + + +/* ================================================= external data structures */ + + +/* ====================================================== function prototypes */ + + + +#endif /* UTIL_H */ + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/VorbisLibEncoder.cpp b/darkice/tags/darkice-0_10/src/VorbisLibEncoder.cpp new file mode 100644 index 0000000..c6fd28a --- /dev/null +++ b/darkice/tags/darkice-0_10/src/VorbisLibEncoder.cpp @@ -0,0 +1,357 @@ +/*------------------------------------------------------------------------------ + + 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 */ + +/*------------------------------------------------------------------------------ + * Open an encoding session + *----------------------------------------------------------------------------*/ +bool +VorbisLibEncoder :: open ( void ) + throw ( Exception ) +{ + int ret; + + if ( isOpen() ) { + close(); + } + + vorbis_info_init( &vorbisInfo); + + switch ( getOutBitrateMode() ) { + + case cbr: + ret = vorbis_encode_setup_managed( &vorbisInfo, + getInChannel(), + getOutSampleRate(), + -1, + getOutBitrate() * 1000, + -1) + || vorbis_encode_ctl( &vorbisInfo, OV_ECTL_RATEMANAGE_AVG, NULL) + || vorbis_encode_setup_init( &vorbisInfo); + if ( ret ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + break; + + case abr: + if ( (ret = vorbis_encode_init( &vorbisInfo, + getInChannel(), + getOutSampleRate(), + -1, + getOutBitrate() * 1000, + -1 )) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + break; + + case vbr: + if ( (ret = vorbis_encode_init_vbr( &vorbisInfo, + getInChannel(), + 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); + } + + // open the underlying sink + if ( !sink->open() ) { + throw Exception( __FILE__, __LINE__, + "vorbis lib opening underlying sink error"); + } + + // create an empty vorbis_comment structure + vorbis_comment_init( &vorbisComment); + + // 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() ) { + return 0; + } + + unsigned int bitsPerSample = getInBitsPerSample(); + unsigned int channels = getInChannel(); + + if ( channels != 1 && channels != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of channels for the encoder", + channels ); + } + + unsigned int 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 = totalSamples; + 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 / channels); + Util::conv( resampledBuffer, converted, vorbisBuffer, channels); + delete[] resampledBuffer; + + vorbis_analysis_wrote( &vorbisDspState, converted / channels); + + } 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; + } +} + + +#endif // HAVE_VORBIS_LIB + + +/*------------------------------------------------------------------------------ + + $Source$ + + $Log$ + 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_10/src/VorbisLibEncoder.h b/darkice/tags/darkice-0_10/src/VorbisLibEncoder.h new file mode 100644 index 0000000..94395dd --- /dev/null +++ b/darkice/tags/darkice-0_10/src/VorbisLibEncoder.h @@ -0,0 +1,471 @@ +/*------------------------------------------------------------------------------ + + 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 "Sink.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 mp3 data to + */ + Ref sink; + + /** + * Resample ratio + */ + double resampleRatio; + + /** + * aflibConverter object for possible resampling + */ + aflibConverter * converter; + + /** + * Initialize the object. + * + * @param sink the sink to send mp3 output to + * @exception Exception + */ + inline void + init ( Sink * sink ) throw ( Exception ) + { + this->sink = sink; + + if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getOutSampleRate() == getInSampleRate() ) { + resampleRatio = 1; + converter = 0; + } else { + resampleRatio = ( (double) getOutSampleRate() / + (double) getInSampleRate() ); + // open the aflibConverter in + // - high quality + // - not linear (quadratic) interpolation + // - not filter interpolation + converter = new aflibConverter( true, true, false); + } + + if ( getInChannel() != getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "different in and out channels not supported"); + } + + encoderOpen = false; + } + + /** + * De-initialize the object. + * + * @exception Exception + */ + inline void + strip ( void ) throw ( Exception ) + { + } + + /** + * 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 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. + * @exception Exception + */ + inline + VorbisLibEncoder ( 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 ) + throw ( Exception ) + + : AudioEncoder ( inSampleRate, + inBitsPerSample, + inChannel, + inBigEndian, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink); + } + + /** + * 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. + * @exception Exception + */ + inline + VorbisLibEncoder ( Sink * sink, + const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, + double outQuality, + unsigned int outSampleRate = 0, + unsigned int outChannel = 0 ) + throw ( Exception ) + + : AudioEncoder ( as, + outBitrateMode, + outBitrate, + outQuality, + outSampleRate, + outChannel ) + { + init( sink); + } + + /** + * 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()); + } + + /** + * 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()); + } + + return *this; + } + + /** + * 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.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_10/src/aflibConverter.cc b/darkice/tags/darkice-0_10/src/aflibConverter.cc new file mode 100644 index 0000000..5a2272e --- /dev/null +++ b/darkice/tags/darkice-0_10/src/aflibConverter.cc @@ -0,0 +1,735 @@ +/* + * 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@adnc.com) to make it + into a C++ class +*/ + + +#include +#include +#include +#include + +#include "aflibConverter.h" +#include "aflibConverterLargeFilter.h" +#include "aflibConverterSmallFilter.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++ = (HWORD) 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( + HWORD X[], + HWORD Y[], + double factor, + UWORD *Time, + UHWORD& Nx, + UHWORD Nout) +{ + HWORD iconst; + HWORD *Xp, *Ystart; + WORD v,x1,x2; + + double dt; /* Step through input signal */ + UWORD dtb; /* Fixed-point version of Dt */ + UWORD endTime; /* When Time reaches EndTime, return to user */ + UWORD start_sample, end_sample; + + dt = 1.0/factor; /* Output sampling period */ + dtb = (UWORD)(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( + HWORD X[], + HWORD Y[], + double factor, + UWORD *Time, + UHWORD& Nx, + UHWORD Nout, + UHWORD Nwing, + UHWORD LpScl, + HWORD Imp[], + HWORD ImpD[], + BOOL Interp) +{ + HWORD *Xp, *Ystart; + WORD v; + + double dt; /* Step through input signal */ + UWORD dtb; /* Fixed-point version of Dt */ + UWORD endTime; /* When Time reaches EndTime, return to user */ + UWORD start_sample, end_sample; + + dt = 1.0/factor; /* Output sampling period */ + dtb = (UWORD)(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, (HWORD)(*Time&Pmask),-1); + /* Perform right-wing inner product */ + v += FilterUp(Imp, ImpD, Nwing, Interp, Xp+1, + (HWORD)((-*Time)&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( + HWORD X[], + HWORD Y[], + double factor, + UWORD *Time, + UHWORD& Nx, + UHWORD Nout, + UHWORD Nwing, + UHWORD LpScl, + HWORD Imp[], + HWORD ImpD[], + BOOL Interp) +{ + HWORD *Xp, *Ystart; + WORD v; + + double dh; /* Step through filter impulse response */ + double dt; /* Step through input signal */ + UWORD endTime; /* When Time reaches EndTime, return to user */ + UWORD dhb, dtb; /* Fixed-point versions of Dh,Dt */ + UWORD start_sample, end_sample; + + dt = 1.0/factor; /* Output sampling period */ + dtb = (UWORD)(dt*(1<>Np; + Ystart = Y; + endTime = *Time + (1<>Np]; /* Ptr to current input sample */ + v = FilterUD(Imp, ImpD, Nwing, Interp, Xp, (HWORD)(*Time&Pmask), + -1, dhb); /* Perform left-wing inner product */ + v += FilterUD(Imp, ImpD, Nwing, Interp, Xp+1, (HWORD)((-*Time)&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 */ + HWORD inArray[], /* input data */ + HWORD outArray[]) /* output data */ +{ + UWORD Time2; /* Current time/pos in input sample */ +#if 0 + UHWORD Ncreep; +#endif + UHWORD Xp, Xoff, Xread; + int OBUFFSIZE = (int)(((double)IBUFFSIZE)*factor); + UHWORD Nout = 0, Nx; + UHWORD 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 - (UHWORD)(2*Xoff*factor); + else + maxOutput = outCount-Ycount; + + for (c = 0; c < nChans; c++) + { + Time2 = Time; + /* Resample stuff in input buffer */ + Nout=SrcLinear(X[c],Y[c],factor,&Time2,Nx,maxOutput); + } + 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] = Y[c][i]; + + total_inCount += Nx; + + } while (Ycount (OBUFFSIZE - (2*Xoff*factor)) ) + maxOutput = OBUFFSIZE - (UHWORD)(2*Xoff*factor); + else + maxOutput = outCount-Ycount; + + for (c = 0; c < nChans; c++) + { + Time2 = Time; + /* Resample stuff in input buffer */ + if (factor >= 1) { /* SrcUp() is faster if we can use it */ + Nout=SrcUp(X[c],Y[c],factor,&Time2,Nx,maxOutput,Nwing,LpScl,Imp,ImpD,interpFilt); + } + else { + Nout=SrcUD(X[c],Y[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] = Y[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 += (((WORD)*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); +} + + +WORD +aflibConverter::FilterUD( HWORD Imp[], HWORD ImpD[], + UHWORD Nwing, BOOL Interp, + HWORD *Xp, HWORD Ph, HWORD Inc, UHWORD dhb) +{ + HWORD a; + HWORD *Hp, *Hdp, *End; + WORD v, t; + UWORD Ho; + + v=0; + Ho = (Ph*(UWORD)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 += (((WORD)*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_10/src/aflibConverter.h b/darkice/tags/darkice-0_10/src/aflibConverter.h new file mode 100644 index 0000000..e8d9500 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/aflibConverter.h @@ -0,0 +1,245 @@ +/* + * 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@adnc.com) to make it + into a C++ class +*/ + + +#ifndef _AFLIBCONVERTER_H_ +#define _AFLIBCONVERTER_H_ + +#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) + +typedef char BOOL; +typedef short HWORD; +typedef unsigned short UHWORD; +typedef int WORD; +typedef unsigned int UWORD; +#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 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 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 */ + + int + resample( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + HWORD inArray[], /* input array data (length inCount * nChans) */ + HWORD 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 */ + HWORD inArray[], /* input data */ + HWORD *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 HWORD + WordToHword(WORD v, int scl) + { + HWORD out; + WORD llsb = (1<<(scl-1)); + v += llsb; /* round */ + v >>= scl; + if (v>MAX_HWORD) { +#ifdef DEBUG + if (pof == 0) + fprintf(stderr, "*** resample: sound sample overflow\n"); + else if ((pof % 10000) == 0) + fprintf(stderr, "*** resample: another ten thousand overflows\n"); + pof++; +#endif + v = MAX_HWORD; + } else if (v < MIN_HWORD) { +#ifdef DEBUG + if (nof == 0) + fprintf(stderr, "*** resample: sound sample (-) overflow\n"); + else if ((nof % 1000) == 0) + fprintf(stderr, "*** resample: another thousand (-) overflows\n"); + nof++; +#endif + v = MIN_HWORD; + } + out = (HWORD) v; + return out; + }; + + int + SrcLinear( + HWORD X[], + HWORD Y[], + double factor, + UWORD *Time, + UHWORD& Nx, + UHWORD Nout); + + int + SrcUp( + HWORD X[], + HWORD Y[], + double factor, + UWORD *Time, + UHWORD& Nx, + UHWORD Nout, + UHWORD Nwing, + UHWORD LpScl, + HWORD Imp[], + HWORD ImpD[], + BOOL Interp); + + int + SrcUD( + HWORD X[], + HWORD Y[], + double factor, + UWORD *Time, + UHWORD& Nx, + UHWORD Nout, + UHWORD Nwing, + UHWORD LpScl, + HWORD Imp[], + HWORD ImpD[], + BOOL Interp); + + WORD + FilterUp( + HWORD Imp[], + HWORD ImpD[], + UHWORD Nwing, + BOOL Interp, + HWORD *Xp, + HWORD Ph, + HWORD Inc); + + WORD + FilterUD( + HWORD Imp[], + HWORD ImpD[], + UHWORD Nwing, + BOOL Interp, + HWORD *Xp, + HWORD Ph, + HWORD Inc, + UHWORD dhb); + + int + resampleFast( /* number of output samples returned */ + int& inCount, /* number of input samples to convert */ + int outCount, /* number of output samples to compute */ + HWORD inArray[], /* input array data (length inCount * nChans) */ + HWORD 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 */ + HWORD inArray[], /* input array data (length inCount * nChans) */ + HWORD outArray[], /* output array data (length outCount * nChans) */ + HWORD Imp[], HWORD ImpD[], + UHWORD LpScl, UHWORD Nmult, UHWORD Nwing); + + +static HWORD SMALL_FILTER_IMP[]; +static HWORD LARGE_FILTER_IMP[]; + +bool interpFilt; +bool largeFilter; +bool linearInterp; +HWORD ** X; +HWORD ** Y; +UWORD Time; +double factor; +int nChans; +bool initial; + +}; + + +#endif diff --git a/darkice/tags/darkice-0_10/src/aflibConverterLargeFilter.h b/darkice/tags/darkice-0_10/src/aflibConverterLargeFilter.h new file mode 100644 index 0000000..61f4642 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/aflibConverterLargeFilter.h @@ -0,0 +1,16427 @@ +/* + * 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. + +*/ + +#define LARGE_FILTER_NMULT ((HWORD)65) +#define LARGE_FILTER_SCALE 14746 /* Unity-gain scale factor */ +#define LARGE_FILTER_NWING 8192 /* Filter table length */ + +HWORD 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 HWORD 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_10/src/aflibConverterSmallFilter.h b/darkice/tags/darkice-0_10/src/aflibConverterSmallFilter.h new file mode 100644 index 0000000..d1084d7 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/aflibConverterSmallFilter.h @@ -0,0 +1,4638 @@ +/* + * 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 + * + */ + +#define SMALL_FILTER_NMULT ((HWORD)13) +#define SMALL_FILTER_SCALE 13128 /* Unity-gain scale factor */ +#define SMALL_FILTER_NWING 1536 /* Filter table length */ + +HWORD 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 HWORD 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_10/src/main.cpp b/darkice/tags/darkice-0_10/src/main.cpp new file mode 100644 index 0000000..0182db3 --- /dev/null +++ b/darkice/tags/darkice-0_10/src/main.cpp @@ -0,0 +1,205 @@ +/*------------------------------------------------------------------------------ + + 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-2002, 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); + Config config( configFile); + Ref di = new DarkIce( config); + di->setReportVerbosity( verbosity ); + di->setReportOutputStream( std::cout ); + + 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.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_10/stamp-h.in b/darkice/tags/darkice-0_10/stamp-h.in new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/darkice/tags/darkice-0_10/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/darkice/tags/darkice-0_10/update-conf b/darkice/tags/darkice-0_10/update-conf new file mode 100755 index 0000000..3b0242b --- /dev/null +++ b/darkice/tags/darkice-0_10/update-conf @@ -0,0 +1,10 @@ +#!/bin/sh +# +# Update the automake / autoconf configuration +# + +rm -f config.cache config.log config.status +rm -f configure config.h config.h.in aclocal.m4 +rm -f Makefile Makefile.in */Makefile */Makefile.in +autoheader && automake && aclocal && autoheader && autoconf && ./configure +